diff --git a/.coderabbit.yaml b/.coderabbit.yaml
new file mode 100644
index 00000000..895a591c
--- /dev/null
+++ b/.coderabbit.yaml
@@ -0,0 +1,43 @@
+language: "ko-KR"
+
+reviews:
+ profile: "chill"
+ high_level_summary: true
+ poem: false
+
+ auto_review:
+ enabled: true
+ drafts: false
+ base_branches:
+ - "main"
+ - "develop"
+
+ request_changes_workflow: false
+
+ path_filters:
+ - "src/**"
+ - "!dist/**"
+ - "!pnpm-lock.yaml"
+ - "!build/**"
+ - "!**/*.lock"
+
+ path_instructions:
+ - path: "src/**"
+ instructions: >
+ 다음 핵심 영역에 집중하여 리뷰한다.
+ 1. 상태 관리: 서버 상태(React Query)와 전역 상태(Zustand)의 분리 여부 확인. useMutation, useQuery의 올바른 사용 확인.
+ 2. 구조와 책임 분리: 페이지에 비즈니스 로직이 과도하지 않은지 확인. 커스텀 훅으로의 분리 여부 검토.
+ 3. Hook 사용: useEffect 의존성 배열 및 불필요한 사용 검토. useCallback, useMemo의 적절한 사용.
+ 4. 타입 안정성: TypeScript 타입의 명확성 확인. any 사용 지양, 제네릭 활용 검토.
+ 5. 성능: 불필요한 리렌더링 체크. React.memo, useCallback 사용 검토.
+ 6. 에러 처리: API 실패 대응 및 사용자 피드백 적절성 검토. 에러 바운더리 사용 확인.
+ 7. 접근성: 시맨틱 HTML, ARIA 속성 사용 확인.
+
+chat:
+ auto_reply: true
+
+tone_instructions: >
+ 모든 리뷰는 반드시 한국어로, 팀원들에게 말하듯이 작성한다.
+ 구조, 상태 관리, 접근성, 성능, 안정성, 버그 중심으로 리뷰한다.
+ 피드백은 명확하고 구체적으로 작성하며, 문제의 원인과 개선 방법을 함께 제시한다.
+ 차분하고 전문적인 톤을 유지하되, 이해하기 쉽게 전달한다.
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..b8b97a4b
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,9 @@
+* text=auto eol=lf
+
+*.png binary
+*.jpg binary
+*.jpeg binary
+*.gif binary
+*.webp binary
+*.ico binary
+*.pdf binary
diff --git "a/.github/ISSUE_TEMPLATE/\342\231\273\357\270\217-refactor.md" "b/.github/ISSUE_TEMPLATE/\342\231\273\357\270\217-refactor.md"
index c74b1ba1..eb01bdfc 100644
--- "a/.github/ISSUE_TEMPLATE/\342\231\273\357\270\217-refactor.md"
+++ "b/.github/ISSUE_TEMPLATE/\342\231\273\357\270\217-refactor.md"
@@ -3,16 +3,19 @@ name: "♻️ Refactor"
about: "Code refactoring Template "
title: "♻️ [Refactor] "
labels: ♻️ Refactor
-assignees: ''
-
+assignees: ""
---
## 🛠️ Issue Description
-[//]: # (해당 이슈에 대한 설명을 작성해주세요.)
+
+[//]: # "해당 이슈에 대한 설명을 작성해주세요."
## 💭 Cause and effect
-[//]: # (코드 리팩토링을 하는 이유와 예상 결과를 작성해주세요.)
+
+[//]: # "코드 리팩토링을 하는 이유와 예상 결과를 작성해주세요."
### 📝 check-lists
-[//]: # (업무 체크리스트를 작성해주세요.)
+
+[//]: # "업무 체크리스트를 작성해주세요."
+
- [ ] Task1
diff --git "a/.github/ISSUE_TEMPLATE/\342\232\231\357\270\217-setting.md" "b/.github/ISSUE_TEMPLATE/\342\232\231\357\270\217-setting.md"
index 8ec7503a..bd527599 100644
--- "a/.github/ISSUE_TEMPLATE/\342\232\231\357\270\217-setting.md"
+++ "b/.github/ISSUE_TEMPLATE/\342\232\231\357\270\217-setting.md"
@@ -3,16 +3,19 @@ name: "⚙️ Setting"
about: "Development environment setup Template "
title: "⚙️ [Setting] "
labels: ⚙️ Setting
-assignees: ''
-
+assignees: ""
---
## 🛠️ Issue Description
-[//]: # (해당 이슈에 대한 설명을 작성해주세요.)
+
+[//]: # "해당 이슈에 대한 설명을 작성해주세요."
## 💭 Setting Environment
-[//]: # (세팅한 환경이 무엇인지, 어떤 방법으로 세팅할 예정인지 작성해주세요.)
+
+[//]: # "세팅한 환경이 무엇인지, 어떤 방법으로 세팅할 예정인지 작성해주세요."
### 📝 check-lists
-[//]: # (업무 체크리스트를 작성해주세요.)
+
+[//]: # "업무 체크리스트를 작성해주세요."
+
- [ ] Task1
diff --git "a/.github/ISSUE_TEMPLATE/\342\234\250-feature.md" "b/.github/ISSUE_TEMPLATE/\342\234\250-feature.md"
index 57b7637c..5a7cae7d 100644
--- "a/.github/ISSUE_TEMPLATE/\342\234\250-feature.md"
+++ "b/.github/ISSUE_TEMPLATE/\342\234\250-feature.md"
@@ -3,16 +3,19 @@ name: "✨ Feature"
about: "Feature Template "
title: "✨ [Feature] "
labels: ✨ Feature
-assignees: ''
-
+assignees: ""
---
## 🛠️ Issue Description
-[//]: # (해당 이슈에 대한 설명을 작성해주세요.)
+
+[//]: # "해당 이슈에 대한 설명을 작성해주세요."
## 💭 Functional role
-[//]: # (기능이 가지는 역할과 영향을 설명해주세요.)
+
+[//]: # "기능이 가지는 역할과 영향을 설명해주세요."
### 📝 check-lists
-[//]: # (업무 체크리스트를 작성해주세요.)
+
+[//]: # "업무 체크리스트를 작성해주세요."
+
- [ ] Task1
diff --git "a/.github/ISSUE_TEMPLATE/\360\237\214\217-deploy.md" "b/.github/ISSUE_TEMPLATE/\360\237\214\217-deploy.md"
index 31d7d133..a53a2b96 100644
--- "a/.github/ISSUE_TEMPLATE/\360\237\214\217-deploy.md"
+++ "b/.github/ISSUE_TEMPLATE/\360\237\214\217-deploy.md"
@@ -3,16 +3,19 @@ name: "🌏 Deploy"
about: "Deploy Template "
title: "🌏 [Deploy] "
labels: 🌏 Deploy
-assignees: ''
-
+assignees: ""
---
## 🛠️ Issue Description
-[//]: # (해당 이슈에 대한 설명을 작성해주세요.)
+
+[//]: # "해당 이슈에 대한 설명을 작성해주세요."
## 💭 How to deploy
-[//]: # (배포 방법에 대한 설명을 작성해주세요.)
+
+[//]: # "배포 방법에 대한 설명을 작성해주세요."
### 📝 check-lists
-[//]: # (업무 체크리스트를 작성해주세요.)
+
+[//]: # "업무 체크리스트를 작성해주세요."
+
- [ ] Task1
diff --git "a/.github/ISSUE_TEMPLATE/\360\237\220\236-bugFix.md" "b/.github/ISSUE_TEMPLATE/\360\237\220\236-bugFix.md"
index 67127596..7a0e439b 100644
--- "a/.github/ISSUE_TEMPLATE/\360\237\220\236-bugFix.md"
+++ "b/.github/ISSUE_TEMPLATE/\360\237\220\236-bugFix.md"
@@ -3,16 +3,19 @@ name: "🐞 BugFix"
about: "Something isn't working Template "
title: "🐞 [BugFix] "
labels: 🐞 BugFix
-assignees: ''
-
+assignees: ""
---
## 🛠️ Issue Description
-[//]: # (해당 이슈에 대한 설명을 작성해주세요.)
+
+[//]: # "해당 이슈에 대한 설명을 작성해주세요."
## 💭 Bug Description
-[//]: # (버그가 끼치는 영향과 문제를 설명해주세요.)
+
+[//]: # "버그가 끼치는 영향과 문제를 설명해주세요."
### 📝 check-lists
-[//]: # (업무 체크리스트를 작성해주세요.)
+
+[//]: # "업무 체크리스트를 작성해주세요."
+
- [ ] Task1
diff --git "a/.github/ISSUE_TEMPLATE/\360\237\223\203-docs.md" "b/.github/ISSUE_TEMPLATE/\360\237\223\203-docs.md"
index 30a75496..b1a2fab2 100644
--- "a/.github/ISSUE_TEMPLATE/\360\237\223\203-docs.md"
+++ "b/.github/ISSUE_TEMPLATE/\360\237\223\203-docs.md"
@@ -3,16 +3,19 @@ name: "📃 Docs"
about: "Documentation writing and editing (README.md, etc.) Template "
title: "📃 [Docs] "
labels: 📃 Docs
-assignees: ''
-
+assignees: ""
---
## 🛠️ Issue Description
-[//]: # (해당 이슈에 대한 설명을 작성해주세요.)
+
+[//]: # "해당 이슈에 대한 설명을 작성해주세요."
## 💭 Documents and objectives
-[//]: # (문서의 종류가 무엇인지, 목적이 무엇인지 작성해주세요.)
+
+[//]: # "문서의 종류가 무엇인지, 목적이 무엇인지 작성해주세요."
### 📝 check-lists
-[//]: # (업무 체크리스트를 작성해주세요.)
+
+[//]: # "업무 체크리스트를 작성해주세요."
+
- [ ] Task1
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 05870cee..29b459c0 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,33 +1,52 @@
+
+
## 🚨 관련 이슈
[//]: # "작성하실 때는 '#이슈 번호'를 남겨주시면 자동으로 링크가 생성됩니다."
## ✨ 변경사항
-[//]: # '어떤 변경사항이 있었나요? 체크해주세요 !'
+[//]: # "어떤 변경사항이 있었나요? 체크해주세요 !"
-- [ ] 🐞 BugFix Something isn't working
-- [ ] 💻 CrossBrowsing Browser compatibility
-- [ ] 🌏 Deploy Deploy
-- [ ] 🎨 Design Markup & styling
-- [ ] 📃 Docs Documentation writing and editing (README.md, etc.)
-- [ ] ✨ Feature Feature
-- [ ] 🔨 Refactor Code refactoring
-- [ ] ⚙️ Setting Development environment setup
-- [ ] ✅ Test Test related (storybook, jest, etc.)
+- [ ] 🐞 BugFix Something isn't working
+- [ ] 💻 CrossBrowsing Browser compatibility
+- [ ] 🌏 Deploy Deploy
+- [ ] 🎨 Design Markup & styling
+- [ ] 📃 Docs Documentation writing and editing (README.md, etc.)
+- [ ] ✨ Feature Feature
+- [ ] 🔨 Refactor Code refactoring
+- [ ] ⚙️ Setting Development environment setup
+- [ ] ✅ Test Test related (storybook, jest, etc.)
## ✏️ 작업 내용
-[//]: # '작업 내용을 작성해주세요. 스크린샷을 첨부해주셔도 좋습니다.'
+[//]: # "작업 내용을 작성해주세요. 스크린샷을 첨부해주셔도 좋습니다."
-- 작업 내용
+- 작업 내용
## 😅 미완성 작업
-[//]: # '없다면 N/A'
+[//]: # "없다면 N/A"
-- [ ] Task1
+- [ ] Task1
## 📢 논의 사항 및 참고 사항
-[//]: # '리뷰어가 알면 좋은 내용을 작성해주세요.'
+[//]: # "리뷰어가 알면 좋은 내용을 작성해주세요."
+
+> 💬 리뷰어 가이드 (P-Rules)
+> **P1: 필수 반영 (Critical)** - 버그 가능성, 컨벤션 위반. 해결 전 머지 불가.
+> **P2: 적극 권장 (Recommended)** - 더 나은 대안 제시. 가급적 반영 권장.
+> **P3: 제안 (Suggestion)** - 아이디어 공유. 반영 여부는 드라이버 자율.
+> **P4: 단순 확인/칭찬 (Nit)** - 사소한 오타, 칭찬 등 피드백.
diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml
new file mode 100644
index 00000000..f7ec135b
--- /dev/null
+++ b/.github/workflows/chromatic.yml
@@ -0,0 +1,56 @@
+name: Chromatic Deployment
+
+on:
+ push:
+ branches:
+ - "develop"
+ pull_request:
+ branches:
+ - develop
+
+jobs:
+ chromatic-deploy:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ pull-requests: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ cache: pnpm
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Run Chromatic
+ id: chromatic
+ uses: chromaui/action@latest
+ with:
+ projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
+ token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Comment Storybook URL on PR
+ if: github.event_name == 'pull_request'
+ uses: thollander/actions-comment-pull-request@v2
+ with:
+ message: |
+ ## 📚 Storybook 배포 완료
+
+ | 항목 | 링크 |
+ |------|------|
+ | 📖 Storybook | ${{ steps.chromatic.outputs.storybookUrl }} |
+ | 🔍 Chromatic | ${{ steps.chromatic.outputs.buildUrl }} |
+ comment_tag: storybook-url
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 87c4c4c4..a05741a8 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -15,15 +15,15 @@ jobs:
- name: Checkout source code
uses: actions/checkout@v4
+ - name: Install pnpm
+ run: npm install -g pnpm
+
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- - name: Install pnpm
- run: npm install -g pnpm
-
- name: Install dependencies
run: pnpm install --frozen-lockfile
diff --git a/.gitignore b/.gitignore
index 82abc0fb..e97d3b74 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,4 +23,14 @@ dist-ssr
*.sln
*.sw?
.env
-node_modules/
\ No newline at end of file
+node_modules/
+*storybook.log
+storybook-static
+
+# Claude Code
+.claude/
+.claude/skills
+.claude/agents
+
+# Local: Cursor commit message trailer stripper (keep on machine only)
+scripts/strip-cursor-attribution.mjs
diff --git a/.husky/commit-msg b/.husky/commit-msg
index 9ef41ae4..65e5a8ad 100755
--- a/.husky/commit-msg
+++ b/.husky/commit-msg
@@ -1 +1,2 @@
-pnpm commitlint --edit "$1"
+node scripts/strip-cursor-attribution.mjs "$1"
+pnpm exec commitlint --edit "$1"
diff --git a/.storybook/main.ts b/.storybook/main.ts
new file mode 100644
index 00000000..7ef96386
--- /dev/null
+++ b/.storybook/main.ts
@@ -0,0 +1,8 @@
+import type { StorybookConfig } from "@storybook/react-vite";
+
+const config: StorybookConfig = {
+ stories: ["../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
+ addons: ["@storybook/addon-essentials"],
+ framework: "@storybook/react-vite",
+};
+export default config;
diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx
new file mode 100644
index 00000000..86263cbb
--- /dev/null
+++ b/.storybook/preview.tsx
@@ -0,0 +1,24 @@
+import "../src/index.css";
+
+import { MemoryRouter } from "react-router-dom";
+import type { Preview } from "@storybook/react";
+
+const preview: Preview = {
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+ parameters: {
+ controls: {
+ matchers: {
+ color: /(background|color)$/i,
+ date: /Date$/i,
+ },
+ },
+ },
+};
+
+export default preview;
diff --git a/README.md b/README.md
index 265ceeff..07dc98f8 100644
--- a/README.md
+++ b/README.md
@@ -1,53 +1,163 @@
-# Where You Ad (Frontend)
+# WhereYouAd Frontend
+**2026 Capstone · Graduation Project**
-Where You Ad 서비스의 프론트엔드 리포지토리입니다.
+WhereYouAd는 **광고 성과 및 워크스페이스 관리를 효율적으로 지원하는 웹 서비스**입니다.
+본 레포지토리는 2026 캡스톤(졸업 프로젝트)을 위해 개발 중인 프론트엔드 애플리케이션으로,
+사용자 친화적인 대시보드 UI와 안정적인 상태 관리, 확장 가능한 아키텍처를 목표로 합니다.
-## 🛠 Tech Stack
+
+
+## 프로젝트 개요
+
+- **프로젝트명**: WhereYouAd
+- **목적**: 광고 및 워크스페이스 관리 서비스의 프론트엔드 구현
+- **성격**: 2026 캡스톤 디자인 · 졸업 프로젝트
+
+### 주요 기능
+
+- **광고 성과 지표 대시보드** 제공
+- 워크스페이스 **단위 광고 및 캠페인 관리**
+- **성과 데이터 시각화** 및 요약 리포트 제공
+- 사용자 인증 및 **권한 기반 접근 제어**
+
+
+### 기술 방향성
+- 빠른 화면 렌더링과 효율적인 데이터 패칭
+- 명확한 상태 관리 분리 (UI State / Server State)
+- 팀 협업을 고려한 컨벤션 및 코드 품질 관리
+
+
+
+## 팀 구성 (Frontend)
+
+|
[서제경](https://github.com/Seojegyeong)
| [박재선](https://github.com/jjjsun)
| [임예림](https://github.com/YermIm)
|
+| --- | --- | --- |
+| | | |
+| 프론트엔드TEAM LEADER
| 프론트엔드
| 프론트엔드
|
+
+
+
+
+## 기술 스택
### Core
-- **React 19**: 최신 리액트 기능을 활용한 UI 개발
-- **TypeScript**: 정적 타입 시스템을 통한 안정성 확보
-- **Vite**: 빠른 개발 서버 및 빌드 도구
+- **Framework**: React 19, TypeScript, Vite
+- **Routing**: react-router-dom (v7)
+
+### State Management
+- **Client State**: zustand
+- **Server State**: @tanstack/react-query
### Styling
-- **Tailwind CSS 4**: 유틸리티 퍼스트 CSS 프레임워크
+- **CSS Framework**: Tailwind CSS v4
+- **Utilities**: clsx
+- **SVG Handling**: vite-plugin-svgr
-### State Management & Data Fetching
-- **Zustand**: 전역 상태 관리
-- **TanStack Query (React Query)**: 비동기 서버 상태 관리
+### Form & Validation
+- **Form**: react-hook-form
+- **Schema Validation**: zod, @hookform/resolvers
+- **UI Feedback**: sonner (Toast)
-### Validation & Form
-- **React Hook Form**: 폼 상태 관리
-- **Zod**: 스키마 기반 유효성 검사
+### Code Quality & Collaboration
+- **Linting / Formatting**: ESLint (v9), Prettier
+- **Git Hooks**: husky, lint-staged
+- **Commit Convention**: commitlint (Conventional Commits)
-### Linting & Formatting
-- **ESLint**: 코드 린팅
-- **Prettier**: 코드 포맷팅
-- **Husky & lint-staged**: 커밋 시 자동 코드 점검 (Git Hook)
+
----
+## 개발 환경
-## 🚀 Getting Started
+- **Node.js**: v20.x.x (LTS 권장)
+- **패키지 매니저**: pnpm
-### 1. Prerequisites
-이 프로젝트는 **pnpm**을 패키지 매니저로 사용합니다.
+팀 내 개발 환경 차이를 최소화하기 위해 **Node 20 LTS 기준**으로 개발합니다.
-### 2. Installation
+
-```bash
-# 의존성 설치
-pnpm install
-```
+## 주요 스크립트
-### 3. Git Hook Setup (필수)
+| Script | 설명 |
+| --- | --- |
+| `pnpm run dev` | Vite 개발 서버 실행 |
+| `pnpm run build` | TypeScript + Vite 프로덕션 빌드 |
+| `pnpm run preview` | 빌드 결과 미리보기 |
+| `pnpm run lint` | ESLint 전체 검사 |
+| `pnpm run prepare` | Husky Git Hook 설정 |
+
+
-```bash
-# git 초기화 (필요한 경우)
-git init
-### 4. Running the App
+## 프로젝트 구조
+
+현재 프로젝트는 **기능별(Pages)** 및 **재사용성(Components/Layout)** 을 중심으로 구성되어 있습니다.
```bash
-# 개발 서버 실행
-pnpm dev
+src
+├── api/ # API 통신 및 요청 로직
+├── assets/ # 이미지, 아이콘, 폰트 등 정적 리소스
+├── components/ # UI 컴포넌트 모음
+├── constants/ # 상수 데이터 관리
+├── layout/ # 페이지 레이아웃 구조
+├── pages/ # 라우트 단위 페이지
+├── routes/ # 라우터 설정
+├── store/ # Zustand 전역 상태 관리
+├── types/ # 공통 타입 정의
+└── utils/ # 유틸리티 함수 및 헬퍼
```
+
+
+
+## 협업 컨벤션
+
+### 1. Branch Strategy
+- **main**: 배포 가능한 상태의 브랜치 (Production)
+- **develop**: 다음 버전을 위한 개발 브랜치
+- **feature/#[이슈번호]**: 새로운 기능 개발 브랜치 (예: `feature/#1`)
+
+
+
+### 2. Commit Convention
+Angular Commit Convention을 따르며, `commitlint`로 관리됩니다.
+
+`type: subject`
+
+| Type | 설명 |
+| --- | --- |
+| `feat` | 새로운 기능 추가 |
+| `fix` | 버그 수정 |
+| `docs` | 문서 수정 (README 등) |
+| `style` | 코드 포맷팅, 세미콜론 누락, 공백 등 (코드 변경 없음) |
+| `refactor` | 코드 리팩토링 (기능 변화 없음) |
+| `test` | 테스트 코드 추가/수정 |
+| `chore` | 빌드, 설정, 패키지 매니저 등 기타 변경사항 |
+| `ci` | CI 관련 설정 변경 |
+| `setting` | 프로젝트 환경 설정 변경 |
+
+
+
+### 3. Code Style & Import Rule
+
+팀 전체의 코드 스타일 일관성을 위해 **ESLint 기반 자동화 규칙**을 적용합니다.
+
+- **Import 정렬 플러그인**: eslint-plugin-simple-import-sort
+- **설정 파일**: eslint/import.mjs
+- `.vscode/settings.json`에 `codeActionsOnSave`가 설정되어 있으며
+- 파일 저장 시 `source.fixAll.eslint`가 자동 실행됩니다.
+- 별도의 명령 없이도 저장 시 Import 정렬 및 ESLint 수정 사항이 자동 반영됩니다.
+
+이를 통해 팀 전체가 동일한 코드 스타일을 유지하며,
+코드 리뷰 시 스타일 관련 피드백을 최소화합니다.
+
+
+
+### 4. PR Process
+PR 템플릿에 따라 작성하며, **리뷰어 가이드**를 준수합니다.
+
+- **Title**: `[Type/#이슈번호] 작업 요약` (예: `[Feature/#1] 로그인 페이지 UI 구현`)
+- **Review Labels**:
+ - `P1`: **필수 반영 (Critical)** - 버그/컨벤션 위반 (머지 불가)
+ - `P2`: **적극 권장 (Recommended)** - 더 나은 대안 (반영 권장)
+ - `P3`: **제안 (Suggestion)** - 아이디어 공유 (자율)
+ - `P4`: **단순 확인 (Nit)** - 오타/칭찬 등
+
+
diff --git a/commitlint.config.cjs b/commitlint.config.cjs
index 41cdca79..0e18adc2 100644
--- a/commitlint.config.cjs
+++ b/commitlint.config.cjs
@@ -1,21 +1,21 @@
module.exports = {
- extends: ['@commitlint/config-conventional'],
- rules: {
- 'type-enum': [
- 2,
- 'always',
- [
- 'feat', // ✨ 새로운 기능 추가
- 'fix', // 🐛 버그 수정
- 'docs', // 📝 문서 수정 (README 등)
- 'style', // 💄 코드 포맷팅, 세미콜론 누락, 공백 등 (기능/로직 변경 없음)
- 'refactor', // ♻️ 리팩토링 (기능 변화 없는 코드 개선)
- 'test', // ✅ 테스트 코드 추가/수정
- 'chore', // 🔧 그 외 변경사항 (빌드, 설정, 패키지 매니저 등)
- 'ci', // 🛠 CI 관련 설정 변경
- 'setting', // 프로젝트 설정 변경 (예: ESLint, Prettier 등)
- ],
- ],
- 'subject-case': [0], // 메시지 제목 스타일은 자유롭게
- },
+ extends: ["@commitlint/config-conventional"],
+ rules: {
+ "type-enum": [
+ 2,
+ "always",
+ [
+ "feat", // ✨ 새로운 기능 추가
+ "fix", // 🐛 버그 수정
+ "docs", // 📝 문서 수정 (README 등)
+ "style", // 💄 코드 포맷팅, 세미콜론 누락, 공백 등 (기능/로직 변경 없음)
+ "refactor", // ♻️ 리팩토링 (기능 변화 없는 코드 개선)
+ "test", // ✅ 테스트 코드 추가/수정
+ "chore", // 🔧 그 외 변경사항 (빌드, 설정, 패키지 매니저 등)
+ "ci", // 🛠 CI 관련 설정 변경
+ "setting", // 프로젝트 설정 변경 (예: ESLint, Prettier 등)
+ ],
+ ],
+ "subject-case": [0], // 메시지 제목 스타일은 자유롭게
+ },
};
diff --git a/docs/code-review-guideline.md b/docs/code-review-guideline.md
new file mode 100644
index 00000000..323c33ae
--- /dev/null
+++ b/docs/code-review-guideline.md
@@ -0,0 +1,66 @@
+# Code Review Guideline
+
+## CodeRabbit 도입 의도
+
+- **일관된 코드 품질 유지**
+
+ 개인의 리뷰 스타일이나 컨디션에 영향을 받지 않고, 설정된 기준에 따라 일관된 리뷰를 제공하기 위함입니다.
+
+- **리뷰 효율화**
+
+ 단순 문법 오류, 컨벤션, 구조적 패턴 검증은 AI가 선행하고, 팀원들은 비즈니스 로직과 설계 판단에 더 집중할 수 있도록 합니다.
+
+
+
+## 팀 코드 리뷰 원칙
+
+우리 팀은 다음 가치를 최우선으로 생각하며 코드를 작성하고 리뷰합니다.
+
+- 서버 상태와 UI 상태의 명확한 분리
+- 책임과 역할이 분명한 구조 설계
+- 타입 안정성을 통한 예측 가능한 코드
+- 불필요한 복잡성 최소화
+- 장기 유지보수를 고려한 구현
+
+
+
+## 핵심 리뷰 영역
+
+위 코드 리뷰 원칙을 바탕으로, CodeRabbit은 다음 핵심 영역을 중심으로 리뷰합니다.
+
+### 1. 상태 관리
+
+- 서버 상태(React Query)와 전역 상태(Zustand)의 분리 여부 확인
+- `useQuery`, `useMutation`의 올바른 사용 여부 검토
+
+### 2. 구조와 책임 분리
+
+- 페이지에 비즈니스 로직이 과도하게 포함되지 않았는지 확인
+- 커스텀 훅으로의 분리 여부 검토
+
+### 3. Hook 사용
+
+- `useEffect` 의존성 배열의 정확성 확인
+- 불필요한 Hook 사용 여부 검토
+- `useCallback`, `useMemo`의 적절한 사용 여부 확인
+
+### 4. 타입 안정성
+
+- TypeScript 타입이 명확하게 정의되어 있는지 확인
+- `any` 사용 지양
+- 제네릭 활용 검토
+
+### 5. 성능
+
+- 불필요한 리렌더링 체크
+- `React.memo`, `useCallback` 등의 적절한 사용 여부 검토
+
+### 6. 에러 처리
+
+- API 실패 대응이 적절히 구현되어 있는지 확인
+- 사용자 피드백 적절성 검토
+- Error Boundary 사용 확인
+
+### 7. 접근성
+
+- 시맨틱 HTML, ARIA 속성 사용 확인
diff --git a/eslint.config.js b/eslint.config.js
index 8c92757f..3b60eba8 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -1,7 +1,9 @@
+// For more info, see https://github.com/storybookjs/eslint-plugin-storybook#configuration-flat-config-format
import pluginJs from "@eslint/js";
import typescriptParser from "@typescript-eslint/parser";
import prettierPluginRecommended from "eslint-plugin-prettier/recommended";
import globals from "globals";
+import tseslint from "typescript-eslint";
import defaultConfig from "./eslint/default.mjs";
import importConfig from "./eslint/import.mjs";
@@ -37,4 +39,8 @@ export default [
importConfig,
reactConfig,
prettierPluginRecommended,
+ {
+ files: ["**/*.{js,mjs,cjs}"],
+ ...tseslint.configs.disableTypeChecked,
+ },
];
diff --git a/eslint/default.mjs b/eslint/default.mjs
index 96146589..9502d504 100644
--- a/eslint/default.mjs
+++ b/eslint/default.mjs
@@ -1,34 +1,34 @@
-import jsxA11y from 'eslint-plugin-jsx-a11y';
+import jsxA11y from "eslint-plugin-jsx-a11y";
export default {
- plugins: {
- 'jsx-a11y': jsxA11y,
- },
- rules: {
- // 비상호작용 엘리먼트에 상호작용 역할을 할당하는 것을 허용합니다.
- 'jsx-a11y/no-noninteractive-element-to-interactive-role': 'off',
+ plugins: {
+ "jsx-a11y": jsxA11y,
+ },
+ rules: {
+ // 비상호작용 엘리먼트에 상호작용 역할을 할당하는 것을 허용합니다.
+ "jsx-a11y/no-noninteractive-element-to-interactive-role": "off",
- // click 이벤트에 key 이벤트가 없을 때 허용합니다.
- 'jsx-a11y/click-events-have-key-events': 'off',
+ // click 이벤트에 key 이벤트가 없을 때 허용합니다.
+ "jsx-a11y/click-events-have-key-events": "off",
- // 비상호작용 엘리먼트에서 상호작용을 허용합니다.
- 'jsx-a11y/no-noninteractive-element-interactions': 'off',
+ // 비상호작용 엘리먼트에서 상호작용을 허용합니다.
+ "jsx-a11y/no-noninteractive-element-interactions": "off",
- // devDependencies 사용을 허용합니다.
- 'no-extraneous-dependencies': 'off',
+ // devDependencies 사용을 허용합니다.
+ "no-extraneous-dependencies": "off",
- // div에 onClick 이벤트 사용을 허용합니다.
- 'jsx-a11y/no-static-element-interactions': 'off',
+ // div에 onClick 이벤트 사용을 허용합니다.
+ "jsx-a11y/no-static-element-interactions": "off",
- // console.log(), console.warn(), console.error()를 사용할 때 경고를 표시합니다.
- // 'no-console': 'warn',
+ // console.log(), console.warn(), console.error()를 사용할 때 경고를 표시합니다.
+ // 'no-console': 'warn',
- // 가능한 경우 dot notation을 사용하도록 경고를 표시합니다.
- 'dot-notation': 'warn',
+ // 가능한 경우 dot notation을 사용하도록 경고를 표시합니다.
+ "dot-notation": "warn",
- // 사용하지 않는 변수에 대해 경고를 표시합니다.
- 'no-unused-vars': 'warn',
+ // 사용하지 않는 변수에 대해 경고를 표시합니다.
+ "no-unused-vars": "warn",
- '@typescript-eslint/no-explicit-any': 'off',
- },
+ "@typescript-eslint/no-explicit-any": "off",
+ },
};
diff --git a/eslint/import.mjs b/eslint/import.mjs
index d74dd087..923b24c4 100644
--- a/eslint/import.mjs
+++ b/eslint/import.mjs
@@ -1,64 +1,66 @@
-import eslintImport from 'eslint-plugin-import';
-import eslintName from 'eslint-plugin-import-name';
-import simpleImportSort from 'eslint-plugin-simple-import-sort';
+import eslintImport from "eslint-plugin-import";
+import eslintName from "eslint-plugin-import-name";
+import simpleImportSort from "eslint-plugin-simple-import-sort";
export default {
- plugins: {
- 'simple-import-sort': simpleImportSort,
- 'import': eslintImport,
- 'import-name': eslintName,
- },
- rules: {
- // 패키지명을 camelCase화해서 사용하도록 강제하여 코드의 일관성을 유지합니다.
- // 예외적으로 react와 clsx는 별도의 명명 규칙을 따릅니다.
- 'import-name/all-imports-name': [
- 'error',
- {
- clsx: 'cx',
- },
- ],
- // 유사한 항목을 그룹으로 묶어서 import를 정렬합니다.
- 'simple-import-sort/imports': [
- 'error',
- {
- groups: [
- // Side effect imports: Place imports with side effects first.
- ['^\\u0000'],
- // Node.js built-in modules.
- ['^(assert|buffer|child_process|crypto|dns|events|fs|http|https|net|os|path|querystring|stream|tls|url|util|zlib)(/|$)'],
- // Packages: react related packages come first, then other packages.
- ['^react', '^@?\\w'],
- // Aliased imports: Project path aliases.
- ['^@/types', '^@/constants', '^@/enums'],
- ['^@/libs', '^@/utils', '^@/apis'],
- ['^@/stores', '^@/hooks'],
- ['^@/components'],
- // Relative imports: Imports from the same folder first, then parent folders.
- ['^\\./', '^\\.\\./'],
- // Static asset imports: SVG files, JSON files.
- ['^.+\\.svg$', '^.+\\.json$'],
- // Style imports: CSS files.
- ['^.+\\.style.ts$'],
- ],
- },
+ plugins: {
+ "simple-import-sort": simpleImportSort,
+ import: eslintImport,
+ "import-name": eslintName,
+ },
+ rules: {
+ // 패키지명을 camelCase화해서 사용하도록 강제하여 코드의 일관성을 유지합니다.
+ // 예외적으로 react와 clsx는 별도의 명명 규칙을 따릅니다.
+ "import-name/all-imports-name": [
+ "error",
+ {
+ clsx: "cx",
+ },
+ ],
+ // 유사한 항목을 그룹으로 묶어서 import를 정렬합니다.
+ "simple-import-sort/imports": [
+ "error",
+ {
+ groups: [
+ // Side effect imports: Place imports with side effects first.
+ ["^\\u0000"],
+ // Node.js built-in modules.
+ [
+ "^(assert|buffer|child_process|crypto|dns|events|fs|http|https|net|os|path|querystring|stream|tls|url|util|zlib)(/|$)",
+ ],
+ // Packages: react related packages come first, then other packages.
+ ["^react", "^@?\\w"],
+ // Aliased imports: Project path aliases.
+ ["^@/types", "^@/constants", "^@/enums"],
+ ["^@/libs", "^@/utils", "^@/apis"],
+ ["^@/stores", "^@/hooks"],
+ ["^@/components"],
+ // Relative imports: Imports from the same folder first, then parent folders.
+ ["^\\./", "^\\.\\./"],
+ // Static asset imports: SVG files, JSON files.
+ ["^.+\\.svg$", "^.+\\.json$"],
+ // Style imports: CSS files.
+ ["^.+\\.style.ts$"],
],
+ },
+ ],
- // export를 정렬하여 가독성을 높입니다.
- 'simple-import-sort/exports': 'error',
- // import 문을 문서의 상단에 위치시켜 코드 구조를 일관되게 유지합니다.
- 'import/first': 'error',
+ // export를 정렬하여 가독성을 높입니다.
+ "simple-import-sort/exports": "error",
+ // import 문을 문서의 상단에 위치시켜 코드 구조를 일관되게 유지합니다.
+ "import/first": "error",
- // import 문 다음에 빈 줄을 삽입하여 코드의 가독성을 높입니다.
- 'import/newline-after-import': 'error',
+ // import 문 다음에 빈 줄을 삽입하여 코드의 가독성을 높입니다.
+ "import/newline-after-import": "error",
- // 중복된 import를 허용하지 않습니다.
- 'import/no-duplicates': 'error',
+ // 중복된 import를 허용하지 않습니다.
+ "import/no-duplicates": "error",
- // import 플러그인으로도 정렬을 강제할 수 있지만, order group 지정을 더 간편하게 할 수 있는 simple-import-sort 플러그인을 대신 사용합니다.
- 'import/order': 'off',
+ // import 플러그인으로도 정렬을 강제할 수 있지만, order group 지정을 더 간편하게 할 수 있는 simple-import-sort 플러그인을 대신 사용합니다.
+ "import/order": "off",
- // 한 파일에 여러 개의 export가 늘어날 가능성을 고려하여 default export를 사용하지 않습니다.
- // 이는 명명된 export를 사용하여 모듈의 재사용성을 높이고, 코드의 가독성을 향상시킵니다.
- 'import/prefer-default-export': 'off',
- },
+ // 한 파일에 여러 개의 export가 늘어날 가능성을 고려하여 default export를 사용하지 않습니다.
+ // 이는 명명된 export를 사용하여 모듈의 재사용성을 높이고, 코드의 가독성을 향상시킵니다.
+ "import/prefer-default-export": "off",
+ },
};
diff --git a/eslint/react.mjs b/eslint/react.mjs
index f2cbd9f6..9f895a8c 100644
--- a/eslint/react.mjs
+++ b/eslint/react.mjs
@@ -1,75 +1,75 @@
-import pluginReact from 'eslint-plugin-react';
+import pluginReact from "eslint-plugin-react";
export default {
- plugins: {
- react: pluginReact,
- },
- ...pluginReact.configs.flat.recommended,
- rules: {
- // 3항연산자 중첩 허용: 적절하게 쓰면 가독성을 해치지 않기 때문입니다.
- 'no-nested-ternary': 'off',
+ plugins: {
+ react: pluginReact,
+ },
+ ...pluginReact.configs.flat.recommended,
+ rules: {
+ // 3항연산자 중첩 허용: 적절하게 쓰면 가독성을 해치지 않기 때문입니다.
+ "no-nested-ternary": "off",
- // 무조건 typescript를 쓸 것을 가정하고 있기 때문에 defaultProps 정의할 필요 없음
- 'react/require-default-props': 'off',
+ // 무조건 typescript를 쓸 것을 가정하고 있기 때문에 defaultProps 정의할 필요 없음
+ "react/require-default-props": "off",
- // props spreading 허용합니다. 이는 재사용성 높은 컴포넌트를 만들 때 유용합니다.
- 'react/jsx-props-no-spreading': 'off',
+ // props spreading 허용합니다. 이는 재사용성 높은 컴포넌트를 만들 때 유용합니다.
+ "react/jsx-props-no-spreading": "off",
- // 리액트 컴포넌트 파일을 만들 때 .jsx 나 .tsx 나 .svg 확장자를 사용해야만 합니다.
- 'react/jsx-filename-extension': [
- 'error',
- {
- extensions: ['.jsx', '.tsx', '.svg'],
- },
- ],
+ // 리액트 컴포넌트 파일을 만들 때 .jsx 나 .tsx 나 .svg 확장자를 사용해야만 합니다.
+ "react/jsx-filename-extension": [
+ "error",
+ {
+ extensions: [".jsx", ".tsx", ".svg"],
+ },
+ ],
- // label 태그는 관련 control 태그를 감싸고 있어야 합니다. (assert: 'both'를 'either'로 변경하여 유연성을 높입니다)
- 'jsx-a11y/label-has-associated-control': [
- 'error',
- {
- labelComponents: [],
- labelAttributes: [],
- controlComponents: [],
- assert: 'either',
- depth: 25,
- },
- ],
+ // label 태그는 관련 control 태그를 감싸고 있어야 합니다. (assert: 'both'를 'either'로 변경하여 유연성을 높입니다)
+ "jsx-a11y/label-has-associated-control": [
+ "error",
+ {
+ labelComponents: [],
+ labelAttributes: [],
+ controlComponents: [],
+ assert: "either",
+ depth: 25,
+ },
+ ],
- // React 컴포넌트는 function 키워드를 사용하는 named function으로 선언합니다.
- // 콜백이나 함수의 반환 값으로 사용되는 unnamed component는 arrow function으로 작성합니다.
- 'react/function-component-definition': [
- 'error',
- {
- namedComponents: 'function-declaration',
- unnamedComponents: 'arrow-function',
- },
- ],
+ // React 컴포넌트는 function 키워드를 사용하는 named function으로 선언합니다.
+ // 콜백이나 함수의 반환 값으로 사용되는 unnamed component는 arrow function으로 작성합니다.
+ "react/function-component-definition": [
+ "error",
+ {
+ namedComponents: "function-declaration",
+ unnamedComponents: "arrow-function",
+ },
+ ],
- // 함수의 인자나 콜백으로 사용되는 컴포넌트를 named function으로 작성하기 위해 예외를 허용합니다. (e.g. React.forwardRef)
- 'prefer-arrow-callback': ['error', { allowNamedFunctions: true }],
+ // 함수의 인자나 콜백으로 사용되는 컴포넌트를 named function으로 작성하기 위해 예외를 허용합니다. (e.g. React.forwardRef)
+ "prefer-arrow-callback": ["error", { allowNamedFunctions: true }],
- // React 17 이상에서는 JSX를 사용할 때 React를 명시적으로 import할 필요가 없습니다.
- 'react/react-in-jsx-scope': 'off',
+ // React 17 이상에서는 JSX를 사용할 때 React를 명시적으로 import할 필요가 없습니다.
+ "react/react-in-jsx-scope": "off",
- // React 컴포넌트 내에서 state와 props에 구조분해 할당을 사용하도록 경고합니다.
- 'react/destructuring-assignment': 'warn',
+ // React 컴포넌트 내에서 state와 props에 구조분해 할당을 사용하도록 경고합니다.
+ "react/destructuring-assignment": "warn",
- // React 컴포넌트 이름은 PascalCase로 작성하도록 강제합니다.
- 'react/jsx-pascal-case': 'error',
+ // React 컴포넌트 이름은 PascalCase로 작성하도록 강제합니다.
+ "react/jsx-pascal-case": "error",
- // 사용되지 않는 state가 있을 경우 경고를 표시합니다.
- 'react/no-unused-state': 'warn',
+ // 사용되지 않는 state가 있을 경우 경고를 표시합니다.
+ "react/no-unused-state": "warn",
- // 반복문으로 생성하는 요소에는 key 속성을 반드시 포함해야 합니다.
- 'react/jsx-key': 'warn',
+ // 반복문으로 생성하는 요소에는 key 속성을 반드시 포함해야 합니다.
+ "react/jsx-key": "warn",
- // 가능한 경우 셀프 클로징 태그를 사용하도록 경고합니다.
- 'react/self-closing-comp': 'warn',
+ // 가능한 경우 셀프 클로징 태그를 사용하도록 경고합니다.
+ "react/self-closing-comp": "warn",
- // 배열의 인덱스를 key로 사용하는 것을 허용합니다.
- 'react/no-array-index-key': 'off',
+ // 배열의 인덱스를 key로 사용하는 것을 허용합니다.
+ "react/no-array-index-key": "off",
- // React Hook 규칙을 비활성화합니다.
- 'react-hooks/rules-of-hooks': 'off',
- },
+ // React Hook 규칙을 비활성화합니다.
+ "react-hooks/rules-of-hooks": "off",
+ },
};
diff --git a/eslint/typescript.mjs b/eslint/typescript.mjs
index 28357eb2..bdeaf134 100644
--- a/eslint/typescript.mjs
+++ b/eslint/typescript.mjs
@@ -1,39 +1,42 @@
-import tslint from '@typescript-eslint/eslint-plugin';
+import tslint from "@typescript-eslint/eslint-plugin";
export default {
- plugins: {
- '@typescript-eslint': tslint,
- },
- rules: {
- '@typescript-eslint/no-unsafe-assignment': 'off',
- 'no-use-before-define': 'off',
- '@typescript-eslint/no-use-before-define': ['error', { functions: false }],
- '@typescript-eslint/consistent-type-imports': 'error',
- '@typescript-eslint/explicit-module-boundary-types': 'off',
- '@typescript-eslint/no-floating-promises': 'off',
- 'no-void': ['error', { allowAsStatement: true }],
- 'no-shadow': 'off',
- '@typescript-eslint/no-shadow': 'error',
- '@typescript-eslint/no-non-null-assertion': 'off',
- '@typescript-eslint/camelcase': 'off',
- 'camelcase': 'off',
- '@typescript-eslint/no-misused-promises': ['error', { checksVoidReturn: { attributes: false } }],
- '@typescript-eslint/naming-convention': [
- 'error',
- {
- selector: 'interface',
- format: ['PascalCase'],
- custom: { regex: '^I[A-Z]', match: true },
- },
- {
- selector: 'typeAlias',
- format: ['PascalCase'],
- custom: { regex: '^T[A-Z]', match: true },
- },
- ],
- '@typescript-eslint/no-unused-vars': 'warn',
- '@typescript-eslint/consistent-type-assertions': 'off',
- '@typescript-eslint/no-unsafe-call': 'off',
- '@typescript-eslint/no-unsafe-member-access': 'off',
- },
+ plugins: {
+ "@typescript-eslint": tslint,
+ },
+ rules: {
+ "@typescript-eslint/no-unsafe-assignment": "off",
+ "no-use-before-define": "off",
+ "@typescript-eslint/no-use-before-define": ["error", { functions: false }],
+ "@typescript-eslint/consistent-type-imports": "error",
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "@typescript-eslint/no-floating-promises": "off",
+ "no-void": ["error", { allowAsStatement: true }],
+ "no-shadow": "off",
+ "@typescript-eslint/no-shadow": "error",
+ "@typescript-eslint/no-non-null-assertion": "off",
+ "@typescript-eslint/camelcase": "off",
+ camelcase: "off",
+ "@typescript-eslint/no-misused-promises": [
+ "error",
+ { checksVoidReturn: { attributes: false } },
+ ],
+ "@typescript-eslint/naming-convention": [
+ "error",
+ {
+ selector: "interface",
+ format: ["PascalCase"],
+ custom: { regex: "^I[A-Z]", match: true },
+ },
+ {
+ selector: "typeAlias",
+ format: ["PascalCase"],
+ custom: { regex: "^T[A-Z]", match: true },
+ },
+ ],
+ "@typescript-eslint/no-unused-vars": "warn",
+ "@typescript-eslint/consistent-type-assertions": "off",
+ "@typescript-eslint/no-unsafe-call": "off",
+ "@typescript-eslint/no-unsafe-member-access": "off",
+ },
};
diff --git a/index.html b/index.html
index 5fd693ef..073ad93b 100644
--- a/index.html
+++ b/index.html
@@ -2,12 +2,13 @@
-
+
- whereyouad_fe
+ whereyouad
+
diff --git a/labels.json b/labels.json
new file mode 100644
index 00000000..714ac3f2
--- /dev/null
+++ b/labels.json
@@ -0,0 +1,62 @@
+[
+ {
+ "name": "⚙ Setting",
+ "color": "e3dede",
+ "description": "개발 환경 세팅"
+ },
+ {
+ "name": "✨ Feature",
+ "color": "a2eeef",
+ "description": "기능 개발"
+ },
+ {
+ "name": "🌏 Deploy",
+ "color": "C2E0C6",
+ "description": "배포 관련"
+ },
+ {
+ "name": "🎨 Html&css",
+ "color": "FEF2C0",
+ "description": "마크업 & 스타일링"
+ },
+ {
+ "name": "🐞 BugFix",
+ "color": "d73a4a",
+ "description": "Something isn't working"
+ },
+ {
+ "name": "💻 CrossBrowsing",
+ "color": "C5DEF5",
+ "description": "브라우저 호환성"
+ },
+ {
+ "name": "📃 Docs",
+ "color": "1D76DB",
+ "description": "문서 작성 및 수정 (README.md 등)"
+ },
+ {
+ "name": "📬 API",
+ "color": "D4C5F9",
+ "description": "서버 API 통신"
+ },
+ {
+ "name": "🔨 Refactor",
+ "color": "f29a4e",
+ "description": "코드 리팩토링"
+ },
+ {
+ "name": "🙋♂️ Question",
+ "color": "9ED447",
+ "description": "Further information is requested"
+ },
+ {
+ "name": "🥰 Accessibility",
+ "color": "facfcf",
+ "description": "웹접근성 관련"
+ },
+ {
+ "name": "✅ Test",
+ "color": "ccffc4",
+ "description": "test 관련(storybook, jest...)"
+ }
+]
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..81cbed65
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,11779 @@
+{
+ "name": "whereyouad_fe",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "whereyouad_fe",
+ "version": "0.0.0",
+ "dependencies": {
+ "@hookform/resolvers": "^5.2.2",
+ "@microsoft/fetch-event-source": "^2.0.1",
+ "@tailwindcss/vite": "^4.1.18",
+ "@tanstack/react-query": "^5.90.17",
+ "apexcharts": "^5.7.0",
+ "axios": "^1.13.4",
+ "clsx": "^2.1.1",
+ "framer-motion": "^12.38.0",
+ "react": "^19.2.0",
+ "react-apexcharts": "^2.0.1",
+ "react-dom": "^19.2.0",
+ "react-hook-form": "^7.71.1",
+ "react-markdown": "^10.1.0",
+ "react-remove-scroll": "^2.7.2",
+ "react-router-dom": "^7.12.0",
+ "sonner": "^2.0.7",
+ "tailwind-merge": "^3.4.1",
+ "tailwindcss": "^4.1.18",
+ "zod": "^4.3.5",
+ "zustand": "^5.0.10"
+ },
+ "devDependencies": {
+ "@commitlint/cli": "^20.3.1",
+ "@commitlint/config-conventional": "^20.3.1",
+ "@eslint/js": "^9.39.2",
+ "@storybook/addon-essentials": "8.6.17",
+ "@storybook/react": "8.6.17",
+ "@storybook/react-vite": "8.6.17",
+ "@storybook/test": "8.6.17",
+ "@tailwindcss/forms": "^0.5.11",
+ "@types/node": "^24.10.1",
+ "@types/react": "^19.2.5",
+ "@types/react-dom": "^19.2.3",
+ "@typescript-eslint/eslint-plugin": "^8.53.0",
+ "@typescript-eslint/parser": "^8.53.0",
+ "@vitejs/plugin-react-swc": "^3.11.0",
+ "eslint": "^9.39.2",
+ "eslint-config-prettier": "^10.1.8",
+ "eslint-plugin-import": "^2.32.0",
+ "eslint-plugin-import-name": "^1.2.3",
+ "eslint-plugin-jsx-a11y": "^6.10.2",
+ "eslint-plugin-prettier": "^5.5.4",
+ "eslint-plugin-react": "^7.37.5",
+ "eslint-plugin-react-hooks": "^7.0.1",
+ "eslint-plugin-react-refresh": "^0.4.26",
+ "eslint-plugin-simple-import-sort": "^12.1.1",
+ "eslint-plugin-unused-imports": "^4.3.0",
+ "globals": "^16.5.0",
+ "husky": "^9.1.7",
+ "lint-staged": "^16.2.7",
+ "prettier": "^3.7.4",
+ "storybook": "8.6.17",
+ "typescript": "~5.9.3",
+ "typescript-eslint": "^8.53.0",
+ "vite": "^6.4.1",
+ "vite-plugin-svgr": "^4.5.0"
+ }
+ },
+ "node_modules/@adobe/css-tools": {
+ "version": "4.4.4",
+ "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz",
+ "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
+ "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.28.5",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz",
+ "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz",
+ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.0",
+ "@babel/generator": "^7.29.0",
+ "@babel/helper-compilation-targets": "^7.28.6",
+ "@babel/helper-module-transforms": "^7.28.6",
+ "@babel/helpers": "^7.28.6",
+ "@babel/parser": "^7.29.0",
+ "@babel/template": "^7.28.6",
+ "@babel/traverse": "^7.29.0",
+ "@babel/types": "^7.29.0",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.29.1",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
+ "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.0",
+ "@babel/types": "^7.29.0",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
+ "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.28.6",
+ "@babel/helper-validator-option": "^7.27.1",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
+ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
+ "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
+ "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.28.6",
+ "@babel/helper-validator-identifier": "^7.28.5",
+ "@babel/traverse": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
+ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz",
+ "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
+ "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.0"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
+ "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
+ "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.28.6",
+ "@babel/parser": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
+ "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.0",
+ "@babel/generator": "^7.29.0",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.29.0",
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.29.0",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
+ "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@commitlint/cli": {
+ "version": "20.4.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-20.4.1.tgz",
+ "integrity": "sha512-uuFKKpc7OtQM+6SRqT+a4kV818o1pS+uvv/gsRhyX7g4x495jg+Q7P0+O9VNGyLXBYP0syksS7gMRDJKcekr6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/format": "^20.4.0",
+ "@commitlint/lint": "^20.4.1",
+ "@commitlint/load": "^20.4.0",
+ "@commitlint/read": "^20.4.0",
+ "@commitlint/types": "^20.4.0",
+ "tinyexec": "^1.0.0",
+ "yargs": "^17.0.0"
+ },
+ "bin": {
+ "commitlint": "cli.js"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/config-conventional": {
+ "version": "20.4.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-20.4.1.tgz",
+ "integrity": "sha512-0YUvIeBtpi86XriqrR+TCULVFiyYTIOEPjK7tTRMxjcBm1qlzb+kz7IF2WxL6Fq5DaundG8VO37BNgMkMTBwqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^20.4.0",
+ "conventional-changelog-conventionalcommits": "^9.1.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/config-validator": {
+ "version": "20.4.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-20.4.0.tgz",
+ "integrity": "sha512-zShmKTF+sqyNOfAE0vKcqnpvVpG0YX8F9G/ZIQHI2CoKyK+PSdladXMSns400aZ5/QZs+0fN75B//3Q5CHw++w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^20.4.0",
+ "ajv": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/ensure": {
+ "version": "20.4.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-20.4.1.tgz",
+ "integrity": "sha512-WLQqaFx1pBooiVvBrA1YfJNFqZF8wS/YGOtr5RzApDbV9tQ52qT5VkTsY65hFTnXhW8PcDfZLaknfJTmPejmlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^20.4.0",
+ "lodash.camelcase": "^4.3.0",
+ "lodash.kebabcase": "^4.1.1",
+ "lodash.snakecase": "^4.1.1",
+ "lodash.startcase": "^4.4.0",
+ "lodash.upperfirst": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/execute-rule": {
+ "version": "20.0.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-20.0.0.tgz",
+ "integrity": "sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/format": {
+ "version": "20.4.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-20.4.0.tgz",
+ "integrity": "sha512-i3ki3WR0rgolFVX6r64poBHXM1t8qlFel1G1eCBvVgntE3fCJitmzSvH5JD/KVJN/snz6TfaX2CLdON7+s4WVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^20.4.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/is-ignored": {
+ "version": "20.4.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-20.4.1.tgz",
+ "integrity": "sha512-In5EO4JR1lNsAv1oOBBO24V9ND1IqdAJDKZiEpdfjDl2HMasAcT7oA+5BKONv1pRoLG380DGPE2W2RIcUwdgLA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^20.4.0",
+ "semver": "^7.6.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/lint": {
+ "version": "20.4.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-20.4.1.tgz",
+ "integrity": "sha512-g94LrGl/c6UhuhDQqNqU232aslLEN2vzc7MPfQTHzwzM4GHNnEAwVWWnh0zX8S5YXecuLXDwbCsoGwmpAgPWKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/is-ignored": "^20.4.1",
+ "@commitlint/parse": "^20.4.1",
+ "@commitlint/rules": "^20.4.1",
+ "@commitlint/types": "^20.4.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/load": {
+ "version": "20.4.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-20.4.0.tgz",
+ "integrity": "sha512-Dauup/GfjwffBXRJUdlX/YRKfSVXsXZLnINXKz0VZkXdKDcaEILAi9oflHGbfydonJnJAbXEbF3nXPm9rm3G6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/config-validator": "^20.4.0",
+ "@commitlint/execute-rule": "^20.0.0",
+ "@commitlint/resolve-extends": "^20.4.0",
+ "@commitlint/types": "^20.4.0",
+ "cosmiconfig": "^9.0.0",
+ "cosmiconfig-typescript-loader": "^6.1.0",
+ "is-plain-obj": "^4.1.0",
+ "lodash.mergewith": "^4.6.2",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/message": {
+ "version": "20.4.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-20.4.0.tgz",
+ "integrity": "sha512-B5lGtvHgiLAIsK5nLINzVW0bN5hXv+EW35sKhYHE8F7V9Uz1fR4tx3wt7mobA5UNhZKUNgB/+ldVMQE6IHZRyA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/parse": {
+ "version": "20.4.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-20.4.1.tgz",
+ "integrity": "sha512-XNtZjeRcFuAfUnhYrCY02+mpxwY4OmnvD3ETbVPs25xJFFz1nRo/25nHj+5eM+zTeRFvWFwD4GXWU2JEtoK1/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^20.4.0",
+ "conventional-changelog-angular": "^8.1.0",
+ "conventional-commits-parser": "^6.2.1"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/read": {
+ "version": "20.4.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-20.4.0.tgz",
+ "integrity": "sha512-QfpFn6/I240ySEGv7YWqho4vxqtPpx40FS7kZZDjUJ+eHxu3azfhy7fFb5XzfTqVNp1hNoI3tEmiEPbDB44+cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/top-level": "^20.4.0",
+ "@commitlint/types": "^20.4.0",
+ "git-raw-commits": "^4.0.0",
+ "minimist": "^1.2.8",
+ "tinyexec": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/resolve-extends": {
+ "version": "20.4.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-20.4.0.tgz",
+ "integrity": "sha512-ay1KM8q0t+/OnlpqXJ+7gEFQNlUtSU5Gxr8GEwnVf2TPN3+ywc5DzL3JCxmpucqxfHBTFwfRMXxPRRnR5Ki20g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/config-validator": "^20.4.0",
+ "@commitlint/types": "^20.4.0",
+ "global-directory": "^4.0.1",
+ "import-meta-resolve": "^4.0.0",
+ "lodash.mergewith": "^4.6.2",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/rules": {
+ "version": "20.4.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-20.4.1.tgz",
+ "integrity": "sha512-WtqypKEPbQEuJwJS4aKs0OoJRBKz1HXPBC9wRtzVNH68FLhPWzxXlF09hpUXM9zdYTpm4vAdoTGkWiBgQ/vL0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/ensure": "^20.4.1",
+ "@commitlint/message": "^20.4.0",
+ "@commitlint/to-lines": "^20.0.0",
+ "@commitlint/types": "^20.4.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/to-lines": {
+ "version": "20.0.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-20.0.0.tgz",
+ "integrity": "sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/top-level": {
+ "version": "20.4.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-20.4.0.tgz",
+ "integrity": "sha512-NDzq8Q6jmFaIIBC/GG6n1OQEaHdmaAAYdrZRlMgW6glYWGZ+IeuXmiymDvQNXPc82mVxq2KiE3RVpcs+1OeDeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/types": {
+ "version": "20.4.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-20.4.0.tgz",
+ "integrity": "sha512-aO5l99BQJ0X34ft8b0h7QFkQlqxC6e7ZPVmBKz13xM9O8obDaM1Cld4sQlJDXXU/VFuUzQ30mVtHjVz74TuStw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "conventional-commits-parser": "^6.2.1",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
+ "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz",
+ "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",
+ "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz",
+ "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",
+ "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",
+ "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",
+ "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",
+ "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",
+ "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",
+ "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",
+ "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",
+ "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",
+ "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",
+ "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",
+ "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz",
+ "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",
+ "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",
+ "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",
+ "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",
+ "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",
+ "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
+ "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.2",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
+ "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz",
+ "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.7",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
+ "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.17.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
+ "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz",
+ "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.1",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.39.2",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz",
+ "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
+ "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
+ "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.17.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@hookform/resolvers": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.2.2.tgz",
+ "integrity": "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA==",
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/utils": "^0.3.0"
+ },
+ "peerDependencies": {
+ "react-hook-form": "^7.55.0"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
+ "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.4.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@joshwooding/vite-plugin-react-docgen-typescript": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.5.0.tgz",
+ "integrity": "sha512-qYDdL7fPwLRI+bJNurVcis+tNgJmvWjH4YTBGXTA8xMuxFrnAz6E5o35iyzyKbq5J5Lr8mJGfrR5GXl+WGwhgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "glob": "^10.0.0",
+ "magic-string": "^0.27.0",
+ "react-docgen-typescript": "^2.2.2"
+ },
+ "peerDependencies": {
+ "typescript": ">= 4.3.x",
+ "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/magic-string": {
+ "version": "0.27.0",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz",
+ "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.4.13"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@mdx-js/react": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz",
+ "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdx": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16",
+ "react": ">=16"
+ }
+ },
+ "node_modules/@microsoft/fetch-event-source": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz",
+ "integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==",
+ "license": "MIT"
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@pkgr/core": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz",
+ "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/pkgr"
+ }
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-beta.27",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz",
+ "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz",
+ "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/pluginutils/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz",
+ "integrity": "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.1.tgz",
+ "integrity": "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.1.tgz",
+ "integrity": "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.1.tgz",
+ "integrity": "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.1.tgz",
+ "integrity": "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.1.tgz",
+ "integrity": "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.1.tgz",
+ "integrity": "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.1.tgz",
+ "integrity": "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.1.tgz",
+ "integrity": "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.1.tgz",
+ "integrity": "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.1.tgz",
+ "integrity": "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.1.tgz",
+ "integrity": "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.1.tgz",
+ "integrity": "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.1.tgz",
+ "integrity": "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.1.tgz",
+ "integrity": "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.1.tgz",
+ "integrity": "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.1.tgz",
+ "integrity": "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.1.tgz",
+ "integrity": "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.1.tgz",
+ "integrity": "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.1.tgz",
+ "integrity": "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.1.tgz",
+ "integrity": "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.1.tgz",
+ "integrity": "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.1.tgz",
+ "integrity": "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.1.tgz",
+ "integrity": "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.1.tgz",
+ "integrity": "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rtsao/scc": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
+ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@standard-schema/utils": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz",
+ "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==",
+ "license": "MIT"
+ },
+ "node_modules/@storybook/addon-actions": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.17.tgz",
+ "integrity": "sha512-/G3Y7WIzGHMtKT6r3KCqgY/pAzfMhNHvBoRWoPfxMa27GiwmUaJlbfRPSReK/jGz6ye0Uwqix+NFbRXKiTqOJQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/global": "^5.0.0",
+ "@types/uuid": "^9.0.1",
+ "dequal": "^2.0.2",
+ "polished": "^4.2.2",
+ "uuid": "^9.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.6.17"
+ }
+ },
+ "node_modules/@storybook/addon-backgrounds": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.17.tgz",
+ "integrity": "sha512-oh7jEQUt8WhH7cBm0jsJ1dujyaujM5rVS5IXJmDgdFJ8l0pqGzOUDmgkBVX147Uo5W1U47Sx+hA69lg6TKPOMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/global": "^5.0.0",
+ "memoizerific": "^1.11.3",
+ "ts-dedent": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.6.17"
+ }
+ },
+ "node_modules/@storybook/addon-controls": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.17.tgz",
+ "integrity": "sha512-kquUfiJyJMh8IHviTIz1A4UKqqNfvqrYFku9D3UukqkTriM1ngDOb9nryaJcUNTkco5JmIuGjYEJisva+u13lw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/global": "^5.0.0",
+ "dequal": "^2.0.2",
+ "ts-dedent": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.6.17"
+ }
+ },
+ "node_modules/@storybook/addon-docs": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.17.tgz",
+ "integrity": "sha512-zvcSzoYvaZO4l9NxsviDr5vmuq8GVnH4Ap0v+5sSTq192yevm/iQcRnkWYBD9E/Lg5GBeyE+Ml2vjEOK+EPBEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@mdx-js/react": "^3.0.0",
+ "@storybook/blocks": "8.6.17",
+ "@storybook/csf-plugin": "8.6.17",
+ "@storybook/react-dom-shim": "8.6.17",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "ts-dedent": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.6.17"
+ }
+ },
+ "node_modules/@storybook/addon-essentials": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.17.tgz",
+ "integrity": "sha512-nyp2RUxWGpD+xhGWOo221kHOY6cZlgXsV1F11sn7WxkH+yA7YHhLLYlIPHmNKKH+hdxN0rnlcpwjbr21u0Katg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/addon-actions": "8.6.17",
+ "@storybook/addon-backgrounds": "8.6.17",
+ "@storybook/addon-controls": "8.6.17",
+ "@storybook/addon-docs": "8.6.17",
+ "@storybook/addon-highlight": "8.6.17",
+ "@storybook/addon-measure": "8.6.17",
+ "@storybook/addon-outline": "8.6.17",
+ "@storybook/addon-toolbars": "8.6.17",
+ "@storybook/addon-viewport": "8.6.17",
+ "ts-dedent": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.6.17"
+ }
+ },
+ "node_modules/@storybook/addon-highlight": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.17.tgz",
+ "integrity": "sha512-Tf7DxksSg+DqH0a0rLIpB5g9bJBUHcqmEGeYGX7EPQrXBpQAtFXz/XdzuD8eYDlPC1r42iQQw4w+CQnXJCOHFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/global": "^5.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.6.17"
+ }
+ },
+ "node_modules/@storybook/addon-measure": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.17.tgz",
+ "integrity": "sha512-OFGmCrz9MTWfxa0t2GP+633VXZS7W3ahIM5bRmCTeG+jF/gdiVw3S2Adq7YiIZw+nROW9VtHBjuWGvy2miZxcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/global": "^5.0.0",
+ "tiny-invariant": "^1.3.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.6.17"
+ }
+ },
+ "node_modules/@storybook/addon-outline": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.17.tgz",
+ "integrity": "sha512-UfFThgImS8cuv9Mts5JozGO2/SgjU61uKZxn7w+YpJQu0r2UAF56ZBBMZF/Ur5IC4HaoqDWF5DksMlFqMHPBsw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/global": "^5.0.0",
+ "ts-dedent": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.6.17"
+ }
+ },
+ "node_modules/@storybook/addon-toolbars": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.17.tgz",
+ "integrity": "sha512-LoWtnMVQJWivAu+SZdgYIsaiEqIq0mZ8Ses2xSwLnQZxndCakyqPYv/7YcdLDJaX5f8DpjPvSzJ77oa75oKgFw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.6.17"
+ }
+ },
+ "node_modules/@storybook/addon-viewport": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.17.tgz",
+ "integrity": "sha512-gVUtbFQq/mpD5CFOqXGAu5hUpGm/t5G/psg3YsTjnaRBd18dJZ/+//HzZVbX9aEW8t5qTJeJcEYaF5463BVfNA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "memoizerific": "^1.11.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.6.17"
+ }
+ },
+ "node_modules/@storybook/blocks": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.17.tgz",
+ "integrity": "sha512-zuYHH+0egovMrjWRKwOtgVGbz6KALGowPSWBzQ8deTBu6IXfkz6Ce1hRLJPn5S6/jDqqr9xx8vuAiypnRQ98tA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/icons": "^1.2.12",
+ "ts-dedent": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "storybook": "^8.6.17"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@storybook/builder-vite": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-8.6.17.tgz",
+ "integrity": "sha512-ZqFaLUKlRNaU4ovEa5R6D5YTbft1CUcNHLhzpmL9JWInEh4PrUkxiLD/jjB6fiYLcRpSpcs2DF+O/Jh2GDWemA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/csf-plugin": "8.6.17",
+ "browser-assert": "^1.2.1",
+ "ts-dedent": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.6.17",
+ "vite": "^4.0.0 || ^5.0.0 || ^6.0.0"
+ }
+ },
+ "node_modules/@storybook/components": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.17.tgz",
+ "integrity": "sha512-0b8xkkuPCNbM8LTOzyfxuo2KdJCHIfu3+QxWBFllXap0eYNHwVeSxE5KERQ/bk2GDCiRzaUbwH9PeLorxOzJJQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
+ }
+ },
+ "node_modules/@storybook/core": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.17.tgz",
+ "integrity": "sha512-lndZDYIvUddWk54HmgYwE4h2B0JtWt8ztIRAzHRt6ReZZ9QQbmM5b85Qpa+ng4dyQEKc2JAtYD3Du7RRFcpHlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/theming": "8.6.17",
+ "better-opn": "^3.0.2",
+ "browser-assert": "^1.2.1",
+ "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0",
+ "esbuild-register": "^3.5.0",
+ "jsdoc-type-pratt-parser": "^4.0.0",
+ "process": "^0.11.10",
+ "recast": "^0.23.5",
+ "semver": "^7.6.2",
+ "util": "^0.12.5",
+ "ws": "^8.2.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "prettier": "^2 || ^3"
+ },
+ "peerDependenciesMeta": {
+ "prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@storybook/csf-plugin": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.17.tgz",
+ "integrity": "sha512-ouvF/izbKclZxpfnRUkyC5ZVDU7QA0cHhjQnXTDT4F8b0uciQUDw1LosDZy5MXf03BeIDdyBAtzd/ym3wzd+kw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "unplugin": "^1.3.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.6.17"
+ }
+ },
+ "node_modules/@storybook/global": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz",
+ "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@storybook/icons": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-1.6.0.tgz",
+ "integrity": "sha512-hcFZIjW8yQz8O8//2WTIXylm5Xsgc+lW9ISLgUk1xGmptIJQRdlhVIXCpSyLrQaaRiyhQRaVg7l3BD9S216BHw==",
+ "dev": true,
+ "license": "MIT",
+ "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"
+ }
+ },
+ "node_modules/@storybook/instrumenter": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.6.17.tgz",
+ "integrity": "sha512-uPqC0sPY2tYGkEVi1x+L4hvhkTwxT16B/LB8xIXh68co3gR8vY6wVskoBp2tM7LSUGl08U2ksZWxyTo1DaQY5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/global": "^5.0.0",
+ "@vitest/utils": "^2.1.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.6.17"
+ }
+ },
+ "node_modules/@storybook/manager-api": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.17.tgz",
+ "integrity": "sha512-sPJytvClNrw5GgKcPletMTxDOAYcTRA8VRt9E+ncKvPSYHtPDqLfGTgWajXmt0hRsiBUN5bOgLS9bmNjNQWhrw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
+ }
+ },
+ "node_modules/@storybook/preview-api": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.6.17.tgz",
+ "integrity": "sha512-vpTCTkw11wXerYnlG5Q0y4SbFqG9O6GhR0hlYgCn3Z9kcHlNjK/xuwd3h4CvwNXxRNWZGT8qYYCLn5gSSrX6fA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
+ }
+ },
+ "node_modules/@storybook/react": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.6.17.tgz",
+ "integrity": "sha512-yoOzgyZ2VXPJBmvcKS4EVoAf7SJxXbMBcLjWGvmWdDnS+hd7S9cHG/SbgQ+9/vgiLUc+uEuvQjiKrwY3iOA5rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/components": "8.6.17",
+ "@storybook/global": "^5.0.0",
+ "@storybook/manager-api": "8.6.17",
+ "@storybook/preview-api": "8.6.17",
+ "@storybook/react-dom-shim": "8.6.17",
+ "@storybook/theming": "8.6.17"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "@storybook/test": "8.6.17",
+ "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.6.17",
+ "typescript": ">= 4.2.x"
+ },
+ "peerDependenciesMeta": {
+ "@storybook/test": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@storybook/react-dom-shim": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.17.tgz",
+ "integrity": "sha512-bHLsR9b/tiwm9lXbN8kp9XlOgkRXeg84UFwXaWBPu3pOO7vRXukk23SQUpLW+HhjKtCJ3xClSi5uMpse5MpkVQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
+ "storybook": "^8.6.17"
+ }
+ },
+ "node_modules/@storybook/react-vite": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-8.6.17.tgz",
+ "integrity": "sha512-Tsn16nN++3j0fynrPQkuxxNQHHh06nqgYRTfCTT5qQUV6hDY1uiwN7ZkJEIODEqc26O4HRd0yrAA6lOnr1KZOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@joshwooding/vite-plugin-react-docgen-typescript": "0.5.0",
+ "@rollup/pluginutils": "^5.0.2",
+ "@storybook/builder-vite": "8.6.17",
+ "@storybook/react": "8.6.17",
+ "find-up": "^5.0.0",
+ "magic-string": "^0.30.0",
+ "react-docgen": "^7.0.0",
+ "resolve": "^1.22.8",
+ "tsconfig-paths": "^4.2.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "@storybook/test": "8.6.17",
+ "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.6.17",
+ "vite": "^4.0.0 || ^5.0.0 || ^6.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@storybook/test": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@storybook/react-vite/node_modules/tsconfig-paths": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz",
+ "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json5": "^2.2.2",
+ "minimist": "^1.2.6",
+ "strip-bom": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@storybook/test": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.6.17.tgz",
+ "integrity": "sha512-VTuCylXGQrFDZXqZ29+yvJ+A4TZ69jG72rLjiic8hI0SOt87AC/8X1NaYvd2NS4TY0G0PwqtxmKeig8qRDrhNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/global": "^5.0.0",
+ "@storybook/instrumenter": "8.6.17",
+ "@testing-library/dom": "10.4.0",
+ "@testing-library/jest-dom": "6.5.0",
+ "@testing-library/user-event": "14.5.2",
+ "@vitest/expect": "2.0.5",
+ "@vitest/spy": "2.0.5"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.6.17"
+ }
+ },
+ "node_modules/@storybook/theming": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.17.tgz",
+ "integrity": "sha512-IttFvRqozpuzN5MlQEWGOzUA2rZg86688Dyv1d+bjpYcFHtY1X4XyTCGwv1BPTaTsB959oM8R2yoNYWQkABbBA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-add-jsx-attribute": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
+ "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-remove-jsx-attribute": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz",
+ "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz",
+ "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz",
+ "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-svg-dynamic-title": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz",
+ "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-svg-em-dimensions": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz",
+ "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-transform-react-native-svg": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz",
+ "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-transform-svg-component": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz",
+ "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-preset": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz",
+ "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@svgr/babel-plugin-add-jsx-attribute": "8.0.0",
+ "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0",
+ "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0",
+ "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0",
+ "@svgr/babel-plugin-svg-dynamic-title": "8.0.0",
+ "@svgr/babel-plugin-svg-em-dimensions": "8.0.0",
+ "@svgr/babel-plugin-transform-react-native-svg": "8.1.0",
+ "@svgr/babel-plugin-transform-svg-component": "8.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/core": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz",
+ "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.21.3",
+ "@svgr/babel-preset": "8.1.0",
+ "camelcase": "^6.2.0",
+ "cosmiconfig": "^8.1.3",
+ "snake-case": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ }
+ },
+ "node_modules/@svgr/core/node_modules/cosmiconfig": {
+ "version": "8.3.6",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
+ "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0",
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@svgr/hast-util-to-babel-ast": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz",
+ "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.21.3",
+ "entities": "^4.4.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ }
+ },
+ "node_modules/@svgr/plugin-jsx": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz",
+ "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.21.3",
+ "@svgr/babel-preset": "8.1.0",
+ "@svgr/hast-util-to-babel-ast": "8.0.0",
+ "svg-parser": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@svgr/core": "*"
+ }
+ },
+ "node_modules/@swc/core": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.11.tgz",
+ "integrity": "sha512-iLmLTodbYxU39HhMPaMUooPwO/zqJWvsqkrXv1ZI38rMb048p6N7qtAtTp37sw9NzSrvH6oli8EdDygo09IZ/w==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/counter": "^0.1.3",
+ "@swc/types": "^0.1.25"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/swc"
+ },
+ "optionalDependencies": {
+ "@swc/core-darwin-arm64": "1.15.11",
+ "@swc/core-darwin-x64": "1.15.11",
+ "@swc/core-linux-arm-gnueabihf": "1.15.11",
+ "@swc/core-linux-arm64-gnu": "1.15.11",
+ "@swc/core-linux-arm64-musl": "1.15.11",
+ "@swc/core-linux-x64-gnu": "1.15.11",
+ "@swc/core-linux-x64-musl": "1.15.11",
+ "@swc/core-win32-arm64-msvc": "1.15.11",
+ "@swc/core-win32-ia32-msvc": "1.15.11",
+ "@swc/core-win32-x64-msvc": "1.15.11"
+ },
+ "peerDependencies": {
+ "@swc/helpers": ">=0.5.17"
+ },
+ "peerDependenciesMeta": {
+ "@swc/helpers": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@swc/core-darwin-arm64": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.11.tgz",
+ "integrity": "sha512-QoIupRWVH8AF1TgxYyeA5nS18dtqMuxNwchjBIwJo3RdwLEFiJq6onOx9JAxHtuPwUkIVuU2Xbp+jCJ7Vzmgtg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-darwin-x64": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.11.tgz",
+ "integrity": "sha512-S52Gu1QtPSfBYDiejlcfp9GlN+NjTZBRRNsz8PNwBgSE626/FUf2PcllVUix7jqkoMC+t0rS8t+2/aSWlMuQtA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm-gnueabihf": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.11.tgz",
+ "integrity": "sha512-lXJs8oXo6Z4yCpimpQ8vPeCjkgoHu5NoMvmJZ8qxDyU99KVdg6KwU9H79vzrmB+HfH+dCZ7JGMqMF//f8Cfvdg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-gnu": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.11.tgz",
+ "integrity": "sha512-chRsz1K52/vj8Mfq/QOugVphlKPWlMh10V99qfH41hbGvwAU6xSPd681upO4bKiOr9+mRIZZW+EfJqY42ZzRyA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-musl": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.11.tgz",
+ "integrity": "sha512-PYftgsTaGnfDK4m6/dty9ryK1FbLk+LosDJ/RJR2nkXGc8rd+WenXIlvHjWULiBVnS1RsjHHOXmTS4nDhe0v0w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-gnu": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.11.tgz",
+ "integrity": "sha512-DKtnJKIHiZdARyTKiX7zdRjiDS1KihkQWatQiCHMv+zc2sfwb4Glrodx2VLOX4rsa92NLR0Sw8WLcPEMFY1szQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-musl": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.11.tgz",
+ "integrity": "sha512-mUjjntHj4+8WBaiDe5UwRNHuEzLjIWBTSGTw0JT9+C9/Yyuh4KQqlcEQ3ro6GkHmBGXBFpGIj/o5VMyRWfVfWw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-arm64-msvc": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.11.tgz",
+ "integrity": "sha512-ZkNNG5zL49YpaFzfl6fskNOSxtcZ5uOYmWBkY4wVAvgbSAQzLRVBp+xArGWh2oXlY/WgL99zQSGTv7RI5E6nzA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-ia32-msvc": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.11.tgz",
+ "integrity": "sha512-6XnzORkZCQzvTQ6cPrU7iaT9+i145oLwnin8JrfsLG41wl26+5cNQ2XV3zcbrnFEV6esjOceom9YO1w9mGJByw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-x64-msvc": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.11.tgz",
+ "integrity": "sha512-IQ2n6af7XKLL6P1gIeZACskSxK8jWtoKpJWLZmdXTDj1MGzktUy4i+FvpdtxFmJWNavRWH1VmTr6kAubRDHeKw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/counter": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/@swc/types": {
+ "version": "0.1.25",
+ "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz",
+ "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/counter": "^0.1.3"
+ }
+ },
+ "node_modules/@tailwindcss/forms": {
+ "version": "0.5.11",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.11.tgz",
+ "integrity": "sha512-h9wegbZDPurxG22xZSoWtdzc41/OlNEUQERNqI/0fOwa2aVlWGu7C35E/x6LDyD3lgtztFSSjKZyuVM0hxhbgA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mini-svg-data-uri": "^1.2.3"
+ },
+ "peerDependencies": {
+ "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1"
+ }
+ },
+ "node_modules/@tailwindcss/node": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz",
+ "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/remapping": "^2.3.4",
+ "enhanced-resolve": "^5.18.3",
+ "jiti": "^2.6.1",
+ "lightningcss": "1.30.2",
+ "magic-string": "^0.30.21",
+ "source-map-js": "^1.2.1",
+ "tailwindcss": "4.1.18"
+ }
+ },
+ "node_modules/@tailwindcss/oxide": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz",
+ "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ },
+ "optionalDependencies": {
+ "@tailwindcss/oxide-android-arm64": "4.1.18",
+ "@tailwindcss/oxide-darwin-arm64": "4.1.18",
+ "@tailwindcss/oxide-darwin-x64": "4.1.18",
+ "@tailwindcss/oxide-freebsd-x64": "4.1.18",
+ "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18",
+ "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18",
+ "@tailwindcss/oxide-linux-arm64-musl": "4.1.18",
+ "@tailwindcss/oxide-linux-x64-gnu": "4.1.18",
+ "@tailwindcss/oxide-linux-x64-musl": "4.1.18",
+ "@tailwindcss/oxide-wasm32-wasi": "4.1.18",
+ "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18",
+ "@tailwindcss/oxide-win32-x64-msvc": "4.1.18"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-android-arm64": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz",
+ "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-arm64": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz",
+ "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-x64": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz",
+ "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-freebsd-x64": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz",
+ "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz",
+ "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz",
+ "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz",
+ "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz",
+ "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-musl": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz",
+ "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz",
+ "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==",
+ "bundleDependencies": [
+ "@napi-rs/wasm-runtime",
+ "@emnapi/core",
+ "@emnapi/runtime",
+ "@tybys/wasm-util",
+ "@emnapi/wasi-threads",
+ "tslib"
+ ],
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "^1.7.1",
+ "@emnapi/runtime": "^1.7.1",
+ "@emnapi/wasi-threads": "^1.1.0",
+ "@napi-rs/wasm-runtime": "^1.1.0",
+ "@tybys/wasm-util": "^0.10.1",
+ "tslib": "^2.4.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz",
+ "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz",
+ "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/vite": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.18.tgz",
+ "integrity": "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==",
+ "license": "MIT",
+ "dependencies": {
+ "@tailwindcss/node": "4.1.18",
+ "@tailwindcss/oxide": "4.1.18",
+ "tailwindcss": "4.1.18"
+ },
+ "peerDependencies": {
+ "vite": "^5.2.0 || ^6 || ^7"
+ }
+ },
+ "node_modules/@tanstack/query-core": {
+ "version": "5.90.20",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.20.tgz",
+ "integrity": "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/react-query": {
+ "version": "5.90.21",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.21.tgz",
+ "integrity": "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==",
+ "license": "MIT",
+ "dependencies": {
+ "@tanstack/query-core": "5.90.20"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^18 || ^19"
+ }
+ },
+ "node_modules/@testing-library/dom": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
+ "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/runtime": "^7.12.5",
+ "@types/aria-query": "^5.0.1",
+ "aria-query": "5.3.0",
+ "chalk": "^4.1.0",
+ "dom-accessibility-api": "^0.5.9",
+ "lz-string": "^1.5.0",
+ "pretty-format": "^27.0.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@testing-library/dom/node_modules/aria-query": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
+ "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "dequal": "^2.0.3"
+ }
+ },
+ "node_modules/@testing-library/jest-dom": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz",
+ "integrity": "sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@adobe/css-tools": "^4.4.0",
+ "aria-query": "^5.0.0",
+ "chalk": "^3.0.0",
+ "css.escape": "^1.5.1",
+ "dom-accessibility-api": "^0.6.3",
+ "lodash": "^4.17.21",
+ "redent": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14",
+ "npm": ">=6",
+ "yarn": ">=1"
+ }
+ },
+ "node_modules/@testing-library/jest-dom/node_modules/chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
+ "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@testing-library/user-event": {
+ "version": "14.5.2",
+ "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz",
+ "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12",
+ "npm": ">=6"
+ },
+ "peerDependencies": {
+ "@testing-library/dom": ">=7.21.4"
+ }
+ },
+ "node_modules/@types/aria-query": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
+ "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.2"
+ }
+ },
+ "node_modules/@types/debug": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
+ "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/ms": "*"
+ }
+ },
+ "node_modules/@types/doctrine": {
+ "version": "0.0.9",
+ "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz",
+ "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "license": "MIT"
+ },
+ "node_modules/@types/estree-jsx": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz",
+ "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/hast": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
+ "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json5": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/mdast": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
+ "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/mdx": {
+ "version": "2.0.13",
+ "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz",
+ "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/ms": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
+ "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "24.10.13",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.13.tgz",
+ "integrity": "sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.16.0"
+ }
+ },
+ "node_modules/@types/react": {
+ "version": "19.2.14",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
+ "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
+ "license": "MIT",
+ "dependencies": {
+ "csstype": "^3.2.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "19.2.3",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
+ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^19.2.0"
+ }
+ },
+ "node_modules/@types/resolve": {
+ "version": "1.20.6",
+ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz",
+ "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/unist": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
+ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
+ "license": "MIT"
+ },
+ "node_modules/@types/uuid": {
+ "version": "9.0.8",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
+ "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.55.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.55.0.tgz",
+ "integrity": "sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.12.2",
+ "@typescript-eslint/scope-manager": "8.55.0",
+ "@typescript-eslint/type-utils": "8.55.0",
+ "@typescript-eslint/utils": "8.55.0",
+ "@typescript-eslint/visitor-keys": "8.55.0",
+ "ignore": "^7.0.5",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.4.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.55.0",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.55.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.55.0.tgz",
+ "integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.55.0",
+ "@typescript-eslint/types": "8.55.0",
+ "@typescript-eslint/typescript-estree": "8.55.0",
+ "@typescript-eslint/visitor-keys": "8.55.0",
+ "debug": "^4.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.55.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.55.0.tgz",
+ "integrity": "sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.55.0",
+ "@typescript-eslint/types": "^8.55.0",
+ "debug": "^4.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.55.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.55.0.tgz",
+ "integrity": "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.55.0",
+ "@typescript-eslint/visitor-keys": "8.55.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.55.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.55.0.tgz",
+ "integrity": "sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.55.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.55.0.tgz",
+ "integrity": "sha512-x1iH2unH4qAt6I37I2CGlsNs+B9WGxurP2uyZLRz6UJoZWDBx9cJL1xVN/FiOmHEONEg6RIufdvyT0TEYIgC5g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.55.0",
+ "@typescript-eslint/typescript-estree": "8.55.0",
+ "@typescript-eslint/utils": "8.55.0",
+ "debug": "^4.4.3",
+ "ts-api-utils": "^2.4.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.55.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.55.0.tgz",
+ "integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.55.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz",
+ "integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.55.0",
+ "@typescript-eslint/tsconfig-utils": "8.55.0",
+ "@typescript-eslint/types": "8.55.0",
+ "@typescript-eslint/visitor-keys": "8.55.0",
+ "debug": "^4.4.3",
+ "minimatch": "^9.0.5",
+ "semver": "^7.7.3",
+ "tinyglobby": "^0.2.15",
+ "ts-api-utils": "^2.4.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.55.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.55.0.tgz",
+ "integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.9.1",
+ "@typescript-eslint/scope-manager": "8.55.0",
+ "@typescript-eslint/types": "8.55.0",
+ "@typescript-eslint/typescript-estree": "8.55.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.55.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.55.0.tgz",
+ "integrity": "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.55.0",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
+ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
+ "license": "ISC"
+ },
+ "node_modules/@vitejs/plugin-react-swc": {
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.11.0.tgz",
+ "integrity": "sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rolldown/pluginutils": "1.0.0-beta.27",
+ "@swc/core": "^1.12.11"
+ },
+ "peerDependencies": {
+ "vite": "^4 || ^5 || ^6 || ^7"
+ }
+ },
+ "node_modules/@vitest/expect": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz",
+ "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "2.0.5",
+ "@vitest/utils": "2.0.5",
+ "chai": "^5.1.1",
+ "tinyrainbow": "^1.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/expect/node_modules/@vitest/pretty-format": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz",
+ "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyrainbow": "^1.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/expect/node_modules/@vitest/utils": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz",
+ "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "2.0.5",
+ "estree-walker": "^3.0.3",
+ "loupe": "^3.1.1",
+ "tinyrainbow": "^1.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/expect/node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/@vitest/pretty-format": {
+ "version": "2.1.9",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz",
+ "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyrainbow": "^1.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/spy": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz",
+ "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyspy": "^3.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/utils": {
+ "version": "2.1.9",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz",
+ "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "2.1.9",
+ "loupe": "^3.1.2",
+ "tinyrainbow": "^1.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@yr/monotone-cubic-spline": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz",
+ "integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==",
+ "license": "MIT"
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz",
+ "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "environment": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/apexcharts": {
+ "version": "5.7.0",
+ "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-5.7.0.tgz",
+ "integrity": "sha512-NxGX3QT1zhM6aLVQobx0KJxYiq6wrKcscnyiKtL9lodS6PuLzaPc84BhHhzxFxkWjbsBZTbrrvrFuhvkHs7G6Q==",
+ "license": "SEE LICENSE IN LICENSE",
+ "dependencies": {
+ "@yr/monotone-cubic-spline": "^1.0.3"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/aria-query": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
+ "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-ify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
+ "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.9",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz",
+ "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.24.0",
+ "es-object-atoms": "^1.1.1",
+ "get-intrinsic": "^1.3.0",
+ "is-string": "^1.1.1",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.findlast": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz",
+ "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.findlastindex": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz",
+ "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "es-shim-unscopables": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz",
+ "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
+ "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.tosorted": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz",
+ "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.3",
+ "es-errors": "^1.3.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/assertion-error": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/ast-types": {
+ "version": "0.16.1",
+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz",
+ "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ast-types-flow": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz",
+ "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/async-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
+ "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/axe-core": {
+ "version": "4.11.1",
+ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.1.tgz",
+ "integrity": "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/axios": {
+ "version": "1.13.5",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
+ "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.11",
+ "form-data": "^4.0.5",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/axobject-query": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
+ "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/bail": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
+ "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.9.19",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz",
+ "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.js"
+ }
+ },
+ "node_modules/better-opn": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz",
+ "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "open": "^8.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browser-assert": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz",
+ "integrity": "sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==",
+ "dev": true
+ },
+ "node_modules/browserslist": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
+ "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.9.0",
+ "caniuse-lite": "^1.0.30001759",
+ "electron-to-chromium": "^1.5.263",
+ "node-releases": "^2.0.27",
+ "update-browserslist-db": "^1.2.0"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001770",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz",
+ "integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/ccount": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+ "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/chai": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz",
+ "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assertion-error": "^2.0.1",
+ "check-error": "^2.1.1",
+ "deep-eql": "^5.0.1",
+ "loupe": "^3.1.0",
+ "pathval": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/character-entities": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
+ "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-html4": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
+ "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-reference-invalid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
+ "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/check-error": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz",
+ "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 16"
+ }
+ },
+ "node_modules/cli-cursor": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
+ "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-truncate": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.1.tgz",
+ "integrity": "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "slice-ansi": "^7.1.0",
+ "string-width": "^8.0.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cliui/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/comma-separated-tokens": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
+ "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/commander": {
+ "version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
+ "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/compare-func": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz",
+ "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-ify": "^1.0.0",
+ "dot-prop": "^5.1.0"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/conventional-changelog-angular": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.1.0.tgz",
+ "integrity": "sha512-GGf2Nipn1RUCAktxuVauVr1e3r8QrLP/B0lEUsFktmGqc3ddbQkhoJZHJctVU829U1c6mTSWftrVOCHaL85Q3w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "compare-func": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/conventional-changelog-conventionalcommits": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-9.1.0.tgz",
+ "integrity": "sha512-MnbEysR8wWa8dAEvbj5xcBgJKQlX/m0lhS8DsyAAWDHdfs2faDJxTgzRYlRYpXSe7UiKrIIlB4TrBKU9q9DgkA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "compare-func": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/conventional-commits-parser": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.2.1.tgz",
+ "integrity": "sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "meow": "^13.0.0"
+ },
+ "bin": {
+ "conventional-commits-parser": "dist/cli/index.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookie": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
+ "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/cosmiconfig": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
+ "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "env-paths": "^2.2.1",
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/cosmiconfig-typescript-loader": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.2.0.tgz",
+ "integrity": "sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jiti": "^2.6.1"
+ },
+ "engines": {
+ "node": ">=v18"
+ },
+ "peerDependencies": {
+ "@types/node": "*",
+ "cosmiconfig": ">=9",
+ "typescript": ">=5"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/css.escape": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
+ "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "license": "MIT"
+ },
+ "node_modules/damerau-levenshtein": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
+ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/dargs": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz",
+ "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/data-view-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
+ "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
+ "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/inspect-js"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
+ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decode-named-character-reference": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz",
+ "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==",
+ "license": "MIT",
+ "dependencies": {
+ "character-entities": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/deep-eql": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
+ "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-lazy-prop": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
+ "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/detect-node-es": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
+ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
+ "license": "MIT"
+ },
+ "node_modules/devlop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+ "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/dom-accessibility-api": {
+ "version": "0.5.16",
+ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
+ "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/dot-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
+ "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/dot-prop": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+ "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-obj": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.286",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz",
+ "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.19.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz",
+ "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==",
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.3.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/environment": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz",
+ "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz",
+ "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.24.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz",
+ "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.2",
+ "arraybuffer.prototype.slice": "^1.0.4",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "data-view-buffer": "^1.0.2",
+ "data-view-byte-length": "^1.0.2",
+ "data-view-byte-offset": "^1.0.1",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "es-set-tostringtag": "^2.1.0",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.8",
+ "get-intrinsic": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "get-symbol-description": "^1.1.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.1.0",
+ "is-array-buffer": "^3.0.5",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.2",
+ "is-negative-zero": "^2.0.3",
+ "is-regex": "^1.2.1",
+ "is-set": "^2.0.3",
+ "is-shared-array-buffer": "^1.0.4",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.15",
+ "is-weakref": "^1.1.1",
+ "math-intrinsics": "^1.1.0",
+ "object-inspect": "^1.13.4",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.7",
+ "own-keys": "^1.0.1",
+ "regexp.prototype.flags": "^1.5.4",
+ "safe-array-concat": "^1.1.3",
+ "safe-push-apply": "^1.0.0",
+ "safe-regex-test": "^1.1.0",
+ "set-proto": "^1.0.0",
+ "stop-iteration-iterator": "^1.1.0",
+ "string.prototype.trim": "^1.2.10",
+ "string.prototype.trimend": "^1.0.9",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.3",
+ "typed-array-byte-length": "^1.0.3",
+ "typed-array-byte-offset": "^1.0.4",
+ "typed-array-length": "^1.0.7",
+ "unbox-primitive": "^1.1.0",
+ "which-typed-array": "^1.1.19"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-iterator-helpers": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.2.tgz",
+ "integrity": "sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.24.1",
+ "es-errors": "^1.3.0",
+ "es-set-tostringtag": "^2.1.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.3.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "internal-slot": "^1.1.0",
+ "iterator.prototype": "^1.1.5",
+ "safe-array-concat": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-shim-unscopables": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz",
+ "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
+ "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.0.5",
+ "is-symbol": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
+ "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.12",
+ "@esbuild/android-arm": "0.25.12",
+ "@esbuild/android-arm64": "0.25.12",
+ "@esbuild/android-x64": "0.25.12",
+ "@esbuild/darwin-arm64": "0.25.12",
+ "@esbuild/darwin-x64": "0.25.12",
+ "@esbuild/freebsd-arm64": "0.25.12",
+ "@esbuild/freebsd-x64": "0.25.12",
+ "@esbuild/linux-arm": "0.25.12",
+ "@esbuild/linux-arm64": "0.25.12",
+ "@esbuild/linux-ia32": "0.25.12",
+ "@esbuild/linux-loong64": "0.25.12",
+ "@esbuild/linux-mips64el": "0.25.12",
+ "@esbuild/linux-ppc64": "0.25.12",
+ "@esbuild/linux-riscv64": "0.25.12",
+ "@esbuild/linux-s390x": "0.25.12",
+ "@esbuild/linux-x64": "0.25.12",
+ "@esbuild/netbsd-arm64": "0.25.12",
+ "@esbuild/netbsd-x64": "0.25.12",
+ "@esbuild/openbsd-arm64": "0.25.12",
+ "@esbuild/openbsd-x64": "0.25.12",
+ "@esbuild/openharmony-arm64": "0.25.12",
+ "@esbuild/sunos-x64": "0.25.12",
+ "@esbuild/win32-arm64": "0.25.12",
+ "@esbuild/win32-ia32": "0.25.12",
+ "@esbuild/win32-x64": "0.25.12"
+ }
+ },
+ "node_modules/esbuild-register": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz",
+ "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.4"
+ },
+ "peerDependencies": {
+ "esbuild": ">=0.12 <1"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.39.2",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz",
+ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.1",
+ "@eslint/config-helpers": "^0.4.2",
+ "@eslint/core": "^0.17.0",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.39.2",
+ "@eslint/plugin-kit": "^0.4.1",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "10.1.8",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz",
+ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-config-prettier"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-import-resolver-node": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
+ "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^3.2.7",
+ "is-core-module": "^2.13.0",
+ "resolve": "^1.22.4"
+ }
+ },
+ "node_modules/eslint-import-resolver-node/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-module-utils": {
+ "version": "2.12.1",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz",
+ "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^3.2.7"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import": {
+ "version": "2.32.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz",
+ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rtsao/scc": "^1.1.0",
+ "array-includes": "^3.1.9",
+ "array.prototype.findlastindex": "^1.2.6",
+ "array.prototype.flat": "^1.3.3",
+ "array.prototype.flatmap": "^1.3.3",
+ "debug": "^3.2.7",
+ "doctrine": "^2.1.0",
+ "eslint-import-resolver-node": "^0.3.9",
+ "eslint-module-utils": "^2.12.1",
+ "hasown": "^2.0.2",
+ "is-core-module": "^2.16.1",
+ "is-glob": "^4.0.3",
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.8",
+ "object.groupby": "^1.0.3",
+ "object.values": "^1.2.1",
+ "semver": "^6.3.1",
+ "string.prototype.trimend": "^1.0.9",
+ "tsconfig-paths": "^3.15.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
+ }
+ },
+ "node_modules/eslint-plugin-import-name": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import-name/-/eslint-plugin-import-name-1.2.3.tgz",
+ "integrity": "sha512-Fwh+khN9JT78NT75b7AxJGHMYsmpSPJ4Sw3R3GXPWuv8HkYlNLQYIfF11Pv20dcWGrI2Dv4scFn2tlQ4WFQQGA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/eslint-plugin-import/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-plugin-jsx-a11y": {
+ "version": "6.10.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz",
+ "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "aria-query": "^5.3.2",
+ "array-includes": "^3.1.8",
+ "array.prototype.flatmap": "^1.3.2",
+ "ast-types-flow": "^0.0.8",
+ "axe-core": "^4.10.0",
+ "axobject-query": "^4.1.0",
+ "damerau-levenshtein": "^1.0.8",
+ "emoji-regex": "^9.2.2",
+ "hasown": "^2.0.2",
+ "jsx-ast-utils": "^3.3.5",
+ "language-tags": "^1.0.9",
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.8",
+ "safe-regex-test": "^1.0.3",
+ "string.prototype.includes": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependencies": {
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9"
+ }
+ },
+ "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/eslint-plugin-prettier": {
+ "version": "5.5.5",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.5.tgz",
+ "integrity": "sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prettier-linter-helpers": "^1.0.1",
+ "synckit": "^0.11.12"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-plugin-prettier"
+ },
+ "peerDependencies": {
+ "@types/eslint": ">=8.0.0",
+ "eslint": ">=8.0.0",
+ "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0",
+ "prettier": ">=3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/eslint": {
+ "optional": true
+ },
+ "eslint-config-prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-react": {
+ "version": "7.37.5",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz",
+ "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-includes": "^3.1.8",
+ "array.prototype.findlast": "^1.2.5",
+ "array.prototype.flatmap": "^1.3.3",
+ "array.prototype.tosorted": "^1.1.4",
+ "doctrine": "^2.1.0",
+ "es-iterator-helpers": "^1.2.1",
+ "estraverse": "^5.3.0",
+ "hasown": "^2.0.2",
+ "jsx-ast-utils": "^2.4.1 || ^3.0.0",
+ "minimatch": "^3.1.2",
+ "object.entries": "^1.1.9",
+ "object.fromentries": "^2.0.8",
+ "object.values": "^1.2.1",
+ "prop-types": "^15.8.1",
+ "resolve": "^2.0.0-next.5",
+ "semver": "^6.3.1",
+ "string.prototype.matchall": "^4.0.12",
+ "string.prototype.repeat": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7"
+ }
+ },
+ "node_modules/eslint-plugin-react-hooks": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz",
+ "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.24.4",
+ "@babel/parser": "^7.24.4",
+ "hermes-parser": "^0.25.1",
+ "zod": "^3.25.0 || ^4.0.0",
+ "zod-validation-error": "^3.5.0 || ^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-react-refresh": {
+ "version": "0.4.26",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.26.tgz",
+ "integrity": "sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "eslint": ">=8.40"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/resolve": {
+ "version": "2.0.0-next.5",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
+ "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-plugin-simple-import-sort": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz",
+ "integrity": "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "eslint": ">=5.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-unused-imports": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.4.1.tgz",
+ "integrity": "sha512-oZGYUz1X3sRMGUB+0cZyK2VcvRX5lm/vB56PgNNcU+7ficUCKm66oZWKUubXWnOuPjQ8PvmXtCViXBMONPe7tQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0",
+ "eslint": "^10.0.0 || ^9.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@typescript-eslint/eslint-plugin": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/eslint/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/eslint/node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/eslint/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
+ "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-util-is-identifier-name": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz",
+ "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eventemitter3": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz",
+ "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "license": "MIT"
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-diff": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
+ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
+ "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
+ "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/framer-motion": {
+ "version": "12.38.0",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.38.0.tgz",
+ "integrity": "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-dom": "^12.38.0",
+ "motion-utils": "^12.36.0",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz",
+ "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "functions-have-names": "^1.2.3",
+ "hasown": "^2.0.2",
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/generator-function": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz",
+ "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-east-asian-width": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz",
+ "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-nonce": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
+ "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/git-raw-commits": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz",
+ "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dargs": "^8.0.0",
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
+ },
+ "bin": {
+ "git-raw-commits": "cli.mjs"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/git-raw-commits/node_modules/meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/global-directory": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz",
+ "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ini": "4.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globals": {
+ "version": "16.5.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz",
+ "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "license": "ISC"
+ },
+ "node_modules/has-bigints": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hast-util-to-jsx-runtime": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz",
+ "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "devlop": "^1.0.0",
+ "estree-util-is-identifier-name": "^3.0.0",
+ "hast-util-whitespace": "^3.0.0",
+ "mdast-util-mdx-expression": "^2.0.0",
+ "mdast-util-mdx-jsx": "^3.0.0",
+ "mdast-util-mdxjs-esm": "^2.0.0",
+ "property-information": "^7.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "style-to-js": "^1.0.0",
+ "unist-util-position": "^5.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-whitespace": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
+ "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hermes-estree": {
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
+ "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/hermes-parser": {
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz",
+ "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hermes-estree": "0.25.1"
+ }
+ },
+ "node_modules/html-url-attributes": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz",
+ "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/husky": {
+ "version": "9.1.7",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz",
+ "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "husky": "bin.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/typicode"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-fresh/node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/import-meta-resolve": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz",
+ "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ini": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz",
+ "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/inline-style-parser": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz",
+ "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==",
+ "license": "MIT"
+ },
+ "node_modules/internal-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-alphabetical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
+ "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-alphanumerical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
+ "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
+ "license": "MIT",
+ "dependencies": {
+ "is-alphabetical": "^2.0.0",
+ "is-decimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-arguments": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
+ "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-async-function": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
+ "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-function": "^1.0.0",
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-decimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
+ "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finalizationregistry": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz",
+ "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-east-asian-width": "^1.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz",
+ "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.4",
+ "generator-function": "^2.0.0",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-hexadecimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
+ "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+ "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz",
+ "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/iterator.prototype": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz",
+ "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.6",
+ "get-proto": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/jiti": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
+ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
+ "license": "MIT",
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsdoc-type-pratt-parser": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.8.0.tgz",
+ "integrity": "sha512-iZ8Bdb84lWRuGHamRXFyML07r21pcwBrLkHEuHgEY5UbCouBwv7ECknDRKzsQIXMiqpPymqtIf8TC/shYKB5rw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jsx-ast-utils": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
+ "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-includes": "^3.1.6",
+ "array.prototype.flat": "^1.3.1",
+ "object.assign": "^4.1.4",
+ "object.values": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/language-subtag-registry": {
+ "version": "0.3.23",
+ "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz",
+ "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/language-tags": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz",
+ "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "language-subtag-registry": "^0.3.20"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lightningcss": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz",
+ "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==",
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-android-arm64": "1.30.2",
+ "lightningcss-darwin-arm64": "1.30.2",
+ "lightningcss-darwin-x64": "1.30.2",
+ "lightningcss-freebsd-x64": "1.30.2",
+ "lightningcss-linux-arm-gnueabihf": "1.30.2",
+ "lightningcss-linux-arm64-gnu": "1.30.2",
+ "lightningcss-linux-arm64-musl": "1.30.2",
+ "lightningcss-linux-x64-gnu": "1.30.2",
+ "lightningcss-linux-x64-musl": "1.30.2",
+ "lightningcss-win32-arm64-msvc": "1.30.2",
+ "lightningcss-win32-x64-msvc": "1.30.2"
+ }
+ },
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz",
+ "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz",
+ "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz",
+ "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz",
+ "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz",
+ "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz",
+ "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz",
+ "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz",
+ "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz",
+ "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz",
+ "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz",
+ "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lint-staged": {
+ "version": "16.2.7",
+ "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.2.7.tgz",
+ "integrity": "sha512-lDIj4RnYmK7/kXMya+qJsmkRFkGolciXjrsZ6PC25GdTfWOAWetR0ZbsNXRAj1EHHImRSalc+whZFg56F5DVow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^14.0.2",
+ "listr2": "^9.0.5",
+ "micromatch": "^4.0.8",
+ "nano-spawn": "^2.0.0",
+ "pidtree": "^0.6.0",
+ "string-argv": "^0.3.2",
+ "yaml": "^2.8.1"
+ },
+ "bin": {
+ "lint-staged": "bin/lint-staged.js"
+ },
+ "engines": {
+ "node": ">=20.17"
+ },
+ "funding": {
+ "url": "https://opencollective.com/lint-staged"
+ }
+ },
+ "node_modules/listr2": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz",
+ "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cli-truncate": "^5.0.0",
+ "colorette": "^2.0.20",
+ "eventemitter3": "^5.0.1",
+ "log-update": "^6.1.0",
+ "rfdc": "^1.4.1",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.23",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
+ "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.kebabcase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
+ "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.mergewith": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
+ "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.snakecase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
+ "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.startcase": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz",
+ "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.upperfirst": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz",
+ "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/log-update": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz",
+ "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-escapes": "^7.0.0",
+ "cli-cursor": "^5.0.0",
+ "slice-ansi": "^7.1.0",
+ "strip-ansi": "^7.1.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/longest-streak": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
+ "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/loupe": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz",
+ "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lower-case": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+ "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/lz-string": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
+ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "lz-string": "bin/bin.js"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/map-or-similar": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/map-or-similar/-/map-or-similar-1.5.0.tgz",
+ "integrity": "sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/mdast-util-from-markdown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz",
+ "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-to-string": "^4.0.0",
+ "micromark": "^4.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-decode-string": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdx-expression": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz",
+ "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdx-jsx": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz",
+ "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "ccount": "^2.0.0",
+ "devlop": "^1.1.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0",
+ "parse-entities": "^4.0.0",
+ "stringify-entities": "^4.0.0",
+ "unist-util-stringify-position": "^4.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdxjs-esm": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz",
+ "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-phrasing": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz",
+ "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-hast": {
+ "version": "13.2.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz",
+ "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@ungap/structured-clone": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "trim-lines": "^3.0.0",
+ "unist-util-position": "^5.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-markdown": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz",
+ "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "longest-streak": "^3.0.0",
+ "mdast-util-phrasing": "^4.0.0",
+ "mdast-util-to-string": "^4.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-decode-string": "^2.0.0",
+ "unist-util-visit": "^5.0.0",
+ "zwitch": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
+ "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/memoizerific": {
+ "version": "1.11.3",
+ "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz",
+ "integrity": "sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "map-or-similar": "^1.5.0"
+ }
+ },
+ "node_modules/meow": {
+ "version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz",
+ "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/micromark": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz",
+ "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@types/debug": "^4.0.0",
+ "debug": "^4.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-core-commonmark": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-combine-extensions": "^2.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-core-commonmark": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz",
+ "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-factory-destination": "^2.0.0",
+ "micromark-factory-label": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-factory-title": "^2.0.0",
+ "micromark-factory-whitespace": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-html-tag-name": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-destination": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
+ "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-label": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz",
+ "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-space": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-title": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz",
+ "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-whitespace": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz",
+ "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-character": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-chunked": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz",
+ "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-classify-character": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz",
+ "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-combine-extensions": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz",
+ "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-decode-numeric-character-reference": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz",
+ "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-decode-string": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz",
+ "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "decode-named-character-reference": "^1.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-encode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
+ "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-html-tag-name": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
+ "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-normalize-identifier": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz",
+ "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-resolve-all": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz",
+ "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-sanitize-uri": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
+ "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-subtokenize": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz",
+ "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-symbol": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-types": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
+ "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-function": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
+ "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/min-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mini-svg-data-uri": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
+ "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mini-svg-data-uri": "cli.js"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/motion-dom": {
+ "version": "12.38.0",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.38.0.tgz",
+ "integrity": "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-utils": "^12.36.0"
+ }
+ },
+ "node_modules/motion-utils": {
+ "version": "12.36.0",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.36.0.tgz",
+ "integrity": "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==",
+ "license": "MIT"
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/nano-spawn": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-2.0.0.tgz",
+ "integrity": "sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/nano-spawn?sponsor=1"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/no-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+ "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lower-case": "^2.0.2",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.27",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
+ "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.entries": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz",
+ "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.fromentries": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
+ "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.groupby": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz",
+ "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.values": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz",
+ "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
+ "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-function": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/open": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
+ "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-lazy-prop": "^2.0.0",
+ "is-docker": "^2.1.1",
+ "is-wsl": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/own-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz",
+ "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.6",
+ "object-keys": "^1.1.1",
+ "safe-push-apply": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-entities": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz",
+ "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "character-entities-legacy": "^3.0.0",
+ "character-reference-invalid": "^2.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "is-alphanumerical": "^2.0.0",
+ "is-decimal": "^2.0.0",
+ "is-hexadecimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/parse-entities/node_modules/@types/unist": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
+ "license": "MIT"
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pathval": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz",
+ "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.16"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pidtree": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
+ "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "pidtree": "bin/pidtree.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/polished": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz",
+ "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.17.8"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz",
+ "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/prettier-linter-helpers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz",
+ "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-diff": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/pretty-format": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/pretty-format/node_modules/react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/property-information": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz",
+ "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/react": {
+ "version": "19.2.4",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
+ "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-apexcharts": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-2.0.1.tgz",
+ "integrity": "sha512-AN9u5C0kDAkQyMyJP6yXORexiuiaTa0GaxR5dOaF075vWLTTbQxxtYF/kXyvUo4jjtBEIe4lLoCZTo/kB3bRoA==",
+ "license": "SEE LICENSE IN LICENSE",
+ "dependencies": {
+ "prop-types": "^15.8.1"
+ },
+ "peerDependencies": {
+ "apexcharts": ">=5.6.0",
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/react-docgen": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-7.1.1.tgz",
+ "integrity": "sha512-hlSJDQ2synMPKFZOsKo9Hi8WWZTC7POR8EmWvTSjow+VDgKzkmjQvFm2fk0tmRw+f0vTOIYKlarR0iL4996pdg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.18.9",
+ "@babel/traverse": "^7.18.9",
+ "@babel/types": "^7.18.9",
+ "@types/babel__core": "^7.18.0",
+ "@types/babel__traverse": "^7.18.0",
+ "@types/doctrine": "^0.0.9",
+ "@types/resolve": "^1.20.2",
+ "doctrine": "^3.0.0",
+ "resolve": "^1.22.1",
+ "strip-indent": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.14.0"
+ }
+ },
+ "node_modules/react-docgen-typescript": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.4.0.tgz",
+ "integrity": "sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "typescript": ">= 4.3.x"
+ }
+ },
+ "node_modules/react-docgen/node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "19.2.4",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
+ "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
+ "license": "MIT",
+ "dependencies": {
+ "scheduler": "^0.27.0"
+ },
+ "peerDependencies": {
+ "react": "^19.2.4"
+ }
+ },
+ "node_modules/react-hook-form": {
+ "version": "7.71.1",
+ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.1.tgz",
+ "integrity": "sha512-9SUJKCGKo8HUSsCO+y0CtqkqI5nNuaDqTxyqPsZPqIwudpj4rCrAz/jZV+jn57bx5gtZKOh3neQu94DXMc+w5w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/react-hook-form"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17 || ^18 || ^19"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "license": "MIT"
+ },
+ "node_modules/react-markdown": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz",
+ "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "hast-util-to-jsx-runtime": "^2.0.0",
+ "html-url-attributes": "^3.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "remark-parse": "^11.0.0",
+ "remark-rehype": "^11.0.0",
+ "unified": "^11.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18",
+ "react": ">=18"
+ }
+ },
+ "node_modules/react-remove-scroll": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz",
+ "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==",
+ "license": "MIT",
+ "dependencies": {
+ "react-remove-scroll-bar": "^2.3.7",
+ "react-style-singleton": "^2.2.3",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.3",
+ "use-sidecar": "^1.1.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-remove-scroll-bar": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",
+ "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",
+ "license": "MIT",
+ "dependencies": {
+ "react-style-singleton": "^2.2.2",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-router": {
+ "version": "7.13.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.0.tgz",
+ "integrity": "sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==",
+ "license": "MIT",
+ "dependencies": {
+ "cookie": "^1.0.1",
+ "set-cookie-parser": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "7.13.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.0.tgz",
+ "integrity": "sha512-5CO/l5Yahi2SKC6rGZ+HDEjpjkGaG/ncEP7eWFTvFxbHP8yeeI0PxTDjimtpXYlR3b3i9/WIL4VJttPrESIf2g==",
+ "license": "MIT",
+ "dependencies": {
+ "react-router": "7.13.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
+ "node_modules/react-style-singleton": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
+ "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",
+ "license": "MIT",
+ "dependencies": {
+ "get-nonce": "^1.0.0",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/recast": {
+ "version": "0.23.11",
+ "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz",
+ "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ast-types": "^0.16.1",
+ "esprima": "~4.0.0",
+ "source-map": "~0.6.1",
+ "tiny-invariant": "^1.3.3",
+ "tslib": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/redent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
+ "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "indent-string": "^4.0.0",
+ "strip-indent": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/redent/node_modules/strip-indent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
+ "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "min-indent": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
+ "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.1",
+ "which-builtin-type": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/remark-parse": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
+ "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "unified": "^11.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remark-rehype": {
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz",
+ "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "unified": "^11.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.11",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
+ "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.16.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
+ "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^7.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rollup": {
+ "version": "4.57.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.1.tgz",
+ "integrity": "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.57.1",
+ "@rollup/rollup-android-arm64": "4.57.1",
+ "@rollup/rollup-darwin-arm64": "4.57.1",
+ "@rollup/rollup-darwin-x64": "4.57.1",
+ "@rollup/rollup-freebsd-arm64": "4.57.1",
+ "@rollup/rollup-freebsd-x64": "4.57.1",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.57.1",
+ "@rollup/rollup-linux-arm-musleabihf": "4.57.1",
+ "@rollup/rollup-linux-arm64-gnu": "4.57.1",
+ "@rollup/rollup-linux-arm64-musl": "4.57.1",
+ "@rollup/rollup-linux-loong64-gnu": "4.57.1",
+ "@rollup/rollup-linux-loong64-musl": "4.57.1",
+ "@rollup/rollup-linux-ppc64-gnu": "4.57.1",
+ "@rollup/rollup-linux-ppc64-musl": "4.57.1",
+ "@rollup/rollup-linux-riscv64-gnu": "4.57.1",
+ "@rollup/rollup-linux-riscv64-musl": "4.57.1",
+ "@rollup/rollup-linux-s390x-gnu": "4.57.1",
+ "@rollup/rollup-linux-x64-gnu": "4.57.1",
+ "@rollup/rollup-linux-x64-musl": "4.57.1",
+ "@rollup/rollup-openbsd-x64": "4.57.1",
+ "@rollup/rollup-openharmony-arm64": "4.57.1",
+ "@rollup/rollup-win32-arm64-msvc": "4.57.1",
+ "@rollup/rollup-win32-ia32-msvc": "4.57.1",
+ "@rollup/rollup-win32-x64-gnu": "4.57.1",
+ "@rollup/rollup-win32-x64-msvc": "4.57.1",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/safe-array-concat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
+ "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "has-symbols": "^1.1.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-push-apply": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
+ "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.27.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
+ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
+ "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
+ "license": "MIT"
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-proto": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz",
+ "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/slice-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz",
+ "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "is-fullwidth-code-point": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/slice-ansi/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/snake-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
+ "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dot-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/sonner": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.7.tgz",
+ "integrity": "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc",
+ "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/space-separated-tokens": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
+ "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 10.x"
+ }
+ },
+ "node_modules/stop-iteration-iterator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
+ "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "internal-slot": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/storybook": {
+ "version": "8.6.17",
+ "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.17.tgz",
+ "integrity": "sha512-krR/l680A6qVnkGiK9p8jY0ucX3+kFCs2f4zw+S3w2Cdq8EiM/tFebPcX2V4S3z2UsO0v0dwAJOJNpzbFPdmVg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/core": "8.6.17"
+ },
+ "bin": {
+ "getstorybook": "bin/index.cjs",
+ "sb": "bin/index.cjs",
+ "storybook": "bin/index.cjs"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "prettier": "^2 || ^3"
+ },
+ "peerDependenciesMeta": {
+ "prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/string-argv": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
+ "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6.19"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.1.tgz",
+ "integrity": "sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-east-asian-width": "^1.3.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string.prototype.includes": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz",
+ "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/string.prototype.matchall": {
+ "version": "4.0.12",
+ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
+ "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.6",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.6",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "internal-slot": "^1.1.0",
+ "regexp.prototype.flags": "^1.5.3",
+ "set-function-name": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.repeat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz",
+ "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.10",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
+ "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-data-property": "^1.1.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-object-atoms": "^1.0.0",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
+ "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/stringify-entities": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
+ "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
+ "license": "MIT",
+ "dependencies": {
+ "character-entities-html4": "^2.0.0",
+ "character-entities-legacy": "^3.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
+ "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-indent": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.1.tgz",
+ "integrity": "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/style-to-js": {
+ "version": "1.1.21",
+ "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz",
+ "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==",
+ "license": "MIT",
+ "dependencies": {
+ "style-to-object": "1.0.14"
+ }
+ },
+ "node_modules/style-to-object": {
+ "version": "1.0.14",
+ "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz",
+ "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==",
+ "license": "MIT",
+ "dependencies": {
+ "inline-style-parser": "0.2.7"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/svg-parser": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz",
+ "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/synckit": {
+ "version": "0.11.12",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz",
+ "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@pkgr/core": "^0.2.9"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/synckit"
+ }
+ },
+ "node_modules/tailwind-merge": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.1.tgz",
+ "integrity": "sha512-2OA0rFqWOkITEAOFWSBSApYkDeH9t2B3XSJuI4YztKBzK3mX0737A2qtxDZ7xkw9Zfh0bWl+r34sF3HXV+Ig7Q==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/dcastil"
+ }
+ },
+ "node_modules/tailwindcss": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz",
+ "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==",
+ "license": "MIT"
+ },
+ "node_modules/tapable": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz",
+ "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/tiny-invariant": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
+ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyexec": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz",
+ "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinyglobby/node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tinyglobby/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/tinyrainbow": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz",
+ "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/tinyspy": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz",
+ "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/trim-lines": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
+ "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/trough": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz",
+ "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
+ "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/ts-dedent": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz",
+ "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.10"
+ }
+ },
+ "node_modules/tsconfig-paths": {
+ "version": "3.15.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
+ "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.2",
+ "minimist": "^1.2.6",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "node_modules/tsconfig-paths/node_modules/json5": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
+ "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "reflect.getprototypeof": "^1.0.9"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
+ "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0",
+ "reflect.getprototypeof": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.55.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.55.0.tgz",
+ "integrity": "sha512-HE4wj+r5lmDVS9gdaN0/+iqNvPZwGfnJ5lZuz7s5vLlg9ODw0bIiiETaios9LvFI1U94/VBXGm3CB2Y5cNFMpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.55.0",
+ "@typescript-eslint/parser": "8.55.0",
+ "@typescript-eslint/typescript-estree": "8.55.0",
+ "@typescript-eslint/utils": "8.55.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "which-boxed-primitive": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/unified": {
+ "version": "11.0.5",
+ "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",
+ "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "bail": "^2.0.0",
+ "devlop": "^1.0.0",
+ "extend": "^3.0.0",
+ "is-plain-obj": "^4.0.0",
+ "trough": "^2.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-is": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz",
+ "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-position": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz",
+ "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-stringify-position": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
+ "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz",
+ "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0",
+ "unist-util-visit-parents": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit-parents": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz",
+ "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unplugin": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz",
+ "integrity": "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.14.0",
+ "webpack-virtual-modules": "^0.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/use-callback-ref": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",
+ "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/use-sidecar": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
+ "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "detect-node-es": "^1.1.0",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/util": {
+ "version": "0.12.5",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
+ "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "is-arguments": "^1.0.4",
+ "is-generator-function": "^1.0.7",
+ "is-typed-array": "^1.1.3",
+ "which-typed-array": "^1.1.2"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+ "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/vfile": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
+ "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vfile-message": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz",
+ "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vite": {
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
+ "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.25.0",
+ "fdir": "^6.4.4",
+ "picomatch": "^4.0.2",
+ "postcss": "^8.5.3",
+ "rollup": "^4.34.9",
+ "tinyglobby": "^0.2.13"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "jiti": ">=1.21.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-plugin-svgr": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.5.0.tgz",
+ "integrity": "sha512-W+uoSpmVkSmNOGPSsDCWVW/DDAyv+9fap9AZXBvWiQqrboJ08j2vh0tFxTD/LjwqwAd3yYSVJgm54S/1GhbdnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.2.0",
+ "@svgr/core": "^8.1.0",
+ "@svgr/plugin-jsx": "^8.1.0"
+ },
+ "peerDependencies": {
+ "vite": ">=2.6.0"
+ }
+ },
+ "node_modules/vite/node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/webpack-virtual-modules": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
+ "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-builtin-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.2.1",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.20",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz",
+ "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+ "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ws": {
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
+ "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yaml": {
+ "version": "2.8.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
+ "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
+ "devOptional": true,
+ "license": "ISC",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/eemeli"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/yargs/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/zod": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
+ "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/zod-validation-error": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz",
+ "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "zod": "^3.25.0 || ^4.0.0"
+ }
+ },
+ "node_modules/zustand": {
+ "version": "5.0.11",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.11.tgz",
+ "integrity": "sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18.0.0",
+ "immer": ">=9.0.6",
+ "react": ">=18.0.0",
+ "use-sync-external-store": ">=1.2.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "immer": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "use-sync-external-store": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/zwitch": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+ "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index b9df5e9f..c777a93d 100644
--- a/package.json
+++ b/package.json
@@ -8,28 +8,48 @@
"build": "tsc -b && vite build",
"lint": "eslint .",
"prepare": "husky",
- "preview": "vite preview"
+ "preview": "vite preview",
+ "storybook": "storybook dev -p 6006",
+ "build-storybook": "storybook build",
+ "chromatic": "npx chromatic --project-token=$CHROMATIC_PROJECT_TOKEN"
},
"dependencies": {
"@hookform/resolvers": "^5.2.2",
+ "@microsoft/fetch-event-source": "^2.0.1",
"@tailwindcss/vite": "^4.1.18",
"@tanstack/react-query": "^5.90.17",
+ "apexcharts": "^5.7.0",
+ "axios": "^1.13.4",
+ "clsx": "^2.1.1",
+ "framer-motion": "^12.38.0",
"react": "^19.2.0",
+ "react-apexcharts": "^2.0.1",
"react-dom": "^19.2.0",
"react-hook-form": "^7.71.1",
+ "react-markdown": "^10.1.0",
+ "react-remove-scroll": "^2.7.2",
"react-router-dom": "^7.12.0",
+ "sonner": "^2.0.7",
+ "tailwind-merge": "^3.4.1",
"tailwindcss": "^4.1.18",
"zod": "^4.3.5",
"zustand": "^5.0.10"
},
"devDependencies": {
+ "@commitlint/cli": "^20.3.1",
+ "@commitlint/config-conventional": "^20.3.1",
"@eslint/js": "^9.39.2",
+ "@storybook/addon-essentials": "8.6.17",
+ "@storybook/react": "8.6.17",
+ "@storybook/react-vite": "8.6.17",
+ "@storybook/test": "8.6.17",
+ "@tailwindcss/forms": "^0.5.11",
"@types/node": "^24.10.1",
"@types/react": "^19.2.5",
"@types/react-dom": "^19.2.3",
"@typescript-eslint/eslint-plugin": "^8.53.0",
"@typescript-eslint/parser": "^8.53.0",
- "@vitejs/plugin-react-swc": "^4.2.2",
+ "@vitejs/plugin-react-swc": "^3.11.0",
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-import": "^2.32.0",
@@ -45,9 +65,10 @@
"husky": "^9.1.7",
"lint-staged": "^16.2.7",
"prettier": "^3.7.4",
+ "storybook": "8.6.17",
"typescript": "~5.9.3",
"typescript-eslint": "^8.53.0",
- "vite": "^7.2.4",
+ "vite": "^6.4.1",
"vite-plugin-svgr": "^4.5.0"
},
"lint-staged": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b6bf1b12..6978dac5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -10,56 +10,107 @@ importers:
dependencies:
'@hookform/resolvers':
specifier: ^5.2.2
- version: 5.2.2(react-hook-form@7.71.1(react@19.2.3))
+ version: 5.2.2(react-hook-form@7.71.1(react@19.2.4))
+ '@microsoft/fetch-event-source':
+ specifier: ^2.0.1
+ version: 2.0.1
'@tailwindcss/vite':
specifier: ^4.1.18
- version: 4.1.18(vite@7.3.1(@types/node@24.10.8)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))
+ version: 4.2.0(vite@6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2))
'@tanstack/react-query':
specifier: ^5.90.17
- version: 5.90.17(react@19.2.3)
+ version: 5.90.21(react@19.2.4)
+ apexcharts:
+ specifier: ^5.7.0
+ version: 5.10.3
+ axios:
+ specifier: ^1.13.4
+ version: 1.13.5
+ clsx:
+ specifier: ^2.1.1
+ version: 2.1.1
+ framer-motion:
+ specifier: ^12.38.0
+ version: 12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
react:
specifier: ^19.2.0
- version: 19.2.3
+ version: 19.2.4
+ react-apexcharts:
+ specifier: ^2.0.1
+ version: 2.1.0(apexcharts@5.10.3)(react@19.2.4)
react-dom:
specifier: ^19.2.0
- version: 19.2.3(react@19.2.3)
+ version: 19.2.4(react@19.2.4)
react-hook-form:
specifier: ^7.71.1
- version: 7.71.1(react@19.2.3)
+ version: 7.71.1(react@19.2.4)
+ react-markdown:
+ specifier: ^10.1.0
+ version: 10.1.0(@types/react@19.2.14)(react@19.2.4)
+ react-remove-scroll:
+ specifier: ^2.7.2
+ version: 2.7.2(@types/react@19.2.14)(react@19.2.4)
react-router-dom:
specifier: ^7.12.0
- version: 7.12.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ version: 7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
+ sonner:
+ specifier: ^2.0.7
+ version: 2.0.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
+ tailwind-merge:
+ specifier: ^3.4.1
+ version: 3.5.0
tailwindcss:
specifier: ^4.1.18
- version: 4.1.18
+ version: 4.2.0
zod:
specifier: ^4.3.5
- version: 4.3.5
+ version: 4.3.6
zustand:
specifier: ^5.0.10
- version: 5.0.10(@types/react@19.2.8)(react@19.2.3)
+ version: 5.0.11(@types/react@19.2.14)(react@19.2.4)
devDependencies:
+ '@commitlint/cli':
+ specifier: ^20.3.1
+ version: 20.4.1(@types/node@24.10.13)(typescript@5.9.3)
+ '@commitlint/config-conventional':
+ specifier: ^20.3.1
+ version: 20.4.1
'@eslint/js':
specifier: ^9.39.2
version: 9.39.2
+ '@storybook/addon-essentials':
+ specifier: 8.6.17
+ version: 8.6.17(@types/react@19.2.14)(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/react':
+ specifier: 8.6.17
+ version: 8.6.17(@storybook/test@8.6.17(storybook@8.6.17(prettier@3.8.1)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.6.17(prettier@3.8.1))(typescript@5.9.3)
+ '@storybook/react-vite':
+ specifier: 8.6.17
+ version: 8.6.17(@storybook/test@8.6.17(storybook@8.6.17(prettier@3.8.1)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.57.1)(storybook@8.6.17(prettier@3.8.1))(typescript@5.9.3)(vite@6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2))
+ '@storybook/test':
+ specifier: 8.6.17
+ version: 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ '@tailwindcss/forms':
+ specifier: ^0.5.11
+ version: 0.5.11(tailwindcss@4.2.0)
'@types/node':
specifier: ^24.10.1
- version: 24.10.8
+ version: 24.10.13
'@types/react':
specifier: ^19.2.5
- version: 19.2.8
+ version: 19.2.14
'@types/react-dom':
specifier: ^19.2.3
- version: 19.2.3(@types/react@19.2.8)
+ version: 19.2.3(@types/react@19.2.14)
'@typescript-eslint/eslint-plugin':
specifier: ^8.53.0
- version: 8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ version: 8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/parser':
specifier: ^8.53.0
- version: 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ version: 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
'@vitejs/plugin-react-swc':
- specifier: ^4.2.2
- version: 4.2.2(vite@7.3.1(@types/node@24.10.8)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))
+ specifier: ^3.11.0
+ version: 3.11.0(vite@6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2))
eslint:
specifier: ^9.39.2
version: 9.39.2(jiti@2.6.1)
@@ -68,7 +119,7 @@ importers:
version: 10.1.8(eslint@9.39.2(jiti@2.6.1))
eslint-plugin-import:
specifier: ^2.32.0
- version: 2.32.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))
+ version: 2.32.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))
eslint-plugin-import-name:
specifier: ^1.2.3
version: 1.2.3
@@ -77,7 +128,7 @@ importers:
version: 6.10.2(eslint@9.39.2(jiti@2.6.1))
eslint-plugin-prettier:
specifier: ^5.5.4
- version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(prettier@3.7.4)
+ version: 5.5.5(eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(prettier@3.8.1)
eslint-plugin-react:
specifier: ^7.37.5
version: 7.37.5(eslint@9.39.2(jiti@2.6.1))
@@ -92,7 +143,7 @@ importers:
version: 12.1.1(eslint@9.39.2(jiti@2.6.1))
eslint-plugin-unused-imports:
specifier: ^4.3.0
- version: 4.3.0(@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))
+ version: 4.4.1(@typescript-eslint/eslint-plugin@8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))
globals:
specifier: ^16.5.0
version: 16.5.0
@@ -104,36 +155,42 @@ importers:
version: 16.2.7
prettier:
specifier: ^3.7.4
- version: 3.7.4
+ version: 3.8.1
+ storybook:
+ specifier: 8.6.17
+ version: 8.6.17(prettier@3.8.1)
typescript:
specifier: ~5.9.3
version: 5.9.3
typescript-eslint:
specifier: ^8.53.0
- version: 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ version: 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
vite:
- specifier: ^7.2.4
- version: 7.3.1(@types/node@24.10.8)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)
+ specifier: ^6.4.1
+ version: 6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2)
vite-plugin-svgr:
specifier: ^4.5.0
- version: 4.5.0(rollup@4.55.1)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.8)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))
+ version: 4.5.0(rollup@4.57.1)(typescript@5.9.3)(vite@6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2))
packages:
- '@babel/code-frame@7.28.6':
- resolution: {integrity: sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==}
+ '@adobe/css-tools@4.4.4':
+ resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==}
+
+ '@babel/code-frame@7.29.0':
+ resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
engines: {node: '>=6.9.0'}
- '@babel/compat-data@7.28.6':
- resolution: {integrity: sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==}
+ '@babel/compat-data@7.29.0':
+ resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==}
engines: {node: '>=6.9.0'}
- '@babel/core@7.28.6':
- resolution: {integrity: sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==}
+ '@babel/core@7.29.0':
+ resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==}
engines: {node: '>=6.9.0'}
- '@babel/generator@7.28.6':
- resolution: {integrity: sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==}
+ '@babel/generator@7.29.1':
+ resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==}
engines: {node: '>=6.9.0'}
'@babel/helper-compilation-targets@7.28.6':
@@ -170,175 +227,248 @@ packages:
resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==}
engines: {node: '>=6.9.0'}
- '@babel/parser@7.28.6':
- resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==}
+ '@babel/parser@7.29.0':
+ resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==}
engines: {node: '>=6.0.0'}
hasBin: true
+ '@babel/runtime@7.28.6':
+ resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==}
+ engines: {node: '>=6.9.0'}
+
'@babel/template@7.28.6':
resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==}
engines: {node: '>=6.9.0'}
- '@babel/traverse@7.28.6':
- resolution: {integrity: sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==}
+ '@babel/traverse@7.29.0':
+ resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==}
engines: {node: '>=6.9.0'}
- '@babel/types@7.28.6':
- resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==}
+ '@babel/types@7.29.0':
+ resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
engines: {node: '>=6.9.0'}
- '@esbuild/aix-ppc64@0.27.2':
- resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==}
+ '@commitlint/cli@20.4.1':
+ resolution: {integrity: sha512-uuFKKpc7OtQM+6SRqT+a4kV818o1pS+uvv/gsRhyX7g4x495jg+Q7P0+O9VNGyLXBYP0syksS7gMRDJKcekr6A==}
+ engines: {node: '>=v18'}
+ hasBin: true
+
+ '@commitlint/config-conventional@20.4.1':
+ resolution: {integrity: sha512-0YUvIeBtpi86XriqrR+TCULVFiyYTIOEPjK7tTRMxjcBm1qlzb+kz7IF2WxL6Fq5DaundG8VO37BNgMkMTBwqA==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/config-validator@20.4.0':
+ resolution: {integrity: sha512-zShmKTF+sqyNOfAE0vKcqnpvVpG0YX8F9G/ZIQHI2CoKyK+PSdladXMSns400aZ5/QZs+0fN75B//3Q5CHw++w==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/ensure@20.4.1':
+ resolution: {integrity: sha512-WLQqaFx1pBooiVvBrA1YfJNFqZF8wS/YGOtr5RzApDbV9tQ52qT5VkTsY65hFTnXhW8PcDfZLaknfJTmPejmlw==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/execute-rule@20.0.0':
+ resolution: {integrity: sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/format@20.4.0':
+ resolution: {integrity: sha512-i3ki3WR0rgolFVX6r64poBHXM1t8qlFel1G1eCBvVgntE3fCJitmzSvH5JD/KVJN/snz6TfaX2CLdON7+s4WVQ==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/is-ignored@20.4.1':
+ resolution: {integrity: sha512-In5EO4JR1lNsAv1oOBBO24V9ND1IqdAJDKZiEpdfjDl2HMasAcT7oA+5BKONv1pRoLG380DGPE2W2RIcUwdgLA==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/lint@20.4.1':
+ resolution: {integrity: sha512-g94LrGl/c6UhuhDQqNqU232aslLEN2vzc7MPfQTHzwzM4GHNnEAwVWWnh0zX8S5YXecuLXDwbCsoGwmpAgPWKA==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/load@20.4.0':
+ resolution: {integrity: sha512-Dauup/GfjwffBXRJUdlX/YRKfSVXsXZLnINXKz0VZkXdKDcaEILAi9oflHGbfydonJnJAbXEbF3nXPm9rm3G6A==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/message@20.4.0':
+ resolution: {integrity: sha512-B5lGtvHgiLAIsK5nLINzVW0bN5hXv+EW35sKhYHE8F7V9Uz1fR4tx3wt7mobA5UNhZKUNgB/+ldVMQE6IHZRyA==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/parse@20.4.1':
+ resolution: {integrity: sha512-XNtZjeRcFuAfUnhYrCY02+mpxwY4OmnvD3ETbVPs25xJFFz1nRo/25nHj+5eM+zTeRFvWFwD4GXWU2JEtoK1/w==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/read@20.4.0':
+ resolution: {integrity: sha512-QfpFn6/I240ySEGv7YWqho4vxqtPpx40FS7kZZDjUJ+eHxu3azfhy7fFb5XzfTqVNp1hNoI3tEmiEPbDB44+cg==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/resolve-extends@20.4.0':
+ resolution: {integrity: sha512-ay1KM8q0t+/OnlpqXJ+7gEFQNlUtSU5Gxr8GEwnVf2TPN3+ywc5DzL3JCxmpucqxfHBTFwfRMXxPRRnR5Ki20g==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/rules@20.4.1':
+ resolution: {integrity: sha512-WtqypKEPbQEuJwJS4aKs0OoJRBKz1HXPBC9wRtzVNH68FLhPWzxXlF09hpUXM9zdYTpm4vAdoTGkWiBgQ/vL0g==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/to-lines@20.0.0':
+ resolution: {integrity: sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/top-level@20.4.0':
+ resolution: {integrity: sha512-NDzq8Q6jmFaIIBC/GG6n1OQEaHdmaAAYdrZRlMgW6glYWGZ+IeuXmiymDvQNXPc82mVxq2KiE3RVpcs+1OeDeA==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/types@20.4.0':
+ resolution: {integrity: sha512-aO5l99BQJ0X34ft8b0h7QFkQlqxC6e7ZPVmBKz13xM9O8obDaM1Cld4sQlJDXXU/VFuUzQ30mVtHjVz74TuStw==}
+ engines: {node: '>=v18'}
+
+ '@esbuild/aix-ppc64@0.25.12':
+ resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
- '@esbuild/android-arm64@0.27.2':
- resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==}
+ '@esbuild/android-arm64@0.25.12':
+ resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
- '@esbuild/android-arm@0.27.2':
- resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==}
+ '@esbuild/android-arm@0.25.12':
+ resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
- '@esbuild/android-x64@0.27.2':
- resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==}
+ '@esbuild/android-x64@0.25.12':
+ resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
- '@esbuild/darwin-arm64@0.27.2':
- resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==}
+ '@esbuild/darwin-arm64@0.25.12':
+ resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
- '@esbuild/darwin-x64@0.27.2':
- resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==}
+ '@esbuild/darwin-x64@0.25.12':
+ resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
- '@esbuild/freebsd-arm64@0.27.2':
- resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==}
+ '@esbuild/freebsd-arm64@0.25.12':
+ resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
- '@esbuild/freebsd-x64@0.27.2':
- resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==}
+ '@esbuild/freebsd-x64@0.25.12':
+ resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
- '@esbuild/linux-arm64@0.27.2':
- resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==}
+ '@esbuild/linux-arm64@0.25.12':
+ resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
- '@esbuild/linux-arm@0.27.2':
- resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==}
+ '@esbuild/linux-arm@0.25.12':
+ resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
- '@esbuild/linux-ia32@0.27.2':
- resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==}
+ '@esbuild/linux-ia32@0.25.12':
+ resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
- '@esbuild/linux-loong64@0.27.2':
- resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==}
+ '@esbuild/linux-loong64@0.25.12':
+ resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
- '@esbuild/linux-mips64el@0.27.2':
- resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==}
+ '@esbuild/linux-mips64el@0.25.12':
+ resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
- '@esbuild/linux-ppc64@0.27.2':
- resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==}
+ '@esbuild/linux-ppc64@0.25.12':
+ resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
- '@esbuild/linux-riscv64@0.27.2':
- resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==}
+ '@esbuild/linux-riscv64@0.25.12':
+ resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
- '@esbuild/linux-s390x@0.27.2':
- resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==}
+ '@esbuild/linux-s390x@0.25.12':
+ resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
- '@esbuild/linux-x64@0.27.2':
- resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==}
+ '@esbuild/linux-x64@0.25.12':
+ resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
- '@esbuild/netbsd-arm64@0.27.2':
- resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==}
+ '@esbuild/netbsd-arm64@0.25.12':
+ resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
- '@esbuild/netbsd-x64@0.27.2':
- resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==}
+ '@esbuild/netbsd-x64@0.25.12':
+ resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
- '@esbuild/openbsd-arm64@0.27.2':
- resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==}
+ '@esbuild/openbsd-arm64@0.25.12':
+ resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
- '@esbuild/openbsd-x64@0.27.2':
- resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==}
+ '@esbuild/openbsd-x64@0.25.12':
+ resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
- '@esbuild/openharmony-arm64@0.27.2':
- resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==}
+ '@esbuild/openharmony-arm64@0.25.12':
+ resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openharmony]
- '@esbuild/sunos-x64@0.27.2':
- resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==}
+ '@esbuild/sunos-x64@0.25.12':
+ resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
- '@esbuild/win32-arm64@0.27.2':
- resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==}
+ '@esbuild/win32-arm64@0.25.12':
+ resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
- '@esbuild/win32-ia32@0.27.2':
- resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==}
+ '@esbuild/win32-ia32@0.25.12':
+ resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
- '@esbuild/win32-x64@0.27.2':
- resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==}
+ '@esbuild/win32-x64@0.25.12':
+ resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
@@ -402,6 +532,19 @@ packages:
resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
engines: {node: '>=18.18'}
+ '@isaacs/cliui@8.0.2':
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
+ engines: {node: '>=12'}
+
+ '@joshwooding/vite-plugin-react-docgen-typescript@0.5.0':
+ resolution: {integrity: sha512-qYDdL7fPwLRI+bJNurVcis+tNgJmvWjH4YTBGXTA8xMuxFrnAz6E5o35iyzyKbq5J5Lr8mJGfrR5GXl+WGwhgQ==}
+ 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.13':
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
@@ -418,12 +561,25 @@ packages:
'@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+ '@mdx-js/react@3.1.1':
+ resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==}
+ peerDependencies:
+ '@types/react': '>=16'
+ react: '>=16'
+
+ '@microsoft/fetch-event-source@2.0.1':
+ resolution: {integrity: sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==}
+
+ '@pkgjs/parseargs@0.11.0':
+ resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
+ engines: {node: '>=14'}
+
'@pkgr/core@0.2.9':
resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
- '@rolldown/pluginutils@1.0.0-beta.47':
- resolution: {integrity: sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw==}
+ '@rolldown/pluginutils@1.0.0-beta.27':
+ resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==}
'@rollup/pluginutils@5.3.0':
resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==}
@@ -434,128 +590,128 @@ packages:
rollup:
optional: true
- '@rollup/rollup-android-arm-eabi@4.55.1':
- resolution: {integrity: sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==}
+ '@rollup/rollup-android-arm-eabi@4.57.1':
+ resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==}
cpu: [arm]
os: [android]
- '@rollup/rollup-android-arm64@4.55.1':
- resolution: {integrity: sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==}
+ '@rollup/rollup-android-arm64@4.57.1':
+ resolution: {integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==}
cpu: [arm64]
os: [android]
- '@rollup/rollup-darwin-arm64@4.55.1':
- resolution: {integrity: sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==}
+ '@rollup/rollup-darwin-arm64@4.57.1':
+ resolution: {integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==}
cpu: [arm64]
os: [darwin]
- '@rollup/rollup-darwin-x64@4.55.1':
- resolution: {integrity: sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==}
+ '@rollup/rollup-darwin-x64@4.57.1':
+ resolution: {integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==}
cpu: [x64]
os: [darwin]
- '@rollup/rollup-freebsd-arm64@4.55.1':
- resolution: {integrity: sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==}
+ '@rollup/rollup-freebsd-arm64@4.57.1':
+ resolution: {integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==}
cpu: [arm64]
os: [freebsd]
- '@rollup/rollup-freebsd-x64@4.55.1':
- resolution: {integrity: sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==}
+ '@rollup/rollup-freebsd-x64@4.57.1':
+ resolution: {integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==}
cpu: [x64]
os: [freebsd]
- '@rollup/rollup-linux-arm-gnueabihf@4.55.1':
- resolution: {integrity: sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==}
+ '@rollup/rollup-linux-arm-gnueabihf@4.57.1':
+ resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==}
cpu: [arm]
os: [linux]
- '@rollup/rollup-linux-arm-musleabihf@4.55.1':
- resolution: {integrity: sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==}
+ '@rollup/rollup-linux-arm-musleabihf@4.57.1':
+ resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==}
cpu: [arm]
os: [linux]
- '@rollup/rollup-linux-arm64-gnu@4.55.1':
- resolution: {integrity: sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==}
+ '@rollup/rollup-linux-arm64-gnu@4.57.1':
+ resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==}
cpu: [arm64]
os: [linux]
- '@rollup/rollup-linux-arm64-musl@4.55.1':
- resolution: {integrity: sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==}
+ '@rollup/rollup-linux-arm64-musl@4.57.1':
+ resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==}
cpu: [arm64]
os: [linux]
- '@rollup/rollup-linux-loong64-gnu@4.55.1':
- resolution: {integrity: sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==}
+ '@rollup/rollup-linux-loong64-gnu@4.57.1':
+ resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==}
cpu: [loong64]
os: [linux]
- '@rollup/rollup-linux-loong64-musl@4.55.1':
- resolution: {integrity: sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==}
+ '@rollup/rollup-linux-loong64-musl@4.57.1':
+ resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==}
cpu: [loong64]
os: [linux]
- '@rollup/rollup-linux-ppc64-gnu@4.55.1':
- resolution: {integrity: sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==}
+ '@rollup/rollup-linux-ppc64-gnu@4.57.1':
+ resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==}
cpu: [ppc64]
os: [linux]
- '@rollup/rollup-linux-ppc64-musl@4.55.1':
- resolution: {integrity: sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==}
+ '@rollup/rollup-linux-ppc64-musl@4.57.1':
+ resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==}
cpu: [ppc64]
os: [linux]
- '@rollup/rollup-linux-riscv64-gnu@4.55.1':
- resolution: {integrity: sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==}
+ '@rollup/rollup-linux-riscv64-gnu@4.57.1':
+ resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==}
cpu: [riscv64]
os: [linux]
- '@rollup/rollup-linux-riscv64-musl@4.55.1':
- resolution: {integrity: sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==}
+ '@rollup/rollup-linux-riscv64-musl@4.57.1':
+ resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==}
cpu: [riscv64]
os: [linux]
- '@rollup/rollup-linux-s390x-gnu@4.55.1':
- resolution: {integrity: sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==}
+ '@rollup/rollup-linux-s390x-gnu@4.57.1':
+ resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==}
cpu: [s390x]
os: [linux]
- '@rollup/rollup-linux-x64-gnu@4.55.1':
- resolution: {integrity: sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==}
+ '@rollup/rollup-linux-x64-gnu@4.57.1':
+ resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==}
cpu: [x64]
os: [linux]
- '@rollup/rollup-linux-x64-musl@4.55.1':
- resolution: {integrity: sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==}
+ '@rollup/rollup-linux-x64-musl@4.57.1':
+ resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==}
cpu: [x64]
os: [linux]
- '@rollup/rollup-openbsd-x64@4.55.1':
- resolution: {integrity: sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==}
+ '@rollup/rollup-openbsd-x64@4.57.1':
+ resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==}
cpu: [x64]
os: [openbsd]
- '@rollup/rollup-openharmony-arm64@4.55.1':
- resolution: {integrity: sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==}
+ '@rollup/rollup-openharmony-arm64@4.57.1':
+ resolution: {integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==}
cpu: [arm64]
os: [openharmony]
- '@rollup/rollup-win32-arm64-msvc@4.55.1':
- resolution: {integrity: sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==}
+ '@rollup/rollup-win32-arm64-msvc@4.57.1':
+ resolution: {integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==}
cpu: [arm64]
os: [win32]
- '@rollup/rollup-win32-ia32-msvc@4.55.1':
- resolution: {integrity: sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==}
+ '@rollup/rollup-win32-ia32-msvc@4.57.1':
+ resolution: {integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==}
cpu: [ia32]
os: [win32]
- '@rollup/rollup-win32-x64-gnu@4.55.1':
- resolution: {integrity: sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==}
+ '@rollup/rollup-win32-x64-gnu@4.57.1':
+ resolution: {integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==}
cpu: [x64]
os: [win32]
- '@rollup/rollup-win32-x64-msvc@4.55.1':
- resolution: {integrity: sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==}
+ '@rollup/rollup-win32-x64-msvc@4.57.1':
+ resolution: {integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==}
cpu: [x64]
os: [win32]
@@ -565,6 +721,162 @@ packages:
'@standard-schema/utils@0.3.0':
resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==}
+ '@storybook/addon-actions@8.6.17':
+ resolution: {integrity: sha512-/G3Y7WIzGHMtKT6r3KCqgY/pAzfMhNHvBoRWoPfxMa27GiwmUaJlbfRPSReK/jGz6ye0Uwqix+NFbRXKiTqOJQ==}
+ peerDependencies:
+ storybook: ^8.6.17
+
+ '@storybook/addon-backgrounds@8.6.17':
+ resolution: {integrity: sha512-oh7jEQUt8WhH7cBm0jsJ1dujyaujM5rVS5IXJmDgdFJ8l0pqGzOUDmgkBVX147Uo5W1U47Sx+hA69lg6TKPOMQ==}
+ peerDependencies:
+ storybook: ^8.6.17
+
+ '@storybook/addon-controls@8.6.17':
+ resolution: {integrity: sha512-kquUfiJyJMh8IHviTIz1A4UKqqNfvqrYFku9D3UukqkTriM1ngDOb9nryaJcUNTkco5JmIuGjYEJisva+u13lw==}
+ peerDependencies:
+ storybook: ^8.6.17
+
+ '@storybook/addon-docs@8.6.17':
+ resolution: {integrity: sha512-zvcSzoYvaZO4l9NxsviDr5vmuq8GVnH4Ap0v+5sSTq192yevm/iQcRnkWYBD9E/Lg5GBeyE+Ml2vjEOK+EPBEg==}
+ peerDependencies:
+ storybook: ^8.6.17
+
+ '@storybook/addon-essentials@8.6.17':
+ resolution: {integrity: sha512-nyp2RUxWGpD+xhGWOo221kHOY6cZlgXsV1F11sn7WxkH+yA7YHhLLYlIPHmNKKH+hdxN0rnlcpwjbr21u0Katg==}
+ peerDependencies:
+ storybook: ^8.6.17
+
+ '@storybook/addon-highlight@8.6.17':
+ resolution: {integrity: sha512-Tf7DxksSg+DqH0a0rLIpB5g9bJBUHcqmEGeYGX7EPQrXBpQAtFXz/XdzuD8eYDlPC1r42iQQw4w+CQnXJCOHFw==}
+ peerDependencies:
+ storybook: ^8.6.17
+
+ '@storybook/addon-measure@8.6.17':
+ resolution: {integrity: sha512-OFGmCrz9MTWfxa0t2GP+633VXZS7W3ahIM5bRmCTeG+jF/gdiVw3S2Adq7YiIZw+nROW9VtHBjuWGvy2miZxcQ==}
+ peerDependencies:
+ storybook: ^8.6.17
+
+ '@storybook/addon-outline@8.6.17':
+ resolution: {integrity: sha512-UfFThgImS8cuv9Mts5JozGO2/SgjU61uKZxn7w+YpJQu0r2UAF56ZBBMZF/Ur5IC4HaoqDWF5DksMlFqMHPBsw==}
+ peerDependencies:
+ storybook: ^8.6.17
+
+ '@storybook/addon-toolbars@8.6.17':
+ resolution: {integrity: sha512-LoWtnMVQJWivAu+SZdgYIsaiEqIq0mZ8Ses2xSwLnQZxndCakyqPYv/7YcdLDJaX5f8DpjPvSzJ77oa75oKgFw==}
+ peerDependencies:
+ storybook: ^8.6.17
+
+ '@storybook/addon-viewport@8.6.17':
+ resolution: {integrity: sha512-gVUtbFQq/mpD5CFOqXGAu5hUpGm/t5G/psg3YsTjnaRBd18dJZ/+//HzZVbX9aEW8t5qTJeJcEYaF5463BVfNA==}
+ peerDependencies:
+ storybook: ^8.6.17
+
+ '@storybook/blocks@8.6.17':
+ resolution: {integrity: sha512-zuYHH+0egovMrjWRKwOtgVGbz6KALGowPSWBzQ8deTBu6IXfkz6Ce1hRLJPn5S6/jDqqr9xx8vuAiypnRQ98tA==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ storybook: ^8.6.17
+ peerDependenciesMeta:
+ react:
+ optional: true
+ react-dom:
+ optional: true
+
+ '@storybook/builder-vite@8.6.17':
+ resolution: {integrity: sha512-ZqFaLUKlRNaU4ovEa5R6D5YTbft1CUcNHLhzpmL9JWInEh4PrUkxiLD/jjB6fiYLcRpSpcs2DF+O/Jh2GDWemA==}
+ peerDependencies:
+ storybook: ^8.6.17
+ vite: ^4.0.0 || ^5.0.0 || ^6.0.0
+
+ '@storybook/components@8.6.17':
+ resolution: {integrity: sha512-0b8xkkuPCNbM8LTOzyfxuo2KdJCHIfu3+QxWBFllXap0eYNHwVeSxE5KERQ/bk2GDCiRzaUbwH9PeLorxOzJJQ==}
+ peerDependencies:
+ storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
+
+ '@storybook/core@8.6.17':
+ resolution: {integrity: sha512-lndZDYIvUddWk54HmgYwE4h2B0JtWt8ztIRAzHRt6ReZZ9QQbmM5b85Qpa+ng4dyQEKc2JAtYD3Du7RRFcpHlw==}
+ peerDependencies:
+ prettier: ^2 || ^3
+ peerDependenciesMeta:
+ prettier:
+ optional: true
+
+ '@storybook/csf-plugin@8.6.17':
+ resolution: {integrity: sha512-ouvF/izbKclZxpfnRUkyC5ZVDU7QA0cHhjQnXTDT4F8b0uciQUDw1LosDZy5MXf03BeIDdyBAtzd/ym3wzd+kw==}
+ peerDependencies:
+ storybook: ^8.6.17
+
+ '@storybook/global@5.0.0':
+ resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==}
+
+ '@storybook/icons@1.6.0':
+ resolution: {integrity: sha512-hcFZIjW8yQz8O8//2WTIXylm5Xsgc+lW9ISLgUk1xGmptIJQRdlhVIXCpSyLrQaaRiyhQRaVg7l3BD9S216BHw==}
+ 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.6.17':
+ resolution: {integrity: sha512-uPqC0sPY2tYGkEVi1x+L4hvhkTwxT16B/LB8xIXh68co3gR8vY6wVskoBp2tM7LSUGl08U2ksZWxyTo1DaQY5Q==}
+ peerDependencies:
+ storybook: ^8.6.17
+
+ '@storybook/manager-api@8.6.17':
+ resolution: {integrity: sha512-sPJytvClNrw5GgKcPletMTxDOAYcTRA8VRt9E+ncKvPSYHtPDqLfGTgWajXmt0hRsiBUN5bOgLS9bmNjNQWhrw==}
+ 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.6.17':
+ resolution: {integrity: sha512-vpTCTkw11wXerYnlG5Q0y4SbFqG9O6GhR0hlYgCn3Z9kcHlNjK/xuwd3h4CvwNXxRNWZGT8qYYCLn5gSSrX6fA==}
+ 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.6.17':
+ resolution: {integrity: sha512-bHLsR9b/tiwm9lXbN8kp9XlOgkRXeg84UFwXaWBPu3pOO7vRXukk23SQUpLW+HhjKtCJ3xClSi5uMpse5MpkVQ==}
+ 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.6.17
+
+ '@storybook/react-vite@8.6.17':
+ resolution: {integrity: sha512-Tsn16nN++3j0fynrPQkuxxNQHHh06nqgYRTfCTT5qQUV6hDY1uiwN7ZkJEIODEqc26O4HRd0yrAA6lOnr1KZOg==}
+ engines: {node: '>=18.0.0'}
+ peerDependencies:
+ '@storybook/test': 8.6.17
+ 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.6.17
+ vite: ^4.0.0 || ^5.0.0 || ^6.0.0
+ peerDependenciesMeta:
+ '@storybook/test':
+ optional: true
+
+ '@storybook/react@8.6.17':
+ resolution: {integrity: sha512-yoOzgyZ2VXPJBmvcKS4EVoAf7SJxXbMBcLjWGvmWdDnS+hd7S9cHG/SbgQ+9/vgiLUc+uEuvQjiKrwY3iOA5rg==}
+ engines: {node: '>=18.0.0'}
+ peerDependencies:
+ '@storybook/test': 8.6.17
+ 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.6.17
+ typescript: '>= 4.2.x'
+ peerDependenciesMeta:
+ '@storybook/test':
+ optional: true
+ typescript:
+ optional: true
+
+ '@storybook/test@8.6.17':
+ resolution: {integrity: sha512-VTuCylXGQrFDZXqZ29+yvJ+A4TZ69jG72rLjiic8hI0SOt87AC/8X1NaYvd2NS4TY0G0PwqtxmKeig8qRDrhNg==}
+ peerDependencies:
+ storybook: ^8.6.17
+
+ '@storybook/theming@8.6.17':
+ resolution: {integrity: sha512-IttFvRqozpuzN5MlQEWGOzUA2rZg86688Dyv1d+bjpYcFHtY1X4XyTCGwv1BPTaTsB959oM8R2yoNYWQkABbBA==}
+ 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'}
@@ -633,68 +945,68 @@ packages:
peerDependencies:
'@svgr/core': '*'
- '@swc/core-darwin-arm64@1.15.8':
- resolution: {integrity: sha512-M9cK5GwyWWRkRGwwCbREuj6r8jKdES/haCZ3Xckgkl8MUQJZA3XB7IXXK1IXRNeLjg6m7cnoMICpXv1v1hlJOg==}
+ '@swc/core-darwin-arm64@1.15.11':
+ resolution: {integrity: sha512-QoIupRWVH8AF1TgxYyeA5nS18dtqMuxNwchjBIwJo3RdwLEFiJq6onOx9JAxHtuPwUkIVuU2Xbp+jCJ7Vzmgtg==}
engines: {node: '>=10'}
cpu: [arm64]
os: [darwin]
- '@swc/core-darwin-x64@1.15.8':
- resolution: {integrity: sha512-j47DasuOvXl80sKJHSi2X25l44CMc3VDhlJwA7oewC1nV1VsSzwX+KOwE5tLnfORvVJJyeiXgJORNYg4jeIjYQ==}
+ '@swc/core-darwin-x64@1.15.11':
+ resolution: {integrity: sha512-S52Gu1QtPSfBYDiejlcfp9GlN+NjTZBRRNsz8PNwBgSE626/FUf2PcllVUix7jqkoMC+t0rS8t+2/aSWlMuQtA==}
engines: {node: '>=10'}
cpu: [x64]
os: [darwin]
- '@swc/core-linux-arm-gnueabihf@1.15.8':
- resolution: {integrity: sha512-siAzDENu2rUbwr9+fayWa26r5A9fol1iORG53HWxQL1J8ym4k7xt9eME0dMPXlYZDytK5r9sW8zEA10F2U3Xwg==}
+ '@swc/core-linux-arm-gnueabihf@1.15.11':
+ resolution: {integrity: sha512-lXJs8oXo6Z4yCpimpQ8vPeCjkgoHu5NoMvmJZ8qxDyU99KVdg6KwU9H79vzrmB+HfH+dCZ7JGMqMF//f8Cfvdg==}
engines: {node: '>=10'}
cpu: [arm]
os: [linux]
- '@swc/core-linux-arm64-gnu@1.15.8':
- resolution: {integrity: sha512-o+1y5u6k2FfPYbTRUPvurwzNt5qd0NTumCTFscCNuBksycloXY16J8L+SMW5QRX59n4Hp9EmFa3vpvNHRVv1+Q==}
+ '@swc/core-linux-arm64-gnu@1.15.11':
+ resolution: {integrity: sha512-chRsz1K52/vj8Mfq/QOugVphlKPWlMh10V99qfH41hbGvwAU6xSPd681upO4bKiOr9+mRIZZW+EfJqY42ZzRyA==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
- '@swc/core-linux-arm64-musl@1.15.8':
- resolution: {integrity: sha512-koiCqL09EwOP1S2RShCI7NbsQuG6r2brTqUYE7pV7kZm9O17wZ0LSz22m6gVibpwEnw8jI3IE1yYsQTVpluALw==}
+ '@swc/core-linux-arm64-musl@1.15.11':
+ resolution: {integrity: sha512-PYftgsTaGnfDK4m6/dty9ryK1FbLk+LosDJ/RJR2nkXGc8rd+WenXIlvHjWULiBVnS1RsjHHOXmTS4nDhe0v0w==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
- '@swc/core-linux-x64-gnu@1.15.8':
- resolution: {integrity: sha512-4p6lOMU3bC+Vd5ARtKJ/FxpIC5G8v3XLoPEZ5s7mLR8h7411HWC/LmTXDHcrSXRC55zvAVia1eldy6zDLz8iFQ==}
+ '@swc/core-linux-x64-gnu@1.15.11':
+ resolution: {integrity: sha512-DKtnJKIHiZdARyTKiX7zdRjiDS1KihkQWatQiCHMv+zc2sfwb4Glrodx2VLOX4rsa92NLR0Sw8WLcPEMFY1szQ==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
- '@swc/core-linux-x64-musl@1.15.8':
- resolution: {integrity: sha512-z3XBnbrZAL+6xDGAhJoN4lOueIxC/8rGrJ9tg+fEaeqLEuAtHSW2QHDHxDwkxZMjuF/pZ6MUTjHjbp8wLbuRLA==}
+ '@swc/core-linux-x64-musl@1.15.11':
+ resolution: {integrity: sha512-mUjjntHj4+8WBaiDe5UwRNHuEzLjIWBTSGTw0JT9+C9/Yyuh4KQqlcEQ3ro6GkHmBGXBFpGIj/o5VMyRWfVfWw==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
- '@swc/core-win32-arm64-msvc@1.15.8':
- resolution: {integrity: sha512-djQPJ9Rh9vP8GTS/Df3hcc6XP6xnG5c8qsngWId/BLA9oX6C7UzCPAn74BG/wGb9a6j4w3RINuoaieJB3t+7iQ==}
+ '@swc/core-win32-arm64-msvc@1.15.11':
+ resolution: {integrity: sha512-ZkNNG5zL49YpaFzfl6fskNOSxtcZ5uOYmWBkY4wVAvgbSAQzLRVBp+xArGWh2oXlY/WgL99zQSGTv7RI5E6nzA==}
engines: {node: '>=10'}
cpu: [arm64]
os: [win32]
- '@swc/core-win32-ia32-msvc@1.15.8':
- resolution: {integrity: sha512-/wfAgxORg2VBaUoFdytcVBVCgf1isWZIEXB9MZEUty4wwK93M/PxAkjifOho9RN3WrM3inPLabICRCEgdHpKKQ==}
+ '@swc/core-win32-ia32-msvc@1.15.11':
+ resolution: {integrity: sha512-6XnzORkZCQzvTQ6cPrU7iaT9+i145oLwnin8JrfsLG41wl26+5cNQ2XV3zcbrnFEV6esjOceom9YO1w9mGJByw==}
engines: {node: '>=10'}
cpu: [ia32]
os: [win32]
- '@swc/core-win32-x64-msvc@1.15.8':
- resolution: {integrity: sha512-GpMePrh9Sl4d61o4KAHOOv5is5+zt6BEXCOCgs/H0FLGeii7j9bWDE8ExvKFy2GRRZVNR1ugsnzaGWHKM6kuzA==}
+ '@swc/core-win32-x64-msvc@1.15.11':
+ resolution: {integrity: sha512-IQ2n6af7XKLL6P1gIeZACskSxK8jWtoKpJWLZmdXTDj1MGzktUy4i+FvpdtxFmJWNavRWH1VmTr6kAubRDHeKw==}
engines: {node: '>=10'}
cpu: [x64]
os: [win32]
- '@swc/core@1.15.8':
- resolution: {integrity: sha512-T8keoJjXaSUoVBCIjgL6wAnhADIb09GOELzKg10CjNg+vLX48P93SME6jTfte9MZIm5m+Il57H3rTSk/0kzDUw==}
+ '@swc/core@1.15.11':
+ resolution: {integrity: sha512-iLmLTodbYxU39HhMPaMUooPwO/zqJWvsqkrXv1ZI38rMb048p6N7qtAtTp37sw9NzSrvH6oli8EdDygo09IZ/w==}
engines: {node: '>=10'}
peerDependencies:
'@swc/helpers': '>=0.5.17'
@@ -708,65 +1020,70 @@ packages:
'@swc/types@0.1.25':
resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==}
- '@tailwindcss/node@4.1.18':
- resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==}
+ '@tailwindcss/forms@0.5.11':
+ resolution: {integrity: sha512-h9wegbZDPurxG22xZSoWtdzc41/OlNEUQERNqI/0fOwa2aVlWGu7C35E/x6LDyD3lgtztFSSjKZyuVM0hxhbgA==}
+ peerDependencies:
+ tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1'
+
+ '@tailwindcss/node@4.2.0':
+ resolution: {integrity: sha512-Yv+fn/o2OmL5fh/Ir62VXItdShnUxfpkMA4Y7jdeC8O81WPB8Kf6TT6GSHvnqgSwDzlB5iT7kDpeXxLsUS0T6Q==}
- '@tailwindcss/oxide-android-arm64@4.1.18':
- resolution: {integrity: sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==}
- engines: {node: '>= 10'}
+ '@tailwindcss/oxide-android-arm64@4.2.0':
+ resolution: {integrity: sha512-F0QkHAVaW/JNBWl4CEKWdZ9PMb0khw5DCELAOnu+RtjAfx5Zgw+gqCHFvqg3AirU1IAd181fwOtJQ5I8Yx5wtw==}
+ engines: {node: '>= 20'}
cpu: [arm64]
os: [android]
- '@tailwindcss/oxide-darwin-arm64@4.1.18':
- resolution: {integrity: sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==}
- engines: {node: '>= 10'}
+ '@tailwindcss/oxide-darwin-arm64@4.2.0':
+ resolution: {integrity: sha512-I0QylkXsBsJMZ4nkUNSR04p6+UptjcwhcVo3Zu828ikiEqHjVmQL9RuQ6uT/cVIiKpvtVA25msu/eRV97JeNSA==}
+ engines: {node: '>= 20'}
cpu: [arm64]
os: [darwin]
- '@tailwindcss/oxide-darwin-x64@4.1.18':
- resolution: {integrity: sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==}
- engines: {node: '>= 10'}
+ '@tailwindcss/oxide-darwin-x64@4.2.0':
+ resolution: {integrity: sha512-6TmQIn4p09PBrmnkvbYQ0wbZhLtbaksCDx7Y7R3FYYx0yxNA7xg5KP7dowmQ3d2JVdabIHvs3Hx4K3d5uCf8xg==}
+ engines: {node: '>= 20'}
cpu: [x64]
os: [darwin]
- '@tailwindcss/oxide-freebsd-x64@4.1.18':
- resolution: {integrity: sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==}
- engines: {node: '>= 10'}
+ '@tailwindcss/oxide-freebsd-x64@4.2.0':
+ resolution: {integrity: sha512-qBudxDvAa2QwGlq9y7VIzhTvp2mLJ6nD/G8/tI70DCDoneaUeLWBJaPcbfzqRIWraj+o969aDQKvKW9dvkUizw==}
+ engines: {node: '>= 20'}
cpu: [x64]
os: [freebsd]
- '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18':
- resolution: {integrity: sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==}
- engines: {node: '>= 10'}
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.0':
+ resolution: {integrity: sha512-7XKkitpy5NIjFZNUQPeUyNJNJn1CJeV7rmMR+exHfTuOsg8rxIO9eNV5TSEnqRcaOK77zQpsyUkBWmPy8FgdSg==}
+ engines: {node: '>= 20'}
cpu: [arm]
os: [linux]
- '@tailwindcss/oxide-linux-arm64-gnu@4.1.18':
- resolution: {integrity: sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==}
- engines: {node: '>= 10'}
+ '@tailwindcss/oxide-linux-arm64-gnu@4.2.0':
+ resolution: {integrity: sha512-Mff5a5Q3WoQR01pGU1gr29hHM1N93xYrKkGXfPw/aRtK4bOc331Ho4Tgfsm5WDGvpevqMpdlkCojT3qlCQbCpA==}
+ engines: {node: '>= 20'}
cpu: [arm64]
os: [linux]
- '@tailwindcss/oxide-linux-arm64-musl@4.1.18':
- resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==}
- engines: {node: '>= 10'}
+ '@tailwindcss/oxide-linux-arm64-musl@4.2.0':
+ resolution: {integrity: sha512-XKcSStleEVnbH6W/9DHzZv1YhjE4eSS6zOu2eRtYAIh7aV4o3vIBs+t/B15xlqoxt6ef/0uiqJVB6hkHjWD/0A==}
+ engines: {node: '>= 20'}
cpu: [arm64]
os: [linux]
- '@tailwindcss/oxide-linux-x64-gnu@4.1.18':
- resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==}
- engines: {node: '>= 10'}
+ '@tailwindcss/oxide-linux-x64-gnu@4.2.0':
+ resolution: {integrity: sha512-/hlXCBqn9K6fi7eAM0RsobHwJYa5V/xzWspVTzxnX+Ft9v6n+30Pz8+RxCn7sQL/vRHHLS30iQPrHQunu6/vJA==}
+ engines: {node: '>= 20'}
cpu: [x64]
os: [linux]
- '@tailwindcss/oxide-linux-x64-musl@4.1.18':
- resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==}
- engines: {node: '>= 10'}
+ '@tailwindcss/oxide-linux-x64-musl@4.2.0':
+ resolution: {integrity: sha512-lKUaygq4G7sWkhQbfdRRBkaq4LY39IriqBQ+Gk6l5nKq6Ay2M2ZZb1tlIyRNgZKS8cbErTwuYSor0IIULC0SHw==}
+ engines: {node: '>= 20'}
cpu: [x64]
os: [linux]
- '@tailwindcss/oxide-wasm32-wasi@4.1.18':
- resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==}
+ '@tailwindcss/oxide-wasm32-wasi@4.2.0':
+ resolution: {integrity: sha512-xuDjhAsFdUuFP5W9Ze4k/o4AskUtI8bcAGU4puTYprr89QaYFmhYOPfP+d1pH+k9ets6RoE23BXZM1X1jJqoyw==}
engines: {node: '>=14.0.0'}
cpu: [wasm32]
bundledDependencies:
@@ -777,120 +1094,205 @@ packages:
- '@emnapi/wasi-threads'
- tslib
- '@tailwindcss/oxide-win32-arm64-msvc@4.1.18':
- resolution: {integrity: sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==}
- engines: {node: '>= 10'}
+ '@tailwindcss/oxide-win32-arm64-msvc@4.2.0':
+ resolution: {integrity: sha512-2UU/15y1sWDEDNJXxEIrfWKC2Yb4YgIW5Xz2fKFqGzFWfoMHWFlfa1EJlGO2Xzjkq/tvSarh9ZTjvbxqWvLLXA==}
+ engines: {node: '>= 20'}
cpu: [arm64]
os: [win32]
- '@tailwindcss/oxide-win32-x64-msvc@4.1.18':
- resolution: {integrity: sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==}
- engines: {node: '>= 10'}
+ '@tailwindcss/oxide-win32-x64-msvc@4.2.0':
+ resolution: {integrity: sha512-CrFadmFoc+z76EV6LPG1jx6XceDsaCG3lFhyLNo/bV9ByPrE+FnBPckXQVP4XRkN76h3Fjt/a+5Er/oA/nCBvQ==}
+ engines: {node: '>= 20'}
cpu: [x64]
os: [win32]
- '@tailwindcss/oxide@4.1.18':
- resolution: {integrity: sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==}
- engines: {node: '>= 10'}
+ '@tailwindcss/oxide@4.2.0':
+ resolution: {integrity: sha512-AZqQzADaj742oqn2xjl5JbIOzZB/DGCYF/7bpvhA8KvjUj9HJkag6bBuwZvH1ps6dfgxNHyuJVlzSr2VpMgdTQ==}
+ engines: {node: '>= 20'}
- '@tailwindcss/vite@4.1.18':
- resolution: {integrity: sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==}
+ '@tailwindcss/vite@4.2.0':
+ resolution: {integrity: sha512-da9mFCaHpoOgtQiWtDGIikTrSpUFBtIZCG3jy/u2BGV+l/X1/pbxzmIUxNt6JWm19N3WtGi4KlJdSH/Si83WOA==}
peerDependencies:
vite: ^5.2.0 || ^6 || ^7
- '@tanstack/query-core@5.90.17':
- resolution: {integrity: sha512-hDww+RyyYhjhUfoYQ4es6pbgxY7LNiPWxt4l1nJqhByjndxJ7HIjDxTBtfvMr5HwjYavMrd+ids5g4Rfev3lVQ==}
+ '@tanstack/query-core@5.90.20':
+ resolution: {integrity: sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==}
- '@tanstack/react-query@5.90.17':
- resolution: {integrity: sha512-PGc2u9KLwohDUSchjW9MZqeDQJfJDON7y4W7REdNBgiFKxQy+Pf7eGjiFWEj5xPqKzAeHYdAb62IWI1a9UJyGQ==}
+ '@tanstack/react-query@5.90.21':
+ resolution: {integrity: sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==}
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==}
+
+ '@types/babel__generator@7.27.0':
+ resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==}
+
+ '@types/babel__template@7.4.4':
+ resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
+
+ '@types/babel__traverse@7.28.0':
+ resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==}
+
+ '@types/debug@4.1.12':
+ resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
+
+ '@types/doctrine@0.0.9':
+ resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==}
+
+ '@types/estree-jsx@1.0.5':
+ resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
+
'@types/estree@1.0.8':
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
+ '@types/hast@3.0.4':
+ resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
+
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
'@types/json5@0.0.29':
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
- '@types/node@24.10.8':
- resolution: {integrity: sha512-r0bBaXu5Swb05doFYO2kTWHMovJnNVbCsII0fhesM8bNRlLhXIuckley4a2DaD+vOdmm5G+zGkQZAPZsF80+YQ==}
+ '@types/mdast@4.0.4':
+ resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
+
+ '@types/mdx@2.0.13':
+ resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==}
+
+ '@types/ms@2.1.0':
+ resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
+
+ '@types/node@24.10.13':
+ resolution: {integrity: sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg==}
'@types/react-dom@19.2.3':
resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
peerDependencies:
'@types/react': ^19.2.0
- '@types/react@19.2.8':
- resolution: {integrity: sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg==}
+ '@types/react@19.2.14':
+ resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==}
+
+ '@types/resolve@1.20.6':
+ resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==}
+
+ '@types/unist@2.0.11':
+ resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
- '@typescript-eslint/eslint-plugin@8.53.0':
- resolution: {integrity: sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg==}
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
+ '@types/uuid@9.0.8':
+ resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==}
+
+ '@typescript-eslint/eslint-plugin@8.56.0':
+ resolution: {integrity: sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
- '@typescript-eslint/parser': ^8.53.0
- eslint: ^8.57.0 || ^9.0.0
+ '@typescript-eslint/parser': ^8.56.0
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/parser@8.53.0':
- resolution: {integrity: sha512-npiaib8XzbjtzS2N4HlqPvlpxpmZ14FjSJrteZpPxGUaYPlvhzlzUZ4mZyABo0EFrOWnvyd0Xxroq//hKhtAWg==}
+ '@typescript-eslint/parser@8.56.0':
+ resolution: {integrity: sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
- eslint: ^8.57.0 || ^9.0.0
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/project-service@8.53.0':
- resolution: {integrity: sha512-Bl6Gdr7NqkqIP5yP9z1JU///Nmes4Eose6L1HwpuVHwScgDPPuEWbUVhvlZmb8hy0vX9syLk5EGNL700WcBlbg==}
+ '@typescript-eslint/project-service@8.56.0':
+ resolution: {integrity: sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/scope-manager@8.53.0':
- resolution: {integrity: sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g==}
+ '@typescript-eslint/scope-manager@8.56.0':
+ resolution: {integrity: sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@typescript-eslint/tsconfig-utils@8.53.0':
- resolution: {integrity: sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA==}
+ '@typescript-eslint/tsconfig-utils@8.56.0':
+ resolution: {integrity: sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/type-utils@8.53.0':
- resolution: {integrity: sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw==}
+ '@typescript-eslint/type-utils@8.56.0':
+ resolution: {integrity: sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
- eslint: ^8.57.0 || ^9.0.0
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/types@8.53.0':
- resolution: {integrity: sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==}
+ '@typescript-eslint/types@8.56.0':
+ resolution: {integrity: sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@typescript-eslint/typescript-estree@8.53.0':
- resolution: {integrity: sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw==}
+ '@typescript-eslint/typescript-estree@8.56.0':
+ resolution: {integrity: sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/utils@8.53.0':
- resolution: {integrity: sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA==}
+ '@typescript-eslint/utils@8.56.0':
+ resolution: {integrity: sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
- eslint: ^8.57.0 || ^9.0.0
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/visitor-keys@8.53.0':
- resolution: {integrity: sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw==}
+ '@typescript-eslint/visitor-keys@8.56.0':
+ resolution: {integrity: sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@vitejs/plugin-react-swc@4.2.2':
- resolution: {integrity: sha512-x+rE6tsxq/gxrEJN3Nv3dIV60lFflPj94c90b+NNo6n1QV1QQUTLoL0MpaOVasUZ0zqVBn7ead1B5ecx1JAGfA==}
- engines: {node: ^20.19.0 || >=22.12.0}
+ '@ungap/structured-clone@1.3.0':
+ resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
+
+ '@vitejs/plugin-react-swc@3.11.0':
+ resolution: {integrity: sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w==}
peerDependencies:
vite: ^4 || ^5 || ^6 || ^7
+ '@vitest/expect@2.0.5':
+ resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==}
+
+ '@vitest/pretty-format@2.0.5':
+ resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==}
+
+ '@vitest/pretty-format@2.1.9':
+ resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==}
+
+ '@vitest/spy@2.0.5':
+ resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==}
+
+ '@vitest/utils@2.0.5':
+ resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==}
+
+ '@vitest/utils@2.1.9':
+ resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==}
+
+ '@yr/monotone-cubic-spline@1.0.3':
+ resolution: {integrity: sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==}
+
acorn-jsx@5.3.2:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
@@ -904,10 +1306,17 @@ packages:
ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
- ansi-escapes@7.2.0:
- resolution: {integrity: sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==}
+ ajv@8.18.0:
+ resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==}
+
+ ansi-escapes@7.3.0:
+ resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==}
engines: {node: '>=18'}
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
ansi-regex@6.2.2:
resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
engines: {node: '>=12'}
@@ -916,13 +1325,23 @@ packages:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
+ ansi-styles@5.2.0:
+ resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
+ engines: {node: '>=10'}
+
ansi-styles@6.2.3:
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
engines: {node: '>=12'}
+ apexcharts@5.10.3:
+ resolution: {integrity: sha512-wwvkSLsodNOc/rHo5MJsn3GPM4Krc5Gs0zKX4Lfzq4LohcTbyKylYUGEqJFmXXxGR7yLbZQz31sB5RTqT5mv1g==}
+
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'}
@@ -931,6 +1350,9 @@ packages:
resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
engines: {node: '>= 0.4'}
+ array-ify@1.0.0:
+ resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==}
+
array-includes@3.1.9:
resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==}
engines: {node: '>= 0.4'}
@@ -959,13 +1381,24 @@ packages:
resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
engines: {node: '>= 0.4'}
+ assertion-error@2.0.1:
+ resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+ engines: {node: '>=12'}
+
ast-types-flow@0.0.8:
resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==}
+ ast-types@0.16.1:
+ resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==}
+ engines: {node: '>=4'}
+
async-function@1.0.0:
resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
engines: {node: '>= 0.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'}
@@ -974,17 +1407,27 @@ packages:
resolution: {integrity: sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==}
engines: {node: '>=4'}
+ axios@1.13.5:
+ resolution: {integrity: sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==}
+
axobject-query@4.1.0:
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
engines: {node: '>= 0.4'}
+ bail@2.0.2:
+ resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
+
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
- baseline-browser-mapping@2.9.14:
- resolution: {integrity: sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==}
+ baseline-browser-mapping@2.9.19:
+ resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==}
hasBin: true
+ better-opn@3.0.2:
+ resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==}
+ engines: {node: '>=12.0.0'}
+
brace-expansion@1.1.12:
resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
@@ -995,6 +1438,9 @@ 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.28.1:
resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
@@ -1020,13 +1466,40 @@ packages:
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
engines: {node: '>=10'}
- caniuse-lite@1.0.30001764:
- resolution: {integrity: sha512-9JGuzl2M+vPL+pz70gtMF9sHdMFbY9FJaQBi186cHKH3pSzDvzoUJUPV6fqiKIMyXbud9ZLg4F3Yza1vJ1+93g==}
+ caniuse-lite@1.0.30001770:
+ resolution: {integrity: sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==}
+
+ ccount@2.0.1:
+ resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+
+ chai@5.3.3:
+ resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==}
+ engines: {node: '>=18'}
+
+ 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'}
+ character-entities-html4@2.1.0:
+ resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
+
+ character-entities-legacy@3.0.0:
+ resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
+
+ character-entities@2.0.2:
+ resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
+
+ character-reference-invalid@2.0.1:
+ resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
+
+ check-error@2.1.3:
+ resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==}
+ engines: {node: '>= 16'}
+
cli-cursor@5.0.0:
resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==}
engines: {node: '>=18'}
@@ -1035,6 +1508,14 @@ packages:
resolution: {integrity: sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==}
engines: {node: '>=20'}
+ cliui@8.0.1:
+ resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
+ engines: {node: '>=12'}
+
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
@@ -1045,13 +1526,36 @@ packages:
colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
- commander@14.0.2:
- resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==}
+ combined-stream@1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+
+ comma-separated-tokens@2.0.3:
+ resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
+
+ commander@14.0.3:
+ resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==}
engines: {node: '>=20'}
+ compare-func@2.0.0:
+ resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==}
+
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+ conventional-changelog-angular@8.1.0:
+ resolution: {integrity: sha512-GGf2Nipn1RUCAktxuVauVr1e3r8QrLP/B0lEUsFktmGqc3ddbQkhoJZHJctVU829U1c6mTSWftrVOCHaL85Q3w==}
+ engines: {node: '>=18'}
+
+ conventional-changelog-conventionalcommits@9.1.0:
+ resolution: {integrity: sha512-MnbEysR8wWa8dAEvbj5xcBgJKQlX/m0lhS8DsyAAWDHdfs2faDJxTgzRYlRYpXSe7UiKrIIlB4TrBKU9q9DgkA==}
+ engines: {node: '>=18'}
+
+ conventional-commits-parser@6.2.1:
+ resolution: {integrity: sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
@@ -1059,6 +1563,14 @@ packages:
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
engines: {node: '>=18'}
+ cosmiconfig-typescript-loader@6.2.0:
+ resolution: {integrity: sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==}
+ engines: {node: '>=v18'}
+ peerDependencies:
+ '@types/node': '*'
+ cosmiconfig: '>=9'
+ typescript: '>=5'
+
cosmiconfig@8.3.6:
resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==}
engines: {node: '>=14'}
@@ -1068,16 +1580,32 @@ packages:
typescript:
optional: true
+ cosmiconfig@9.0.0:
+ resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ typescript: '>=4.9.5'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
+ css.escape@1.5.1:
+ resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==}
+
csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
damerau-levenshtein@1.0.8:
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
+ dargs@8.1.0:
+ resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==}
+ engines: {node: '>=12'}
+
data-view-buffer@1.0.2:
resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
engines: {node: '>= 0.4'}
@@ -1107,6 +1635,13 @@ packages:
supports-color:
optional: true
+ decode-named-character-reference@1.3.0:
+ resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==}
+
+ deep-eql@5.0.2:
+ resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
+ engines: {node: '>=6'}
+
deep-is@0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
@@ -1114,42 +1649,84 @@ packages:
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'}
+
detect-libc@2.1.2:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'}
+ detect-node-es@1.1.0:
+ resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
+
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
doctrine@2.1.0:
resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
engines: {node: '>=0.10.0'}
+ 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==}
+
dot-case@3.0.4:
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
+ dot-prop@5.3.0:
+ resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
+ engines: {node: '>=8'}
+
dunder-proto@1.0.1:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
- electron-to-chromium@1.5.267:
- resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==}
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
+ electron-to-chromium@1.5.286:
+ resolution: {integrity: sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==}
emoji-regex@10.6.0:
resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==}
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
emoji-regex@9.2.2:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
- enhanced-resolve@5.18.4:
- resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==}
+ enhanced-resolve@5.19.0:
+ resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==}
engines: {node: '>=10.13.0'}
entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
+ env-paths@2.2.1:
+ resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
+ engines: {node: '>=6'}
+
environment@1.1.0:
resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==}
engines: {node: '>=18'}
@@ -1189,8 +1766,13 @@ packages:
resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
engines: {node: '>= 0.4'}
- esbuild@0.27.2:
- resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
+ esbuild-register@3.6.0:
+ resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==}
+ peerDependencies:
+ esbuild: '>=0.12 <1'
+
+ esbuild@0.25.12:
+ resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==}
engines: {node: '>=18'}
hasBin: true
@@ -1251,8 +1833,8 @@ packages:
peerDependencies:
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9
- eslint-plugin-prettier@5.5.4:
- resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==}
+ eslint-plugin-prettier@5.5.5:
+ resolution: {integrity: sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
'@types/eslint': '>=8.0.0'
@@ -1287,11 +1869,11 @@ packages:
peerDependencies:
eslint: '>=5.0.0'
- eslint-plugin-unused-imports@4.3.0:
- resolution: {integrity: sha512-ZFBmXMGBYfHttdRtOG9nFFpmUvMtbHSjsKrS20vdWdbfiVYsO3yA2SGYy9i9XmZJDfMGBflZGBCm70SEnFQtOA==}
+ eslint-plugin-unused-imports@4.4.1:
+ resolution: {integrity: sha512-oZGYUz1X3sRMGUB+0cZyK2VcvRX5lm/vB56PgNNcU+7ficUCKm66oZWKUubXWnOuPjQ8PvmXtCViXBMONPe7tQ==}
peerDependencies:
'@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0
- eslint: ^9.0.0 || ^8.0.0
+ eslint: ^10.0.0 || ^9.0.0 || ^8.0.0
peerDependenciesMeta:
'@typescript-eslint/eslint-plugin':
optional: true
@@ -1308,6 +1890,10 @@ packages:
resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ eslint-visitor-keys@5.0.0:
+ resolution: {integrity: sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
eslint@9.39.2:
resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -1322,6 +1908,11 @@ packages:
resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
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.7.0:
resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==}
engines: {node: '>=0.10'}
@@ -1334,15 +1925,24 @@ packages:
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
engines: {node: '>=4.0'}
+ estree-util-is-identifier-name@3.0.0:
+ resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==}
+
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@5.0.1:
- resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
+ eventemitter3@5.0.4:
+ resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==}
+
+ extend@3.0.2:
+ resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
@@ -1356,6 +1956,9 @@ packages:
fast-levenshtein@2.0.6:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+ fast-uri@3.1.0:
+ resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
+
fdir@6.5.0:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'}
@@ -1384,10 +1987,41 @@ packages:
flatted@3.3.3:
resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
+ follow-redirects@1.15.11:
+ resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ debug: '*'
+ peerDependenciesMeta:
+ debug:
+ optional: true
+
for-each@0.3.5:
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
engines: {node: '>= 0.4'}
+ foreground-child@3.3.1:
+ resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
+ engines: {node: '>=14'}
+
+ form-data@4.0.5:
+ resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
+ engines: {node: '>= 6'}
+
+ framer-motion@12.38.0:
+ resolution: {integrity: sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==}
+ peerDependencies:
+ '@emotion/is-prop-valid': '*'
+ react: ^18.0.0 || ^19.0.0
+ react-dom: ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@emotion/is-prop-valid':
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -1411,14 +2045,22 @@ packages:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'}
- get-east-asian-width@1.4.0:
- resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==}
+ get-caller-file@2.0.5:
+ resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
+ engines: {node: 6.* || 8.* || >= 10.*}
+
+ get-east-asian-width@1.5.0:
+ resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==}
engines: {node: '>=18'}
get-intrinsic@1.3.0:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'}
+ get-nonce@1.0.1:
+ resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
+ engines: {node: '>=6'}
+
get-proto@1.0.1:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'}
@@ -1427,10 +2069,24 @@ packages:
resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
engines: {node: '>= 0.4'}
+ git-raw-commits@4.0.0:
+ resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==}
+ engines: {node: '>=16'}
+ hasBin: true
+
glob-parent@6.0.2:
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
engines: {node: '>=10.13.0'}
+ glob@10.5.0:
+ resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==}
+ deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
+ hasBin: true
+
+ global-directory@4.0.1:
+ resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==}
+ engines: {node: '>=18'}
+
globals@14.0.0:
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
engines: {node: '>=18'}
@@ -1477,12 +2133,21 @@ packages:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
+ hast-util-to-jsx-runtime@2.3.6:
+ resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==}
+
+ hast-util-whitespace@3.0.0:
+ resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+
hermes-estree@0.25.1:
resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==}
hermes-parser@0.25.1:
resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==}
+ html-url-attributes@3.0.1:
+ resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==}
+
husky@9.1.7:
resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==}
engines: {node: '>=18'}
@@ -1500,14 +2165,41 @@ packages:
resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
engines: {node: '>=6'}
+ import-meta-resolve@4.2.0:
+ resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==}
+
imurmurhash@0.1.4:
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==}
+
+ ini@4.1.1:
+ resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+
+ inline-style-parser@0.2.7:
+ resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==}
+
internal-slot@1.1.0:
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
engines: {node: '>= 0.4'}
+ is-alphabetical@2.0.1:
+ resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
+
+ is-alphanumerical@2.0.1:
+ resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==}
+
+ is-arguments@1.2.0:
+ resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==}
+ engines: {node: '>= 0.4'}
+
is-array-buffer@3.0.5:
resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
engines: {node: '>= 0.4'}
@@ -1543,14 +2235,26 @@ packages:
resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==}
engines: {node: '>= 0.4'}
- is-extglob@2.1.1:
- resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ is-decimal@2.0.1:
+ resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
+
+ 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-finalizationregistry@1.1.1:
resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==}
engines: {node: '>= 0.4'}
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
is-fullwidth-code-point@5.1.0:
resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==}
engines: {node: '>=18'}
@@ -1563,6 +2267,9 @@ packages:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
+ is-hexadecimal@2.0.1:
+ resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
+
is-map@2.0.3:
resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
engines: {node: '>= 0.4'}
@@ -1579,6 +2286,14 @@ packages:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
+ is-obj@2.0.0:
+ resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
+ engines: {node: '>=8'}
+
+ is-plain-obj@4.1.0:
+ resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
+ engines: {node: '>=12'}
+
is-regex@1.2.1:
resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
engines: {node: '>= 0.4'}
@@ -1615,6 +2330,10 @@ packages:
resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==}
engines: {node: '>= 0.4'}
+ is-wsl@2.2.0:
+ resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
+ engines: {node: '>=8'}
+
isarray@2.0.5:
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
@@ -1625,6 +2344,9 @@ packages:
resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
engines: {node: '>= 0.4'}
+ jackspeak@3.4.3:
+ resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
+
jiti@2.6.1:
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
hasBin: true
@@ -1636,6 +2358,10 @@ packages:
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
hasBin: true
+ jsdoc-type-pratt-parser@4.8.0:
+ resolution: {integrity: sha512-iZ8Bdb84lWRuGHamRXFyML07r21pcwBrLkHEuHgEY5UbCouBwv7ECknDRKzsQIXMiqpPymqtIf8TC/shYKB5rw==}
+ engines: {node: '>=12.0.0'}
+
jsesc@3.1.0:
resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
engines: {node: '>=6'}
@@ -1650,6 +2376,9 @@ packages:
json-schema-traverse@0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
@@ -1680,74 +2409,74 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
- lightningcss-android-arm64@1.30.2:
- resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==}
+ lightningcss-android-arm64@1.31.1:
+ resolution: {integrity: sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [android]
- lightningcss-darwin-arm64@1.30.2:
- resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==}
+ lightningcss-darwin-arm64@1.31.1:
+ resolution: {integrity: sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [darwin]
- lightningcss-darwin-x64@1.30.2:
- resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==}
+ lightningcss-darwin-x64@1.31.1:
+ resolution: {integrity: sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [darwin]
- lightningcss-freebsd-x64@1.30.2:
- resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==}
+ lightningcss-freebsd-x64@1.31.1:
+ resolution: {integrity: sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [freebsd]
- lightningcss-linux-arm-gnueabihf@1.30.2:
- resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==}
+ lightningcss-linux-arm-gnueabihf@1.31.1:
+ resolution: {integrity: sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==}
engines: {node: '>= 12.0.0'}
cpu: [arm]
os: [linux]
- lightningcss-linux-arm64-gnu@1.30.2:
- resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==}
+ lightningcss-linux-arm64-gnu@1.31.1:
+ resolution: {integrity: sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
- lightningcss-linux-arm64-musl@1.30.2:
- resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==}
+ lightningcss-linux-arm64-musl@1.31.1:
+ resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
- lightningcss-linux-x64-gnu@1.30.2:
- resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==}
+ lightningcss-linux-x64-gnu@1.31.1:
+ resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
- lightningcss-linux-x64-musl@1.30.2:
- resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==}
+ lightningcss-linux-x64-musl@1.31.1:
+ resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
- lightningcss-win32-arm64-msvc@1.30.2:
- resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==}
+ lightningcss-win32-arm64-msvc@1.31.1:
+ resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [win32]
- lightningcss-win32-x64-msvc@1.30.2:
- resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==}
+ lightningcss-win32-x64-msvc@1.31.1:
+ resolution: {integrity: sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [win32]
- lightningcss@1.30.2:
- resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==}
+ lightningcss@1.31.1:
+ resolution: {integrity: sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==}
engines: {node: '>= 12.0.0'}
lines-and-columns@1.2.4:
@@ -1766,38 +2495,193 @@ packages:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
+ lodash.camelcase@4.3.0:
+ resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
+
+ lodash.kebabcase@4.1.1:
+ resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==}
+
lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+ lodash.mergewith@4.6.2:
+ resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==}
+
+ lodash.snakecase@4.1.1:
+ resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==}
+
+ lodash.startcase@4.4.0:
+ resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==}
+
+ lodash.upperfirst@4.3.1:
+ resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==}
+
+ lodash@4.17.23:
+ resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==}
+
log-update@6.1.0:
resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==}
engines: {node: '>=18'}
+ longest-streak@3.1.0:
+ resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
+
loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
+ loupe@3.2.1:
+ resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==}
+
lower-case@2.0.2:
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
+ lru-cache@10.4.3:
+ resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
+
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.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+ 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'}
+ mdast-util-from-markdown@2.0.2:
+ resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==}
+
+ mdast-util-mdx-expression@2.0.1:
+ resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==}
+
+ mdast-util-mdx-jsx@3.2.0:
+ resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==}
+
+ mdast-util-mdxjs-esm@2.0.1:
+ resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==}
+
+ mdast-util-phrasing@4.1.0:
+ resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
+
+ mdast-util-to-hast@13.2.1:
+ resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==}
+
+ mdast-util-to-markdown@2.1.2:
+ resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==}
+
+ mdast-util-to-string@4.0.0:
+ resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
+
+ memoizerific@1.11.3:
+ resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==}
+
+ meow@12.1.1:
+ resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==}
+ engines: {node: '>=16.10'}
+
+ meow@13.2.0:
+ resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==}
+ engines: {node: '>=18'}
+
+ micromark-core-commonmark@2.0.3:
+ resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
+
+ micromark-factory-destination@2.0.1:
+ resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==}
+
+ micromark-factory-label@2.0.1:
+ resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==}
+
+ micromark-factory-space@2.0.1:
+ resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==}
+
+ micromark-factory-title@2.0.1:
+ resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==}
+
+ micromark-factory-whitespace@2.0.1:
+ resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==}
+
+ micromark-util-character@2.1.1:
+ resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
+
+ micromark-util-chunked@2.0.1:
+ resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==}
+
+ micromark-util-classify-character@2.0.1:
+ resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==}
+
+ micromark-util-combine-extensions@2.0.1:
+ resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==}
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==}
+
+ micromark-util-decode-string@2.0.1:
+ resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==}
+
+ micromark-util-encode@2.0.1:
+ resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
+
+ micromark-util-html-tag-name@2.0.1:
+ resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==}
+
+ micromark-util-normalize-identifier@2.0.1:
+ resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==}
+
+ micromark-util-resolve-all@2.0.1:
+ resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==}
+
+ micromark-util-sanitize-uri@2.0.1:
+ resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
+
+ micromark-util-subtokenize@2.1.0:
+ resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==}
+
+ micromark-util-symbol@2.0.1:
+ resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
+
+ micromark-util-types@2.0.2:
+ resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==}
+
+ micromark@4.0.2:
+ resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==}
+
micromatch@4.0.8:
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'}
+
mimic-function@5.0.1:
resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
engines: {node: '>=18'}
+ min-indent@1.0.1:
+ resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
+ engines: {node: '>=4'}
+
+ mini-svg-data-uri@1.4.4:
+ resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==}
+ hasBin: true
+
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -1808,6 +2692,16 @@ packages:
minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+ minipass@7.1.3:
+ resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ motion-dom@12.38.0:
+ resolution: {integrity: sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==}
+
+ motion-utils@12.36.0:
+ resolution: {integrity: sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==}
+
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
@@ -1826,6 +2720,10 @@ packages:
no-case@3.0.4:
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
+ node-exports-info@1.6.0:
+ resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==}
+ engines: {node: '>= 0.4'}
+
node-releases@2.0.27:
resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
@@ -1865,6 +2763,10 @@ packages:
resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
engines: {node: '>=18'}
+ 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'}
@@ -1881,10 +2783,16 @@ packages:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
+ package-json-from-dist@1.0.1:
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+
parent-module@1.0.1:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
+ parse-entities@4.0.2:
+ resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==}
+
parse-json@5.2.0:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'}
@@ -1900,10 +2808,18 @@ packages:
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+ path-scurry@1.11.1:
+ resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
+ engines: {node: '>=16 || 14 >=14.18'}
+
path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
+ pathval@2.0.1:
+ resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==}
+ engines: {node: '>= 14.16'}
+
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@@ -1920,6 +2836,10 @@ packages:
engines: {node: '>=0.10'}
hasBin: true
+ polished@4.3.1:
+ resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==}
+ engines: {node: '>=10'}
+
possible-typed-array-names@1.1.0:
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
engines: {node: '>= 0.4'}
@@ -1936,22 +2856,51 @@ packages:
resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==}
engines: {node: '>=6.0.0'}
- prettier@3.7.4:
- resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==}
+ prettier@3.8.1:
+ resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==}
engines: {node: '>=14'}
hasBin: true
+ 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'}
+
prop-types@15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
+ property-information@7.1.0:
+ resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
+
+ proxy-from-env@1.1.0:
+ resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+
punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
- react-dom@19.2.3:
- resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==}
+ react-apexcharts@2.1.0:
+ resolution: {integrity: sha512-xrmeTKRKHh3cvvLc8SasqFjlOgIqGpyHc81qjnRtcjUM0Fu7qEjgVRWGPokGFjqhwRZVgEym8zmuEyYr5LMYIg==}
+ peerDependencies:
+ apexcharts: '>=5.10.1'
+ react: '>=16.8.0'
+
+ react-docgen-typescript@2.4.0:
+ resolution: {integrity: sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==}
+ peerDependencies:
+ typescript: '>= 4.3.x'
+
+ react-docgen@7.1.1:
+ resolution: {integrity: sha512-hlSJDQ2synMPKFZOsKo9Hi8WWZTC7POR8EmWvTSjow+VDgKzkmjQvFm2fk0tmRw+f0vTOIYKlarR0iL4996pdg==}
+ engines: {node: '>=16.14.0'}
+
+ react-dom@19.2.4:
+ resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==}
peerDependencies:
- react: ^19.2.3
+ react: ^19.2.4
react-hook-form@7.71.1:
resolution: {integrity: sha512-9SUJKCGKo8HUSsCO+y0CtqkqI5nNuaDqTxyqPsZPqIwudpj4rCrAz/jZV+jn57bx5gtZKOh3neQu94DXMc+w5w==}
@@ -1962,15 +2911,44 @@ packages:
react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
- react-router-dom@7.12.0:
- resolution: {integrity: sha512-pfO9fiBcpEfX4Tx+iTYKDtPbrSLLCbwJ5EqP+SPYQu1VYCXdy79GSj0wttR0U4cikVdlImZuEZ/9ZNCgoaxwBA==}
+ react-is@17.0.2:
+ resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
+
+ react-markdown@10.1.0:
+ resolution: {integrity: sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==}
+ peerDependencies:
+ '@types/react': '>=18'
+ react: '>=18'
+
+ react-remove-scroll-bar@2.3.8:
+ resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-remove-scroll@2.7.2:
+ resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-router-dom@7.13.0:
+ resolution: {integrity: sha512-5CO/l5Yahi2SKC6rGZ+HDEjpjkGaG/ncEP7eWFTvFxbHP8yeeI0PxTDjimtpXYlR3b3i9/WIL4VJttPrESIf2g==}
engines: {node: '>=20.0.0'}
peerDependencies:
react: '>=18'
react-dom: '>=18'
- react-router@7.12.0:
- resolution: {integrity: sha512-kTPDYPFzDVGIIGNLS5VJykK0HfHLY5MF3b+xj0/tTyNYL1gF1qs7u67Z9jEhQk2sQ98SUaHxlG31g1JtF7IfVw==}
+ react-router@7.13.0:
+ resolution: {integrity: sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==}
engines: {node: '>=20.0.0'}
peerDependencies:
react: '>=18'
@@ -1979,10 +2957,28 @@ packages:
react-dom:
optional: true
- react@19.2.3:
- resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==}
+ react-style-singleton@2.2.3:
+ resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react@19.2.4:
+ resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
engines: {node: '>=0.10.0'}
+ recast@0.23.11:
+ resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==}
+ engines: {node: '>= 4'}
+
+ redent@3.0.0:
+ resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
+ engines: {node: '>=8'}
+
reflect.getprototypeof@1.0.10:
resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
engines: {node: '>= 0.4'}
@@ -1991,17 +2987,36 @@ packages:
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
engines: {node: '>= 0.4'}
+ remark-parse@11.0.0:
+ resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
+
+ remark-rehype@11.1.2:
+ resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==}
+
+ require-directory@2.1.1:
+ resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
+ engines: {node: '>=0.10.0'}
+
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
resolve-from@4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
+ resolve-from@5.0.0:
+ resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
+ engines: {node: '>=8'}
+
resolve@1.22.11:
resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
engines: {node: '>= 0.4'}
hasBin: true
- resolve@2.0.0-next.5:
- resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==}
+ resolve@2.0.0-next.6:
+ resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==}
+ engines: {node: '>= 0.4'}
hasBin: true
restore-cursor@5.1.0:
@@ -2011,8 +3026,8 @@ packages:
rfdc@1.4.1:
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
- rollup@4.55.1:
- resolution: {integrity: sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==}
+ rollup@4.57.1:
+ resolution: {integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
@@ -2035,8 +3050,8 @@ packages:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
- semver@7.7.3:
- resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==}
+ semver@7.7.4:
+ resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
engines: {node: '>=10'}
hasBin: true
@@ -2090,24 +3105,58 @@ packages:
snake-case@3.0.4:
resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
+ sonner@2.0.7:
+ resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==}
+ peerDependencies:
+ react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+
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'}
+
+ space-separated-tokens@2.0.2:
+ resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
+
+ split2@4.2.0:
+ resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
+ engines: {node: '>= 10.x'}
+
stop-iteration-iterator@1.1.0:
resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
engines: {node: '>= 0.4'}
+ storybook@8.6.17:
+ resolution: {integrity: sha512-krR/l680A6qVnkGiK9p8jY0ucX3+kFCs2f4zw+S3w2Cdq8EiM/tFebPcX2V4S3z2UsO0v0dwAJOJNpzbFPdmVg==}
+ hasBin: true
+ peerDependencies:
+ prettier: ^2 || ^3
+ peerDependenciesMeta:
+ prettier:
+ optional: true
+
string-argv@0.3.2:
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
engines: {node: '>=0.6.19'}
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+
string-width@7.2.0:
resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
engines: {node: '>=18'}
- string-width@8.1.0:
- resolution: {integrity: sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==}
+ string-width@8.2.0:
+ resolution: {integrity: sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==}
engines: {node: '>=20'}
string.prototype.includes@2.0.1:
@@ -2133,6 +3182,13 @@ packages:
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
engines: {node: '>= 0.4'}
+ stringify-entities@4.0.4:
+ resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
strip-ansi@7.1.2:
resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==}
engines: {node: '>=12'}
@@ -2141,10 +3197,24 @@ packages:
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.1.1:
+ resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==}
+ engines: {node: '>=12'}
+
strip-json-comments@3.1.1:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
+ style-to-js@1.1.21:
+ resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==}
+
+ style-to-object@1.0.14:
+ resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==}
+
supports-color@7.2.0:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'}
@@ -2160,30 +3230,62 @@ packages:
resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==}
engines: {node: ^14.18.0 || >=16.0.0}
- tailwindcss@4.1.18:
- resolution: {integrity: sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==}
+ tailwind-merge@3.5.0:
+ resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==}
+
+ tailwindcss@4.2.0:
+ resolution: {integrity: sha512-yYzTZ4++b7fNYxFfpnberEEKu43w44aqDMNM9MHMmcKuCH7lL8jJ4yJ7LGHv7rSwiqM0nkiobF9I6cLlpS2P7Q==}
tapable@2.3.0:
resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==}
engines: {node: '>=6'}
+ tiny-invariant@1.3.3:
+ resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
+
+ tinyexec@1.0.2:
+ resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==}
+ engines: {node: '>=18'}
+
tinyglobby@0.2.15:
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
engines: {node: '>=12.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'}
+ trim-lines@3.0.1:
+ resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
+
+ trough@2.2.0:
+ resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
+
ts-api-utils@2.4.0:
resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==}
engines: {node: '>=18.12'}
peerDependencies:
typescript: '>=4.8.4'
+ ts-dedent@2.2.0:
+ resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==}
+ engines: {node: '>=6.10'}
+
tsconfig-paths@3.15.0:
resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
+ tsconfig-paths@4.2.0:
+ resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==}
+ engines: {node: '>=6'}
+
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
@@ -2207,11 +3309,11 @@ packages:
resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==}
engines: {node: '>= 0.4'}
- typescript-eslint@8.53.0:
- resolution: {integrity: sha512-xHURCQNxZ1dsWn0sdOaOfCSQG0HKeqSj9OexIxrz6ypU6wHYOdX2I3D2b8s8wFSsSOYJb+6q283cLiLlkEsBYw==}
+ typescript-eslint@8.56.0:
+ resolution: {integrity: sha512-c7toRLrotJ9oixgdW7liukZpsnq5CZ7PuKztubGYlNppuTqhIoWfhgHo/7EU0v06gS2l/x0i2NEFK1qMIf0rIg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
- eslint: ^8.57.0 || ^9.0.0
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0'
typescript@5.9.3:
@@ -2226,6 +3328,28 @@ packages:
undici-types@7.16.0:
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
+ unified@11.0.5:
+ resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
+
+ unist-util-is@6.0.1:
+ resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==}
+
+ unist-util-position@5.0.0:
+ resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+
+ unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+
+ unist-util-visit-parents@6.0.2:
+ resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==}
+
+ unist-util-visit@5.1.0:
+ resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==}
+
+ unplugin@1.16.1:
+ resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==}
+ engines: {node: '>=14.0.0'}
+
update-browserslist-db@1.2.3:
resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
hasBin: true
@@ -2235,24 +3359,57 @@ packages:
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ use-callback-ref@1.3.3:
+ resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ use-sidecar@1.1.3:
+ resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ util@0.12.5:
+ resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==}
+
+ uuid@9.0.1:
+ resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
+ hasBin: true
+
+ vfile-message@4.0.3:
+ resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
+
+ vfile@6.0.3:
+ resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+
vite-plugin-svgr@4.5.0:
resolution: {integrity: sha512-W+uoSpmVkSmNOGPSsDCWVW/DDAyv+9fap9AZXBvWiQqrboJ08j2vh0tFxTD/LjwqwAd3yYSVJgm54S/1GhbdnA==}
peerDependencies:
vite: '>=2.6.0'
- vite@7.3.1:
- resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==}
- engines: {node: ^20.19.0 || >=22.12.0}
+ vite@6.4.1:
+ resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
hasBin: true
peerDependencies:
- '@types/node': ^20.19.0 || >=22.12.0
+ '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
jiti: '>=1.21.0'
- less: ^4.0.0
+ less: '*'
lightningcss: ^1.21.0
- sass: ^1.70.0
- sass-embedded: ^1.70.0
- stylus: '>=0.54.8'
- sugarss: ^5.0.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
terser: ^5.16.0
tsx: ^4.8.1
yaml: ^2.4.2
@@ -2280,6 +3437,9 @@ packages:
yaml:
optional: true
+ webpack-virtual-modules@0.6.2:
+ resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
+
which-boxed-primitive@1.1.1:
resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
engines: {node: '>= 0.4'}
@@ -2292,8 +3452,8 @@ packages:
resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
engines: {node: '>= 0.4'}
- which-typed-array@1.1.19:
- resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==}
+ which-typed-array@1.1.20:
+ resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==}
engines: {node: '>= 0.4'}
which@2.0.2:
@@ -2305,10 +3465,34 @@ packages:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
wrap-ansi@9.0.2:
resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==}
engines: {node: '>=18'}
+ ws@8.19.0:
+ resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==}
+ 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==}
@@ -2317,6 +3501,14 @@ packages:
engines: {node: '>= 14.6'}
hasBin: true
+ 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'}
@@ -2327,11 +3519,11 @@ packages:
peerDependencies:
zod: ^3.25.0 || ^4.0.0
- zod@4.3.5:
- resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==}
+ zod@4.3.6:
+ resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
- zustand@5.0.10:
- resolution: {integrity: sha512-U1AiltS1O9hSy3rul+Ub82ut2fqIAefiSuwECWt6jlMVUGejvf+5omLcRBSzqbRagSM3hQZbtzdeRc6QVScXTg==}
+ zustand@5.0.11:
+ resolution: {integrity: sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg==}
engines: {node: '>=12.20.0'}
peerDependencies:
'@types/react': '>=18.0.0'
@@ -2348,27 +3540,32 @@ packages:
use-sync-external-store:
optional: true
+ zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+
snapshots:
- '@babel/code-frame@7.28.6':
+ '@adobe/css-tools@4.4.4': {}
+
+ '@babel/code-frame@7.29.0':
dependencies:
'@babel/helper-validator-identifier': 7.28.5
js-tokens: 4.0.0
picocolors: 1.1.1
- '@babel/compat-data@7.28.6': {}
+ '@babel/compat-data@7.29.0': {}
- '@babel/core@7.28.6':
+ '@babel/core@7.29.0':
dependencies:
- '@babel/code-frame': 7.28.6
- '@babel/generator': 7.28.6
+ '@babel/code-frame': 7.29.0
+ '@babel/generator': 7.29.1
'@babel/helper-compilation-targets': 7.28.6
- '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.6)
+ '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0)
'@babel/helpers': 7.28.6
- '@babel/parser': 7.28.6
+ '@babel/parser': 7.29.0
'@babel/template': 7.28.6
- '@babel/traverse': 7.28.6
- '@babel/types': 7.28.6
+ '@babel/traverse': 7.29.0
+ '@babel/types': 7.29.0
'@jridgewell/remapping': 2.3.5
convert-source-map: 2.0.0
debug: 4.4.3
@@ -2378,17 +3575,17 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@babel/generator@7.28.6':
+ '@babel/generator@7.29.1':
dependencies:
- '@babel/parser': 7.28.6
- '@babel/types': 7.28.6
+ '@babel/parser': 7.29.0
+ '@babel/types': 7.29.0
'@jridgewell/gen-mapping': 0.3.13
'@jridgewell/trace-mapping': 0.3.31
jsesc: 3.1.0
'@babel/helper-compilation-targets@7.28.6':
dependencies:
- '@babel/compat-data': 7.28.6
+ '@babel/compat-data': 7.29.0
'@babel/helper-validator-option': 7.27.1
browserslist: 4.28.1
lru-cache: 5.1.1
@@ -2398,17 +3595,17 @@ snapshots:
'@babel/helper-module-imports@7.28.6':
dependencies:
- '@babel/traverse': 7.28.6
- '@babel/types': 7.28.6
+ '@babel/traverse': 7.29.0
+ '@babel/types': 7.29.0
transitivePeerDependencies:
- supports-color
- '@babel/helper-module-transforms@7.28.6(@babel/core@7.28.6)':
+ '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)':
dependencies:
- '@babel/core': 7.28.6
+ '@babel/core': 7.29.0
'@babel/helper-module-imports': 7.28.6
'@babel/helper-validator-identifier': 7.28.5
- '@babel/traverse': 7.28.6
+ '@babel/traverse': 7.29.0
transitivePeerDependencies:
- supports-color
@@ -2421,111 +3618,222 @@ snapshots:
'@babel/helpers@7.28.6':
dependencies:
'@babel/template': 7.28.6
- '@babel/types': 7.28.6
+ '@babel/types': 7.29.0
- '@babel/parser@7.28.6':
+ '@babel/parser@7.29.0':
dependencies:
- '@babel/types': 7.28.6
+ '@babel/types': 7.29.0
+
+ '@babel/runtime@7.28.6': {}
'@babel/template@7.28.6':
dependencies:
- '@babel/code-frame': 7.28.6
- '@babel/parser': 7.28.6
- '@babel/types': 7.28.6
+ '@babel/code-frame': 7.29.0
+ '@babel/parser': 7.29.0
+ '@babel/types': 7.29.0
- '@babel/traverse@7.28.6':
+ '@babel/traverse@7.29.0':
dependencies:
- '@babel/code-frame': 7.28.6
- '@babel/generator': 7.28.6
+ '@babel/code-frame': 7.29.0
+ '@babel/generator': 7.29.1
'@babel/helper-globals': 7.28.0
- '@babel/parser': 7.28.6
+ '@babel/parser': 7.29.0
'@babel/template': 7.28.6
- '@babel/types': 7.28.6
+ '@babel/types': 7.29.0
debug: 4.4.3
transitivePeerDependencies:
- supports-color
- '@babel/types@7.28.6':
+ '@babel/types@7.29.0':
dependencies:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
- '@esbuild/aix-ppc64@0.27.2':
+ '@commitlint/cli@20.4.1(@types/node@24.10.13)(typescript@5.9.3)':
+ dependencies:
+ '@commitlint/format': 20.4.0
+ '@commitlint/lint': 20.4.1
+ '@commitlint/load': 20.4.0(@types/node@24.10.13)(typescript@5.9.3)
+ '@commitlint/read': 20.4.0
+ '@commitlint/types': 20.4.0
+ tinyexec: 1.0.2
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - '@types/node'
+ - typescript
+
+ '@commitlint/config-conventional@20.4.1':
+ dependencies:
+ '@commitlint/types': 20.4.0
+ conventional-changelog-conventionalcommits: 9.1.0
+
+ '@commitlint/config-validator@20.4.0':
+ dependencies:
+ '@commitlint/types': 20.4.0
+ ajv: 8.18.0
+
+ '@commitlint/ensure@20.4.1':
+ dependencies:
+ '@commitlint/types': 20.4.0
+ lodash.camelcase: 4.3.0
+ lodash.kebabcase: 4.1.1
+ lodash.snakecase: 4.1.1
+ lodash.startcase: 4.4.0
+ lodash.upperfirst: 4.3.1
+
+ '@commitlint/execute-rule@20.0.0': {}
+
+ '@commitlint/format@20.4.0':
+ dependencies:
+ '@commitlint/types': 20.4.0
+ picocolors: 1.1.1
+
+ '@commitlint/is-ignored@20.4.1':
+ dependencies:
+ '@commitlint/types': 20.4.0
+ semver: 7.7.4
+
+ '@commitlint/lint@20.4.1':
+ dependencies:
+ '@commitlint/is-ignored': 20.4.1
+ '@commitlint/parse': 20.4.1
+ '@commitlint/rules': 20.4.1
+ '@commitlint/types': 20.4.0
+
+ '@commitlint/load@20.4.0(@types/node@24.10.13)(typescript@5.9.3)':
+ dependencies:
+ '@commitlint/config-validator': 20.4.0
+ '@commitlint/execute-rule': 20.0.0
+ '@commitlint/resolve-extends': 20.4.0
+ '@commitlint/types': 20.4.0
+ cosmiconfig: 9.0.0(typescript@5.9.3)
+ cosmiconfig-typescript-loader: 6.2.0(@types/node@24.10.13)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3)
+ is-plain-obj: 4.1.0
+ lodash.mergewith: 4.6.2
+ picocolors: 1.1.1
+ transitivePeerDependencies:
+ - '@types/node'
+ - typescript
+
+ '@commitlint/message@20.4.0': {}
+
+ '@commitlint/parse@20.4.1':
+ dependencies:
+ '@commitlint/types': 20.4.0
+ conventional-changelog-angular: 8.1.0
+ conventional-commits-parser: 6.2.1
+
+ '@commitlint/read@20.4.0':
+ dependencies:
+ '@commitlint/top-level': 20.4.0
+ '@commitlint/types': 20.4.0
+ git-raw-commits: 4.0.0
+ minimist: 1.2.8
+ tinyexec: 1.0.2
+
+ '@commitlint/resolve-extends@20.4.0':
+ dependencies:
+ '@commitlint/config-validator': 20.4.0
+ '@commitlint/types': 20.4.0
+ global-directory: 4.0.1
+ import-meta-resolve: 4.2.0
+ lodash.mergewith: 4.6.2
+ resolve-from: 5.0.0
+
+ '@commitlint/rules@20.4.1':
+ dependencies:
+ '@commitlint/ensure': 20.4.1
+ '@commitlint/message': 20.4.0
+ '@commitlint/to-lines': 20.0.0
+ '@commitlint/types': 20.4.0
+
+ '@commitlint/to-lines@20.0.0': {}
+
+ '@commitlint/top-level@20.4.0':
+ dependencies:
+ escalade: 3.2.0
+
+ '@commitlint/types@20.4.0':
+ dependencies:
+ conventional-commits-parser: 6.2.1
+ picocolors: 1.1.1
+
+ '@esbuild/aix-ppc64@0.25.12':
optional: true
- '@esbuild/android-arm64@0.27.2':
+ '@esbuild/android-arm64@0.25.12':
optional: true
- '@esbuild/android-arm@0.27.2':
+ '@esbuild/android-arm@0.25.12':
optional: true
- '@esbuild/android-x64@0.27.2':
+ '@esbuild/android-x64@0.25.12':
optional: true
- '@esbuild/darwin-arm64@0.27.2':
+ '@esbuild/darwin-arm64@0.25.12':
optional: true
- '@esbuild/darwin-x64@0.27.2':
+ '@esbuild/darwin-x64@0.25.12':
optional: true
- '@esbuild/freebsd-arm64@0.27.2':
+ '@esbuild/freebsd-arm64@0.25.12':
optional: true
- '@esbuild/freebsd-x64@0.27.2':
+ '@esbuild/freebsd-x64@0.25.12':
optional: true
- '@esbuild/linux-arm64@0.27.2':
+ '@esbuild/linux-arm64@0.25.12':
optional: true
- '@esbuild/linux-arm@0.27.2':
+ '@esbuild/linux-arm@0.25.12':
optional: true
- '@esbuild/linux-ia32@0.27.2':
+ '@esbuild/linux-ia32@0.25.12':
optional: true
- '@esbuild/linux-loong64@0.27.2':
+ '@esbuild/linux-loong64@0.25.12':
optional: true
- '@esbuild/linux-mips64el@0.27.2':
+ '@esbuild/linux-mips64el@0.25.12':
optional: true
- '@esbuild/linux-ppc64@0.27.2':
+ '@esbuild/linux-ppc64@0.25.12':
optional: true
- '@esbuild/linux-riscv64@0.27.2':
+ '@esbuild/linux-riscv64@0.25.12':
optional: true
- '@esbuild/linux-s390x@0.27.2':
+ '@esbuild/linux-s390x@0.25.12':
optional: true
- '@esbuild/linux-x64@0.27.2':
+ '@esbuild/linux-x64@0.25.12':
optional: true
- '@esbuild/netbsd-arm64@0.27.2':
+ '@esbuild/netbsd-arm64@0.25.12':
optional: true
- '@esbuild/netbsd-x64@0.27.2':
+ '@esbuild/netbsd-x64@0.25.12':
optional: true
- '@esbuild/openbsd-arm64@0.27.2':
+ '@esbuild/openbsd-arm64@0.25.12':
optional: true
- '@esbuild/openbsd-x64@0.27.2':
+ '@esbuild/openbsd-x64@0.25.12':
optional: true
- '@esbuild/openharmony-arm64@0.27.2':
+ '@esbuild/openharmony-arm64@0.25.12':
optional: true
- '@esbuild/sunos-x64@0.27.2':
+ '@esbuild/sunos-x64@0.25.12':
optional: true
- '@esbuild/win32-arm64@0.27.2':
+ '@esbuild/win32-arm64@0.25.12':
optional: true
- '@esbuild/win32-ia32@0.27.2':
+ '@esbuild/win32-ia32@0.25.12':
optional: true
- '@esbuild/win32-x64@0.27.2':
+ '@esbuild/win32-x64@0.25.12':
optional: true
'@eslint-community/eslint-utils@4.9.1(eslint@9.39.2(jiti@2.6.1))':
@@ -2574,10 +3882,10 @@ snapshots:
'@eslint/core': 0.17.0
levn: 0.4.1
- '@hookform/resolvers@5.2.2(react-hook-form@7.71.1(react@19.2.3))':
+ '@hookform/resolvers@5.2.2(react-hook-form@7.71.1(react@19.2.4))':
dependencies:
'@standard-schema/utils': 0.3.0
- react-hook-form: 7.71.1(react@19.2.3)
+ react-hook-form: 7.71.1(react@19.2.4)
'@humanfs/core@0.19.1': {}
@@ -2590,10 +3898,28 @@ snapshots:
'@humanwhocodes/retry@0.4.3': {}
- '@jridgewell/gen-mapping@0.3.13':
+ '@isaacs/cliui@8.0.2':
dependencies:
- '@jridgewell/sourcemap-codec': 1.5.5
- '@jridgewell/trace-mapping': 0.3.31
+ string-width: 5.1.2
+ string-width-cjs: string-width@4.2.3
+ strip-ansi: 7.1.2
+ strip-ansi-cjs: strip-ansi@6.0.1
+ wrap-ansi: 8.1.0
+ wrap-ansi-cjs: wrap-ansi@7.0.0
+
+ '@joshwooding/vite-plugin-react-docgen-typescript@0.5.0(typescript@5.9.3)(vite@6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2))':
+ dependencies:
+ glob: 10.5.0
+ magic-string: 0.27.0
+ react-docgen-typescript: 2.4.0(typescript@5.9.3)
+ vite: 6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2)
+ optionalDependencies:
+ typescript: 5.9.3
+
+ '@jridgewell/gen-mapping@0.3.13':
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.31
'@jridgewell/remapping@2.3.5':
dependencies:
@@ -2609,145 +3935,360 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
+ '@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4)':
+ dependencies:
+ '@types/mdx': 2.0.13
+ '@types/react': 19.2.14
+ react: 19.2.4
+
+ '@microsoft/fetch-event-source@2.0.1': {}
+
+ '@pkgjs/parseargs@0.11.0':
+ optional: true
+
'@pkgr/core@0.2.9': {}
- '@rolldown/pluginutils@1.0.0-beta.47': {}
+ '@rolldown/pluginutils@1.0.0-beta.27': {}
- '@rollup/pluginutils@5.3.0(rollup@4.55.1)':
+ '@rollup/pluginutils@5.3.0(rollup@4.57.1)':
dependencies:
'@types/estree': 1.0.8
estree-walker: 2.0.2
picomatch: 4.0.3
optionalDependencies:
- rollup: 4.55.1
+ rollup: 4.57.1
- '@rollup/rollup-android-arm-eabi@4.55.1':
+ '@rollup/rollup-android-arm-eabi@4.57.1':
optional: true
- '@rollup/rollup-android-arm64@4.55.1':
+ '@rollup/rollup-android-arm64@4.57.1':
optional: true
- '@rollup/rollup-darwin-arm64@4.55.1':
+ '@rollup/rollup-darwin-arm64@4.57.1':
optional: true
- '@rollup/rollup-darwin-x64@4.55.1':
+ '@rollup/rollup-darwin-x64@4.57.1':
optional: true
- '@rollup/rollup-freebsd-arm64@4.55.1':
+ '@rollup/rollup-freebsd-arm64@4.57.1':
optional: true
- '@rollup/rollup-freebsd-x64@4.55.1':
+ '@rollup/rollup-freebsd-x64@4.57.1':
optional: true
- '@rollup/rollup-linux-arm-gnueabihf@4.55.1':
+ '@rollup/rollup-linux-arm-gnueabihf@4.57.1':
optional: true
- '@rollup/rollup-linux-arm-musleabihf@4.55.1':
+ '@rollup/rollup-linux-arm-musleabihf@4.57.1':
optional: true
- '@rollup/rollup-linux-arm64-gnu@4.55.1':
+ '@rollup/rollup-linux-arm64-gnu@4.57.1':
optional: true
- '@rollup/rollup-linux-arm64-musl@4.55.1':
+ '@rollup/rollup-linux-arm64-musl@4.57.1':
optional: true
- '@rollup/rollup-linux-loong64-gnu@4.55.1':
+ '@rollup/rollup-linux-loong64-gnu@4.57.1':
optional: true
- '@rollup/rollup-linux-loong64-musl@4.55.1':
+ '@rollup/rollup-linux-loong64-musl@4.57.1':
optional: true
- '@rollup/rollup-linux-ppc64-gnu@4.55.1':
+ '@rollup/rollup-linux-ppc64-gnu@4.57.1':
optional: true
- '@rollup/rollup-linux-ppc64-musl@4.55.1':
+ '@rollup/rollup-linux-ppc64-musl@4.57.1':
optional: true
- '@rollup/rollup-linux-riscv64-gnu@4.55.1':
+ '@rollup/rollup-linux-riscv64-gnu@4.57.1':
optional: true
- '@rollup/rollup-linux-riscv64-musl@4.55.1':
+ '@rollup/rollup-linux-riscv64-musl@4.57.1':
optional: true
- '@rollup/rollup-linux-s390x-gnu@4.55.1':
+ '@rollup/rollup-linux-s390x-gnu@4.57.1':
optional: true
- '@rollup/rollup-linux-x64-gnu@4.55.1':
+ '@rollup/rollup-linux-x64-gnu@4.57.1':
optional: true
- '@rollup/rollup-linux-x64-musl@4.55.1':
+ '@rollup/rollup-linux-x64-musl@4.57.1':
optional: true
- '@rollup/rollup-openbsd-x64@4.55.1':
+ '@rollup/rollup-openbsd-x64@4.57.1':
optional: true
- '@rollup/rollup-openharmony-arm64@4.55.1':
+ '@rollup/rollup-openharmony-arm64@4.57.1':
optional: true
- '@rollup/rollup-win32-arm64-msvc@4.55.1':
+ '@rollup/rollup-win32-arm64-msvc@4.57.1':
optional: true
- '@rollup/rollup-win32-ia32-msvc@4.55.1':
+ '@rollup/rollup-win32-ia32-msvc@4.57.1':
optional: true
- '@rollup/rollup-win32-x64-gnu@4.55.1':
+ '@rollup/rollup-win32-x64-gnu@4.57.1':
optional: true
- '@rollup/rollup-win32-x64-msvc@4.55.1':
+ '@rollup/rollup-win32-x64-msvc@4.57.1':
optional: true
'@rtsao/scc@1.1.0': {}
'@standard-schema/utils@0.3.0': {}
- '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.6)':
+ '@storybook/addon-actions@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ '@storybook/global': 5.0.0
+ '@types/uuid': 9.0.8
+ dequal: 2.0.3
+ polished: 4.3.1
+ storybook: 8.6.17(prettier@3.8.1)
+ uuid: 9.0.1
+
+ '@storybook/addon-backgrounds@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ '@storybook/global': 5.0.0
+ memoizerific: 1.11.3
+ storybook: 8.6.17(prettier@3.8.1)
+ ts-dedent: 2.2.0
+
+ '@storybook/addon-controls@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ '@storybook/global': 5.0.0
+ dequal: 2.0.3
+ storybook: 8.6.17(prettier@3.8.1)
+ ts-dedent: 2.2.0
+
+ '@storybook/addon-docs@8.6.17(@types/react@19.2.14)(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.4)
+ '@storybook/blocks': 8.6.17(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/csf-plugin': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/react-dom-shim': 8.6.17(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.6.17(prettier@3.8.1))
+ react: 19.2.4
+ react-dom: 19.2.4(react@19.2.4)
+ storybook: 8.6.17(prettier@3.8.1)
+ ts-dedent: 2.2.0
+ transitivePeerDependencies:
+ - '@types/react'
+
+ '@storybook/addon-essentials@8.6.17(@types/react@19.2.14)(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ '@storybook/addon-actions': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/addon-backgrounds': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/addon-controls': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/addon-docs': 8.6.17(@types/react@19.2.14)(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/addon-highlight': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/addon-measure': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/addon-outline': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/addon-toolbars': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/addon-viewport': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ storybook: 8.6.17(prettier@3.8.1)
+ ts-dedent: 2.2.0
+ transitivePeerDependencies:
+ - '@types/react'
+
+ '@storybook/addon-highlight@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ '@storybook/global': 5.0.0
+ storybook: 8.6.17(prettier@3.8.1)
+
+ '@storybook/addon-measure@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ '@storybook/global': 5.0.0
+ storybook: 8.6.17(prettier@3.8.1)
+ tiny-invariant: 1.3.3
+
+ '@storybook/addon-outline@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ '@storybook/global': 5.0.0
+ storybook: 8.6.17(prettier@3.8.1)
+ ts-dedent: 2.2.0
+
+ '@storybook/addon-toolbars@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ storybook: 8.6.17(prettier@3.8.1)
+
+ '@storybook/addon-viewport@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ memoizerific: 1.11.3
+ storybook: 8.6.17(prettier@3.8.1)
+
+ '@storybook/blocks@8.6.17(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ '@storybook/icons': 1.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
+ storybook: 8.6.17(prettier@3.8.1)
+ ts-dedent: 2.2.0
+ optionalDependencies:
+ react: 19.2.4
+ react-dom: 19.2.4(react@19.2.4)
+
+ '@storybook/builder-vite@8.6.17(storybook@8.6.17(prettier@3.8.1))(vite@6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2))':
+ dependencies:
+ '@storybook/csf-plugin': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ browser-assert: 1.2.1
+ storybook: 8.6.17(prettier@3.8.1)
+ ts-dedent: 2.2.0
+ vite: 6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2)
+
+ '@storybook/components@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ storybook: 8.6.17(prettier@3.8.1)
+
+ '@storybook/core@8.6.17(prettier@3.8.1)(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ '@storybook/theming': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ better-opn: 3.0.2
+ browser-assert: 1.2.1
+ esbuild: 0.25.12
+ esbuild-register: 3.6.0(esbuild@0.25.12)
+ jsdoc-type-pratt-parser: 4.8.0
+ process: 0.11.10
+ recast: 0.23.11
+ semver: 7.7.4
+ util: 0.12.5
+ ws: 8.19.0
+ optionalDependencies:
+ prettier: 3.8.1
+ transitivePeerDependencies:
+ - bufferutil
+ - storybook
+ - supports-color
+ - utf-8-validate
+
+ '@storybook/csf-plugin@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ storybook: 8.6.17(prettier@3.8.1)
+ unplugin: 1.16.1
+
+ '@storybook/global@5.0.0': {}
+
+ '@storybook/icons@1.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
+ dependencies:
+ react: 19.2.4
+ react-dom: 19.2.4(react@19.2.4)
+
+ '@storybook/instrumenter@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ '@storybook/global': 5.0.0
+ '@vitest/utils': 2.1.9
+ storybook: 8.6.17(prettier@3.8.1)
+
+ '@storybook/manager-api@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ storybook: 8.6.17(prettier@3.8.1)
+
+ '@storybook/preview-api@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ storybook: 8.6.17(prettier@3.8.1)
+
+ '@storybook/react-dom-shim@8.6.17(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ react: 19.2.4
+ react-dom: 19.2.4(react@19.2.4)
+ storybook: 8.6.17(prettier@3.8.1)
+
+ '@storybook/react-vite@8.6.17(@storybook/test@8.6.17(storybook@8.6.17(prettier@3.8.1)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.57.1)(storybook@8.6.17(prettier@3.8.1))(typescript@5.9.3)(vite@6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2))':
+ dependencies:
+ '@joshwooding/vite-plugin-react-docgen-typescript': 0.5.0(typescript@5.9.3)(vite@6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2))
+ '@rollup/pluginutils': 5.3.0(rollup@4.57.1)
+ '@storybook/builder-vite': 8.6.17(storybook@8.6.17(prettier@3.8.1))(vite@6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2))
+ '@storybook/react': 8.6.17(@storybook/test@8.6.17(storybook@8.6.17(prettier@3.8.1)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.6.17(prettier@3.8.1))(typescript@5.9.3)
+ find-up: 5.0.0
+ magic-string: 0.30.21
+ react: 19.2.4
+ react-docgen: 7.1.1
+ react-dom: 19.2.4(react@19.2.4)
+ resolve: 1.22.11
+ storybook: 8.6.17(prettier@3.8.1)
+ tsconfig-paths: 4.2.0
+ vite: 6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2)
+ optionalDependencies:
+ '@storybook/test': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ transitivePeerDependencies:
+ - rollup
+ - supports-color
+ - typescript
+
+ '@storybook/react@8.6.17(@storybook/test@8.6.17(storybook@8.6.17(prettier@3.8.1)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.6.17(prettier@3.8.1))(typescript@5.9.3)':
+ dependencies:
+ '@storybook/components': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/global': 5.0.0
+ '@storybook/manager-api': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/preview-api': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/react-dom-shim': 8.6.17(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.6.17(prettier@3.8.1))
+ '@storybook/theming': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ react: 19.2.4
+ react-dom: 19.2.4(react@19.2.4)
+ storybook: 8.6.17(prettier@3.8.1)
+ optionalDependencies:
+ '@storybook/test': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ typescript: 5.9.3
+
+ '@storybook/test@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ '@storybook/global': 5.0.0
+ '@storybook/instrumenter': 8.6.17(storybook@8.6.17(prettier@3.8.1))
+ '@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.6.17(prettier@3.8.1)
+
+ '@storybook/theming@8.6.17(storybook@8.6.17(prettier@3.8.1))':
+ dependencies:
+ storybook: 8.6.17(prettier@3.8.1)
+
+ '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.29.0)':
dependencies:
- '@babel/core': 7.28.6
+ '@babel/core': 7.29.0
- '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.28.6)':
+ '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.29.0)':
dependencies:
- '@babel/core': 7.28.6
+ '@babel/core': 7.29.0
- '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.28.6)':
+ '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.29.0)':
dependencies:
- '@babel/core': 7.28.6
+ '@babel/core': 7.29.0
- '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.28.6)':
+ '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.29.0)':
dependencies:
- '@babel/core': 7.28.6
+ '@babel/core': 7.29.0
- '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.28.6)':
+ '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.29.0)':
dependencies:
- '@babel/core': 7.28.6
+ '@babel/core': 7.29.0
- '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.28.6)':
+ '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.29.0)':
dependencies:
- '@babel/core': 7.28.6
+ '@babel/core': 7.29.0
- '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.28.6)':
+ '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.29.0)':
dependencies:
- '@babel/core': 7.28.6
+ '@babel/core': 7.29.0
- '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.28.6)':
+ '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.29.0)':
dependencies:
- '@babel/core': 7.28.6
+ '@babel/core': 7.29.0
- '@svgr/babel-preset@8.1.0(@babel/core@7.28.6)':
+ '@svgr/babel-preset@8.1.0(@babel/core@7.29.0)':
dependencies:
- '@babel/core': 7.28.6
- '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.28.6)
- '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.28.6)
- '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.28.6)
- '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.28.6)
- '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.28.6)
- '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.28.6)
- '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.28.6)
- '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.28.6)
+ '@babel/core': 7.29.0
+ '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.29.0)
+ '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.29.0)
+ '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.29.0)
+ '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.29.0)
+ '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.29.0)
+ '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.29.0)
+ '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.29.0)
+ '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.29.0)
'@svgr/core@8.1.0(typescript@5.9.3)':
dependencies:
- '@babel/core': 7.28.6
- '@svgr/babel-preset': 8.1.0(@babel/core@7.28.6)
+ '@babel/core': 7.29.0
+ '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0)
camelcase: 6.3.0
cosmiconfig: 8.3.6(typescript@5.9.3)
snake-case: 3.0.4
@@ -2757,64 +4298,64 @@ snapshots:
'@svgr/hast-util-to-babel-ast@8.0.0':
dependencies:
- '@babel/types': 7.28.6
+ '@babel/types': 7.29.0
entities: 4.5.0
'@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.9.3))':
dependencies:
- '@babel/core': 7.28.6
- '@svgr/babel-preset': 8.1.0(@babel/core@7.28.6)
+ '@babel/core': 7.29.0
+ '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0)
'@svgr/core': 8.1.0(typescript@5.9.3)
'@svgr/hast-util-to-babel-ast': 8.0.0
svg-parser: 2.0.4
transitivePeerDependencies:
- supports-color
- '@swc/core-darwin-arm64@1.15.8':
+ '@swc/core-darwin-arm64@1.15.11':
optional: true
- '@swc/core-darwin-x64@1.15.8':
+ '@swc/core-darwin-x64@1.15.11':
optional: true
- '@swc/core-linux-arm-gnueabihf@1.15.8':
+ '@swc/core-linux-arm-gnueabihf@1.15.11':
optional: true
- '@swc/core-linux-arm64-gnu@1.15.8':
+ '@swc/core-linux-arm64-gnu@1.15.11':
optional: true
- '@swc/core-linux-arm64-musl@1.15.8':
+ '@swc/core-linux-arm64-musl@1.15.11':
optional: true
- '@swc/core-linux-x64-gnu@1.15.8':
+ '@swc/core-linux-x64-gnu@1.15.11':
optional: true
- '@swc/core-linux-x64-musl@1.15.8':
+ '@swc/core-linux-x64-musl@1.15.11':
optional: true
- '@swc/core-win32-arm64-msvc@1.15.8':
+ '@swc/core-win32-arm64-msvc@1.15.11':
optional: true
- '@swc/core-win32-ia32-msvc@1.15.8':
+ '@swc/core-win32-ia32-msvc@1.15.11':
optional: true
- '@swc/core-win32-x64-msvc@1.15.8':
+ '@swc/core-win32-x64-msvc@1.15.11':
optional: true
- '@swc/core@1.15.8':
+ '@swc/core@1.15.11':
dependencies:
'@swc/counter': 0.1.3
'@swc/types': 0.1.25
optionalDependencies:
- '@swc/core-darwin-arm64': 1.15.8
- '@swc/core-darwin-x64': 1.15.8
- '@swc/core-linux-arm-gnueabihf': 1.15.8
- '@swc/core-linux-arm64-gnu': 1.15.8
- '@swc/core-linux-arm64-musl': 1.15.8
- '@swc/core-linux-x64-gnu': 1.15.8
- '@swc/core-linux-x64-musl': 1.15.8
- '@swc/core-win32-arm64-msvc': 1.15.8
- '@swc/core-win32-ia32-msvc': 1.15.8
- '@swc/core-win32-x64-msvc': 1.15.8
+ '@swc/core-darwin-arm64': 1.15.11
+ '@swc/core-darwin-x64': 1.15.11
+ '@swc/core-linux-arm-gnueabihf': 1.15.11
+ '@swc/core-linux-arm64-gnu': 1.15.11
+ '@swc/core-linux-arm64-musl': 1.15.11
+ '@swc/core-linux-x64-gnu': 1.15.11
+ '@swc/core-linux-x64-musl': 1.15.11
+ '@swc/core-win32-arm64-msvc': 1.15.11
+ '@swc/core-win32-ia32-msvc': 1.15.11
+ '@swc/core-win32-x64-msvc': 1.15.11
'@swc/counter@0.1.3': {}
@@ -2822,107 +4363,190 @@ snapshots:
dependencies:
'@swc/counter': 0.1.3
- '@tailwindcss/node@4.1.18':
+ '@tailwindcss/forms@0.5.11(tailwindcss@4.2.0)':
+ dependencies:
+ mini-svg-data-uri: 1.4.4
+ tailwindcss: 4.2.0
+
+ '@tailwindcss/node@4.2.0':
dependencies:
'@jridgewell/remapping': 2.3.5
- enhanced-resolve: 5.18.4
+ enhanced-resolve: 5.19.0
jiti: 2.6.1
- lightningcss: 1.30.2
+ lightningcss: 1.31.1
magic-string: 0.30.21
source-map-js: 1.2.1
- tailwindcss: 4.1.18
+ tailwindcss: 4.2.0
- '@tailwindcss/oxide-android-arm64@4.1.18':
+ '@tailwindcss/oxide-android-arm64@4.2.0':
optional: true
- '@tailwindcss/oxide-darwin-arm64@4.1.18':
+ '@tailwindcss/oxide-darwin-arm64@4.2.0':
optional: true
- '@tailwindcss/oxide-darwin-x64@4.1.18':
+ '@tailwindcss/oxide-darwin-x64@4.2.0':
optional: true
- '@tailwindcss/oxide-freebsd-x64@4.1.18':
+ '@tailwindcss/oxide-freebsd-x64@4.2.0':
optional: true
- '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18':
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.0':
optional: true
- '@tailwindcss/oxide-linux-arm64-gnu@4.1.18':
+ '@tailwindcss/oxide-linux-arm64-gnu@4.2.0':
optional: true
- '@tailwindcss/oxide-linux-arm64-musl@4.1.18':
+ '@tailwindcss/oxide-linux-arm64-musl@4.2.0':
optional: true
- '@tailwindcss/oxide-linux-x64-gnu@4.1.18':
+ '@tailwindcss/oxide-linux-x64-gnu@4.2.0':
optional: true
- '@tailwindcss/oxide-linux-x64-musl@4.1.18':
+ '@tailwindcss/oxide-linux-x64-musl@4.2.0':
optional: true
- '@tailwindcss/oxide-wasm32-wasi@4.1.18':
+ '@tailwindcss/oxide-wasm32-wasi@4.2.0':
optional: true
- '@tailwindcss/oxide-win32-arm64-msvc@4.1.18':
+ '@tailwindcss/oxide-win32-arm64-msvc@4.2.0':
optional: true
- '@tailwindcss/oxide-win32-x64-msvc@4.1.18':
+ '@tailwindcss/oxide-win32-x64-msvc@4.2.0':
optional: true
- '@tailwindcss/oxide@4.1.18':
+ '@tailwindcss/oxide@4.2.0':
optionalDependencies:
- '@tailwindcss/oxide-android-arm64': 4.1.18
- '@tailwindcss/oxide-darwin-arm64': 4.1.18
- '@tailwindcss/oxide-darwin-x64': 4.1.18
- '@tailwindcss/oxide-freebsd-x64': 4.1.18
- '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.18
- '@tailwindcss/oxide-linux-arm64-gnu': 4.1.18
- '@tailwindcss/oxide-linux-arm64-musl': 4.1.18
- '@tailwindcss/oxide-linux-x64-gnu': 4.1.18
- '@tailwindcss/oxide-linux-x64-musl': 4.1.18
- '@tailwindcss/oxide-wasm32-wasi': 4.1.18
- '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18
- '@tailwindcss/oxide-win32-x64-msvc': 4.1.18
+ '@tailwindcss/oxide-android-arm64': 4.2.0
+ '@tailwindcss/oxide-darwin-arm64': 4.2.0
+ '@tailwindcss/oxide-darwin-x64': 4.2.0
+ '@tailwindcss/oxide-freebsd-x64': 4.2.0
+ '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.0
+ '@tailwindcss/oxide-linux-arm64-gnu': 4.2.0
+ '@tailwindcss/oxide-linux-arm64-musl': 4.2.0
+ '@tailwindcss/oxide-linux-x64-gnu': 4.2.0
+ '@tailwindcss/oxide-linux-x64-musl': 4.2.0
+ '@tailwindcss/oxide-wasm32-wasi': 4.2.0
+ '@tailwindcss/oxide-win32-arm64-msvc': 4.2.0
+ '@tailwindcss/oxide-win32-x64-msvc': 4.2.0
+
+ '@tailwindcss/vite@4.2.0(vite@6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2))':
+ dependencies:
+ '@tailwindcss/node': 4.2.0
+ '@tailwindcss/oxide': 4.2.0
+ tailwindcss: 4.2.0
+ vite: 6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2)
+
+ '@tanstack/query-core@5.90.20': {}
+
+ '@tanstack/react-query@5.90.21(react@19.2.4)':
+ dependencies:
+ '@tanstack/query-core': 5.90.20
+ react: 19.2.4
+
+ '@testing-library/dom@10.4.0':
+ dependencies:
+ '@babel/code-frame': 7.29.0
+ '@babel/runtime': 7.28.6
+ '@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.4
+ aria-query: 5.3.2
+ chalk: 3.0.0
+ css.escape: 1.5.1
+ dom-accessibility-api: 0.6.3
+ lodash: 4.17.23
+ redent: 3.0.0
+
+ '@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0)':
+ dependencies:
+ '@testing-library/dom': 10.4.0
- '@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@24.10.8)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))':
+ '@types/aria-query@5.0.4': {}
+
+ '@types/babel__core@7.20.5':
+ dependencies:
+ '@babel/parser': 7.29.0
+ '@babel/types': 7.29.0
+ '@types/babel__generator': 7.27.0
+ '@types/babel__template': 7.4.4
+ '@types/babel__traverse': 7.28.0
+
+ '@types/babel__generator@7.27.0':
+ dependencies:
+ '@babel/types': 7.29.0
+
+ '@types/babel__template@7.4.4':
+ dependencies:
+ '@babel/parser': 7.29.0
+ '@babel/types': 7.29.0
+
+ '@types/babel__traverse@7.28.0':
+ dependencies:
+ '@babel/types': 7.29.0
+
+ '@types/debug@4.1.12':
dependencies:
- '@tailwindcss/node': 4.1.18
- '@tailwindcss/oxide': 4.1.18
- tailwindcss: 4.1.18
- vite: 7.3.1(@types/node@24.10.8)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)
+ '@types/ms': 2.1.0
- '@tanstack/query-core@5.90.17': {}
+ '@types/doctrine@0.0.9': {}
- '@tanstack/react-query@5.90.17(react@19.2.3)':
+ '@types/estree-jsx@1.0.5':
dependencies:
- '@tanstack/query-core': 5.90.17
- react: 19.2.3
+ '@types/estree': 1.0.8
'@types/estree@1.0.8': {}
+ '@types/hast@3.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
'@types/json-schema@7.0.15': {}
'@types/json5@0.0.29': {}
- '@types/node@24.10.8':
+ '@types/mdast@4.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/mdx@2.0.13': {}
+
+ '@types/ms@2.1.0': {}
+
+ '@types/node@24.10.13':
dependencies:
undici-types: 7.16.0
- '@types/react-dom@19.2.3(@types/react@19.2.8)':
+ '@types/react-dom@19.2.3(@types/react@19.2.14)':
dependencies:
- '@types/react': 19.2.8
+ '@types/react': 19.2.14
- '@types/react@19.2.8':
+ '@types/react@19.2.14':
dependencies:
csstype: 3.2.3
- '@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)':
+ '@types/resolve@1.20.6': {}
+
+ '@types/unist@2.0.11': {}
+
+ '@types/unist@3.0.3': {}
+
+ '@types/uuid@9.0.8': {}
+
+ '@typescript-eslint/eslint-plugin@8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
- '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
- '@typescript-eslint/scope-manager': 8.53.0
- '@typescript-eslint/type-utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
- '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
- '@typescript-eslint/visitor-keys': 8.53.0
+ '@typescript-eslint/parser': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ '@typescript-eslint/scope-manager': 8.56.0
+ '@typescript-eslint/type-utils': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ '@typescript-eslint/visitor-keys': 8.56.0
eslint: 9.39.2(jiti@2.6.1)
ignore: 7.0.5
natural-compare: 1.4.0
@@ -2931,41 +4555,41 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)':
+ '@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
- '@typescript-eslint/scope-manager': 8.53.0
- '@typescript-eslint/types': 8.53.0
- '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3)
- '@typescript-eslint/visitor-keys': 8.53.0
+ '@typescript-eslint/scope-manager': 8.56.0
+ '@typescript-eslint/types': 8.56.0
+ '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3)
+ '@typescript-eslint/visitor-keys': 8.56.0
debug: 4.4.3
eslint: 9.39.2(jiti@2.6.1)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/project-service@8.53.0(typescript@5.9.3)':
+ '@typescript-eslint/project-service@8.56.0(typescript@5.9.3)':
dependencies:
- '@typescript-eslint/tsconfig-utils': 8.53.0(typescript@5.9.3)
- '@typescript-eslint/types': 8.53.0
+ '@typescript-eslint/tsconfig-utils': 8.56.0(typescript@5.9.3)
+ '@typescript-eslint/types': 8.56.0
debug: 4.4.3
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/scope-manager@8.53.0':
+ '@typescript-eslint/scope-manager@8.56.0':
dependencies:
- '@typescript-eslint/types': 8.53.0
- '@typescript-eslint/visitor-keys': 8.53.0
+ '@typescript-eslint/types': 8.56.0
+ '@typescript-eslint/visitor-keys': 8.56.0
- '@typescript-eslint/tsconfig-utils@8.53.0(typescript@5.9.3)':
+ '@typescript-eslint/tsconfig-utils@8.56.0(typescript@5.9.3)':
dependencies:
typescript: 5.9.3
- '@typescript-eslint/type-utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)':
+ '@typescript-eslint/type-utils@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
- '@typescript-eslint/types': 8.53.0
- '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3)
- '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ '@typescript-eslint/types': 8.56.0
+ '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
debug: 4.4.3
eslint: 9.39.2(jiti@2.6.1)
ts-api-utils: 2.4.0(typescript@5.9.3)
@@ -2973,47 +4597,83 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/types@8.53.0': {}
+ '@typescript-eslint/types@8.56.0': {}
- '@typescript-eslint/typescript-estree@8.53.0(typescript@5.9.3)':
+ '@typescript-eslint/typescript-estree@8.56.0(typescript@5.9.3)':
dependencies:
- '@typescript-eslint/project-service': 8.53.0(typescript@5.9.3)
- '@typescript-eslint/tsconfig-utils': 8.53.0(typescript@5.9.3)
- '@typescript-eslint/types': 8.53.0
- '@typescript-eslint/visitor-keys': 8.53.0
+ '@typescript-eslint/project-service': 8.56.0(typescript@5.9.3)
+ '@typescript-eslint/tsconfig-utils': 8.56.0(typescript@5.9.3)
+ '@typescript-eslint/types': 8.56.0
+ '@typescript-eslint/visitor-keys': 8.56.0
debug: 4.4.3
minimatch: 9.0.5
- semver: 7.7.3
+ semver: 7.7.4
tinyglobby: 0.2.15
ts-api-utils: 2.4.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)':
+ '@typescript-eslint/utils@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1))
- '@typescript-eslint/scope-manager': 8.53.0
- '@typescript-eslint/types': 8.53.0
- '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3)
+ '@typescript-eslint/scope-manager': 8.56.0
+ '@typescript-eslint/types': 8.56.0
+ '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3)
eslint: 9.39.2(jiti@2.6.1)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/visitor-keys@8.53.0':
+ '@typescript-eslint/visitor-keys@8.56.0':
dependencies:
- '@typescript-eslint/types': 8.53.0
- eslint-visitor-keys: 4.2.1
+ '@typescript-eslint/types': 8.56.0
+ eslint-visitor-keys: 5.0.0
+
+ '@ungap/structured-clone@1.3.0': {}
- '@vitejs/plugin-react-swc@4.2.2(vite@7.3.1(@types/node@24.10.8)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))':
+ '@vitejs/plugin-react-swc@3.11.0(vite@6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2))':
dependencies:
- '@rolldown/pluginutils': 1.0.0-beta.47
- '@swc/core': 1.15.8
- vite: 7.3.1(@types/node@24.10.8)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)
+ '@rolldown/pluginutils': 1.0.0-beta.27
+ '@swc/core': 1.15.11
+ vite: 6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2)
transitivePeerDependencies:
- '@swc/helpers'
+ '@vitest/expect@2.0.5':
+ dependencies:
+ '@vitest/spy': 2.0.5
+ '@vitest/utils': 2.0.5
+ chai: 5.3.3
+ tinyrainbow: 1.2.0
+
+ '@vitest/pretty-format@2.0.5':
+ dependencies:
+ tinyrainbow: 1.2.0
+
+ '@vitest/pretty-format@2.1.9':
+ dependencies:
+ tinyrainbow: 1.2.0
+
+ '@vitest/spy@2.0.5':
+ dependencies:
+ tinyspy: 3.0.2
+
+ '@vitest/utils@2.0.5':
+ dependencies:
+ '@vitest/pretty-format': 2.0.5
+ estree-walker: 3.0.3
+ loupe: 3.2.1
+ tinyrainbow: 1.2.0
+
+ '@vitest/utils@2.1.9':
+ dependencies:
+ '@vitest/pretty-format': 2.1.9
+ loupe: 3.2.1
+ tinyrainbow: 1.2.0
+
+ '@yr/monotone-cubic-spline@1.0.3': {}
+
acorn-jsx@5.3.2(acorn@8.15.0):
dependencies:
acorn: 8.15.0
@@ -3027,20 +4687,39 @@ snapshots:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
- ansi-escapes@7.2.0:
+ ajv@8.18.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-uri: 3.1.0
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+
+ ansi-escapes@7.3.0:
dependencies:
environment: 1.1.0
+ ansi-regex@5.0.1: {}
+
ansi-regex@6.2.2: {}
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
+ ansi-styles@5.2.0: {}
+
ansi-styles@6.2.3: {}
+ apexcharts@5.10.3:
+ dependencies:
+ '@yr/monotone-cubic-spline': 1.0.3
+
argparse@2.0.1: {}
+ aria-query@5.3.0:
+ dependencies:
+ dequal: 2.0.3
+
aria-query@5.3.2: {}
array-buffer-byte-length@1.0.2:
@@ -3048,6 +4727,8 @@ snapshots:
call-bound: 1.0.4
is-array-buffer: 3.0.5
+ array-ify@1.0.0: {}
+
array-includes@3.1.9:
dependencies:
call-bind: 1.0.8
@@ -3110,21 +4791,43 @@ snapshots:
get-intrinsic: 1.3.0
is-array-buffer: 3.0.5
+ assertion-error@2.0.1: {}
+
ast-types-flow@0.0.8: {}
+ ast-types@0.16.1:
+ dependencies:
+ tslib: 2.8.1
+
async-function@1.0.0: {}
+ asynckit@0.4.0: {}
+
available-typed-arrays@1.0.7:
dependencies:
possible-typed-array-names: 1.1.0
axe-core@4.11.1: {}
+ axios@1.13.5:
+ dependencies:
+ follow-redirects: 1.15.11
+ form-data: 4.0.5
+ proxy-from-env: 1.1.0
+ transitivePeerDependencies:
+ - debug
+
axobject-query@4.1.0: {}
+ bail@2.0.2: {}
+
balanced-match@1.0.2: {}
- baseline-browser-mapping@2.9.14: {}
+ baseline-browser-mapping@2.9.19: {}
+
+ better-opn@3.0.2:
+ dependencies:
+ open: 8.4.2
brace-expansion@1.1.12:
dependencies:
@@ -3139,11 +4842,13 @@ snapshots:
dependencies:
fill-range: 7.1.1
+ browser-assert@1.2.1: {}
+
browserslist@4.28.1:
dependencies:
- baseline-browser-mapping: 2.9.14
- caniuse-lite: 1.0.30001764
- electron-to-chromium: 1.5.267
+ baseline-browser-mapping: 2.9.19
+ caniuse-lite: 1.0.30001770
+ electron-to-chromium: 1.5.286
node-releases: 2.0.27
update-browserslist-db: 1.2.3(browserslist@4.28.1)
@@ -3168,13 +4873,38 @@ snapshots:
camelcase@6.3.0: {}
- caniuse-lite@1.0.30001764: {}
+ caniuse-lite@1.0.30001770: {}
+
+ ccount@2.0.1: {}
+
+ chai@5.3.3:
+ dependencies:
+ assertion-error: 2.0.1
+ check-error: 2.1.3
+ deep-eql: 5.0.2
+ loupe: 3.2.1
+ pathval: 2.0.1
+
+ 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
+ character-entities-html4@2.1.0: {}
+
+ character-entities-legacy@3.0.0: {}
+
+ character-entities@2.0.2: {}
+
+ character-reference-invalid@2.0.1: {}
+
+ check-error@2.1.3: {}
+
cli-cursor@5.0.0:
dependencies:
restore-cursor: 5.1.0
@@ -3182,7 +4912,15 @@ snapshots:
cli-truncate@5.1.1:
dependencies:
slice-ansi: 7.1.2
- string-width: 8.1.0
+ string-width: 8.2.0
+
+ cliui@8.0.1:
+ dependencies:
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ wrap-ansi: 7.0.0
+
+ clsx@2.1.1: {}
color-convert@2.0.1:
dependencies:
@@ -3192,14 +4930,44 @@ snapshots:
colorette@2.0.20: {}
- commander@14.0.2: {}
+ combined-stream@1.0.8:
+ dependencies:
+ delayed-stream: 1.0.0
+
+ comma-separated-tokens@2.0.3: {}
+
+ commander@14.0.3: {}
+
+ compare-func@2.0.0:
+ dependencies:
+ array-ify: 1.0.0
+ dot-prop: 5.3.0
concat-map@0.0.1: {}
+ conventional-changelog-angular@8.1.0:
+ dependencies:
+ compare-func: 2.0.0
+
+ conventional-changelog-conventionalcommits@9.1.0:
+ dependencies:
+ compare-func: 2.0.0
+
+ conventional-commits-parser@6.2.1:
+ dependencies:
+ meow: 13.2.0
+
convert-source-map@2.0.0: {}
cookie@1.1.1: {}
+ cosmiconfig-typescript-loader@6.2.0(@types/node@24.10.13)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3):
+ dependencies:
+ '@types/node': 24.10.13
+ cosmiconfig: 9.0.0(typescript@5.9.3)
+ jiti: 2.6.1
+ typescript: 5.9.3
+
cosmiconfig@8.3.6(typescript@5.9.3):
dependencies:
import-fresh: 3.3.1
@@ -3209,16 +4977,29 @@ snapshots:
optionalDependencies:
typescript: 5.9.3
+ cosmiconfig@9.0.0(typescript@5.9.3):
+ dependencies:
+ env-paths: 2.2.1
+ import-fresh: 3.3.1
+ js-yaml: 4.1.1
+ parse-json: 5.2.0
+ optionalDependencies:
+ typescript: 5.9.3
+
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
shebang-command: 2.0.0
which: 2.0.2
+ css.escape@1.5.1: {}
+
csstype@3.2.3: {}
damerau-levenshtein@1.0.8: {}
+ dargs@8.1.0: {}
+
data-view-buffer@1.0.2:
dependencies:
call-bound: 1.0.4
@@ -3245,6 +5026,12 @@ snapshots:
dependencies:
ms: 2.1.3
+ decode-named-character-reference@1.3.0:
+ dependencies:
+ character-entities: 2.0.2
+
+ deep-eql@5.0.2: {}
+
deep-is@0.1.4: {}
define-data-property@1.1.4:
@@ -3253,42 +5040,72 @@ snapshots:
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: {}
+
detect-libc@2.1.2: {}
+ detect-node-es@1.1.0: {}
+
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
+
doctrine@2.1.0:
dependencies:
esutils: 2.0.3
+ doctrine@3.0.0:
+ dependencies:
+ esutils: 2.0.3
+
+ dom-accessibility-api@0.5.16: {}
+
+ dom-accessibility-api@0.6.3: {}
+
dot-case@3.0.4:
dependencies:
no-case: 3.0.4
tslib: 2.8.1
+ dot-prop@5.3.0:
+ dependencies:
+ is-obj: 2.0.0
+
dunder-proto@1.0.1:
dependencies:
call-bind-apply-helpers: 1.0.2
es-errors: 1.3.0
gopd: 1.2.0
- electron-to-chromium@1.5.267: {}
+ eastasianwidth@0.2.0: {}
+
+ electron-to-chromium@1.5.286: {}
emoji-regex@10.6.0: {}
+ emoji-regex@8.0.0: {}
+
emoji-regex@9.2.2: {}
- enhanced-resolve@5.18.4:
+ enhanced-resolve@5.19.0:
dependencies:
graceful-fs: 4.2.11
tapable: 2.3.0
entities@4.5.0: {}
+ env-paths@2.2.1: {}
+
environment@1.1.0: {}
error-ex@1.3.4:
@@ -3350,7 +5167,7 @@ snapshots:
typed-array-byte-offset: 1.0.4
typed-array-length: 1.0.7
unbox-primitive: 1.1.0
- which-typed-array: 1.1.19
+ which-typed-array: 1.1.20
es-define-property@1.0.1: {}
@@ -3396,34 +5213,41 @@ snapshots:
is-date-object: 1.1.0
is-symbol: 1.1.1
- esbuild@0.27.2:
+ esbuild-register@3.6.0(esbuild@0.25.12):
+ dependencies:
+ debug: 4.4.3
+ esbuild: 0.25.12
+ transitivePeerDependencies:
+ - supports-color
+
+ esbuild@0.25.12:
optionalDependencies:
- '@esbuild/aix-ppc64': 0.27.2
- '@esbuild/android-arm': 0.27.2
- '@esbuild/android-arm64': 0.27.2
- '@esbuild/android-x64': 0.27.2
- '@esbuild/darwin-arm64': 0.27.2
- '@esbuild/darwin-x64': 0.27.2
- '@esbuild/freebsd-arm64': 0.27.2
- '@esbuild/freebsd-x64': 0.27.2
- '@esbuild/linux-arm': 0.27.2
- '@esbuild/linux-arm64': 0.27.2
- '@esbuild/linux-ia32': 0.27.2
- '@esbuild/linux-loong64': 0.27.2
- '@esbuild/linux-mips64el': 0.27.2
- '@esbuild/linux-ppc64': 0.27.2
- '@esbuild/linux-riscv64': 0.27.2
- '@esbuild/linux-s390x': 0.27.2
- '@esbuild/linux-x64': 0.27.2
- '@esbuild/netbsd-arm64': 0.27.2
- '@esbuild/netbsd-x64': 0.27.2
- '@esbuild/openbsd-arm64': 0.27.2
- '@esbuild/openbsd-x64': 0.27.2
- '@esbuild/openharmony-arm64': 0.27.2
- '@esbuild/sunos-x64': 0.27.2
- '@esbuild/win32-arm64': 0.27.2
- '@esbuild/win32-ia32': 0.27.2
- '@esbuild/win32-x64': 0.27.2
+ '@esbuild/aix-ppc64': 0.25.12
+ '@esbuild/android-arm': 0.25.12
+ '@esbuild/android-arm64': 0.25.12
+ '@esbuild/android-x64': 0.25.12
+ '@esbuild/darwin-arm64': 0.25.12
+ '@esbuild/darwin-x64': 0.25.12
+ '@esbuild/freebsd-arm64': 0.25.12
+ '@esbuild/freebsd-x64': 0.25.12
+ '@esbuild/linux-arm': 0.25.12
+ '@esbuild/linux-arm64': 0.25.12
+ '@esbuild/linux-ia32': 0.25.12
+ '@esbuild/linux-loong64': 0.25.12
+ '@esbuild/linux-mips64el': 0.25.12
+ '@esbuild/linux-ppc64': 0.25.12
+ '@esbuild/linux-riscv64': 0.25.12
+ '@esbuild/linux-s390x': 0.25.12
+ '@esbuild/linux-x64': 0.25.12
+ '@esbuild/netbsd-arm64': 0.25.12
+ '@esbuild/netbsd-x64': 0.25.12
+ '@esbuild/openbsd-arm64': 0.25.12
+ '@esbuild/openbsd-x64': 0.25.12
+ '@esbuild/openharmony-arm64': 0.25.12
+ '@esbuild/sunos-x64': 0.25.12
+ '@esbuild/win32-arm64': 0.25.12
+ '@esbuild/win32-ia32': 0.25.12
+ '@esbuild/win32-x64': 0.25.12
escalade@3.2.0: {}
@@ -3441,11 +5265,11 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.12.1(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)):
+ eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)):
dependencies:
debug: 3.2.7
optionalDependencies:
- '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ '@typescript-eslint/parser': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
eslint: 9.39.2(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
transitivePeerDependencies:
@@ -3453,7 +5277,7 @@ snapshots:
eslint-plugin-import-name@1.2.3: {}
- eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)):
+ eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@@ -3464,7 +5288,7 @@ snapshots:
doctrine: 2.1.0
eslint: 9.39.2(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1))
+ eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1))
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@@ -3476,7 +5300,7 @@ snapshots:
string.prototype.trimend: 1.0.9
tsconfig-paths: 3.15.0
optionalDependencies:
- '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ '@typescript-eslint/parser': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
@@ -3501,10 +5325,10 @@ snapshots:
safe-regex-test: 1.1.0
string.prototype.includes: 2.0.1
- eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(prettier@3.7.4):
+ eslint-plugin-prettier@5.5.5(eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(prettier@3.8.1):
dependencies:
eslint: 9.39.2(jiti@2.6.1)
- prettier: 3.7.4
+ prettier: 3.8.1
prettier-linter-helpers: 1.0.1
synckit: 0.11.12
optionalDependencies:
@@ -3512,12 +5336,12 @@ snapshots:
eslint-plugin-react-hooks@7.0.1(eslint@9.39.2(jiti@2.6.1)):
dependencies:
- '@babel/core': 7.28.6
- '@babel/parser': 7.28.6
+ '@babel/core': 7.29.0
+ '@babel/parser': 7.29.0
eslint: 9.39.2(jiti@2.6.1)
hermes-parser: 0.25.1
- zod: 4.3.5
- zod-validation-error: 4.0.2(zod@4.3.5)
+ zod: 4.3.6
+ zod-validation-error: 4.0.2(zod@4.3.6)
transitivePeerDependencies:
- supports-color
@@ -3542,7 +5366,7 @@ snapshots:
object.fromentries: 2.0.8
object.values: 1.2.1
prop-types: 15.8.1
- resolve: 2.0.0-next.5
+ resolve: 2.0.0-next.6
semver: 6.3.1
string.prototype.matchall: 4.0.12
string.prototype.repeat: 1.0.0
@@ -3551,11 +5375,11 @@ snapshots:
dependencies:
eslint: 9.39.2(jiti@2.6.1)
- eslint-plugin-unused-imports@4.3.0(@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)):
+ eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)):
dependencies:
eslint: 9.39.2(jiti@2.6.1)
optionalDependencies:
- '@typescript-eslint/eslint-plugin': 8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ '@typescript-eslint/eslint-plugin': 8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
eslint-scope@8.4.0:
dependencies:
@@ -3566,6 +5390,8 @@ snapshots:
eslint-visitor-keys@4.2.1: {}
+ eslint-visitor-keys@5.0.0: {}
+
eslint@9.39.2(jiti@2.6.1):
dependencies:
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1))
@@ -3613,6 +5439,8 @@ snapshots:
acorn-jsx: 5.3.2(acorn@8.15.0)
eslint-visitor-keys: 4.2.1
+ esprima@4.0.1: {}
+
esquery@1.7.0:
dependencies:
estraverse: 5.3.0
@@ -3623,11 +5451,19 @@ snapshots:
estraverse@5.3.0: {}
+ estree-util-is-identifier-name@3.0.0: {}
+
estree-walker@2.0.2: {}
+ estree-walker@3.0.3:
+ dependencies:
+ '@types/estree': 1.0.8
+
esutils@2.0.3: {}
- eventemitter3@5.0.1: {}
+ eventemitter3@5.0.4: {}
+
+ extend@3.0.2: {}
fast-deep-equal@3.1.3: {}
@@ -3637,6 +5473,8 @@ snapshots:
fast-levenshtein@2.0.6: {}
+ fast-uri@3.1.0: {}
+
fdir@6.5.0(picomatch@4.0.3):
optionalDependencies:
picomatch: 4.0.3
@@ -3661,10 +5499,34 @@ snapshots:
flatted@3.3.3: {}
+ follow-redirects@1.15.11: {}
+
for-each@0.3.5:
dependencies:
is-callable: 1.2.7
+ foreground-child@3.3.1:
+ dependencies:
+ cross-spawn: 7.0.6
+ signal-exit: 4.1.0
+
+ form-data@4.0.5:
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ es-set-tostringtag: 2.1.0
+ hasown: 2.0.2
+ mime-types: 2.1.35
+
+ framer-motion@12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
+ dependencies:
+ motion-dom: 12.38.0
+ motion-utils: 12.36.0
+ tslib: 2.8.1
+ optionalDependencies:
+ react: 19.2.4
+ react-dom: 19.2.4(react@19.2.4)
+
fsevents@2.3.3:
optional: true
@@ -3685,7 +5547,9 @@ snapshots:
gensync@1.0.0-beta.2: {}
- get-east-asian-width@1.4.0: {}
+ get-caller-file@2.0.5: {}
+
+ get-east-asian-width@1.5.0: {}
get-intrinsic@1.3.0:
dependencies:
@@ -3700,6 +5564,8 @@ snapshots:
hasown: 2.0.2
math-intrinsics: 1.1.0
+ get-nonce@1.0.1: {}
+
get-proto@1.0.1:
dependencies:
dunder-proto: 1.0.1
@@ -3711,10 +5577,29 @@ snapshots:
es-errors: 1.3.0
get-intrinsic: 1.3.0
+ git-raw-commits@4.0.0:
+ dependencies:
+ dargs: 8.1.0
+ meow: 12.1.1
+ split2: 4.2.0
+
glob-parent@6.0.2:
dependencies:
is-glob: 4.0.3
+ glob@10.5.0:
+ dependencies:
+ foreground-child: 3.3.1
+ jackspeak: 3.4.3
+ minimatch: 9.0.5
+ minipass: 7.1.3
+ package-json-from-dist: 1.0.1
+ path-scurry: 1.11.1
+
+ global-directory@4.0.1:
+ dependencies:
+ ini: 4.1.1
+
globals@14.0.0: {}
globals@16.5.0: {}
@@ -3750,12 +5635,38 @@ snapshots:
dependencies:
function-bind: 1.1.2
+ hast-util-to-jsx-runtime@2.3.6:
+ dependencies:
+ '@types/estree': 1.0.8
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ hast-util-whitespace: 3.0.0
+ mdast-util-mdx-expression: 2.0.1
+ mdast-util-mdx-jsx: 3.2.0
+ mdast-util-mdxjs-esm: 2.0.1
+ property-information: 7.1.0
+ space-separated-tokens: 2.0.2
+ style-to-js: 1.1.21
+ unist-util-position: 5.0.0
+ vfile-message: 4.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ hast-util-whitespace@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
hermes-estree@0.25.1: {}
hermes-parser@0.25.1:
dependencies:
hermes-estree: 0.25.1
+ html-url-attributes@3.0.1: {}
+
husky@9.1.7: {}
ignore@5.3.2: {}
@@ -3767,14 +5678,36 @@ snapshots:
parent-module: 1.0.1
resolve-from: 4.0.0
+ import-meta-resolve@4.2.0: {}
+
imurmurhash@0.1.4: {}
+ indent-string@4.0.0: {}
+
+ inherits@2.0.4: {}
+
+ ini@4.1.1: {}
+
+ inline-style-parser@0.2.7: {}
+
internal-slot@1.1.0:
dependencies:
es-errors: 1.3.0
hasown: 2.0.2
side-channel: 1.1.0
+ is-alphabetical@2.0.1: {}
+
+ is-alphanumerical@2.0.1:
+ dependencies:
+ is-alphabetical: 2.0.1
+ is-decimal: 2.0.1
+
+ is-arguments@1.2.0:
+ dependencies:
+ call-bound: 1.0.4
+ has-tostringtag: 1.0.2
+
is-array-buffer@3.0.5:
dependencies:
call-bind: 1.0.8
@@ -3817,15 +5750,21 @@ snapshots:
call-bound: 1.0.4
has-tostringtag: 1.0.2
+ is-decimal@2.0.1: {}
+
+ is-docker@2.2.1: {}
+
is-extglob@2.1.1: {}
is-finalizationregistry@1.1.1:
dependencies:
call-bound: 1.0.4
+ is-fullwidth-code-point@3.0.0: {}
+
is-fullwidth-code-point@5.1.0:
dependencies:
- get-east-asian-width: 1.4.0
+ get-east-asian-width: 1.5.0
is-generator-function@1.1.2:
dependencies:
@@ -3839,6 +5778,8 @@ snapshots:
dependencies:
is-extglob: 2.1.1
+ is-hexadecimal@2.0.1: {}
+
is-map@2.0.3: {}
is-negative-zero@2.0.3: {}
@@ -3850,6 +5791,10 @@ snapshots:
is-number@7.0.0: {}
+ is-obj@2.0.0: {}
+
+ is-plain-obj@4.1.0: {}
+
is-regex@1.2.1:
dependencies:
call-bound: 1.0.4
@@ -3876,7 +5821,7 @@ snapshots:
is-typed-array@1.1.15:
dependencies:
- which-typed-array: 1.1.19
+ which-typed-array: 1.1.20
is-weakmap@2.0.2: {}
@@ -3889,6 +5834,10 @@ snapshots:
call-bound: 1.0.4
get-intrinsic: 1.3.0
+ is-wsl@2.2.0:
+ dependencies:
+ is-docker: 2.2.1
+
isarray@2.0.5: {}
isexe@2.0.0: {}
@@ -3902,6 +5851,12 @@ snapshots:
has-symbols: 1.1.0
set-function-name: 2.0.2
+ jackspeak@3.4.3:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
+
jiti@2.6.1: {}
js-tokens@4.0.0: {}
@@ -3910,6 +5865,8 @@ snapshots:
dependencies:
argparse: 2.0.1
+ jsdoc-type-pratt-parser@4.8.0: {}
+
jsesc@3.1.0: {}
json-buffer@3.0.1: {}
@@ -3918,6 +5875,8 @@ snapshots:
json-schema-traverse@0.4.1: {}
+ json-schema-traverse@1.0.0: {}
+
json-stable-stringify-without-jsonify@1.0.1: {}
json5@1.0.2:
@@ -3948,60 +5907,60 @@ snapshots:
prelude-ls: 1.2.1
type-check: 0.4.0
- lightningcss-android-arm64@1.30.2:
+ lightningcss-android-arm64@1.31.1:
optional: true
- lightningcss-darwin-arm64@1.30.2:
+ lightningcss-darwin-arm64@1.31.1:
optional: true
- lightningcss-darwin-x64@1.30.2:
+ lightningcss-darwin-x64@1.31.1:
optional: true
- lightningcss-freebsd-x64@1.30.2:
+ lightningcss-freebsd-x64@1.31.1:
optional: true
- lightningcss-linux-arm-gnueabihf@1.30.2:
+ lightningcss-linux-arm-gnueabihf@1.31.1:
optional: true
- lightningcss-linux-arm64-gnu@1.30.2:
+ lightningcss-linux-arm64-gnu@1.31.1:
optional: true
- lightningcss-linux-arm64-musl@1.30.2:
+ lightningcss-linux-arm64-musl@1.31.1:
optional: true
- lightningcss-linux-x64-gnu@1.30.2:
+ lightningcss-linux-x64-gnu@1.31.1:
optional: true
- lightningcss-linux-x64-musl@1.30.2:
+ lightningcss-linux-x64-musl@1.31.1:
optional: true
- lightningcss-win32-arm64-msvc@1.30.2:
+ lightningcss-win32-arm64-msvc@1.31.1:
optional: true
- lightningcss-win32-x64-msvc@1.30.2:
+ lightningcss-win32-x64-msvc@1.31.1:
optional: true
- lightningcss@1.30.2:
+ lightningcss@1.31.1:
dependencies:
detect-libc: 2.1.2
optionalDependencies:
- lightningcss-android-arm64: 1.30.2
- lightningcss-darwin-arm64: 1.30.2
- lightningcss-darwin-x64: 1.30.2
- lightningcss-freebsd-x64: 1.30.2
- lightningcss-linux-arm-gnueabihf: 1.30.2
- lightningcss-linux-arm64-gnu: 1.30.2
- lightningcss-linux-arm64-musl: 1.30.2
- lightningcss-linux-x64-gnu: 1.30.2
- lightningcss-linux-x64-musl: 1.30.2
- lightningcss-win32-arm64-msvc: 1.30.2
- lightningcss-win32-x64-msvc: 1.30.2
+ lightningcss-android-arm64: 1.31.1
+ lightningcss-darwin-arm64: 1.31.1
+ lightningcss-darwin-x64: 1.31.1
+ lightningcss-freebsd-x64: 1.31.1
+ lightningcss-linux-arm-gnueabihf: 1.31.1
+ lightningcss-linux-arm64-gnu: 1.31.1
+ lightningcss-linux-arm64-musl: 1.31.1
+ lightningcss-linux-x64-gnu: 1.31.1
+ lightningcss-linux-x64-musl: 1.31.1
+ lightningcss-win32-arm64-msvc: 1.31.1
+ lightningcss-win32-x64-msvc: 1.31.1
lines-and-columns@1.2.4: {}
lint-staged@16.2.7:
dependencies:
- commander: 14.0.2
+ commander: 14.0.3
listr2: 9.0.5
micromatch: 4.0.8
nano-spawn: 2.0.0
@@ -4013,7 +5972,7 @@ snapshots:
dependencies:
cli-truncate: 5.1.1
colorette: 2.0.20
- eventemitter3: 5.0.1
+ eventemitter3: 5.0.4
log-update: 6.1.0
rfdc: 1.4.1
wrap-ansi: 9.0.2
@@ -4022,41 +5981,309 @@ snapshots:
dependencies:
p-locate: 5.0.0
+ lodash.camelcase@4.3.0: {}
+
+ lodash.kebabcase@4.1.1: {}
+
lodash.merge@4.6.2: {}
+ lodash.mergewith@4.6.2: {}
+
+ lodash.snakecase@4.1.1: {}
+
+ lodash.startcase@4.4.0: {}
+
+ lodash.upperfirst@4.3.1: {}
+
+ lodash@4.17.23: {}
+
log-update@6.1.0:
dependencies:
- ansi-escapes: 7.2.0
+ ansi-escapes: 7.3.0
cli-cursor: 5.0.0
slice-ansi: 7.1.2
strip-ansi: 7.1.2
wrap-ansi: 9.0.2
+ longest-streak@3.1.0: {}
+
loose-envify@1.4.0:
dependencies:
js-tokens: 4.0.0
+ loupe@3.2.1: {}
+
lower-case@2.0.2:
dependencies:
tslib: 2.8.1
+ lru-cache@10.4.3: {}
+
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.5
+
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
+ map-or-similar@1.5.0: {}
+
math-intrinsics@1.1.0: {}
+ mdast-util-from-markdown@2.0.2:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ mdast-util-to-string: 4.0.0
+ micromark: 4.0.2
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-decode-string: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ unist-util-stringify-position: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdx-expression@2.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdx-jsx@3.2.0:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ parse-entities: 4.0.2
+ stringify-entities: 4.0.4
+ unist-util-stringify-position: 4.0.0
+ vfile-message: 4.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdxjs-esm@2.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-phrasing@4.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ unist-util-is: 6.0.1
+
+ mdast-util-to-hast@13.2.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ '@ungap/structured-clone': 1.3.0
+ devlop: 1.1.0
+ micromark-util-sanitize-uri: 2.0.1
+ trim-lines: 3.0.1
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.1.0
+ vfile: 6.0.3
+
+ mdast-util-to-markdown@2.1.2:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ longest-streak: 3.1.0
+ mdast-util-phrasing: 4.1.0
+ mdast-util-to-string: 4.0.0
+ micromark-util-classify-character: 2.0.1
+ micromark-util-decode-string: 2.0.1
+ unist-util-visit: 5.1.0
+ zwitch: 2.0.4
+
+ mdast-util-to-string@4.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+
+ memoizerific@1.11.3:
+ dependencies:
+ map-or-similar: 1.5.0
+
+ meow@12.1.1: {}
+
+ meow@13.2.0: {}
+
+ micromark-core-commonmark@2.0.3:
+ dependencies:
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ micromark-factory-destination: 2.0.1
+ micromark-factory-label: 2.0.1
+ micromark-factory-space: 2.0.1
+ micromark-factory-title: 2.0.1
+ micromark-factory-whitespace: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-html-tag-name: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-destination@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-label@2.0.1:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-space@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-title@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-whitespace@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-character@2.1.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-chunked@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-classify-character@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-combine-extensions@2.0.1:
+ dependencies:
+ micromark-util-chunked: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-decode-string@2.0.1:
+ dependencies:
+ decode-named-character-reference: 1.3.0
+ micromark-util-character: 2.1.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-encode@2.0.1: {}
+
+ micromark-util-html-tag-name@2.0.1: {}
+
+ micromark-util-normalize-identifier@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-resolve-all@2.0.1:
+ dependencies:
+ micromark-util-types: 2.0.2
+
+ micromark-util-sanitize-uri@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-encode: 2.0.1
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-subtokenize@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-symbol@2.0.1: {}
+
+ micromark-util-types@2.0.2: {}
+
+ micromark@4.0.2:
+ dependencies:
+ '@types/debug': 4.1.12
+ debug: 4.4.3
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.3
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-encode: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ transitivePeerDependencies:
+ - supports-color
+
micromatch@4.0.8:
dependencies:
braces: 3.0.3
picomatch: 2.3.1
+ mime-db@1.52.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
mimic-function@5.0.1: {}
+ min-indent@1.0.1: {}
+
+ mini-svg-data-uri@1.4.4: {}
+
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.12
@@ -4067,6 +6294,14 @@ snapshots:
minimist@1.2.8: {}
+ minipass@7.1.3: {}
+
+ motion-dom@12.38.0:
+ dependencies:
+ motion-utils: 12.36.0
+
+ motion-utils@12.36.0: {}
+
ms@2.1.3: {}
nano-spawn@2.0.0: {}
@@ -4080,6 +6315,13 @@ snapshots:
lower-case: 2.0.2
tslib: 2.8.1
+ node-exports-info@1.6.0:
+ dependencies:
+ array.prototype.flatmap: 1.3.3
+ es-errors: 1.3.0
+ object.entries: 1.1.9
+ semver: 6.3.1
+
node-releases@2.0.27: {}
object-assign@4.1.1: {}
@@ -4128,6 +6370,12 @@ snapshots:
dependencies:
mimic-function: 5.0.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
@@ -4151,13 +6399,25 @@ snapshots:
dependencies:
p-limit: 3.1.0
+ package-json-from-dist@1.0.1: {}
+
parent-module@1.0.1:
dependencies:
callsites: 3.1.0
+ parse-entities@4.0.2:
+ dependencies:
+ '@types/unist': 2.0.11
+ character-entities-legacy: 3.0.0
+ character-reference-invalid: 2.0.1
+ decode-named-character-reference: 1.3.0
+ is-alphanumerical: 2.0.1
+ is-decimal: 2.0.1
+ is-hexadecimal: 2.0.1
+
parse-json@5.2.0:
dependencies:
- '@babel/code-frame': 7.28.6
+ '@babel/code-frame': 7.29.0
error-ex: 1.3.4
json-parse-even-better-errors: 2.3.1
lines-and-columns: 1.2.4
@@ -4168,8 +6428,15 @@ snapshots:
path-parse@1.0.7: {}
+ path-scurry@1.11.1:
+ dependencies:
+ lru-cache: 10.4.3
+ minipass: 7.1.3
+
path-type@4.0.0: {}
+ pathval@2.0.1: {}
+
picocolors@1.1.1: {}
picomatch@2.3.1: {}
@@ -4178,6 +6445,10 @@ snapshots:
pidtree@0.6.0: {}
+ polished@4.3.1:
+ dependencies:
+ '@babel/runtime': 7.28.6
+
possible-typed-array-names@1.1.0: {}
postcss@8.5.6:
@@ -4192,7 +6463,15 @@ snapshots:
dependencies:
fast-diff: 1.3.0
- prettier@3.7.4: {}
+ prettier@3.8.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: {}
prop-types@15.8.1:
dependencies:
@@ -4200,34 +6479,123 @@ snapshots:
object-assign: 4.1.1
react-is: 16.13.1
+ property-information@7.1.0: {}
+
+ proxy-from-env@1.1.0: {}
+
punycode@2.3.1: {}
- react-dom@19.2.3(react@19.2.3):
+ react-apexcharts@2.1.0(apexcharts@5.10.3)(react@19.2.4):
dependencies:
- react: 19.2.3
+ apexcharts: 5.10.3
+ prop-types: 15.8.1
+ react: 19.2.4
+
+ react-docgen-typescript@2.4.0(typescript@5.9.3):
+ dependencies:
+ typescript: 5.9.3
+
+ react-docgen@7.1.1:
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/traverse': 7.29.0
+ '@babel/types': 7.29.0
+ '@types/babel__core': 7.20.5
+ '@types/babel__traverse': 7.28.0
+ '@types/doctrine': 0.0.9
+ '@types/resolve': 1.20.6
+ doctrine: 3.0.0
+ resolve: 1.22.11
+ strip-indent: 4.1.1
+ transitivePeerDependencies:
+ - supports-color
+
+ react-dom@19.2.4(react@19.2.4):
+ dependencies:
+ react: 19.2.4
scheduler: 0.27.0
- react-hook-form@7.71.1(react@19.2.3):
+ react-hook-form@7.71.1(react@19.2.4):
dependencies:
- react: 19.2.3
+ react: 19.2.4
react-is@16.13.1: {}
- react-router-dom@7.12.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
+ react-is@17.0.2: {}
+
+ react-markdown@10.1.0(@types/react@19.2.14)(react@19.2.4):
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ '@types/react': 19.2.14
+ devlop: 1.1.0
+ hast-util-to-jsx-runtime: 2.3.6
+ html-url-attributes: 3.0.1
+ mdast-util-to-hast: 13.2.1
+ react: 19.2.4
+ remark-parse: 11.0.0
+ remark-rehype: 11.1.2
+ unified: 11.0.5
+ unist-util-visit: 5.1.0
+ vfile: 6.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ react-remove-scroll-bar@2.3.8(@types/react@19.2.14)(react@19.2.4):
+ dependencies:
+ react: 19.2.4
+ react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.4)
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.2.14
+
+ react-remove-scroll@2.7.2(@types/react@19.2.14)(react@19.2.4):
+ dependencies:
+ react: 19.2.4
+ react-remove-scroll-bar: 2.3.8(@types/react@19.2.14)(react@19.2.4)
+ react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.4)
+ tslib: 2.8.1
+ use-callback-ref: 1.3.3(@types/react@19.2.14)(react@19.2.4)
+ use-sidecar: 1.1.3(@types/react@19.2.14)(react@19.2.4)
+ optionalDependencies:
+ '@types/react': 19.2.14
+
+ react-router-dom@7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
dependencies:
- react: 19.2.3
- react-dom: 19.2.3(react@19.2.3)
- react-router: 7.12.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ react: 19.2.4
+ react-dom: 19.2.4(react@19.2.4)
+ react-router: 7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
- react-router@7.12.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
+ react-router@7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
dependencies:
cookie: 1.1.1
- react: 19.2.3
+ react: 19.2.4
set-cookie-parser: 2.7.2
optionalDependencies:
- react-dom: 19.2.3(react@19.2.3)
+ react-dom: 19.2.4(react@19.2.4)
+
+ react-style-singleton@2.2.3(@types/react@19.2.14)(react@19.2.4):
+ dependencies:
+ get-nonce: 1.0.1
+ react: 19.2.4
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.2.14
+
+ react@19.2.4: {}
+
+ recast@0.23.11:
+ dependencies:
+ ast-types: 0.16.1
+ esprima: 4.0.1
+ source-map: 0.6.1
+ tiny-invariant: 1.3.3
+ tslib: 2.8.1
- react@19.2.3: {}
+ redent@3.0.0:
+ dependencies:
+ indent-string: 4.0.0
+ strip-indent: 3.0.0
reflect.getprototypeof@1.0.10:
dependencies:
@@ -4249,17 +6617,43 @@ snapshots:
gopd: 1.2.0
set-function-name: 2.0.2
+ remark-parse@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.0.2
+ micromark-util-types: 2.0.2
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-rehype@11.1.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ mdast-util-to-hast: 13.2.1
+ unified: 11.0.5
+ vfile: 6.0.3
+
+ require-directory@2.1.1: {}
+
+ require-from-string@2.0.2: {}
+
resolve-from@4.0.0: {}
+ resolve-from@5.0.0: {}
+
resolve@1.22.11:
dependencies:
is-core-module: 2.16.1
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
- resolve@2.0.0-next.5:
+ resolve@2.0.0-next.6:
dependencies:
+ es-errors: 1.3.0
is-core-module: 2.16.1
+ node-exports-info: 1.6.0
+ object-keys: 1.1.1
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
@@ -4270,35 +6664,35 @@ snapshots:
rfdc@1.4.1: {}
- rollup@4.55.1:
+ rollup@4.57.1:
dependencies:
'@types/estree': 1.0.8
optionalDependencies:
- '@rollup/rollup-android-arm-eabi': 4.55.1
- '@rollup/rollup-android-arm64': 4.55.1
- '@rollup/rollup-darwin-arm64': 4.55.1
- '@rollup/rollup-darwin-x64': 4.55.1
- '@rollup/rollup-freebsd-arm64': 4.55.1
- '@rollup/rollup-freebsd-x64': 4.55.1
- '@rollup/rollup-linux-arm-gnueabihf': 4.55.1
- '@rollup/rollup-linux-arm-musleabihf': 4.55.1
- '@rollup/rollup-linux-arm64-gnu': 4.55.1
- '@rollup/rollup-linux-arm64-musl': 4.55.1
- '@rollup/rollup-linux-loong64-gnu': 4.55.1
- '@rollup/rollup-linux-loong64-musl': 4.55.1
- '@rollup/rollup-linux-ppc64-gnu': 4.55.1
- '@rollup/rollup-linux-ppc64-musl': 4.55.1
- '@rollup/rollup-linux-riscv64-gnu': 4.55.1
- '@rollup/rollup-linux-riscv64-musl': 4.55.1
- '@rollup/rollup-linux-s390x-gnu': 4.55.1
- '@rollup/rollup-linux-x64-gnu': 4.55.1
- '@rollup/rollup-linux-x64-musl': 4.55.1
- '@rollup/rollup-openbsd-x64': 4.55.1
- '@rollup/rollup-openharmony-arm64': 4.55.1
- '@rollup/rollup-win32-arm64-msvc': 4.55.1
- '@rollup/rollup-win32-ia32-msvc': 4.55.1
- '@rollup/rollup-win32-x64-gnu': 4.55.1
- '@rollup/rollup-win32-x64-msvc': 4.55.1
+ '@rollup/rollup-android-arm-eabi': 4.57.1
+ '@rollup/rollup-android-arm64': 4.57.1
+ '@rollup/rollup-darwin-arm64': 4.57.1
+ '@rollup/rollup-darwin-x64': 4.57.1
+ '@rollup/rollup-freebsd-arm64': 4.57.1
+ '@rollup/rollup-freebsd-x64': 4.57.1
+ '@rollup/rollup-linux-arm-gnueabihf': 4.57.1
+ '@rollup/rollup-linux-arm-musleabihf': 4.57.1
+ '@rollup/rollup-linux-arm64-gnu': 4.57.1
+ '@rollup/rollup-linux-arm64-musl': 4.57.1
+ '@rollup/rollup-linux-loong64-gnu': 4.57.1
+ '@rollup/rollup-linux-loong64-musl': 4.57.1
+ '@rollup/rollup-linux-ppc64-gnu': 4.57.1
+ '@rollup/rollup-linux-ppc64-musl': 4.57.1
+ '@rollup/rollup-linux-riscv64-gnu': 4.57.1
+ '@rollup/rollup-linux-riscv64-musl': 4.57.1
+ '@rollup/rollup-linux-s390x-gnu': 4.57.1
+ '@rollup/rollup-linux-x64-gnu': 4.57.1
+ '@rollup/rollup-linux-x64-musl': 4.57.1
+ '@rollup/rollup-openbsd-x64': 4.57.1
+ '@rollup/rollup-openharmony-arm64': 4.57.1
+ '@rollup/rollup-win32-arm64-msvc': 4.57.1
+ '@rollup/rollup-win32-ia32-msvc': 4.57.1
+ '@rollup/rollup-win32-x64-gnu': 4.57.1
+ '@rollup/rollup-win32-x64-msvc': 4.57.1
fsevents: 2.3.3
safe-array-concat@1.1.3:
@@ -4324,7 +6718,7 @@ snapshots:
semver@6.3.1: {}
- semver@7.7.3: {}
+ semver@7.7.4: {}
set-cookie-parser@2.7.2: {}
@@ -4396,24 +6790,57 @@ snapshots:
dot-case: 3.0.4
tslib: 2.8.1
+ sonner@2.0.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
+ dependencies:
+ react: 19.2.4
+ react-dom: 19.2.4(react@19.2.4)
+
source-map-js@1.2.1: {}
+ source-map@0.6.1: {}
+
+ space-separated-tokens@2.0.2: {}
+
+ split2@4.2.0: {}
+
stop-iteration-iterator@1.1.0:
dependencies:
es-errors: 1.3.0
internal-slot: 1.1.0
+ storybook@8.6.17(prettier@3.8.1):
+ dependencies:
+ '@storybook/core': 8.6.17(prettier@3.8.1)(storybook@8.6.17(prettier@3.8.1))
+ optionalDependencies:
+ prettier: 3.8.1
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
string-argv@0.3.2: {}
+ string-width@4.2.3:
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
+ string-width@5.1.2:
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.1.2
+
string-width@7.2.0:
dependencies:
emoji-regex: 10.6.0
- get-east-asian-width: 1.4.0
+ get-east-asian-width: 1.5.0
strip-ansi: 7.1.2
- string-width@8.1.0:
+ string-width@8.2.0:
dependencies:
- get-east-asian-width: 1.4.0
+ get-east-asian-width: 1.5.0
strip-ansi: 7.1.2
string.prototype.includes@2.0.1:
@@ -4466,14 +6893,37 @@ snapshots:
define-properties: 1.2.1
es-object-atoms: 1.1.1
+ stringify-entities@4.0.4:
+ dependencies:
+ character-entities-html4: 2.1.0
+ character-entities-legacy: 3.0.0
+
+ strip-ansi@6.0.1:
+ dependencies:
+ ansi-regex: 5.0.1
+
strip-ansi@7.1.2:
dependencies:
ansi-regex: 6.2.2
strip-bom@3.0.0: {}
+ strip-indent@3.0.0:
+ dependencies:
+ min-indent: 1.0.1
+
+ strip-indent@4.1.1: {}
+
strip-json-comments@3.1.1: {}
+ style-to-js@1.1.21:
+ dependencies:
+ style-to-object: 1.0.14
+
+ style-to-object@1.0.14:
+ dependencies:
+ inline-style-parser: 0.2.7
+
supports-color@7.2.0:
dependencies:
has-flag: 4.0.0
@@ -4486,23 +6936,39 @@ snapshots:
dependencies:
'@pkgr/core': 0.2.9
- tailwindcss@4.1.18: {}
+ tailwind-merge@3.5.0: {}
+
+ tailwindcss@4.2.0: {}
tapable@2.3.0: {}
+ tiny-invariant@1.3.3: {}
+
+ tinyexec@1.0.2: {}
+
tinyglobby@0.2.15:
dependencies:
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
+ tinyrainbow@1.2.0: {}
+
+ tinyspy@3.0.2: {}
+
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
+ trim-lines@3.0.1: {}
+
+ trough@2.2.0: {}
+
ts-api-utils@2.4.0(typescript@5.9.3):
dependencies:
typescript: 5.9.3
+ ts-dedent@2.2.0: {}
+
tsconfig-paths@3.15.0:
dependencies:
'@types/json5': 0.0.29
@@ -4510,6 +6976,12 @@ snapshots:
minimist: 1.2.8
strip-bom: 3.0.0
+ tsconfig-paths@4.2.0:
+ dependencies:
+ json5: 2.2.3
+ minimist: 1.2.8
+ strip-bom: 3.0.0
+
tslib@2.8.1: {}
type-check@0.4.0:
@@ -4549,12 +7021,12 @@ snapshots:
possible-typed-array-names: 1.1.0
reflect.getprototypeof: 1.0.10
- typescript-eslint@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3):
+ typescript-eslint@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3):
dependencies:
- '@typescript-eslint/eslint-plugin': 8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
- '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
- '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3)
- '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ '@typescript-eslint/eslint-plugin': 8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ '@typescript-eslint/parser': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
eslint: 9.39.2(jiti@2.6.1)
typescript: 5.9.3
transitivePeerDependencies:
@@ -4571,6 +7043,44 @@ snapshots:
undici-types@7.16.0: {}
+ unified@11.0.5:
+ dependencies:
+ '@types/unist': 3.0.3
+ bail: 2.0.2
+ devlop: 1.1.0
+ extend: 3.0.2
+ is-plain-obj: 4.1.0
+ trough: 2.2.0
+ vfile: 6.0.3
+
+ unist-util-is@6.0.1:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-stringify-position@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-parents@6.0.2:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+
+ unist-util-visit@5.1.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.0.2
+
+ unplugin@1.16.1:
+ dependencies:
+ acorn: 8.15.0
+ webpack-virtual-modules: 0.6.2
+
update-browserslist-db@1.2.3(browserslist@4.28.1):
dependencies:
browserslist: 4.28.1
@@ -4581,32 +7091,69 @@ snapshots:
dependencies:
punycode: 2.3.1
- vite-plugin-svgr@4.5.0(rollup@4.55.1)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.8)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)):
+ use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.4):
+ dependencies:
+ react: 19.2.4
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.2.14
+
+ use-sidecar@1.1.3(@types/react@19.2.14)(react@19.2.4):
+ dependencies:
+ detect-node-es: 1.1.0
+ react: 19.2.4
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.2.14
+
+ util@0.12.5:
+ dependencies:
+ inherits: 2.0.4
+ is-arguments: 1.2.0
+ is-generator-function: 1.1.2
+ is-typed-array: 1.1.15
+ which-typed-array: 1.1.20
+
+ uuid@9.0.1: {}
+
+ vfile-message@4.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-stringify-position: 4.0.0
+
+ vfile@6.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile-message: 4.0.3
+
+ vite-plugin-svgr@4.5.0(rollup@4.57.1)(typescript@5.9.3)(vite@6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2)):
dependencies:
- '@rollup/pluginutils': 5.3.0(rollup@4.55.1)
+ '@rollup/pluginutils': 5.3.0(rollup@4.57.1)
'@svgr/core': 8.1.0(typescript@5.9.3)
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3))
- vite: 7.3.1(@types/node@24.10.8)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)
+ vite: 6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2)
transitivePeerDependencies:
- rollup
- supports-color
- typescript
- vite@7.3.1(@types/node@24.10.8)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2):
+ vite@6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(yaml@2.8.2):
dependencies:
- esbuild: 0.27.2
+ esbuild: 0.25.12
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
postcss: 8.5.6
- rollup: 4.55.1
+ rollup: 4.57.1
tinyglobby: 0.2.15
optionalDependencies:
- '@types/node': 24.10.8
+ '@types/node': 24.10.13
fsevents: 2.3.3
jiti: 2.6.1
- lightningcss: 1.30.2
+ lightningcss: 1.31.1
yaml: 2.8.2
+ webpack-virtual-modules@0.6.2: {}
+
which-boxed-primitive@1.1.1:
dependencies:
is-bigint: 1.1.0
@@ -4629,7 +7176,7 @@ snapshots:
isarray: 2.0.5
which-boxed-primitive: 1.1.1
which-collection: 1.0.2
- which-typed-array: 1.1.19
+ which-typed-array: 1.1.20
which-collection@1.0.2:
dependencies:
@@ -4638,7 +7185,7 @@ snapshots:
is-weakmap: 2.0.2
is-weakset: 2.0.4
- which-typed-array@1.1.19:
+ which-typed-array@1.1.20:
dependencies:
available-typed-arrays: 1.0.7
call-bind: 1.0.8
@@ -4654,25 +7201,55 @@ snapshots:
word-wrap@1.2.5: {}
+ wrap-ansi@7.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrap-ansi@8.1.0:
+ dependencies:
+ ansi-styles: 6.2.3
+ string-width: 5.1.2
+ strip-ansi: 7.1.2
+
wrap-ansi@9.0.2:
dependencies:
ansi-styles: 6.2.3
string-width: 7.2.0
strip-ansi: 7.1.2
+ ws@8.19.0: {}
+
+ y18n@5.0.8: {}
+
yallist@3.1.1: {}
yaml@2.8.2: {}
+ 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: {}
- zod-validation-error@4.0.2(zod@4.3.5):
+ zod-validation-error@4.0.2(zod@4.3.6):
dependencies:
- zod: 4.3.5
+ zod: 4.3.6
- zod@4.3.5: {}
+ zod@4.3.6: {}
- zustand@5.0.10(@types/react@19.2.8)(react@19.2.3):
+ zustand@5.0.11(@types/react@19.2.14)(react@19.2.4):
optionalDependencies:
- '@types/react': 19.2.8
- react: 19.2.3
+ '@types/react': 19.2.14
+ react: 19.2.4
+
+ zwitch@2.0.4: {}
diff --git a/prettier/default.mjs b/prettier/default.mjs
index 8f4d761c..b7f2334f 100644
--- a/prettier/default.mjs
+++ b/prettier/default.mjs
@@ -1,12 +1,12 @@
export default {
- semi: true,
- tabWidth: 4,
- useTabs: false,
- printWidth: 160,
- singleQuote: true,
- bracketSpacing: true,
- endOfLine: 'auto',
- trailingComma: 'all',
- arrowParens: 'always',
- quoteProps: 'consistent',
+ semi: true,
+ tabWidth: 4,
+ useTabs: false,
+ printWidth: 160,
+ singleQuote: true,
+ bracketSpacing: true,
+ endOfLine: "auto",
+ trailingComma: "all",
+ arrowParens: "always",
+ quoteProps: "consistent",
};
diff --git a/public/logo.svg b/public/logo.svg
new file mode 100644
index 00000000..f2b6747d
--- /dev/null
+++ b/public/logo.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/scripts/strip-cursor-attribution.mjs b/scripts/strip-cursor-attribution.mjs
new file mode 100644
index 00000000..2ff8f730
--- /dev/null
+++ b/scripts/strip-cursor-attribution.mjs
@@ -0,0 +1,20 @@
+/**
+ * Cursor 에이전트가 붙이는 Git 메시지 trailer 제거.
+ * GitHub가 Co-authored-by를 파싱해 Cursor 아바타를 붙이는 것을 막기 위함.
+ */
+import { readFileSync, writeFileSync } from "node:fs";
+
+const path = process.argv[2];
+if (!path) process.exit(0);
+
+let text = readFileSync(path, "utf8");
+const next = text
+ .split("\n")
+ .filter(
+ (line) =>
+ !/^Co-authored-by:\s*Cursor\b/i.test(line) &&
+ !/^Made-with:\s*Cursor\b/i.test(line),
+ )
+ .join("\n");
+
+if (next !== text) writeFileSync(path, next);
diff --git a/src/App.tsx b/src/App.tsx
index 866b0018..2101c5ea 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,10 +1,19 @@
-import './App.css'
-import { RouterProvider } from 'react-router-dom';
-import router from './routes/routes';
+import "./App.css";
+
+import { RouterProvider } from "react-router-dom";
+
+import { useTokenRefresh } from "@/hooks/auth/useTokenRefresh";
+
+import { router } from "@/routes/Router";
function App() {
- return ;
+ useTokenRefresh();
+
+ return (
+ <>
+
+ >
+ );
}
export default App;
-
diff --git a/src/api/ads/ads.ts b/src/api/ads/ads.ts
new file mode 100644
index 00000000..798de46f
--- /dev/null
+++ b/src/api/ads/ads.ts
@@ -0,0 +1,129 @@
+import type {
+ IAd,
+ ICampaign,
+ ICampaignDetail,
+ ICreateCampaignGroupRequest,
+ IPlatformCampaign,
+ TProvider,
+} from "@/types/ads/campaign";
+import type { ICommonResponse } from "@/types/common/common";
+
+import { axiosInstance } from "@/lib/axiosInstance";
+
+interface IAdListResponse {
+ adContentInfoResponses: IAd[];
+}
+
+interface ITrackingUrlResponse {
+ trackingUrl: string;
+}
+
+interface IPlatformCampaignResponse {
+ adCampaigns: IPlatformCampaign[];
+}
+
+export const getCampaignList = async (orgId: number): Promise => {
+ const { data } = await axiosInstance.get<
+ ICommonResponse<{ projects: ICampaign[] }>
+ >(`/api/project/${orgId}`);
+ return data.data.projects;
+};
+
+export const updateAllCampaignStatus = async (
+ orgId: number,
+ status: "ON_GOING" | "PAUSED",
+): Promise => {
+ await axiosInstance.patch(`/api/project/${orgId}/status`, null, {
+ params: { status },
+ });
+};
+
+export const getCampaignDetail = async (
+ orgId: number,
+ projectId: number,
+): Promise => {
+ const { data } = await axiosInstance.get>(
+ `/api/project/${orgId}/${projectId}`,
+ );
+ return data.data;
+};
+
+export const updateCampaignStatus = async (
+ orgId: number,
+ projectId: number,
+ status: "ON_GOING" | "PAUSED" | "OVER",
+): Promise => {
+ await axiosInstance.patch(
+ `/api/advertisement/${orgId}/projects/${projectId}/status`,
+ null,
+ {
+ params: { status },
+ },
+ );
+};
+
+export const getAdList = async (
+ orgId: number,
+ projectId: number,
+): Promise => {
+ const { data } = await axiosInstance.get>(
+ `/api/advertisement/${orgId}/projects/${projectId}/ad-contents`,
+ );
+ return data.data.adContentInfoResponses;
+};
+
+export const getAdDetail = async (
+ orgId: number,
+ projectId: number,
+ adContentId: number,
+): Promise => {
+ const { data } = await axiosInstance.get>(
+ `/api/advertisement/${orgId}/projects/${projectId}/ad-contents/${adContentId}`,
+ );
+ return data.data;
+};
+
+export const createTrackingUrl = async (
+ orgId: number,
+ adContentId: number,
+ landingUrl: string,
+): Promise => {
+ const { data } = await axiosInstance.post<
+ ICommonResponse
+ >(`/api/clicks/${orgId}/${adContentId}/tracking-url`, {
+ landingUrl,
+ });
+ return data.data;
+};
+
+export const updateAdStatus = async (
+ orgId: number,
+ projectId: number,
+ adContentId: number,
+ status: "ON_GOING" | "PAUSED" | "OVER",
+): Promise => {
+ await axiosInstance.patch(
+ `/api/advertisement/${orgId}/projects/${projectId}/ad-contents/${adContentId}/status`,
+ null,
+ {
+ params: { status },
+ },
+ );
+};
+
+export const getPlatformCampaigns = async (
+ orgId: number,
+ providerType: TProvider,
+): Promise => {
+ const { data } = await axiosInstance.get<
+ ICommonResponse
+ >(`/api/advertisement/${orgId}/campaigns`, { params: { providerType } });
+ return data.data.adCampaigns;
+};
+
+export const createCampaignGroup = async (
+ orgId: number,
+ body: ICreateCampaignGroupRequest,
+): Promise => {
+ await axiosInstance.post(`/api/project/create/${orgId}`, body);
+};
diff --git a/src/api/auth/auth.ts b/src/api/auth/auth.ts
new file mode 100644
index 00000000..ec7e7ca8
--- /dev/null
+++ b/src/api/auth/auth.ts
@@ -0,0 +1,123 @@
+import type {
+ IEmailSendRequest,
+ IEmailSendResponse,
+ IEmailVerifyRequest,
+ ILoginRequest,
+ ILoginResponse,
+ IMyPageInfoResponse,
+ IPasswordResetRequest,
+ ISignUpRequest,
+ ISignUpResponse,
+ ISmsSendRequest,
+ ISmsSendResponse,
+ ISmsVerifyRequest,
+ ISmsVerifyResponse,
+ ITokenRefreshResponse,
+} from "@/types/auth/auth";
+import type { ICommonResponse } from "@/types/common/common";
+
+import { authInstance, axiosInstance } from "@/lib/axiosInstance";
+
+export const sendEmail = async ({
+ email,
+}: IEmailSendRequest): Promise> => {
+ const { data } = await axiosInstance.post("/api/users/email-send", { email });
+ return data;
+};
+
+export const verifyEmail = async ({
+ email,
+ authCode,
+}: IEmailVerifyRequest): Promise> => {
+ const { data } = await axiosInstance.post("/api/users/email-verify", {
+ email,
+ authCode,
+ });
+ return data;
+};
+
+export const signUp = async ({
+ email,
+ password,
+ name,
+ phone_number,
+}: ISignUpRequest): Promise> => {
+ const { data } = await axiosInstance.post("/api/users/signup", {
+ email,
+ password,
+ name,
+ phone_number,
+ });
+ return data;
+};
+
+export const reissueToken = async (): Promise<
+ ICommonResponse
+> => {
+ const { data } = await axiosInstance.post("/api/auth/reissue");
+ return data;
+};
+
+export const login = async ({
+ email,
+ password,
+}: ILoginRequest): Promise> => {
+ const { data } = await authInstance.post("/api/auth/login", {
+ email,
+ password,
+ });
+ return data;
+};
+
+export const sendSMS = async ({
+ phoneNumber,
+}: ISmsSendRequest): Promise> => {
+ const { data } = await axiosInstance.post("/api/users/sms-send", {
+ phoneNumber,
+ });
+ return data;
+};
+
+export const verifySMS = async ({
+ phoneNumber,
+ verificationCode,
+}: ISmsVerifyRequest): Promise> => {
+ const { data } = await axiosInstance.post("/api/users/sms-verify", {
+ phoneNumber,
+ verificationCode,
+ });
+ return data;
+};
+
+export const requestPasswordReset = async ({
+ email,
+}: IEmailSendRequest): Promise> => {
+ const { data } = await axiosInstance.post(
+ "/api/users/password-reset/request",
+ {
+ email,
+ },
+ );
+ return data;
+};
+
+export const resetPassword = async ({
+ email,
+ password,
+}: IPasswordResetRequest): Promise> => {
+ const { data } = await axiosInstance.post(
+ "/api/users/password-reset/confirm",
+ {
+ email,
+ password,
+ },
+ );
+ return data;
+};
+
+export const getMyInfo = async (): Promise<
+ ICommonResponse
+> => {
+ const { data } = await axiosInstance.get("/api/users/my");
+ return data;
+};
diff --git a/src/api/dashboard/overview.ts b/src/api/dashboard/overview.ts
new file mode 100644
index 00000000..d5208be3
--- /dev/null
+++ b/src/api/dashboard/overview.ts
@@ -0,0 +1,50 @@
+import type { ICommonResponse } from "@/types/common/common";
+import type {
+ IBudgetsResponse,
+ IMetricsResponse,
+ IRoasRankingsParams,
+ IRoasRankingsResponse,
+ TProviderType,
+} from "@/types/dashboard/overview";
+
+import { axiosInstance } from "@/lib/axiosInstance";
+
+// 대시보드 - 전체 지표 집계 API
+export const getOverview = async (
+ orgId: number,
+ providerType?: TProviderType,
+): Promise => {
+ const { data } = await axiosInstance.get>(
+ `/api/dashboard/${orgId}/metrics`,
+ { params: providerType ? { providerType } : undefined },
+ );
+ return data.data;
+};
+
+// 대시보드 - 예산 집계 API
+export const getBudget = async (
+ orgId: number,
+ providerType?: TProviderType,
+): Promise => {
+ const { data } = await axiosInstance.get>(
+ `/api/dashboard/budgets`,
+ { params: { orgId, ...(providerType ? { providerType } : {}) } },
+ );
+ return data.data;
+};
+
+// 대시보드 - ROAS 성과 순위 조회 API
+export const getRoasRankings = async (
+ orgId: number,
+ params?: IRoasRankingsParams,
+): Promise => {
+ const { data } = await axiosInstance.get<
+ ICommonResponse
+ >(`/api/dashboard/${orgId}/rankings/roas`, { params });
+ return data.data;
+};
+
+// 더미 클릭 데이터 생성 토글 (테스트용)
+export const toggleDummyClicks = async (): Promise => {
+ await axiosInstance.post("/api/clicks/dummy/toggle");
+};
diff --git a/src/api/workspace/org.ts b/src/api/workspace/org.ts
new file mode 100644
index 00000000..1a647f12
--- /dev/null
+++ b/src/api/workspace/org.ts
@@ -0,0 +1,156 @@
+import type { ICommonResponse } from "@/types/common/common";
+import {
+ type TCreateOrgRequest,
+ type TCreateOrgResponse,
+ type TDeleteWorkspaceMemberResponse,
+ type TGetOrgResponse,
+ type TGetWorkspaceMembersData,
+ type TInviteMemberRequest,
+ type TInviteMemberResponse,
+ type TMyOrgsData,
+ type TPendingMemberResponse,
+ type TUpdateMemberRoleRequest,
+ type TUpdateMemberRoleResponse,
+ type TUpdateWorkspaceRequest,
+ type TWorkspace,
+ type TWorkspaceDetail,
+ type TWorkspaceMemberCount,
+} from "@/types/workspace/workspace";
+
+import { axiosInstance } from "@/lib/axiosInstance";
+
+const buildWorkspaceFormData = (
+ request: Record,
+ imageFile?: File | null,
+) => {
+ const formData = new FormData();
+
+ formData.append(
+ "request",
+ new Blob([JSON.stringify(request)], { type: "application/json" }),
+ );
+ if (imageFile) {
+ formData.append("image", imageFile);
+ }
+ return formData;
+};
+
+export const getMyWorkspaces = async (): Promise => {
+ const { data } =
+ await axiosInstance.get>("/api/org/my");
+ return data.data.organizations;
+};
+
+export const createWorkspace = async (
+ body: TCreateOrgRequest,
+): Promise => {
+ const { imageFile, ...request } = body;
+ const formData = buildWorkspaceFormData(request, imageFile);
+ const { data } = await axiosInstance.post<
+ ICommonResponse
+ >("/api/org/create", formData);
+ return data.data;
+};
+
+export const getWorkspace = async (
+ orgId: number,
+): Promise => {
+ const { data } = await axiosInstance.get>(
+ `/api/org/${orgId}`,
+ );
+
+ return data.data;
+};
+
+export const updateWorkspace = async (
+ orgId: number,
+ body: TUpdateWorkspaceRequest,
+): Promise => {
+ const { imageFile, ...request } = body;
+ const formData = buildWorkspaceFormData(request, imageFile);
+ await axiosInstance.patch>(
+ `/api/org/${orgId}`,
+ formData,
+ );
+};
+
+export const deleteWorkspace = async (orgId: number): Promise => {
+ await axiosInstance.delete>(`/api/org/${orgId}`);
+};
+
+export const getWorkspaceMembers = async (
+ orgId: number,
+ cursor?: string | null,
+ size = 20,
+): Promise => {
+ const params: Record = { size };
+ if (cursor) {
+ params.cursor = cursor;
+ }
+ const { data } = await axiosInstance.get<
+ ICommonResponse
+ >(`/api/org/members/${orgId}`, { params });
+ return data.data;
+};
+
+export const getWorkspaceMemberCount = async (
+ orgId: number,
+): Promise => {
+ const { data } = await axiosInstance.get<
+ ICommonResponse
+ >(`/api/org/members/${orgId}/count`);
+ return data.data;
+};
+
+export const updateWorkspaceMemberPermission = async (
+ orgId: number,
+ memberId: number,
+ body: TUpdateMemberRoleRequest,
+): Promise => {
+ const { data } = await axiosInstance.patch<
+ ICommonResponse
+ >(`/api/org/members/${orgId}/${memberId}`, body);
+
+ return data.data;
+};
+
+export const deleteWorkspaceMember = async (
+ orgId: number,
+ memberId: number,
+): Promise => {
+ const { data } = await axiosInstance.delete<
+ ICommonResponse
+ >(`/api/org/${orgId}/members/${memberId}`);
+
+ return data.data;
+};
+
+export const postInviteEmail = async (
+ orgId: number,
+ body: TInviteMemberRequest,
+): Promise => {
+ const { data } = await axiosInstance.post<
+ ICommonResponse
+ >(`/api/org/members/${orgId}/invitation`, body);
+ return data.data;
+};
+
+export const getPendingMember = async (
+ orgId: number,
+): Promise => {
+ const { data } = await axiosInstance.get<
+ ICommonResponse
+ >(`/api/org/members/${orgId}/pending`);
+
+ return data.data;
+};
+export const getSavedWorkspace = async () => {
+ const { data } = await axiosInstance.get>(
+ "/api/org/my/workspace",
+ );
+ return data.data;
+};
+
+export const saveSelectedWorkspace = async (orgId: number): Promise => {
+ await axiosInstance.post(`/api/org/${orgId}/workspace`);
+};
diff --git a/src/assets/docs/marketing-agreement.md b/src/assets/docs/marketing-agreement.md
new file mode 100644
index 00000000..35235251
--- /dev/null
+++ b/src/assets/docs/marketing-agreement.md
@@ -0,0 +1,18 @@
+## 마케팅 정보 수신 동의 (선택)
+
+1. 마케팅 정보 전송 방법
+마케팅 정보는 회사의 각 개별 서비스에서 정한 방식에 따라 전송됩니다.
+
+2. 마케팅 목적의 개인정보 이용
+회사는 이용자의 개인정보를 다음과 같은 마케팅 목적으로 이용할 수 있습니다.
+
+- 이벤트, 프로모션, 혜택 정보 안내
+- 신규 서비스 및 기능 소개
+- 맞춤형 서비스 및 콘텐츠 제공
+
+3. 광고성 정보 전송 수단
+- 이메일
+- 문자메시지(SMS/LMS)
+- 앱 푸시 알림
+
+> ※ 본 동의는 선택 사항이며, 동의하지 않아도 서비스 이용에는 제한이 없습니다.
\ No newline at end of file
diff --git a/src/assets/docs/privacy-collection.md b/src/assets/docs/privacy-collection.md
new file mode 100644
index 00000000..4b1c3987
--- /dev/null
+++ b/src/assets/docs/privacy-collection.md
@@ -0,0 +1,24 @@
+## 개인정보 수집 및 이용 동의 (필수)
+
+1. 개인정보 수집 및 이용 목적
+ 회사는 WhereYouAd 서비스 제공을 위해 아래와 같은 목적으로 개인정보를 수집하고 이용합니다.
+
+- 서비스 제공: 광고 매체 데이터 연동 및 통합 대시보드 제공, 리포트 생성, 맞춤형 광고 성과 분석 서비스 제공
+- 회원 관리: 회원제 서비스 이용에 따른 본인 확인, 개인 식별, 불량 회원의 부정 이용 방지, 가입 의사 확인, 민원 처리 및 고지 사항 전달
+- 서비스 개선: 신규 서비스 개발 및 맞춤 서비스 제공, 서비스 이용 기록 분석 및 통계
+
+2. 수집하는 개인정보 항목
+ 회사는 회원가입, 상담, 서비스 신청 등을 위해 아래와 같은 개인정보를 수집하고 있습니다.
+
+- **필수 항목**: 이메일 주소(ID), 비밀번호, 이름, 휴대전화 번호
+- 자동 수집 정보: 서비스 이용 기록, 접속 로그, 쿠키, 접속 IP 정보, 기기 정보, 브라우저 유저 에이전트
+
+3. 개인정보 보유 및 이용 기간
+ 이용자의 개인정보는 원칙적으로 개인정보 수집 및 이용 목적이 달성된 후(회원 탈퇴 시) 지체 없이 파기합니다. 단, 관계 법령에 의하여 보존할 필요가 있는 경우에는 해당 기간 동안 보관합니다.
+
+- 계약 또는 청약철회 등에 관한 기록: 5년
+- 대금결제 및 재화 등의 공급에 관한 기록: 5년
+- 소비자의 불만 또는 분쟁처리에 관한 기록: 3년
+- 로그기록 (통신비밀보호법): 3개월
+
+> ※ 귀하는 개인정보 수집 및 이용에 대한 동의를 거부할 권리가 있습니다. 단, 동의를 거부할 경우 회원가입 및 주요 서비스 이용이 제한될 수 있습니다.
diff --git a/src/assets/icon/ai/sparkle-circle.svg b/src/assets/icon/ai/sparkle-circle.svg
new file mode 100644
index 00000000..cf946f25
--- /dev/null
+++ b/src/assets/icon/ai/sparkle-circle.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icon/ai/sparkle.svg b/src/assets/icon/ai/sparkle.svg
new file mode 100644
index 00000000..1c9a137e
--- /dev/null
+++ b/src/assets/icon/ai/sparkle.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/assets/icon/chevron/chervon-double-right.svg b/src/assets/icon/chevron/chervon-double-right.svg
new file mode 100644
index 00000000..5deb1f13
--- /dev/null
+++ b/src/assets/icon/chevron/chervon-double-right.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/assets/icon/chevron/chervon-left.svg b/src/assets/icon/chevron/chervon-left.svg
new file mode 100644
index 00000000..84d64412
--- /dev/null
+++ b/src/assets/icon/chevron/chervon-left.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/chevron/chevron-down.svg b/src/assets/icon/chevron/chevron-down.svg
new file mode 100644
index 00000000..a1200509
--- /dev/null
+++ b/src/assets/icon/chevron/chevron-down.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/chevron/chevron-right.svg b/src/assets/icon/chevron/chevron-right.svg
new file mode 100644
index 00000000..6fd1b50e
--- /dev/null
+++ b/src/assets/icon/chevron/chevron-right.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/chevron/chevron-up.svg b/src/assets/icon/chevron/chevron-up.svg
new file mode 100644
index 00000000..f80e2037
--- /dev/null
+++ b/src/assets/icon/chevron/chevron-up.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/chevron/trend-down.svg b/src/assets/icon/chevron/trend-down.svg
new file mode 100644
index 00000000..3363cd30
--- /dev/null
+++ b/src/assets/icon/chevron/trend-down.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/assets/icon/chevron/trend-up.svg b/src/assets/icon/chevron/trend-up.svg
new file mode 100644
index 00000000..08be4678
--- /dev/null
+++ b/src/assets/icon/chevron/trend-up.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/assets/icon/common/building.svg b/src/assets/icon/common/building.svg
new file mode 100644
index 00000000..a514969a
--- /dev/null
+++ b/src/assets/icon/common/building.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/common/check-white.svg b/src/assets/icon/common/check-white.svg
new file mode 100644
index 00000000..3b569791
--- /dev/null
+++ b/src/assets/icon/common/check-white.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/common/check.svg b/src/assets/icon/common/check.svg
new file mode 100644
index 00000000..982630d7
--- /dev/null
+++ b/src/assets/icon/common/check.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/common/close.svg b/src/assets/icon/common/close.svg
new file mode 100644
index 00000000..0bcfc4a0
--- /dev/null
+++ b/src/assets/icon/common/close.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/common/download.svg b/src/assets/icon/common/download.svg
new file mode 100644
index 00000000..5ef62e34
--- /dev/null
+++ b/src/assets/icon/common/download.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/common/eye-off.svg b/src/assets/icon/common/eye-off.svg
new file mode 100644
index 00000000..3c6d4458
--- /dev/null
+++ b/src/assets/icon/common/eye-off.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icon/common/eye.svg b/src/assets/icon/common/eye.svg
new file mode 100644
index 00000000..5c479ab8
--- /dev/null
+++ b/src/assets/icon/common/eye.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icon/common/link.svg b/src/assets/icon/common/link.svg
new file mode 100644
index 00000000..54e21138
--- /dev/null
+++ b/src/assets/icon/common/link.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/common/mail.svg b/src/assets/icon/common/mail.svg
new file mode 100644
index 00000000..6af1a911
--- /dev/null
+++ b/src/assets/icon/common/mail.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/common/more.svg b/src/assets/icon/common/more.svg
new file mode 100644
index 00000000..62803d88
--- /dev/null
+++ b/src/assets/icon/common/more.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/assets/icon/common/plus.svg b/src/assets/icon/common/plus.svg
new file mode 100644
index 00000000..a6449973
--- /dev/null
+++ b/src/assets/icon/common/plus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icon/common/search.svg b/src/assets/icon/common/search.svg
new file mode 100644
index 00000000..06ca731b
--- /dev/null
+++ b/src/assets/icon/common/search.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icon/common/trash.svg b/src/assets/icon/common/trash.svg
new file mode 100644
index 00000000..a4478d1d
--- /dev/null
+++ b/src/assets/icon/common/trash.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/common/uploadImg.svg b/src/assets/icon/common/uploadImg.svg
new file mode 100644
index 00000000..98740532
--- /dev/null
+++ b/src/assets/icon/common/uploadImg.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/common/user.svg b/src/assets/icon/common/user.svg
new file mode 100644
index 00000000..7196dcf3
--- /dev/null
+++ b/src/assets/icon/common/user.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/common/warn-circle.svg b/src/assets/icon/common/warn-circle.svg
new file mode 100644
index 00000000..9bcf8f87
--- /dev/null
+++ b/src/assets/icon/common/warn-circle.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/sidebar/ads.svg b/src/assets/icon/sidebar/ads.svg
new file mode 100644
index 00000000..43670e6c
--- /dev/null
+++ b/src/assets/icon/sidebar/ads.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/assets/icon/sidebar/dashboard.svg b/src/assets/icon/sidebar/dashboard.svg
new file mode 100644
index 00000000..f5c0ef37
--- /dev/null
+++ b/src/assets/icon/sidebar/dashboard.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/assets/icon/sidebar/logout.svg b/src/assets/icon/sidebar/logout.svg
new file mode 100644
index 00000000..5fd33dd8
--- /dev/null
+++ b/src/assets/icon/sidebar/logout.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/sidebar/map.svg b/src/assets/icon/sidebar/map.svg
new file mode 100644
index 00000000..b77bfaa5
--- /dev/null
+++ b/src/assets/icon/sidebar/map.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/assets/icon/sidebar/notification.svg b/src/assets/icon/sidebar/notification.svg
new file mode 100644
index 00000000..2d8ff618
--- /dev/null
+++ b/src/assets/icon/sidebar/notification.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/assets/icon/sidebar/setting.svg b/src/assets/icon/sidebar/setting.svg
new file mode 100644
index 00000000..613b66e7
--- /dev/null
+++ b/src/assets/icon/sidebar/setting.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/sidebar/workspace.svg b/src/assets/icon/sidebar/workspace.svg
new file mode 100644
index 00000000..c1d416fb
--- /dev/null
+++ b/src/assets/icon/sidebar/workspace.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon/timeline/chevron-left.svg b/src/assets/icon/timeline/chevron-left.svg
new file mode 100644
index 00000000..b180e6e9
--- /dev/null
+++ b/src/assets/icon/timeline/chevron-left.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/assets/icon/timeline/chevron-right.svg b/src/assets/icon/timeline/chevron-right.svg
new file mode 100644
index 00000000..4864a6f7
--- /dev/null
+++ b/src/assets/icon/timeline/chevron-right.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/assets/icon/timeline/filter.svg b/src/assets/icon/timeline/filter.svg
new file mode 100644
index 00000000..c5b95a30
--- /dev/null
+++ b/src/assets/icon/timeline/filter.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/assets/icon/timeline/kebab.svg b/src/assets/icon/timeline/kebab.svg
new file mode 100644
index 00000000..bb2ebad9
--- /dev/null
+++ b/src/assets/icon/timeline/kebab.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/assets/icon/timeline/sort.svg b/src/assets/icon/timeline/sort.svg
new file mode 100644
index 00000000..4c287bc9
--- /dev/null
+++ b/src/assets/icon/timeline/sort.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git "a/src/assets/logo/service-logo/ai-\354\232\224\354\225\275\353\262\204\355\212\274.svg" "b/src/assets/logo/service-logo/ai-\354\232\224\354\225\275\353\262\204\355\212\274.svg"
new file mode 100644
index 00000000..21bf98de
--- /dev/null
+++ "b/src/assets/logo/service-logo/ai-\354\232\224\354\225\275\353\262\204\355\212\274.svg"
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/logo/service-logo/logo.svg b/src/assets/logo/service-logo/logo.svg
new file mode 100644
index 00000000..f2b6747d
--- /dev/null
+++ b/src/assets/logo/service-logo/logo.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/assets/logo/service-logo/symbol-white.svg b/src/assets/logo/service-logo/symbol-white.svg
new file mode 100644
index 00000000..837101bf
--- /dev/null
+++ b/src/assets/logo/service-logo/symbol-white.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/assets/logo/social-logo/circle/google-circle.svg b/src/assets/logo/social-logo/circle/google-circle.svg
new file mode 100644
index 00000000..4ff01a49
--- /dev/null
+++ b/src/assets/logo/social-logo/circle/google-circle.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/logo/social-logo/circle/googleAds-circle.svg b/src/assets/logo/social-logo/circle/googleAds-circle.svg
new file mode 100644
index 00000000..5905045b
--- /dev/null
+++ b/src/assets/logo/social-logo/circle/googleAds-circle.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/logo/social-logo/circle/kakao-circle.svg b/src/assets/logo/social-logo/circle/kakao-circle.svg
new file mode 100644
index 00000000..063d6330
--- /dev/null
+++ b/src/assets/logo/social-logo/circle/kakao-circle.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/src/assets/logo/social-logo/circle/meta-circle.svg b/src/assets/logo/social-logo/circle/meta-circle.svg
new file mode 100644
index 00000000..798a9032
--- /dev/null
+++ b/src/assets/logo/social-logo/circle/meta-circle.svg
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/logo/social-logo/circle/naver-circle.svg b/src/assets/logo/social-logo/circle/naver-circle.svg
new file mode 100644
index 00000000..10408f87
--- /dev/null
+++ b/src/assets/logo/social-logo/circle/naver-circle.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/assets/logo/social-logo/plain/google.svg b/src/assets/logo/social-logo/plain/google.svg
new file mode 100644
index 00000000..4f4c16b8
--- /dev/null
+++ b/src/assets/logo/social-logo/plain/google.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/assets/logo/social-logo/plain/google_ads.png b/src/assets/logo/social-logo/plain/google_ads.png
new file mode 100644
index 00000000..587eaeef
Binary files /dev/null and b/src/assets/logo/social-logo/plain/google_ads.png differ
diff --git a/src/assets/logo/social-logo/plain/kakao.svg b/src/assets/logo/social-logo/plain/kakao.svg
new file mode 100644
index 00000000..70cbda90
--- /dev/null
+++ b/src/assets/logo/social-logo/plain/kakao.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/logo/social-logo/plain/meta.svg b/src/assets/logo/social-logo/plain/meta.svg
new file mode 100644
index 00000000..22806c9f
--- /dev/null
+++ b/src/assets/logo/social-logo/plain/meta.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/logo/social-logo/plain/naver.svg b/src/assets/logo/social-logo/plain/naver.svg
new file mode 100644
index 00000000..c209f4da
--- /dev/null
+++ b/src/assets/logo/social-logo/plain/naver.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/logo/social-logo/wordmark/google-wordmark.svg b/src/assets/logo/social-logo/wordmark/google-wordmark.svg
new file mode 100644
index 00000000..9be188be
--- /dev/null
+++ b/src/assets/logo/social-logo/wordmark/google-wordmark.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/logo/social-logo/wordmark/kakao-wordmark.svg b/src/assets/logo/social-logo/wordmark/kakao-wordmark.svg
new file mode 100644
index 00000000..fab4e477
--- /dev/null
+++ b/src/assets/logo/social-logo/wordmark/kakao-wordmark.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/logo/social-logo/wordmark/naver-wordmark.png b/src/assets/logo/social-logo/wordmark/naver-wordmark.png
new file mode 100644
index 00000000..aa323f73
Binary files /dev/null and b/src/assets/logo/social-logo/wordmark/naver-wordmark.png differ
diff --git a/src/assets/mockup/iOS app dock.png b/src/assets/mockup/iOS app dock.png
new file mode 100644
index 00000000..139d5d90
Binary files /dev/null and b/src/assets/mockup/iOS app dock.png differ
diff --git a/src/assets/mockup/iPad Air mockup.png b/src/assets/mockup/iPad Air mockup.png
new file mode 100644
index 00000000..ef5f2af0
Binary files /dev/null and b/src/assets/mockup/iPad Air mockup.png differ
diff --git a/src/assets/mockup/laptop_mockup.png b/src/assets/mockup/laptop_mockup.png
new file mode 100644
index 00000000..68e41c58
Binary files /dev/null and b/src/assets/mockup/laptop_mockup.png differ
diff --git a/src/assets/mockup/optimized/mockup_test.jpg b/src/assets/mockup/optimized/mockup_test.jpg
new file mode 100644
index 00000000..98b6969a
Binary files /dev/null and b/src/assets/mockup/optimized/mockup_test.jpg differ
diff --git a/src/assets/mockup/optimized/timeline_dashboard.jpg b/src/assets/mockup/optimized/timeline_dashboard.jpg
new file mode 100644
index 00000000..bcdb591f
Binary files /dev/null and b/src/assets/mockup/optimized/timeline_dashboard.jpg differ
diff --git a/src/components/ads/AdDetailContent.tsx b/src/components/ads/AdDetailContent.tsx
new file mode 100644
index 00000000..63452183
--- /dev/null
+++ b/src/components/ads/AdDetailContent.tsx
@@ -0,0 +1,271 @@
+import { useParams } from "react-router-dom";
+import { toast } from "sonner";
+
+import type { IAd } from "@/types/ads/campaign";
+
+import { useControlModal } from "@/hooks/ads/useControlModal";
+
+import Badge from "../common/badge/Badge";
+import ControlBox from "../common/controlbox/ControlBox";
+import Modal from "../common/modal/Modal";
+import ModalContent from "../common/modal/ModalContent";
+
+import { createTrackingUrl, updateAdStatus } from "@/api/ads/ads";
+import LinkIcon from "@/assets/icon/common/link.svg?react";
+import WarnCircleIcon from "@/assets/icon/common/warn-circle.svg?react";
+
+export default function AdDetailContent({
+ ad,
+ refetchAds,
+}: {
+ ad: IAd;
+ refetchAds: () => void;
+}) {
+ const { orgId, projectId } = useParams<{
+ orgId: string;
+ projectId: string;
+ }>();
+
+ const stopControl = useControlModal({
+ successMessage: "광고 소재 노출이 중단되었습니다.",
+ errorMessage: "중단 처리에 실패했습니다.",
+ onSuccess: refetchAds,
+ });
+
+ const resumeControl = useControlModal({
+ successMessage: "광고 소재 운영이 재개되었습니다.",
+ errorMessage: "재개 처리에 실패했습니다.",
+ onSuccess: refetchAds,
+ });
+
+ const trackControl = useControlModal({
+ successMessage: "트래킹 링크가 발급되었습니다.",
+ errorMessage: "트래킹 링크 발급에 실패했습니다.",
+ onSuccess: refetchAds,
+ });
+
+ const isTrackingActive = !!ad.trackingUrl && ad.trackingUrl.length > 0;
+
+ //targetInfo 변환
+ const targetTags = () => {
+ try {
+ if (!ad.targetInfo) return [];
+ const parsed = JSON.parse(ad.targetInfo);
+ return Object.values(parsed) as string[];
+ } catch {
+ return ad.targetInfo ? [ad.targetInfo] : [];
+ }
+ };
+
+ const tags = targetTags();
+
+ const handleCopy = async (text: string) => {
+ try {
+ await navigator.clipboard.writeText(text);
+ toast.success("링크가 복사되었습니다.");
+ } catch {
+ toast.error("복사에 실패했습니다.");
+ }
+ };
+
+ return (
+
+
+ {/* description */}
+
+
광고 소재
+
+ {ad.description}
+
+
+
+ {/* tags */}
+
+
타겟
+
+ {tags.length > 0 ? (
+ tags.map((tag, idx) => (
+
+ #{tag}
+
+ ))
+ ) : (
+
+ 설정된 타겟 정보가 없습니다.
+
+ )}
+
+
+
+ {/* link */}
+
+
랜딩 URL
+
+
+
+ {ad.landingUrl}
+
+ {
+ e.stopPropagation();
+ ad.landingUrl && handleCopy(ad.landingUrl);
+ }}
+ className="shrink-0 text-text-placeholder hover:text-primary-main transition-colors p-1"
+ title="링크 복사"
+ >
+
+
+
+
+
+
+
+
+
+ handleCopy(ad.trackingUrl!)
+ : trackControl.openModal
+ }
+ buttonDisabled={false}
+ containerClassName="bg-status-blue/7 border-status-blue px-6 py-4"
+ titleClassName="text-status-blue font-heading4 -mb-1"
+ descriptionClassName="font-caption text-text-sub"
+ buttonSize="small"
+ buttonClassName="bg-status-blue font-body2 tablet:w-full"
+ />
+
+
+
+
+
+ {/* 트래킹 링크 발급 */}
+
+ }
+ title="트래킹 링크를 발급하시겠습니까?"
+ description={
+ <>
+ 발급된 링크를 복사하여 광고 플랫폼에 등록하면
+
+ 트래킹을 활성화할 수 있습니다.
+ >
+ }
+ buttonText="발급하기"
+ onConfirm={() =>
+ trackControl.handleConfirm(async () => {
+ if (!ad.landingUrl) {
+ toast.error(
+ "광고에 등록된 랜딩 URL이 없어 발급이 불가능합니다.",
+ );
+ throw new Error("랜딩 URL이 없습니다.");
+ }
+ await createTrackingUrl(Number(orgId), ad.id, ad.landingUrl);
+ })
+ }
+ isLoading={trackControl.isLoading}
+ variant="primary"
+ />
+
+
+ {/* 광고 소재 중단 */}
+
+ }
+ title="광고 소재를 중단하시겠습니까?"
+ description="해당 광고의 노출이 즉시 중단됩니다."
+ buttonText="중단하기"
+ onConfirm={() =>
+ stopControl.handleConfirm(() =>
+ updateAdStatus(Number(orgId), Number(projectId), ad.id, "PAUSED"),
+ )
+ }
+ isLoading={stopControl.isLoading}
+ variant="danger"
+ />
+
+
+ {/* 광고 소재 재개 */}
+
+ }
+ title="광고 운영을 재개하시겠습니까?"
+ description="중단되었던 광고 소재가 다시 플랫폼에 노출되기 시작합니다."
+ buttonText="시작하기"
+ onConfirm={() =>
+ resumeControl.handleConfirm(() =>
+ updateAdStatus(
+ Number(orgId),
+ Number(projectId),
+ ad.id,
+ "ON_GOING",
+ ),
+ )
+ }
+ isLoading={resumeControl.isLoading}
+ variant="primary"
+ />
+
+
+ );
+}
diff --git a/src/components/ads/AdListTable.tsx b/src/components/ads/AdListTable.tsx
new file mode 100644
index 00000000..1c89a946
--- /dev/null
+++ b/src/components/ads/AdListTable.tsx
@@ -0,0 +1,64 @@
+import { useState } from "react";
+
+import type { IAd, TPlatform } from "@/types/ads/campaign";
+
+import AdDetailContent from "./AdDetailContent";
+import AdRow from "./AdRow";
+
+interface IAdsListTableProps {
+ ads: IAd[];
+ refetchAds: () => void;
+}
+
+export default function AdListTable({ ads, refetchAds }: IAdsListTableProps) {
+ const [openAdId, setOpenAdId] = useState(null);
+
+ const handleToggle = (id: number) => {
+ setOpenAdId((prev) => (prev === id ? null : id));
+ };
+ return (
+
+
광고 모아보기
+
+ {ads && ads.length > 0 ? (
+ ads.map((ad) => {
+ const platform = String(ad.provider).toLowerCase() as TPlatform;
+
+ const isRunning = ad.status === "ON_GOING";
+ const isPaused = ad.status === "PAUSED";
+
+ const runStatus = isRunning ? "running" : "stopped";
+ const runStatusText = isRunning
+ ? "운영 중"
+ : isPaused
+ ? "중단"
+ : "종료";
+
+ return (
+
+
handleToggle(ad.id)}
+ />
+
+ {openAdId === ad.id && (
+
+ )}
+
+ );
+ })
+ ) : (
+
+ 연결된 광고 소재가 없습니다.
+
+ )}
+
+
+ );
+}
diff --git a/src/components/ads/AdRow.tsx b/src/components/ads/AdRow.tsx
new file mode 100644
index 00000000..b5d647a0
--- /dev/null
+++ b/src/components/ads/AdRow.tsx
@@ -0,0 +1,76 @@
+import type { ReactNode } from "react";
+
+import type { TPlatform } from "@/types/ads/campaign";
+
+import Badge from "../common/badge/Badge";
+
+import ChevronIcon from "@/assets/icon/chevron/chevron-up.svg?react";
+import GoogleLogo from "@/assets/logo/social-logo/circle/google-circle.svg?react";
+import KakaoLogo from "@/assets/logo/social-logo/circle/kakao-circle.svg?react";
+import NaverLogo from "@/assets/logo/social-logo/circle/naver-circle.svg?react";
+
+interface IAdRowProps {
+ name: string;
+ runStatus: "running" | "stopped";
+ runStatusText: string;
+ platform: TPlatform;
+ isOpen: boolean;
+ onToggle: () => void;
+}
+
+const LogoMap: Record = {
+ kakao: ,
+ google: ,
+ naver: ,
+};
+
+export default function AdRow({
+ name,
+ runStatus,
+ runStatusText,
+ platform,
+ isOpen,
+ onToggle,
+}: IAdRowProps) {
+ return (
+
+ {/* status badge */}
+
+
+ {runStatusText}
+
+
+
+ {/* platform */}
+
+
+ {LogoMap[platform]}
+
+
+
+ {/* title */}
+
+ {name}
+
+
+ {/* chevron */}
+
+
+
+
+ );
+}
diff --git a/src/components/ads/CampaignInfoCard.tsx b/src/components/ads/CampaignInfoCard.tsx
new file mode 100644
index 00000000..466c002a
--- /dev/null
+++ b/src/components/ads/CampaignInfoCard.tsx
@@ -0,0 +1,42 @@
+import InfoCard from "@/components/common/card/InfoCard";
+
+import Badge from "../common/badge/Badge";
+
+interface ICampaignInfoCardProps {
+ budget: string;
+ date: string;
+ className?: string;
+}
+
+export default function CampaignInfoCard({
+ budget,
+ date,
+ className,
+}: ICampaignInfoCardProps) {
+ const badgeStyle = "border-none bg-bg-disabled text-text-sub";
+ return (
+
+
+ {/* 예산 현황 */}
+
+
+ 예산 현황
+
+
+ {budget}
+
+
+
+ {/* 등록 날짜 */}
+
+
+ 등록 날짜
+
+
+ {date}
+
+
+
+
+ );
+}
diff --git a/src/components/ads/CampaignRow.tsx b/src/components/ads/CampaignRow.tsx
new file mode 100644
index 00000000..61b81616
--- /dev/null
+++ b/src/components/ads/CampaignRow.tsx
@@ -0,0 +1,90 @@
+import type { ReactNode } from "react";
+
+import type { TPlatform, TStatus } from "@/types/ads/campaign";
+
+import ProgressBar from "../common/progressbar/ProgressBar";
+
+import GoogleLogo from "@/assets/logo/social-logo/circle/google-circle.svg?react";
+import KakaoLogo from "@/assets/logo/social-logo/circle/kakao-circle.svg?react";
+import NaverLogo from "@/assets/logo/social-logo/circle/naver-circle.svg?react";
+
+interface ICampaignRowProps {
+ projectId: number;
+ name: string;
+ providers: TPlatform[];
+ status: TStatus;
+ budgetUsageRate: number;
+ onClick?: () => void;
+}
+
+const LogoMap: Record = {
+ kakao: ,
+ google: ,
+ naver: ,
+};
+
+export default function CampaignRow({
+ name,
+ providers,
+ status,
+ budgetUsageRate,
+ onClick,
+}: ICampaignRowProps) {
+ const isPaused = status == "PAUSED";
+ return (
+ {
+ if (onClick && (e.key === "Enter" || e.key === " ")) {
+ e.preventDefault();
+ onClick();
+ }
+ }}
+ >
+ {/* 플랫폼 */}
+
+ {providers && providers.length > 0 ? (
+ providers.map((p, idx) => (
+
+ {LogoMap[p.toLowerCase() as TPlatform]}
+
+ ))
+ ) : (
+
미연결
+ )}
+
+
+ {/* 캠페인 명 */}
+
+
+ {/* 동기화 상태 */}
+ {/*
+
+ {statusText}
+
+
*/}
+
+ {/* 예산 소진 현황 */}
+
+
+ );
+}
diff --git a/src/components/ads/CampaignTable.tsx b/src/components/ads/CampaignTable.tsx
new file mode 100644
index 00000000..bd0b2bac
--- /dev/null
+++ b/src/components/ads/CampaignTable.tsx
@@ -0,0 +1,54 @@
+import type { ICampaign } from "@/types/ads/campaign";
+
+import CampaignRow from "./CampaignRow";
+
+//import { MOCK_CAMPAIGNS } from "@/pages/ads/list/campaign.mock";
+
+interface ICampaignTableProps {
+ campaigns: ICampaign[];
+ onRowClick?: (id: number) => void;
+}
+
+export default function CampaignTable({
+ campaigns,
+ onRowClick,
+}: ICampaignTableProps) {
+ const visibleCampaigns = campaigns.filter(
+ (project) => project.status !== "OVER",
+ );
+
+ return (
+
+ {/* Table Header */}
+
+
+ 플랫폼
+
+
+ 캠페인 명
+
+
+ 예산 소진 현황
+ 예산
+
+
+
+ {/* Row */}
+
+ {visibleCampaigns.length > 0 ? (
+ visibleCampaigns.map((project) => (
+ onRowClick?.(project.projectId)}
+ />
+ ))
+ ) : (
+
+ 현재 표시할 캠페인이 없습니다.
+
+ )}
+
+
+ );
+}
diff --git a/src/components/ads/PlatformCard.tsx b/src/components/ads/PlatformCard.tsx
new file mode 100644
index 00000000..90fcc8ef
--- /dev/null
+++ b/src/components/ads/PlatformCard.tsx
@@ -0,0 +1,40 @@
+import type { ReactNode } from "react";
+
+import type { TPlatform } from "@/types/ads/campaign";
+
+import InfoCard from "@/components/common/card/InfoCard";
+
+import GoogleLogo from "@/assets/logo/social-logo/circle/google-circle.svg?react";
+import KakaoLogo from "@/assets/logo/social-logo/circle/kakao-circle.svg?react";
+import NaverLogo from "@/assets/logo/social-logo/circle/naver-circle.svg?react";
+
+interface IPlatformCardProps {
+ platforms: TPlatform[];
+ className?: string;
+}
+
+const LogoMap: Record = {
+ kakao: ,
+ google: ,
+ naver: ,
+};
+
+export default function PlatformCard({
+ platforms,
+ className,
+}: IPlatformCardProps) {
+ return (
+
+
+ {platforms.map((p, idx) => (
+
+ {LogoMap[p]}
+
+ ))}
+
+
+ );
+}
diff --git a/src/components/auth/common/AuthFormShell.tsx b/src/components/auth/common/AuthFormShell.tsx
new file mode 100644
index 00000000..5f4c084f
--- /dev/null
+++ b/src/components/auth/common/AuthFormShell.tsx
@@ -0,0 +1,30 @@
+import { type ReactNode } from "react";
+import { twMerge } from "tailwind-merge";
+
+const shellBase = "mx-auto w-full max-w-130 px-6";
+
+type TAuthFormShellVariant = "page" | "social" | "step";
+
+const variantClasses: Record = {
+ page: "py-12",
+ social: "flex flex-col items-center",
+ step: "pb-12",
+};
+
+interface IAuthFormShellProps {
+ children: ReactNode;
+ variant?: TAuthFormShellVariant;
+ className?: string;
+}
+
+export default function AuthFormShell({
+ children,
+ variant = "step",
+ className,
+}: IAuthFormShellProps) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/src/components/auth/common/CommonAuthInput.tsx b/src/components/auth/common/CommonAuthInput.tsx
new file mode 100644
index 00000000..b5c72326
--- /dev/null
+++ b/src/components/auth/common/CommonAuthInput.tsx
@@ -0,0 +1,122 @@
+import React, { useState } from "react";
+
+import formatPhoneNumber from "@/utils/formatPhoneNumber";
+
+import Input, { type IInputProps } from "@/components/common/input/Input";
+
+import InputActions from "./InputActions";
+
+import EyeIcon from "@/assets/icon/common/eye.svg?react";
+import EyeOffIcon from "@/assets/icon/common/eye-off.svg?react";
+
+type TCommonAuthInputProps = {
+ type?: string;
+ placeholder?: string;
+ title?: string;
+ validation?: boolean;
+ validationState?: string;
+ error?: boolean;
+ value?: string;
+ errorMessage?: string;
+ button?: boolean;
+ buttonText?: string;
+ onButtonClick?: () => void;
+ timer?: string;
+} & Omit<
+ IInputProps,
+ | "label"
+ | "helperText"
+ | "success"
+ | "rightElement"
+ | "error"
+ | "containerClassName"
+>;
+
+const CommonAuthInput = React.forwardRef<
+ HTMLInputElement,
+ TCommonAuthInputProps
+>(
+ (
+ {
+ type,
+ title,
+ validation = false,
+ error,
+ errorMessage,
+ button,
+ buttonText,
+ onButtonClick,
+ validationState,
+ timer,
+ onChange,
+ className,
+ ...rest
+ },
+ ref,
+ ) => {
+ const [showPassword, setShowPassword] = useState(false);
+
+ const handleTogglePassword = () => {
+ setShowPassword((prev) => !prev);
+ };
+
+ const inputType = type === "password" && showPassword ? "text" : type;
+ const isPhoneNum = type === "tel";
+
+ const renderRightElement = () => {
+ if (type === "password") {
+ return (
+
+ {showPassword ? (
+
+ ) : (
+
+ )}
+
+ );
+ }
+
+ return (
+
+ );
+ };
+
+ return (
+ {
+ if (isPhoneNum) {
+ const formatted = formatPhoneNumber(e.target.value);
+ e.target.value = formatted;
+ }
+
+ onChange?.(e);
+ }}
+ {...rest}
+ />
+ );
+ },
+);
+
+export default CommonAuthInput;
diff --git a/src/components/auth/common/InputActions.tsx b/src/components/auth/common/InputActions.tsx
new file mode 100644
index 00000000..c0bf42df
--- /dev/null
+++ b/src/components/auth/common/InputActions.tsx
@@ -0,0 +1,57 @@
+import { twMerge } from "tailwind-merge";
+
+import Button from "@/components/common/button/Button";
+
+interface IInputActionsProps {
+ button?: boolean;
+ buttonText?: string;
+ onButtonClick?: () => void;
+ validationState?: string;
+ timer?: string;
+ validation?: boolean;
+ error?: boolean;
+ type?: string;
+}
+
+export default function InputActions({
+ button,
+ buttonText,
+ onButtonClick,
+ validationState,
+ timer,
+ validation = false,
+ error = false,
+ type,
+}: IInputActionsProps) {
+ if (!button && !validationState && !timer) {
+ return null;
+ }
+
+ return (
+
+ {timer && {timer} }
+ {button && (
+
+ {buttonText}
+
+ )}
+ {validationState && (
+
+ {validationState}
+
+ )}
+
+ );
+}
diff --git a/src/components/auth/common/PasswordForm.tsx b/src/components/auth/common/PasswordForm.tsx
new file mode 100644
index 00000000..174ba45f
--- /dev/null
+++ b/src/components/auth/common/PasswordForm.tsx
@@ -0,0 +1,79 @@
+import { type ReactNode } from "react";
+import { type SubmitHandler, useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import type { z } from "zod";
+
+import { signupPasswordSchema } from "@/utils/validation";
+
+import AuthFormShell from "@/components/auth/common/AuthFormShell";
+import CommonAuthInput from "@/components/auth/common/CommonAuthInput";
+import Button from "@/components/common/button/Button";
+
+type TSignupPasswordFormValues = z.infer;
+
+interface IPasswordFormProps {
+ title: ReactNode;
+ buttonText: string;
+ onSubmit: (password: string) => void;
+ disabled?: boolean;
+}
+
+export default function PasswordForm({
+ title,
+ buttonText,
+ onSubmit,
+ disabled,
+}: IPasswordFormProps) {
+ const {
+ register,
+ handleSubmit,
+ formState: { errors, isValid },
+ } = useForm({
+ mode: "onBlur",
+ resolver: zodResolver(signupPasswordSchema),
+ });
+
+ const handleFormSubmit: SubmitHandler = (data) => {
+ onSubmit(data.password);
+ };
+
+ return (
+
+ {title}
+
+
+
+ );
+}
diff --git a/src/components/auth/flows/find-email/EnterPhoneStep.tsx b/src/components/auth/flows/find-email/EnterPhoneStep.tsx
new file mode 100644
index 00000000..9c9806d7
--- /dev/null
+++ b/src/components/auth/flows/find-email/EnterPhoneStep.tsx
@@ -0,0 +1,217 @@
+import { useEffect, useState } from "react";
+import { type SubmitHandler, useForm, useWatch } from "react-hook-form";
+import { Link } from "react-router-dom";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { toast } from "sonner";
+import type { z } from "zod";
+
+import { stripPhoneHyphens } from "@/utils/formatPhoneNumber";
+import { findEmailSchema } from "@/utils/validation";
+
+import { useAuth } from "@/hooks/auth/useAuth";
+import { useTimer } from "@/hooks/common/useTimer";
+
+import AuthFormShell from "@/components/auth/common/AuthFormShell";
+import CommonAuthInput from "@/components/auth/common/CommonAuthInput";
+import Button from "@/components/common/button/Button";
+
+import useAuthStore from "@/store/useAuthStore";
+
+interface IEnterPhoneStepProps {
+ onNext: () => void;
+}
+
+type TFindEmailFormValues = z.infer;
+
+export default function EnterPhoneStep({ onNext }: IEnterPhoneStepProps) {
+ const { setEmail } = useAuthStore();
+ const { useSendSMS, useVerifySMS } = useAuth();
+ const { mutate: sendSMSMutate, isPending: isSending } = useSendSMS;
+ const { mutate: verifySMSMutate, isPending: isVerifying } = useVerifySMS;
+
+ const [sendCode, setSendCode] = useState(false);
+ const [codeError, setCodeError] = useState("");
+ const { formattedTime, isExpired, restart, stop } = useTimer(0, {
+ onExpire: () => {
+ toast.error("인증 시간이 만료되었습니다. 다시 시도해주세요.");
+ },
+ });
+
+ const {
+ register,
+ handleSubmit,
+ control,
+ trigger,
+ setValue,
+ formState: { errors, isValid },
+ } = useForm({
+ mode: "onBlur",
+ resolver: zodResolver(findEmailSchema),
+ });
+
+ const watchedPhone = useWatch({ control, name: "phoneNum" });
+ const watchedCode = useWatch({ control, name: "code" });
+
+ const sendVerificationSMS = (phoneNumber: string, message: string) => {
+ sendSMSMutate(
+ { phoneNumber },
+ {
+ onSuccess: (res) => {
+ setSendCode(true);
+ restart(res.data.expireIn);
+ toast.success(message);
+ },
+ onError: (error) => {
+ toast.error(error.message ?? "인증번호 발송에 실패했습니다.");
+ },
+ },
+ );
+ };
+
+ const postSendCode = async () => {
+ const isPhoneValid = await trigger("phoneNum");
+ if (isPhoneValid && watchedPhone) {
+ const phoneNumber = stripPhoneHyphens(watchedPhone);
+ sendVerificationSMS(phoneNumber, "인증번호가 발송되었습니다.");
+ }
+ };
+
+ const handleResendSMS = () => {
+ if (watchedPhone) {
+ const phoneNumber = stripPhoneHyphens(watchedPhone);
+ sendVerificationSMS(phoneNumber, "인증번호가 재발송되었습니다.");
+ }
+ };
+
+ const handleEditPhone = () => {
+ setSendCode(false);
+ stop();
+ setValue("code", "");
+ };
+
+ const onSubmit: SubmitHandler = (formData) => {
+ const phoneNumber = stripPhoneHyphens(formData.phoneNum);
+ verifySMSMutate(
+ { phoneNumber, verificationCode: formData.code },
+ {
+ onSuccess: (res) => {
+ if (res.data.isVerified) {
+ setEmail(res.data.email);
+ onNext();
+ } else {
+ setCodeError(res.data.verificationMessage);
+ }
+ },
+ onError: (error) => {
+ setCodeError(error.message ?? "인증번호가 올바르지 않습니다.");
+ },
+ },
+ );
+ };
+
+ useEffect(() => {
+ setCodeError("");
+ }, [watchedCode, watchedPhone]);
+
+ return (
+
+
+ 이메일 찾기를 위해
+ 휴대폰 인증을 진행할게요
+
+
+
+ {!sendCode ? (
+
+ ) : (
+
+
+
+ 수정
+
+
+ )}
+
+
+
+
+
+
+ 다음으로
+
+
+
+ {sendCode && (
+
+
+ 인증번호 다시 받기
+
+
+ )}
+
+
+
+ 비밀번호 찾기
+
+
+
+ );
+}
diff --git a/src/components/auth/flows/find-email/ShowEmailResultStep.tsx b/src/components/auth/flows/find-email/ShowEmailResultStep.tsx
new file mode 100644
index 00000000..03182de9
--- /dev/null
+++ b/src/components/auth/flows/find-email/ShowEmailResultStep.tsx
@@ -0,0 +1,49 @@
+import { useNavigate } from "react-router-dom";
+
+import { maskEmail } from "@/utils/maskEmail";
+
+import AuthFormShell from "@/components/auth/common/AuthFormShell";
+import Button from "@/components/common/button/Button";
+
+import useAuthStore from "@/store/useAuthStore";
+
+export default function ShowEmailResultStep() {
+ const navigate = useNavigate();
+ const { email } = useAuthStore();
+
+ return (
+
+
+ 입력하신 정보로
+ WYA에 가입된 계정을 찾았어요
+
+
+
+
+
+ 이메일 ID
+
+
+ {maskEmail(email)}
+
+
+
navigate("/find-pw")}
+ >
+ 비밀번호 재설정
+
+
+
+ navigate("/login")}
+ variant="gradient"
+ >
+ 로그인으로 돌아가기
+
+
+ );
+}
diff --git a/src/components/auth/flows/reset-password/EmailVerificationStep.tsx b/src/components/auth/flows/reset-password/EmailVerificationStep.tsx
new file mode 100644
index 00000000..0385b7b7
--- /dev/null
+++ b/src/components/auth/flows/reset-password/EmailVerificationStep.tsx
@@ -0,0 +1,127 @@
+import { useAuth } from "@/hooks/auth/useAuth";
+import { useEmailVerification } from "@/hooks/auth/useEmailVerification";
+
+import AuthFormShell from "@/components/auth/common/AuthFormShell";
+import CommonAuthInput from "@/components/auth/common/CommonAuthInput";
+import Button from "@/components/common/button/Button";
+
+interface IEmailVerificationStepProps {
+ onNext: () => void;
+}
+
+export default function EmailVerificationStep({
+ onNext,
+}: IEmailVerificationStepProps) {
+ const { useRequestPasswordReset } = useAuth();
+ const {
+ form: { register },
+ watchedEmail,
+ sendCode,
+ formattedTime,
+ isExpired,
+ codeError,
+ errors,
+ isValid,
+ isPending,
+ handlers: {
+ postSendCode,
+ handleResendEmail,
+ handleEditEmail,
+ handleSubmit,
+ },
+ } = useEmailVerification({ onNext, sendMutation: useRequestPasswordReset });
+
+ return (
+
+
+ 비밀번호 찾기를 위해
+ 이메일 인증을 진행할게요
+
+
+
+ {!sendCode ? (
+
+ ) : (
+
+
+
+ 수정
+
+
+ )}
+
+
+
+
+
+
+ 다음으로
+
+
+
+ {sendCode && (
+
+
+ 인증번호 다시 받기
+
+
+ )}
+
+ );
+}
diff --git a/src/components/auth/flows/reset-password/NewPasswordStep.tsx b/src/components/auth/flows/reset-password/NewPasswordStep.tsx
new file mode 100644
index 00000000..e0c1a167
--- /dev/null
+++ b/src/components/auth/flows/reset-password/NewPasswordStep.tsx
@@ -0,0 +1,46 @@
+import { useNavigate } from "react-router-dom";
+import { toast } from "sonner";
+
+import { useAuth } from "@/hooks/auth/useAuth";
+
+import PasswordForm from "@/components/auth/common/PasswordForm";
+
+import useAuthStore from "@/store/useAuthStore";
+
+export default function NewPasswordStep() {
+ const navigate = useNavigate();
+ const { email } = useAuthStore();
+ const { useResetPassword } = useAuth();
+
+ const handleSubmit = (password: string) => {
+ useResetPassword.mutate(
+ { email, password },
+ {
+ onSuccess: () => {
+ toast.success("비밀번호가 변경되었습니다.", {
+ description: "로그인 페이지로 이동합니다.",
+ });
+ navigate("/login", { replace: true });
+ },
+ onError: (error) => {
+ toast.error(error.message ?? "비밀번호 변경에 실패했습니다.");
+ },
+ },
+ );
+ };
+
+ return (
+
+ 새로운 비밀번호를
+
+ 입력해 주세요
+ >
+ }
+ buttonText="비밀번호 변경하기"
+ onSubmit={handleSubmit}
+ disabled={useResetPassword.isPending}
+ />
+ );
+}
diff --git a/src/components/auth/flows/signup/EnterEmailStep.tsx b/src/components/auth/flows/signup/EnterEmailStep.tsx
new file mode 100644
index 00000000..ee533db4
--- /dev/null
+++ b/src/components/auth/flows/signup/EnterEmailStep.tsx
@@ -0,0 +1,122 @@
+import { useEmailVerification } from "@/hooks/auth/useEmailVerification";
+
+import AuthFormShell from "@/components/auth/common/AuthFormShell";
+import CommonAuthInput from "@/components/auth/common/CommonAuthInput";
+import Button from "@/components/common/button/Button";
+
+interface IEnterEmailStepProps {
+ onNext: () => void;
+}
+
+export default function EnterEmailStep({ onNext }: IEnterEmailStepProps) {
+ const {
+ form: { register },
+ watchedEmail,
+ sendCode,
+ formattedTime,
+ isExpired,
+ codeError,
+ errors,
+ isValid,
+ isPending,
+ handlers: {
+ postSendCode,
+ handleResendEmail,
+ handleEditEmail,
+ handleSubmit,
+ },
+ } = useEmailVerification({ onNext });
+
+ return (
+
+
+ 회원가입을 위해
+ 이메일 인증을 진행할게요
+
+
+
+ {!sendCode ? (
+
+ ) : (
+
+
+
+ 수정
+
+
+ )}
+
+
+
+
+
+
+ 다음으로
+
+
+
+ {sendCode && (
+
+
+ 인증번호 다시 받기
+
+
+ )}
+
+ );
+}
diff --git a/src/components/auth/flows/signup/PasswordSetupStep.tsx b/src/components/auth/flows/signup/PasswordSetupStep.tsx
new file mode 100644
index 00000000..d7b1b294
--- /dev/null
+++ b/src/components/auth/flows/signup/PasswordSetupStep.tsx
@@ -0,0 +1,21 @@
+import PasswordForm from "@/components/auth/common/PasswordForm";
+
+interface IPasswordSetupStepProps {
+ onNext: (password: string) => void;
+}
+
+export default function PasswordSetupStep({ onNext }: IPasswordSetupStepProps) {
+ return (
+
+ 로그인에 사용할
+
+ 비밀번호를 입력해 주세요
+ >
+ }
+ buttonText="다음으로"
+ onSubmit={onNext}
+ />
+ );
+}
diff --git a/src/components/auth/flows/signup/ProfileSetupStep.tsx b/src/components/auth/flows/signup/ProfileSetupStep.tsx
new file mode 100644
index 00000000..d2a7aef5
--- /dev/null
+++ b/src/components/auth/flows/signup/ProfileSetupStep.tsx
@@ -0,0 +1,149 @@
+import { useEffect } from "react";
+import { type SubmitHandler, useForm } from "react-hook-form";
+import { useNavigate } from "react-router-dom";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { toast } from "sonner";
+import type { z } from "zod";
+
+import { stripPhoneHyphens } from "@/utils/formatPhoneNumber";
+import { signupProfileSchema } from "@/utils/validation";
+
+import { useAuth } from "@/hooks/auth/useAuth";
+
+import AuthFormShell from "@/components/auth/common/AuthFormShell";
+import CommonAuthInput from "@/components/auth/common/CommonAuthInput";
+import Button from "@/components/common/button/Button";
+
+import useAuthStore from "@/store/useAuthStore";
+import useModalStore, { MODAL_TYPES } from "@/store/useModalStore";
+
+type TSignupProfileFormValues = z.infer;
+
+interface IProfileSetupStepProps {
+ password: string;
+}
+
+export default function ProfileSetupStep({ password }: IProfileSetupStepProps) {
+ const navigate = useNavigate();
+ const { email, resetAuth } = useAuthStore();
+ const { openModal } = useModalStore();
+ const { useSignUp } = useAuth();
+
+ useEffect(() => {
+ if (!email || !password) {
+ navigate("/signup", { replace: true });
+ }
+ }, [email, password, navigate]);
+
+ const {
+ register,
+ handleSubmit,
+ setValue,
+ watch,
+ formState: { errors, isValid },
+ } = useForm({
+ mode: "onChange",
+ resolver: zodResolver(signupProfileSchema),
+ });
+
+ const onSubmit: SubmitHandler = (data) => {
+ useSignUp.mutate(
+ {
+ email,
+ password,
+ name: data.name,
+ phone_number: stripPhoneHyphens(data.phoneNum),
+ },
+ {
+ onSuccess: () => {
+ toast.success("회원가입이 완료되었습니다!", {
+ description: `${data.name}님, 환영합니다!`,
+ });
+ resetAuth();
+ navigate("/login");
+ },
+ onError: (error) => {
+ toast.error(error.message ?? "회원가입에 실패했습니다.");
+ },
+ },
+ );
+ };
+
+ return (
+
+
+ 사용자의
+ 기본 정보를 입력해 주세요
+
+
+
+
+ );
+}
diff --git a/src/components/auth/skeleton/AuthFormSkeleton.tsx b/src/components/auth/skeleton/AuthFormSkeleton.tsx
new file mode 100644
index 00000000..db668fd8
--- /dev/null
+++ b/src/components/auth/skeleton/AuthFormSkeleton.tsx
@@ -0,0 +1,26 @@
+import AuthFormShell from "@/components/auth/common/AuthFormShell";
+import { Skeleton } from "@/components/common/skeleton/Skeleton";
+
+export default function AuthFormSkeleton() {
+ return (
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/auth/skeleton/LoginPageSkeleton.tsx b/src/components/auth/skeleton/LoginPageSkeleton.tsx
new file mode 100644
index 00000000..554ec7d9
--- /dev/null
+++ b/src/components/auth/skeleton/LoginPageSkeleton.tsx
@@ -0,0 +1,52 @@
+import AuthFormShell from "@/components/auth/common/AuthFormShell";
+import {
+ Skeleton,
+ SkeletonCircle,
+} from "@/components/common/skeleton/Skeleton";
+
+export default function LoginPageSkeleton() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/auth/skeleton/SignupEmailStepSkeleton.tsx b/src/components/auth/skeleton/SignupEmailStepSkeleton.tsx
new file mode 100644
index 00000000..e3cbdc80
--- /dev/null
+++ b/src/components/auth/skeleton/SignupEmailStepSkeleton.tsx
@@ -0,0 +1,30 @@
+import AuthFormShell from "@/components/auth/common/AuthFormShell";
+import { Skeleton } from "@/components/common/skeleton/Skeleton";
+
+export default function SignupEmailStepSkeleton() {
+ return (
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/auth/skeleton/SignupPageSkeleton.tsx b/src/components/auth/skeleton/SignupPageSkeleton.tsx
new file mode 100644
index 00000000..f8319cf0
--- /dev/null
+++ b/src/components/auth/skeleton/SignupPageSkeleton.tsx
@@ -0,0 +1,19 @@
+import AuthFormShell from "@/components/auth/common/AuthFormShell";
+import { Skeleton } from "@/components/common/skeleton/Skeleton";
+
+export default function SignupPageSkeleton() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/common/PageHeader.tsx b/src/components/common/PageHeader.tsx
new file mode 100644
index 00000000..27fdb560
--- /dev/null
+++ b/src/components/common/PageHeader.tsx
@@ -0,0 +1,36 @@
+import type { ReactNode } from "react";
+import { memo } from "react";
+import { twMerge } from "tailwind-merge";
+
+interface IPageHeaderProps {
+ title: string;
+ description?: string;
+ actions?: ReactNode;
+ className?: string;
+}
+
+const PageHeader = memo(function PageHeader({
+ title,
+ description,
+ actions,
+ className,
+}: IPageHeaderProps) {
+ return (
+
+
+
{title}
+ {description && (
+
{description}
+ )}
+
+ {actions && {actions}
}
+
+ );
+});
+
+export default PageHeader;
diff --git a/src/components/common/alert/Alert.stories.tsx b/src/components/common/alert/Alert.stories.tsx
new file mode 100644
index 00000000..a62962a4
--- /dev/null
+++ b/src/components/common/alert/Alert.stories.tsx
@@ -0,0 +1,45 @@
+import type { Meta, StoryObj } from "@storybook/react";
+
+import Alert from "./Alert";
+
+const meta: Meta = {
+ title: "Common/Alert",
+ component: Alert,
+ parameters: { layout: "centered" },
+};
+
+export default meta;
+
+type TAlertStory = StoryObj;
+
+export const Info: TAlertStory = {
+ args: { variant: "info", title: "안내", children: "정보 메시지입니다." },
+};
+
+export const Success: TAlertStory = {
+ args: {
+ variant: "success",
+ title: "성공",
+ children: "저장이 완료되었습니다.",
+ },
+};
+
+export const Warning: TAlertStory = {
+ args: {
+ variant: "warning",
+ title: "주의",
+ children: "입력 값을 다시 확인해주세요.",
+ },
+};
+
+export const Danger: TAlertStory = {
+ args: {
+ variant: "danger",
+ title: "실패",
+ children: "요청 처리 중 오류가 발생했습니다.",
+ },
+};
+
+export const WithoutTitle: TAlertStory = {
+ args: { variant: "info", children: "타이틀 없이도 사용할 수 있습니다" },
+};
diff --git a/src/components/common/alert/Alert.tsx b/src/components/common/alert/Alert.tsx
new file mode 100644
index 00000000..dce12f01
--- /dev/null
+++ b/src/components/common/alert/Alert.tsx
@@ -0,0 +1,43 @@
+import type { HTMLAttributes, ReactNode } from "react";
+import { twMerge } from "tailwind-merge";
+
+export type TAlertVariant = "info" | "success" | "warning" | "danger";
+
+export interface IAlertProps extends HTMLAttributes {
+ variant?: TAlertVariant;
+ title?: string;
+ icon?: ReactNode;
+}
+
+export default function Alert({
+ variant = "info",
+ title,
+ icon,
+ className,
+ children,
+ ...rest
+}: IAlertProps) {
+ const base = "w-full rounded-component-lg px-5 py-4";
+
+ const variantClasses: Record = {
+ info: "text-brand-700",
+ success: "text-status-blue",
+ warning: "text-status-yellow",
+ danger: "text-status-red",
+ };
+
+ return (
+
+
+ {icon &&
{icon}
}
+
+ {title &&
{title}
}
+
{children}
+
+
+
+ );
+}
diff --git a/src/components/common/badge/Badge.stories.tsx b/src/components/common/badge/Badge.stories.tsx
new file mode 100644
index 00000000..7e106424
--- /dev/null
+++ b/src/components/common/badge/Badge.stories.tsx
@@ -0,0 +1,40 @@
+import type { Meta, StoryObj } from "@storybook/react";
+
+import Badge from "./Badge";
+
+const meta: Meta = {
+ title: "Common/Badge",
+ component: Badge,
+ parameters: { layout: "centered" },
+};
+
+export default meta;
+type TBadgeStory = StoryObj;
+
+export const Syncing: TBadgeStory = {
+ args: { variant: "syncing", children: "동기화중" },
+};
+
+export const Success: TBadgeStory = {
+ args: { variant: "success", children: "완료" },
+};
+
+export const Inactive: TBadgeStory = {
+ args: { variant: "inactive", children: "미동기화" },
+};
+
+export const Running: TBadgeStory = {
+ args: { variant: "running", children: "운영중" },
+};
+
+export const Stopped: TBadgeStory = {
+ args: { variant: "stopped", children: "중단" },
+};
+
+export const SizeSm: TBadgeStory = {
+ args: { size: "sm", variant: "running", children: "운영중작은" },
+};
+
+export const SizeMd: TBadgeStory = {
+ args: { size: "md", variant: "running", children: "운영중큰" },
+};
diff --git a/src/components/common/badge/Badge.tsx b/src/components/common/badge/Badge.tsx
new file mode 100644
index 00000000..b2d9f526
--- /dev/null
+++ b/src/components/common/badge/Badge.tsx
@@ -0,0 +1,56 @@
+import type { HTMLAttributes, ReactNode } from "react";
+import { twMerge } from "tailwind-merge";
+
+export type TBadgeVariant =
+ | "syncing"
+ | "success"
+ | "inactive"
+ | "running"
+ | "stopped";
+
+type TBadgeSize = "sm" | "md";
+
+interface IBadgeProps extends HTMLAttributes {
+ variant?: TBadgeVariant;
+ size?: TBadgeSize;
+ leftIcon?: ReactNode;
+}
+
+export default function Badge({
+ variant = "success",
+ size = "md",
+ leftIcon,
+ className,
+ children,
+ ...rest
+}: IBadgeProps) {
+ const sizeClasses: Record = {
+ sm: "h-7 px-3 py-1 font-caption",
+ md: "h-9 px-4 py-1 font-body2",
+ };
+
+ const variantClasses: Record = {
+ syncing:
+ "bg-status-yellow/15 text-status-yellow border border-status-yellow",
+ success: "bg-status-green/15 text-status-green border border-status-green",
+ inactive: "bg-status-red/15 text-status-red border border-status-red/40",
+ running: "bg-status-blue/15 text-status-blue border border-status-blue/40",
+ stopped: "bg-brand-300 text-text-sub border border-text-placeholder/40",
+ };
+
+ return (
+
+ {leftIcon ? {leftIcon} : null}
+ {children}
+
+ );
+}
diff --git a/src/components/common/button/Button.stories.tsx b/src/components/common/button/Button.stories.tsx
new file mode 100644
index 00000000..fedd8189
--- /dev/null
+++ b/src/components/common/button/Button.stories.tsx
@@ -0,0 +1,75 @@
+import type { Meta, StoryObj } from "@storybook/react";
+
+import Button from "./Button";
+
+const meta: Meta = {
+ title: "Common/Button",
+ component: Button,
+ args: {
+ children: "버튼",
+ size: "small",
+ variant: "primary",
+ },
+ parameters: { layout: "centered" },
+};
+
+export default meta;
+type TButtonStory = StoryObj;
+export const Primary: TButtonStory = {
+ args: { variant: "primary" },
+};
+
+export const Secondary: TButtonStory = {
+ args: { variant: "secondary" },
+};
+
+export const Outline: TButtonStory = {
+ args: { variant: "outline" },
+};
+
+export const Danger: TButtonStory = {
+ args: { variant: "danger" },
+};
+
+export const DangerSoft: TButtonStory = {
+ args: { variant: "dangerSoft" },
+};
+
+export const Gradient: TButtonStory = {
+ args: { variant: "gradient" },
+};
+
+export const Tertiary: TButtonStory = {
+ args: { variant: "tertiary" },
+};
+
+export const Disabled: TButtonStory = {
+ args: { disabled: true },
+};
+
+export const Loading: TButtonStory = {
+ args: { isLoading: true },
+};
+
+export const Sizes: TButtonStory = {
+ render: () => (
+
+
+ Small
+
+
+ Big
+
+
+ ),
+};
+
+export const FullWidth: TButtonStory = {
+ render: () => (
+
+
+ Full width
+
+
+ ),
+};
diff --git a/src/components/common/button/Button.tsx b/src/components/common/button/Button.tsx
new file mode 100644
index 00000000..5b96b782
--- /dev/null
+++ b/src/components/common/button/Button.tsx
@@ -0,0 +1,80 @@
+import type { ButtonHTMLAttributes, ReactNode } from "react";
+import { twMerge } from "tailwind-merge";
+
+interface IButtonProps extends ButtonHTMLAttributes {
+ size?: "big" | "small";
+ variant?:
+ | "primary"
+ | "secondary"
+ | "outline"
+ | "danger"
+ | "dangerSoft"
+ | "gradient"
+ | "tertiary"
+ | "custom";
+ isLoading?: boolean;
+ leftIcon?: ReactNode;
+ fullWidth?: boolean;
+}
+
+export default function Button({
+ size = "small",
+ variant = "primary",
+ isLoading = false,
+ disabled = false,
+ leftIcon,
+ fullWidth = false,
+ className,
+ children,
+ ...rest
+}: IButtonProps) {
+ const sizeClasses = {
+ big: "h-button-big px-6 rounded-component-md font-heading4 transition-colors duration-normal ease-out",
+ small:
+ "h-button-small px-4 rounded-component-sm font-body1 transition-colors duration-normal ease-out",
+ };
+
+ const variantClasses = {
+ primary:
+ "bg-chart-3 text-white hover:bg-[#0e6add] disabled:bg-bg-disabled disabled:text-text-disabled disabled:hover:bg-bg-disabled",
+ secondary:
+ "bg-gray-100 text-brand-900 hover:bg-gray-200 disabled:bg-bg-disabled disabled:text-text-disabled disabled:hover:bg-bg-disabled",
+ outline:
+ "bg-transparent border border-chart-3 text-chart-3 hover:bg-chart-3/5 disabled:border-gray-300 disabled:text-text-disabled disabled:hover:bg-transparent",
+ danger:
+ "bg-status-red text-white hover:bg-[#d91632] disabled:bg-bg-disabled disabled:text-text-disabled disabled:hover:bg-bg-disabled",
+ dangerSoft:
+ "bg-status-red/10 text-status-red border border-status-red hover:bg-status-red/20 disabled:bg-bg-disabled disabled:text-text-disabled disabled:border-gray-300 disabled:hover:bg-bg-disabled",
+ gradient:
+ "bg-linear-to-r from-logo-1 to-logo-2 text-white hover:opacity-90 shadow-brand-500/30 disabled:bg-bg-disabled disabled:text-text-disabled disabled:shadow-none disabled:hover:opacity-50",
+ tertiary:
+ "!h-7 border border-gray-200 text-text-auth-sub px-5 rounded-component-lg bg-white font-body2 hover:bg-gray-100 transition-colors duration-200 ease-in-out",
+ custom: "",
+ };
+
+ return (
+
+ {isLoading && (
+
+ )}
+ {!isLoading && leftIcon && (
+
+ {leftIcon}
+
+ )}
+ {children}
+
+ );
+}
diff --git a/src/components/common/card/Card.stories.tsx b/src/components/common/card/Card.stories.tsx
new file mode 100644
index 00000000..1ebdec85
--- /dev/null
+++ b/src/components/common/card/Card.stories.tsx
@@ -0,0 +1,62 @@
+import type { Meta, StoryObj } from "@storybook/react";
+
+import Card from "./Card";
+import Button from "../button/Button";
+
+const meta: Meta = {
+ title: "Common/Card",
+ component: Card,
+ args: {
+ title: "카드 제목",
+ className: "w-80",
+ },
+ parameters: { layout: "centered" },
+};
+
+export default meta;
+type TCardStory = StoryObj;
+
+export const Default: TCardStory = {
+ args: {
+ title: undefined,
+ children: (
+ 카드 내용이 들어갑니다.
+ ),
+ },
+};
+
+export const WithTitle: TCardStory = {
+ args: {
+ children: (
+ 카드 내용이 들어갑니다.
+ ),
+ },
+};
+
+export const WithDescription: TCardStory = {
+ args: {
+ description: "제목에 대한 설명이 들어갑니다.",
+ children: (
+ 카드 내용이 들어갑니다.
+ ),
+ },
+};
+
+export const WithRightElement: TCardStory = {
+ args: {
+ RightElement: 플랫폼 대시보드 보기 ,
+ children: (
+ 카드 내용이 들어갑니다.
+ ),
+ },
+};
+
+export const WithDescriptionAndRightElement: TCardStory = {
+ args: {
+ description: "데이터 기준 | 2026.01.06 09:13",
+ RightElement: 보기 ,
+ children: (
+ 카드 내용이 들어갑니다.
+ ),
+ },
+};
diff --git a/src/components/common/card/Card.tsx b/src/components/common/card/Card.tsx
new file mode 100644
index 00000000..5e915123
--- /dev/null
+++ b/src/components/common/card/Card.tsx
@@ -0,0 +1,49 @@
+import type { HTMLAttributes, ReactNode } from "react";
+import { memo } from "react";
+import { twMerge } from "tailwind-merge";
+
+export interface ICardProps extends HTMLAttributes {
+ title?: string;
+ description?: ReactNode;
+ RightElement?: ReactNode;
+}
+
+const Card = memo(function Card({
+ title,
+ description,
+ RightElement,
+ children,
+ className,
+ ...rest
+}: ICardProps) {
+ const hasHeader = title || description || RightElement;
+
+ return (
+
+ {hasHeader && (
+
+
+ {title && (
+
+ {title}
+
+ )}
+ {description && (
+
{description}
+ )}
+
+ {RightElement}
+
+ )}
+ {children}
+
+ );
+});
+
+export default Card;
diff --git a/src/components/common/card/InfoCard.stories.tsx b/src/components/common/card/InfoCard.stories.tsx
new file mode 100644
index 00000000..ace57fe4
--- /dev/null
+++ b/src/components/common/card/InfoCard.stories.tsx
@@ -0,0 +1,34 @@
+import type { Meta, StoryObj } from "@storybook/react";
+
+import InfoCard from "./InfoCard";
+
+const meta: Meta = {
+ title: "Common/InfoCard",
+ component: InfoCard,
+ argTypes: {
+ title: {
+ control: "text",
+ description: "카드 상단 제목",
+ },
+ children: {
+ control: false,
+ description: "카드 내부 콘텐츠 영역",
+ },
+ className: {
+ control: "text",
+ description: "추가적인 스타일 확장을 위한 클래스명",
+ },
+ },
+};
+
+export default meta;
+type TStory = StoryObj;
+
+export const Default: TStory = {
+ args: {
+ title: "제목",
+ children: (
+ 내용
+ ),
+ },
+};
diff --git a/src/components/common/card/InfoCard.tsx b/src/components/common/card/InfoCard.tsx
new file mode 100644
index 00000000..242a186a
--- /dev/null
+++ b/src/components/common/card/InfoCard.tsx
@@ -0,0 +1,29 @@
+import type { ReactNode } from "react";
+import { twMerge } from "tailwind-merge";
+
+interface IInfoCardProps {
+ title: string;
+ children: ReactNode;
+ className?: string;
+}
+
+export default function InfoCard({
+ title,
+ children,
+ className,
+}: IInfoCardProps) {
+ return (
+
+
{title}
+
+ {children}
+
+
+ );
+}
diff --git a/src/components/common/card/StatCard.stories.tsx b/src/components/common/card/StatCard.stories.tsx
new file mode 100644
index 00000000..451a87ee
--- /dev/null
+++ b/src/components/common/card/StatCard.stories.tsx
@@ -0,0 +1,67 @@
+import { Fragment } from "react";
+import type { Meta, StoryObj } from "@storybook/react";
+
+import StatCard from "./StatCard";
+
+const meta: Meta = {
+ title: "Common/StatCard",
+ component: StatCard,
+ args: {
+ title: "클릭수(CTR)",
+ value: "1,280",
+ },
+ parameters: { layout: "centered" },
+};
+
+export default meta;
+type TStatCardStory = StoryObj;
+
+export const Default: TStatCardStory = {};
+
+export const WithTrendUp: TStatCardStory = {
+ args: {
+ trend: { direction: "up", value: "13.77%" },
+ },
+};
+
+export const WithTrendDown: TStatCardStory = {
+ args: {
+ title: "노출수",
+ value: "3,175,630",
+ trend: { direction: "down", value: "13.77%" },
+ },
+};
+
+export const KpiGroup: TStatCardStory = {
+ render: () => (
+
+ {[
+ {
+ title: "클릭수(CTR)",
+ value: "1,280",
+ trend: { direction: "up" as const, value: "13.77%" },
+ },
+ {
+ title: "노출수",
+ value: "3,175,630",
+ trend: { direction: "down" as const, value: "13.77%" },
+ },
+ {
+ title: "전환율(CVR)",
+ value: "27.09%",
+ trend: { direction: "up" as const, value: "13.77%" },
+ },
+ {
+ title: "광고비 대비 매출",
+ value: "37.58%",
+ trend: { direction: "down" as const, value: "13.77%" },
+ },
+ ].map((kpi, index) => (
+
+ {index > 0 &&
}
+
+
+ ))}
+
+ ),
+};
diff --git a/src/components/common/card/StatCard.tsx b/src/components/common/card/StatCard.tsx
new file mode 100644
index 00000000..bee8838e
--- /dev/null
+++ b/src/components/common/card/StatCard.tsx
@@ -0,0 +1,70 @@
+import type { HTMLAttributes } from "react";
+import { memo } from "react";
+import { twMerge } from "tailwind-merge";
+
+import TrendDownIcon from "@/assets/icon/chevron/trend-down.svg?react";
+import TrendUpIcon from "@/assets/icon/chevron/trend-up.svg?react";
+
+export interface ITrend {
+ direction: "up" | "down";
+ value: string;
+}
+
+export interface IStatCardProps extends HTMLAttributes {
+ title: string;
+ value: string | number;
+ trend?: ITrend;
+}
+
+const trendClasses: Record = {
+ up: "bg-status-red/[0.08] text-status-red font-bold",
+ down: "bg-status-blue/[0.08] text-status-blue font-bold",
+};
+
+export const TrendBadge = memo(function TrendBadge({
+ direction,
+ value,
+}: ITrend) {
+ return (
+
+ {direction === "up" ? (
+
+ ) : (
+
+ )}
+ {value}
+
+ );
+});
+
+const StatCard = memo(function StatCard({
+ title,
+ value,
+ trend,
+ className,
+ ...rest
+}: IStatCardProps) {
+ return (
+
+
{title}
+
+ {value}
+
+ {trend &&
}
+
+ );
+});
+
+export default StatCard;
diff --git a/src/components/common/chart/ChartLegend.tsx b/src/components/common/chart/ChartLegend.tsx
new file mode 100644
index 00000000..53fe2158
--- /dev/null
+++ b/src/components/common/chart/ChartLegend.tsx
@@ -0,0 +1,36 @@
+import { memo } from "react";
+import { twMerge } from "tailwind-merge";
+
+export interface IChartLegendItem {
+ label: string;
+ colorClass?: string;
+ color?: string;
+}
+
+export interface IChartLegendProps {
+ items: IChartLegendItem[];
+ className?: string;
+}
+
+const ChartLegend = memo(function ChartLegend({
+ items,
+ className,
+}: IChartLegendProps) {
+ return (
+
+ {items.map((item) => (
+
+ ))}
+
+ );
+});
+
+export default ChartLegend;
diff --git a/src/components/common/controlbox/ControlBox.stories.tsx b/src/components/common/controlbox/ControlBox.stories.tsx
new file mode 100644
index 00000000..0275d23f
--- /dev/null
+++ b/src/components/common/controlbox/ControlBox.stories.tsx
@@ -0,0 +1,22 @@
+import type { Meta, StoryObj } from "@storybook/react";
+
+import ControlBox from "./ControlBox";
+
+const meta: Meta = {
+ title: "Common/ControlBox",
+ component: ControlBox,
+ parameters: { layout: "padded" },
+};
+
+export default meta;
+type TControlBoxStory = StoryObj;
+
+export const Default: TControlBoxStory = {
+ args: {
+ title: "제목",
+ description: "설명",
+ buttonText: "버튼",
+ onButtonClick: () => console.log("click"),
+ className: "w-full",
+ },
+};
diff --git a/src/components/common/controlbox/ControlBox.tsx b/src/components/common/controlbox/ControlBox.tsx
new file mode 100644
index 00000000..33a40651
--- /dev/null
+++ b/src/components/common/controlbox/ControlBox.tsx
@@ -0,0 +1,90 @@
+import type { HTMLAttributes, ReactNode } from "react";
+import type React from "react";
+import { twMerge } from "tailwind-merge";
+
+import Button from "../button/Button";
+
+interface IControlBoxProps extends HTMLAttributes {
+ title: string;
+ description: string;
+ buttonText: string;
+ onButtonClick: () => void;
+ containerClassName?: string;
+ titleClassName?: string;
+ descriptionClassName?: string;
+ buttonVariant?: React.ComponentProps["variant"];
+ buttonSize?: React.ComponentProps["size"];
+ buttonClassName?: string;
+ buttonDisabled?: boolean;
+ buttonSlot?: ReactNode;
+ leadingSlot?: ReactNode;
+ contentClassName?: string;
+}
+
+export default function ControlBox({
+ title,
+ description,
+ buttonText,
+ onButtonClick,
+ className,
+ containerClassName,
+ titleClassName,
+ descriptionClassName,
+ buttonVariant = "primary",
+ buttonSize = "small",
+ buttonClassName,
+ buttonDisabled,
+ buttonSlot,
+ leadingSlot,
+ contentClassName,
+ ...rest
+}: IControlBoxProps) {
+ return (
+
+
+ {leadingSlot ?
{leadingSlot}
: null}
+
+
+ {title}
+
+
+ {description}
+
+
+
+
+ {buttonSlot ?? (
+
+ {buttonText}
+
+ )}
+
+ );
+}
diff --git a/src/components/common/drawer/Drawer.tsx b/src/components/common/drawer/Drawer.tsx
new file mode 100644
index 00000000..c90c68a7
--- /dev/null
+++ b/src/components/common/drawer/Drawer.tsx
@@ -0,0 +1,203 @@
+import type { ReactNode, TouchEvent } from "react";
+import { useEffect, useRef, useState } from "react";
+import { createPortal } from "react-dom";
+import { twMerge } from "tailwind-merge";
+
+import { DropdownMenu } from "@/components/common/dropdownmenu/DropdownMenu";
+
+import CloseIcon from "@/assets/icon/common/close.svg?react";
+import MoreIcon from "@/assets/icon/common/more.svg?react";
+
+export interface IDrawerProps {
+ isOpen: boolean;
+ onClose: () => void;
+ title?: ReactNode;
+ children: ReactNode;
+ className?: string;
+ hideHeader?: boolean;
+ dropdownItems?: { label: string; icon?: ReactNode; onClick: () => void }[];
+ disableScroll?: boolean;
+}
+
+const TABLET_MQ = "(max-width: 1024px)";
+const SWIPE_CLOSE_THRESHOLD = 80;
+
+export default function Drawer({
+ isOpen,
+ onClose,
+ title,
+ children,
+ className,
+ hideHeader = false,
+ dropdownItems,
+ disableScroll = false,
+}: IDrawerProps) {
+ const [isMounted, setIsMounted] = useState(false);
+ const panelRef = useRef(null);
+ const touchStartY = useRef(0);
+ const isDragging = useRef(false);
+
+ useEffect(() => {
+ setIsMounted(true);
+ }, []);
+
+ useEffect(() => {
+ if (isOpen) {
+ document.body.style.overflow = "hidden";
+ } else {
+ document.body.style.overflow = "";
+ }
+ return () => {
+ document.body.style.overflow = "";
+ };
+ }, [isOpen]);
+
+ useEffect(() => {
+ const panel = panelRef.current;
+ if (!panel) return;
+ panel.style.transform = "";
+ panel.style.transition = "";
+ }, [isOpen]);
+
+ const handleTouchStart = (e: TouchEvent) => {
+ if (!window.matchMedia(TABLET_MQ).matches) return;
+ touchStartY.current = e.touches[0].clientY;
+ isDragging.current = true;
+ if (panelRef.current) {
+ panelRef.current.style.transition = "none";
+ }
+ };
+
+ const handleTouchMove = (e: TouchEvent) => {
+ if (!isDragging.current || !panelRef.current) return;
+ const delta = e.touches[0].clientY - touchStartY.current;
+ if (delta < 0) return;
+ panelRef.current.style.transform = `translateY(${delta}px)`;
+ };
+
+ const handleTouchEnd = (e: TouchEvent) => {
+ if (!isDragging.current || !panelRef.current) return;
+ isDragging.current = false;
+ const delta = e.changedTouches[0].clientY - touchStartY.current;
+ panelRef.current.style.transition = "";
+
+ if (delta > SWIPE_CLOSE_THRESHOLD) {
+ panelRef.current.style.transform = "";
+ onClose();
+ } else {
+ panelRef.current.style.transform = "";
+ }
+ };
+
+ if (!isMounted) return null;
+
+ return createPortal(
+
+
+
+ {/* 태블릿 드래그 핸들 */}
+
+ {!hideHeader && (
+
+ {title ? (
+ <>
+ {typeof title === "string" ? (
+
+ {title}
+
+ ) : (
+ title
+ )}
+
+ {dropdownItems && dropdownItems.length > 0 && (
+ }
+ aria-label="더보기"
+ className="h-10 w-10 cursor-pointer rounded-component-sm hover:bg-gray-100 transition-colors flex items-center justify-center"
+ items={dropdownItems}
+ />
+ )}
+
+
+
+
+ >
+ ) : (
+ <>
+
+
+
+ {dropdownItems && (
+
+ }
+ aria-label="더보기"
+ className="h-10 w-10 cursor-pointer rounded-component-sm hover:bg-gray-100 transition-colors flex items-center justify-center"
+ items={dropdownItems}
+ />
+
+ )}
+ >
+ )}
+
+ )}
+
+ {children}
+
+
+
,
+ document.body,
+ );
+}
diff --git a/src/components/common/dropdownmenu/DropdownMenu.stories.tsx b/src/components/common/dropdownmenu/DropdownMenu.stories.tsx
new file mode 100644
index 00000000..96757e5c
--- /dev/null
+++ b/src/components/common/dropdownmenu/DropdownMenu.stories.tsx
@@ -0,0 +1,25 @@
+import type { Meta, StoryObj } from "@storybook/react";
+import { fn } from "@storybook/test";
+
+import { DropdownMenu } from "./DropdownMenu";
+
+const meta: Meta = {
+ title: "Common/DropdownMenu",
+ component: DropdownMenu,
+ parameters: { layout: "centered" },
+};
+
+export default meta;
+type TDropdownMenuStory = StoryObj;
+
+export const Default: TDropdownMenuStory = {
+ render: () => (
+ ...}
+ items={[
+ { label: "선택된 부분", active: true, onClick: fn() },
+ { label: "선택 안 된 부분", onClick: fn() },
+ ]}
+ />
+ ),
+};
diff --git a/src/components/common/dropdownmenu/DropdownMenu.tsx b/src/components/common/dropdownmenu/DropdownMenu.tsx
new file mode 100644
index 00000000..25696afd
--- /dev/null
+++ b/src/components/common/dropdownmenu/DropdownMenu.tsx
@@ -0,0 +1,115 @@
+import React, { useEffect, useId, useRef, useState } from "react";
+import { twMerge } from "tailwind-merge";
+
+export type TMenuItem = {
+ label: string;
+ icon?: React.ReactNode;
+ onClick: () => void;
+ active?: boolean;
+};
+
+export function DropdownMenu({
+ trigger,
+ items,
+ className,
+ menuClassName,
+ "aria-label": ariaLabel,
+}: {
+ trigger: React.ReactNode | ((open: boolean) => React.ReactNode);
+ items: TMenuItem[];
+ className?: string;
+ menuClassName?: string;
+ "aria-label"?: string;
+}) {
+ const [open, setOpen] = useState(false);
+ const ref = useRef(null);
+ const menuId = useId();
+
+ useEffect(() => {
+ const onDocClick = (e: MouseEvent) => {
+ if (!ref.current) return;
+ if (!ref.current.contains(e.target as Node)) setOpen(false);
+ };
+ document.addEventListener("mousedown", onDocClick);
+ return () => {
+ document.removeEventListener("mousedown", onDocClick);
+ };
+ }, []);
+
+ return (
+
+
setOpen((v) => !v)}
+ onKeyDown={(e) => {
+ if (e.key === "Enter" || e.key === " ") {
+ e.preventDefault();
+ setOpen((v) => !v);
+ }
+ }}
+ className={twMerge(className)}
+ >
+ {typeof trigger === "function" ? trigger(open) : trigger}
+
+ {open && (
+
+ )}
+
+ );
+}
diff --git a/src/components/common/input/Input.stories.tsx b/src/components/common/input/Input.stories.tsx
new file mode 100644
index 00000000..adee96a5
--- /dev/null
+++ b/src/components/common/input/Input.stories.tsx
@@ -0,0 +1,58 @@
+import type { Meta, StoryObj } from "@storybook/react";
+
+import Input from "./Input";
+
+const meta: Meta = {
+ title: "Common/Input",
+ component: Input,
+ args: {
+ label: "제목",
+ placeholder: "placeholder",
+ },
+ parameters: { layout: "centered" },
+};
+
+export default meta;
+
+type TInputStory = StoryObj;
+
+export const Default: TInputStory = {};
+
+export const HelperText: TInputStory = {
+ args: { helperText: "도움말 텍스트" },
+};
+
+export const ErrorState: TInputStory = {
+ args: {
+ error: true,
+ helperText: "에러 메시지",
+ },
+};
+
+export const Success: TInputStory = {
+ args: {
+ success: true,
+ helperText: "성공 메시지",
+ readOnly: true,
+ },
+};
+
+export const Disabled: TInputStory = {
+ args: {
+ disabled: true,
+ value: "비활성",
+ },
+};
+
+export const RightElement: TInputStory = {
+ args: {
+ rightElement: (
+
+ 지우기
+
+ ),
+ },
+};
diff --git a/src/components/common/input/Input.tsx b/src/components/common/input/Input.tsx
new file mode 100644
index 00000000..4d7f8bb5
--- /dev/null
+++ b/src/components/common/input/Input.tsx
@@ -0,0 +1,105 @@
+import {
+ forwardRef,
+ type InputHTMLAttributes,
+ type ReactNode,
+ useId,
+} from "react";
+import { twMerge } from "tailwind-merge";
+
+export interface IInputProps extends InputHTMLAttributes {
+ label?: string;
+ helperText?: string;
+ error?: boolean;
+ success?: boolean;
+ rightElement?: ReactNode;
+ wrapperClassName?: string;
+ containerClassName?: string;
+ inputClassName?: string;
+}
+
+const Input = forwardRef(
+ (
+ {
+ label,
+ helperText,
+ error,
+ success,
+ rightElement,
+ wrapperClassName,
+ containerClassName,
+ inputClassName,
+ id,
+ disabled,
+ ...props
+ },
+ ref,
+ ) => {
+ const generatedId = useId();
+ const inputId = id || generatedId;
+ const helperTextId = helperText ? `${inputId}-helper-text` : undefined;
+
+ return (
+
+ {label && (
+
+ {label}
+
+ )}
+
+
+ {rightElement && (
+
+ {rightElement}
+
+ )}
+
+ {helperText && (
+
+ {helperText}
+
+ )}
+
+ );
+ },
+);
+
+Input.displayName = "Input";
+
+export default Input;
diff --git a/src/components/common/modal/Modal.stories.tsx b/src/components/common/modal/Modal.stories.tsx
new file mode 100644
index 00000000..914a635d
--- /dev/null
+++ b/src/components/common/modal/Modal.stories.tsx
@@ -0,0 +1,79 @@
+import { useEffect, useState } from "react";
+import type { Meta, StoryObj } from "@storybook/react";
+
+import Modal from "./Modal";
+
+const meta: Meta = {
+ title: "Common/Modal",
+ component: Modal,
+ parameters: { layout: "centered" },
+};
+
+export default meta;
+type TModalStory = StoryObj;
+
+function EnsureModalRoot() {
+ useEffect(() => {
+ let el = document.getElementById("modal-root");
+ let created = false;
+ if (!el) {
+ created = true;
+ el = document.createElement("div");
+ el.id = "modal-root";
+ document.body.appendChild(el);
+ }
+ return () => {
+ if (created) el?.remove();
+ };
+ }, []);
+ return null;
+}
+
+export const Default: TModalStory = {
+ render: () => {
+ const [open, setOpen] = useState(false);
+
+ return (
+ <>
+
+ setOpen(true)}
+ className="h-button-small px-4 rounding-15 bg-status-blue text-white font-body2 hover:bg-status-blue/80 transition"
+ aria-label="모달 열기 버튼"
+ >
+ 모달 열기
+
+ setOpen(false)}
+ title="Modal Title"
+ size="md"
+ padding="md"
+ >
+
+
모달 내용부분
+
+ setOpen(false)}
+ className="h-button-small px-4 rounding-15 bg-brand-300 font-body2 hover:bg-text-main/15 transition-fast"
+ aria-label="모달 닫기 버튼"
+ >
+ 닫기
+
+ alert("확인")}
+ className="h-button-small px-4 rounding-15 bg-status-blue text-white font-body2 hover:bg-status-blue/80 transition-fast"
+ aria-label="모달 확인"
+ >
+ 확인
+
+
+
+
+ >
+ );
+ },
+};
diff --git a/src/components/common/modal/Modal.tsx b/src/components/common/modal/Modal.tsx
new file mode 100644
index 00000000..6740e390
--- /dev/null
+++ b/src/components/common/modal/Modal.tsx
@@ -0,0 +1,172 @@
+import React, {
+ type ReactNode,
+ useCallback,
+ useEffect,
+ useId,
+ useRef,
+ useState,
+} from "react";
+import { createPortal } from "react-dom";
+import { RemoveScroll } from "react-remove-scroll";
+import { twMerge } from "tailwind-merge";
+
+import CloseIcon from "@/assets/icon/common/close.svg?react";
+
+export interface IModalProps {
+ isOpen: boolean;
+ onClose: () => void;
+ children: ReactNode;
+ padding?: "none" | "sm" | "md" | "lg";
+ size?: "sm" | "md" | "lg" | "xl";
+ className?: string;
+ hideCloseButton?: boolean;
+ disableOverlayClick?: boolean;
+ title?: string;
+}
+
+const CLOSE_DURATION = 150; // --duration-fast 와 동일
+
+function Modal({
+ isOpen,
+ onClose,
+ children,
+ padding = "md",
+ size = "md",
+ className,
+ hideCloseButton = false,
+ disableOverlayClick = false,
+ title,
+}: IModalProps) {
+ const modalRef = useRef(null);
+ const previousActiveElement = useRef(null);
+ const titleId = useId();
+ const [shouldRender, setShouldRender] = useState(isOpen);
+ const [isClosing, setIsClosing] = useState(false);
+ const isVisible = isOpen || isClosing; // 모달이 열려있거나 닫히는 중일 때
+
+ // 진입/퇴장 렌더링 제어
+ useEffect(() => {
+ if (isOpen) {
+ setShouldRender(true);
+ setIsClosing(false);
+ } else {
+ setIsClosing(true);
+ const timer = setTimeout(() => {
+ setShouldRender(false);
+ setIsClosing(false);
+ }, CLOSE_DURATION);
+ return () => clearTimeout(timer);
+ }
+ }, [isOpen]);
+
+ // 포커스 관리: 모달 열릴 때 포커스 이동, 닫힘 애니메이션 종료 후 원래 위치로 복귀
+ useEffect(() => {
+ if (isVisible) {
+ previousActiveElement.current = document.activeElement as HTMLElement;
+
+ setTimeout(() => {
+ modalRef.current?.focus();
+ }, 0);
+ } else {
+ if (previousActiveElement.current) {
+ previousActiveElement.current.focus();
+ }
+ }
+ }, [isVisible]);
+
+ // ESC 키로 모달 닫기
+ useEffect(() => {
+ const handleEscape = (e: KeyboardEvent) => {
+ if (e.key === "Escape" && isOpen) {
+ onClose();
+ }
+ };
+
+ document.addEventListener("keydown", handleEscape);
+ return () => document.removeEventListener("keydown", handleEscape);
+ }, [isOpen, onClose]);
+
+ // 오버레이 클릭으로 닫기
+ const handleOverlayClick = useCallback(
+ (e: React.MouseEvent) => {
+ if (disableOverlayClick) return;
+ if (e.target === e.currentTarget) {
+ onClose();
+ }
+ },
+ [disableOverlayClick, onClose],
+ );
+
+ const handleContentClick = useCallback(
+ (e: React.MouseEvent) => {
+ e.stopPropagation();
+ },
+ [],
+ );
+
+ if (!shouldRender) return null;
+
+ const sizeClasses = {
+ sm: "max-w-modal-sm",
+ md: "max-w-modal-md",
+ lg: "max-w-modal-lg",
+ xl: "max-w-modal-xl",
+ };
+
+ const paddingClasses = {
+ none: "p-modal-none",
+ sm: "p-modal-sm",
+ md: "p-modal-md",
+ lg: "p-modal-lg",
+ };
+
+ const modalRoot = document.getElementById("modal-root");
+ if (!modalRoot) {
+ console.warn("모달 루트 요소를 찾을 수 없습니다");
+ return null;
+ }
+
+ return createPortal(
+ // isVisible 기준으로 잠금: 닫힘 애니메이션 중에 배경 스크롤 막음
+
+
+
+ {title && (
+
+ {title}
+
+ )}
+ {!hideCloseButton && (
+
+
+
+ )}
+ {children}
+
+
+ ,
+ modalRoot,
+ );
+}
+
+export default Modal;
diff --git a/src/components/common/modal/ModalContent.tsx b/src/components/common/modal/ModalContent.tsx
new file mode 100644
index 00000000..92e12937
--- /dev/null
+++ b/src/components/common/modal/ModalContent.tsx
@@ -0,0 +1,50 @@
+import type { ReactNode } from "react";
+
+import Button from "@/components/common/button/Button";
+
+interface IModalContentProps {
+ icon?: ReactNode;
+ title: string;
+ description: string | ReactNode;
+ buttonText: string;
+ onConfirm: () => void;
+ isLoading?: boolean;
+ variant?: "danger" | "primary";
+}
+
+export default function ModalContent({
+ icon,
+ title,
+ description,
+ buttonText,
+ onConfirm,
+ isLoading,
+ variant = "danger",
+}: IModalContentProps) {
+ return (
+
+
+ {icon &&
{icon}
}
+
+ {title}
+
+
+
+ {description}
+
+
+
+
+ {isLoading ? "처리 중.." : buttonText}
+
+
+
+ );
+}
diff --git a/src/components/common/progressbar/ProgressBar.stories.tsx b/src/components/common/progressbar/ProgressBar.stories.tsx
new file mode 100644
index 00000000..f4b34381
--- /dev/null
+++ b/src/components/common/progressbar/ProgressBar.stories.tsx
@@ -0,0 +1,19 @@
+import type { Meta, StoryObj } from "@storybook/react";
+
+import ProgressBar from "./ProgressBar";
+
+const meta: Meta = {
+ title: "Common/ProgressBar",
+ component: ProgressBar,
+ parameters: { layout: "padded" },
+};
+
+export default meta;
+type TProgressBarStory = StoryObj;
+
+export const Default: TProgressBarStory = {
+ args: {
+ value: 70,
+ className: "w-[300px]",
+ },
+};
diff --git a/src/components/common/progressbar/ProgressBar.tsx b/src/components/common/progressbar/ProgressBar.tsx
new file mode 100644
index 00000000..3f325fdd
--- /dev/null
+++ b/src/components/common/progressbar/ProgressBar.tsx
@@ -0,0 +1,34 @@
+import type { HTMLAttributes } from "react";
+import { twMerge } from "tailwind-merge";
+
+interface IProgressBarProps extends HTMLAttributes {
+ value: number;
+}
+
+export default function ProgressBar({
+ value,
+ className,
+ ...rest
+}: IProgressBarProps) {
+ const progress = Math.min(Math.max(value, 0), 100);
+
+ return (
+
+ {/* 바 전체 */}
+
+ {/* 퍼센트 텍스트 */}
+
+ {progress}%
+
+
+ );
+}
diff --git a/src/components/common/select/DropdownSelect.tsx b/src/components/common/select/DropdownSelect.tsx
new file mode 100644
index 00000000..634ca8ad
--- /dev/null
+++ b/src/components/common/select/DropdownSelect.tsx
@@ -0,0 +1,104 @@
+import React, { useEffect, useRef, useState } from "react";
+import { twMerge } from "tailwind-merge";
+
+import ChevronDownIcon from "@/assets/icon/chevron/chevron-up.svg?react";
+
+type TDropdownSelectProps = {
+ options: T[];
+ selectedOption: T | null;
+ onSelect: (option: T) => void;
+ placeholder?: string;
+ getOptionKey: (option: T) => string | number;
+ getOptionLabel: (option: T) => string;
+ renderOption?: (option: T) => React.ReactNode;
+ className?: string;
+};
+
+export default function DropdownSelect({
+ options,
+ selectedOption,
+ onSelect,
+ placeholder = "선택..",
+ getOptionKey,
+ getOptionLabel,
+ renderOption,
+ className,
+}: TDropdownSelectProps) {
+ const [isOpen, setIsOpen] = useState(false);
+ const containerRef = useRef(null);
+
+ useEffect(() => {
+ const handleClickOutside = (event: MouseEvent) => {
+ if (
+ containerRef.current &&
+ !containerRef.current.contains(event.target as Node)
+ ) {
+ setIsOpen(false);
+ }
+ };
+ document.addEventListener("mousedown", handleClickOutside);
+ return () => document.removeEventListener("mousedown", handleClickOutside);
+ }, []);
+
+ const handleSelect = (option: T) => {
+ onSelect(option);
+ setIsOpen(false);
+ };
+
+ return (
+
+
setIsOpen(!isOpen)}
+ className={twMerge(
+ "flex items-center justify-between w-full h-14 px-5 bg-white border border-bg-disabled rounded-component-md text-body1 transition-all outline-none",
+ isOpen
+ ? "border-status-blue ring-1 ring-status-blue"
+ : "hover:border-text-disabled focus:border-status-blue focus:ring-1 focus:ring-status-blue",
+ !selectedOption && "text-text-placeholder",
+ )}
+ >
+
+ {selectedOption ? getOptionLabel(selectedOption) : placeholder}
+
+
+
+
+ {isOpen && (
+
+
+ {options.map((option) => {
+ const key = getOptionKey(option);
+ const isSelected =
+ selectedOption && getOptionKey(selectedOption) === key;
+
+ return (
+
+ handleSelect(option)}
+ className={twMerge(
+ "w-full px-5 py-3 text-left text-body1 transition-colors hover:bg-text-placeholder/20",
+ isSelected
+ ? "text-status-blue font-bold bg-status-blue/5"
+ : "text-text-main",
+ )}
+ >
+ {renderOption
+ ? renderOption(option)
+ : getOptionLabel(option)}
+
+
+ );
+ })}
+
+
+ )}
+
+ );
+}
diff --git a/src/components/common/select/SearchSelect.tsx b/src/components/common/select/SearchSelect.tsx
new file mode 100644
index 00000000..1a661572
--- /dev/null
+++ b/src/components/common/select/SearchSelect.tsx
@@ -0,0 +1,159 @@
+import React, { useEffect, useId, useMemo, useRef, useState } from "react";
+
+import Input from "../input/Input";
+
+import SearchIcon from "@/assets/icon/common/search.svg?react";
+
+type TSearchSelectProps = {
+ options: T[];
+ selectedOption: T | null;
+ onSelect: (option: T) => void;
+ isOpen: boolean;
+ onOpenChange: (open: boolean) => void;
+ placeholder?: string;
+ getOptionKey: (option: T) => string | number;
+ getOptionLabel: (option: T) => string;
+ getSearchText: (option: T) => string;
+ renderOption: (option: T) => React.ReactNode;
+ emptyMessage?: string;
+ className?: string;
+};
+
+export default function SearchSelect({
+ options,
+ selectedOption,
+ onSelect,
+ isOpen,
+ onOpenChange,
+ placeholder = "검색하세요",
+ getOptionKey,
+ getOptionLabel,
+ getSearchText,
+ renderOption,
+ emptyMessage = "검색 결과가 없습니다.",
+ className = "",
+}: TSearchSelectProps) {
+ const containerRef = useRef(null);
+ const inputId = useId();
+ const listboxId = useId();
+
+ const getOptionLabelRef = useRef(getOptionLabel);
+
+ const [keyword, setKeyword] = useState(
+ selectedOption ? getOptionLabel(selectedOption) : "",
+ );
+
+ useEffect(() => {
+ getOptionLabelRef.current = getOptionLabel;
+ }, [getOptionLabel]);
+
+ useEffect(() => {
+ setKeyword(selectedOption ? getOptionLabelRef.current(selectedOption) : "");
+ }, [selectedOption]);
+
+ useEffect(() => {
+ const handleOutsideClick = (e: MouseEvent) => {
+ if (!containerRef.current?.contains(e.target as Node)) {
+ onOpenChange(false);
+ }
+ };
+
+ document.addEventListener("mousedown", handleOutsideClick);
+
+ return () => {
+ document.removeEventListener("mousedown", handleOutsideClick);
+ };
+ }, [onOpenChange]);
+
+ const filteredOptions = useMemo(() => {
+ const trimmedKeyword = keyword.trim().toLowerCase();
+
+ if (!trimmedKeyword) {
+ return options;
+ }
+
+ return options.filter((option) =>
+ getSearchText(option).toLowerCase().includes(trimmedKeyword),
+ );
+ }, [getSearchText, keyword, options]);
+
+ const handleFocus = () => {
+ onOpenChange(true);
+ };
+
+ const handleChangeKeyword = (value: string) => {
+ setKeyword(value);
+ onOpenChange(true);
+ };
+
+ const handleSelect = (option: T) => {
+ onSelect(option);
+ setKeyword(getOptionLabelRef.current(option));
+ onOpenChange(false);
+ };
+
+ return (
+
+
+ handleChangeKeyword(e.target.value)}
+ placeholder={placeholder}
+ aria-label={placeholder}
+ role="combobox"
+ aria-expanded={isOpen}
+ aria-controls={listboxId}
+ aria-haspopup="listbox"
+ aria-autocomplete="list"
+ className="h-13 w-full rounded-component-md border border-status-blue px-4 pl-5 font-body1 outline-none transition-colors placeholder:text-text-placeholder focus:border-status-blue"
+ />
+
+
+
+ {isOpen && (
+
+ {filteredOptions.length > 0 ? (
+
+ {filteredOptions.map((option) => {
+ const optionKey = getOptionKey(option);
+ const isSelected =
+ selectedOption !== null &&
+ getOptionKey(selectedOption) === optionKey;
+
+ return (
+
+ handleSelect(option)}
+ className="w-full py-2 text-left hover:bg-gray-50"
+ >
+ {renderOption(option)}
+
+
+ );
+ })}
+
+ ) : (
+
+ {emptyMessage}
+
+ )}
+
+ )}
+
+ );
+}
diff --git a/src/components/common/skeleton/Skeleton.tsx b/src/components/common/skeleton/Skeleton.tsx
new file mode 100644
index 00000000..ccfe67c7
--- /dev/null
+++ b/src/components/common/skeleton/Skeleton.tsx
@@ -0,0 +1,24 @@
+import type { HTMLAttributes } from "react";
+import { twMerge } from "tailwind-merge";
+
+interface ISkeletonProps extends HTMLAttributes {
+ className?: string;
+}
+
+export function Skeleton({ className, ...props }: ISkeletonProps) {
+ return (
+
+ );
+}
+
+export function SkeletonCircle({ className, ...props }: ISkeletonProps) {
+ return (
+
+ );
+}
diff --git a/src/components/common/textarea/TextareaField.tsx b/src/components/common/textarea/TextareaField.tsx
new file mode 100644
index 00000000..a5897f55
--- /dev/null
+++ b/src/components/common/textarea/TextareaField.tsx
@@ -0,0 +1,63 @@
+import type React from "react";
+import { useLayoutEffect, useRef } from "react";
+import { twMerge } from "tailwind-merge";
+
+type TProps = {
+ id: string;
+ label: string;
+ value: string;
+ placeholder?: string;
+ onChange: (e: React.ChangeEvent) => void;
+ className?: string;
+ minRows?: number;
+ disabled?: boolean;
+};
+
+export default function TextareaField({
+ id,
+ label,
+ value,
+ placeholder,
+ onChange,
+ className,
+ disabled = false,
+ minRows = 4,
+}: TProps) {
+ const ref = useRef(null);
+ const resize = () => {
+ const el = ref.current;
+ if (!el) return;
+ el.style.height = "auto";
+ el.style.height = `${el.scrollHeight}px`;
+ };
+ useLayoutEffect(() => {
+ resize();
+ }, [value]);
+
+ return (
+
+ {label && (
+
+ {label}
+
+ )}
+
+
+ );
+}
diff --git a/src/components/common/toggle/Toggle.tsx b/src/components/common/toggle/Toggle.tsx
new file mode 100644
index 00000000..5eeed0d7
--- /dev/null
+++ b/src/components/common/toggle/Toggle.tsx
@@ -0,0 +1,44 @@
+import { twMerge } from "tailwind-merge";
+
+type TToggleProps = {
+ checked: boolean;
+ onToggle: () => void;
+ ariaLabel: string;
+ disabled?: boolean;
+ className?: string;
+ thumbClassName?: string;
+};
+
+export default function Toggle({
+ checked,
+ onToggle,
+ ariaLabel,
+ disabled = false,
+ className,
+ thumbClassName,
+}: TToggleProps) {
+ return (
+
+
+
+ );
+}
diff --git a/src/components/dashboard/charts/AdStatusChart.tsx b/src/components/dashboard/charts/AdStatusChart.tsx
new file mode 100644
index 00000000..94e46e5a
--- /dev/null
+++ b/src/components/dashboard/charts/AdStatusChart.tsx
@@ -0,0 +1,51 @@
+import { memo, useMemo } from "react";
+
+import type { IAdCount } from "@/types/dashboard/platform";
+
+const PLATFORM_COLORS: Record = {
+ GOOGLE: "#f9ab00",
+ NAVER: "#03c75a",
+ META: "#1877f2",
+};
+
+export const AdStatusChart = memo(({ data }: { data: IAdCount[] }) => {
+ const total = useMemo(
+ () => data.reduce((acc, curr) => acc + curr.count, 0),
+ [data],
+ );
+
+ const getWidth = (count: number) => (total > 0 ? (count / total) * 100 : 0);
+
+ return (
+
+ {/* 개수 라벨 */}
+
+ {data.map((item) => (
+
+ {item.count}개
+
+ ))}
+
+
+ {/* 세그먼트 바 */}
+
+ {data.map((item) => (
+
+ ))}
+
+
+ );
+});
+
+export default AdStatusChart;
diff --git a/src/components/dashboard/charts/BudgetGaugeChart.tsx b/src/components/dashboard/charts/BudgetGaugeChart.tsx
new file mode 100644
index 00000000..ee890cda
--- /dev/null
+++ b/src/components/dashboard/charts/BudgetGaugeChart.tsx
@@ -0,0 +1,147 @@
+import { memo } from "react";
+import { twMerge } from "tailwind-merge";
+
+import { useIsMounted } from "@/hooks/common/useIsMounted";
+
+import { type TBadgeVariant } from "@/components/common/badge/Badge";
+
+import WarnCircleIcon from "@/assets/icon/common/warn-circle.svg?react";
+
+interface IBudgetGaugeChartProps {
+ totalBudget: number;
+ spent: number;
+ warningThreshold: number;
+ dangerThreshold: number;
+}
+
+export type TBudgetStatus = "안정" | "주의" | "위험";
+
+export function getBudgetStatus(
+ percentage: number,
+ warningThreshold: number,
+ dangerThreshold: number,
+): TBudgetStatus {
+ if (percentage >= dangerThreshold) return "위험";
+ if (percentage >= warningThreshold) return "주의";
+ return "안정";
+}
+
+export const statusBadgeVariant: Record = {
+ 안정: "success",
+ 주의: "syncing",
+ 위험: "inactive",
+};
+
+const statusPointClasses: Record = {
+ 안정: "bg-status-green",
+ 주의: "bg-status-yellow",
+ 위험: "bg-status-red",
+};
+
+const BudgetGaugeChart = memo(function BudgetGaugeChart({
+ totalBudget,
+ spent,
+ warningThreshold,
+ dangerThreshold,
+}: IBudgetGaugeChartProps) {
+ const mounted = useIsMounted();
+
+ const percentage =
+ totalBudget > 0 ? Math.round((spent / totalBudget) * 100) : 0;
+ const isOverBudget = spent > totalBudget;
+ const remaining = isOverBudget ? spent - totalBudget : totalBudget - spent;
+
+ const status = getBudgetStatus(percentage, warningThreshold, dangerThreshold);
+
+ // 데이터 인사이트 메시지
+ let insightDesc = "";
+
+ if (isOverBudget) {
+ insightDesc = "예산을 초과했습니다. 캠페인 조정이 필요해요.";
+ } else if (percentage >= dangerThreshold) {
+ insightDesc = "예산 소진이 빨라요. 일일 한도 점검을 추천해요.";
+ } else if (percentage >= warningThreshold) {
+ insightDesc = "예산 소진 속도가 다소 높아요. 매체 효율을 확인해 보세요.";
+ } else {
+ insightDesc = "계획된 예산 범위 내에서 잘 사용되고 있어요.";
+ }
+
+ return (
+
+
+
+ 사용 예산
+
+
+
+ {percentage}%
+
+
+ 소진
+
+
+
+
+
+
+
+
+ ₩{spent.toLocaleString()}
+ ₩{totalBudget.toLocaleString()}
+
+
+
+
+
+ 남은 예산
+
+
+ {isOverBudget ? "-" : ""}₩{remaining.toLocaleString()}
+
+
+
+
+
+ );
+});
+
+export default BudgetGaugeChart;
diff --git a/src/components/dashboard/charts/PerformanceEfficiencyChart.tsx b/src/components/dashboard/charts/PerformanceEfficiencyChart.tsx
new file mode 100644
index 00000000..9344541d
--- /dev/null
+++ b/src/components/dashboard/charts/PerformanceEfficiencyChart.tsx
@@ -0,0 +1,49 @@
+import { lazy, memo, Suspense, useMemo } from "react";
+
+import type { IPlatformPerformance } from "@/types/dashboard/platform";
+import { PLATFORM_MAP } from "@/types/dashboard/platform";
+
+import { getMixedChartOptions } from "./performanceEfficiencyChart.config";
+
+const Chart = lazy(() => import("react-apexcharts"));
+
+export const PerformanceEfficiencyChart = memo(
+ ({ data }: { data: IPlatformPerformance[] }) => {
+ const categories = useMemo(
+ () => data.map((d) => PLATFORM_MAP[d.provider] || d.provider),
+ [data],
+ );
+ const options = useMemo(
+ () => getMixedChartOptions(categories),
+ [categories],
+ );
+
+ const series = [
+ {
+ name: "클릭률(CTR)",
+ type: "column", // 세로 막대
+ data: data.map((d) =>
+ d.impressions > 0 ? (d.clicks / d.impressions) * 100 : 0,
+ ),
+ },
+ {
+ name: "전환율(CVR)",
+ type: "column", // 세로 막대
+ data: data.map((d) => d.conversion),
+ },
+ {
+ name: "노출수",
+ type: "line", // 점
+ data: data.map((d) => d.impressions),
+ },
+ ];
+
+ return (
+ }>
+
+
+ );
+ },
+);
+
+export default PerformanceEfficiencyChart;
diff --git a/src/components/dashboard/charts/TrafficChart.tsx b/src/components/dashboard/charts/TrafficChart.tsx
new file mode 100644
index 00000000..0a93409b
--- /dev/null
+++ b/src/components/dashboard/charts/TrafficChart.tsx
@@ -0,0 +1,304 @@
+import {
+ lazy,
+ memo,
+ Suspense,
+ useCallback,
+ useEffect,
+ useMemo,
+ useRef,
+ useState,
+} from "react";
+import type { ApexOptions } from "apexcharts";
+
+import { useClickStream } from "@/hooks/dashboard/useClickStream";
+
+import { DropdownMenu } from "@/components/common/dropdownmenu/DropdownMenu";
+import { Skeleton } from "@/components/common/skeleton/Skeleton";
+
+import {
+ buildChartOptions,
+ CHART_CONTAINER_ID,
+ DOWNLOAD_ITEMS,
+} from "./trafficChart.config";
+import { useAnomalyMarkerPos } from "./useAnomalyMarkerPos";
+
+import { toggleDummyClicks } from "@/api/dashboard/overview";
+import MoreIcon from "@/assets/icon/common/more.svg?react";
+
+const ReactApexChart = lazy(() => import("react-apexcharts"));
+
+// 차트 우측 상단 다운로드 버튼
+export function TrafficChartDownload() {
+ return (
+
+
+
+ }
+ items={DOWNLOAD_ITEMS}
+ />
+ );
+}
+
+// 이상 징후 커스텀 툴팁
+const AnomalyBubble = memo(function AnomalyBubble({
+ x,
+ y,
+ message,
+ timestamp,
+}: {
+ x: number;
+ y: number;
+ message?: string;
+ timestamp?: string;
+}) {
+ const GAP = 12;
+ return (
+
+
+
+
+ {message && (
+
{message}
+ )}
+ {timestamp && (
+
{timestamp}
+ )}
+
+
+
+ );
+});
+
+type TTrafficChartProps = {
+ yAxisMax?: number;
+ height?: number;
+ showAnomaly?: boolean;
+};
+
+const TrafficChart = memo(function TrafficChart({
+ yAxisMax,
+ height = 400,
+ showAnomaly = true,
+}: TTrafficChartProps) {
+ const containerRef = useRef(null);
+ const { data, suspectDetail, isError } = useClickStream("dummy");
+
+ // timeSeriesData → 차트 series 및 카테고리 변환
+ const { series, categories, anomalyCategory, anomalyY } = useMemo(() => {
+ const items = data?.timeSeriesData ?? [];
+ const cats = items.map((d) => {
+ const hh = d.minute.slice(8, 10);
+ const mm = d.minute.slice(10, 12);
+ return `${hh}:${mm}`;
+ });
+ const chartData = items.map((d) => d.count);
+
+ // 이상 징후 발생 시 suspectDetail.timestamp로 해당 분 단위 지점을 마커로 표시
+ let anomCat: string | undefined;
+ let anomY: number | undefined;
+ if (data?.hasSuspect && items.length > 0) {
+ let matchIdx = -1;
+
+ if (suspectDetail?.timestamp) {
+ const ts = new Date(suspectDetail.timestamp);
+ if (!isNaN(ts.getTime())) {
+ const minute =
+ ts.getFullYear().toString() +
+ String(ts.getMonth() + 1).padStart(2, "0") +
+ String(ts.getDate()).padStart(2, "0") +
+ String(ts.getHours()).padStart(2, "0") +
+ String(ts.getMinutes()).padStart(2, "0");
+ matchIdx = items.findIndex((d) => d.minute === minute);
+ }
+ }
+
+ // timestamp 매칭 실패 시 최대 클릭 지점으로 fallback
+ if (matchIdx === -1) {
+ matchIdx = items.reduce(
+ (maxI, cur, i, arr) => (cur.count > arr[maxI].count ? i : maxI),
+ 0,
+ );
+ }
+
+ anomCat = cats[matchIdx];
+ anomY = items[matchIdx].count;
+ }
+
+ return {
+ series: [{ name: "클릭수", data: chartData }],
+ categories: cats,
+ anomalyCategory: anomCat,
+ anomalyY: anomY,
+ };
+ }, [data, suspectDetail]);
+
+ const chartOptions = useMemo(
+ () =>
+ buildChartOptions({
+ categories,
+ maxCount: Math.max(
+ ...(data?.timeSeriesData?.map((d) => d.count) ?? [0]),
+ ),
+ anomalyCategory,
+ anomalyY,
+ }),
+ [categories, data, anomalyCategory, anomalyY],
+ );
+
+ // 빨간 점의 컨테이너 기준 좌표 (anomalyCategory 변경 시 재계산)
+ const markerPos = useAnomalyMarkerPos(containerRef, anomalyCategory);
+ const [isAnomalyHovered, setIsAnomalyHovered] = useState(false);
+ const [isAnomalyFocused, setIsAnomalyFocused] = useState(false);
+
+ // 스크롤 중 pointer-events 제거 - setState 대신 DOM 직접 조작으로 리렌더 방지
+ useEffect(() => {
+ const container = containerRef.current;
+ if (!container) return;
+
+ let timer: ReturnType;
+ const handleScroll = () => {
+ container.style.pointerEvents = "none";
+ container.classList.add("is-scrolling");
+ clearTimeout(timer);
+ timer = setTimeout(() => {
+ container.style.pointerEvents = "";
+ container.classList.remove("is-scrolling");
+ }, 150);
+ };
+ window.addEventListener("scroll", handleScroll, { passive: true });
+ return () => {
+ window.removeEventListener("scroll", handleScroll);
+ clearTimeout(timer);
+ };
+ }, []);
+
+ const handleFocus = useCallback(() => setIsAnomalyFocused(true), []);
+ const handleBlur = useCallback(() => setIsAnomalyFocused(false), []);
+ const handlePointerEnter = useCallback(() => setIsAnomalyHovered(true), []);
+ const handlePointerLeave = useCallback(() => setIsAnomalyHovered(false), []);
+
+ const showBubble = showAnomaly && (isAnomalyHovered || isAnomalyFocused);
+ const apexOptions: ApexOptions = useMemo(() => {
+ if (!yAxisMax) return chartOptions;
+
+ const yaxis = chartOptions.yaxis;
+ if (Array.isArray(yaxis)) {
+ return {
+ ...chartOptions,
+ yaxis: yaxis.map((axis) =>
+ typeof axis === "object" && axis !== null
+ ? { ...axis, max: yAxisMax }
+ : axis,
+ ),
+ };
+ }
+
+ return {
+ ...chartOptions,
+ yaxis:
+ typeof yaxis === "object" && yaxis !== null
+ ? { ...yaxis, max: yAxisMax }
+ : yaxis,
+ };
+ }, [chartOptions, yAxisMax]);
+
+ if (isError && !data) {
+ return (
+
+
실시간 데이터를 불러오지 못했습니다.
+
잠시 후 다시 시도해 주세요.
+
+ );
+ }
+
+ if (!data) {
+ return ;
+ }
+
+ return (
+ <>
+ {/* TODO: 테스트용 - 개발 완료 후 제거 */}
+
+ 더미 데이터 토글
+
+
+
}>
+
+
+
+ {showAnomaly && markerPos && (
+ <>
+
+
+
+ {showBubble && (
+
+ )}
+ >
+ )}
+
+ >
+ );
+});
+
+export default TrafficChart;
diff --git a/src/components/dashboard/charts/budgetGaugeChart.mock.ts b/src/components/dashboard/charts/budgetGaugeChart.mock.ts
new file mode 100644
index 00000000..f51e5fab
--- /dev/null
+++ b/src/components/dashboard/charts/budgetGaugeChart.mock.ts
@@ -0,0 +1,14 @@
+export interface IBudgetGaugeChartData {
+ totalBudget: number; // 총 예산
+ spent: number; // 현재 소진액
+ warningThreshold: number; // 주의
+ dangerThreshold: number; // 위험
+}
+
+// 목업 데이터
+export const budgetGaugeChartMock: IBudgetGaugeChartData = {
+ totalBudget: 10000000,
+ spent: 6200000,
+ warningThreshold: 50,
+ dangerThreshold: 75,
+};
diff --git a/src/components/dashboard/charts/performanceEfficiencyChart.config.ts b/src/components/dashboard/charts/performanceEfficiencyChart.config.ts
new file mode 100644
index 00000000..0e105122
--- /dev/null
+++ b/src/components/dashboard/charts/performanceEfficiencyChart.config.ts
@@ -0,0 +1,87 @@
+import type { ApexOptions } from "apexcharts";
+
+export const getMixedChartOptions = (categories: string[]): ApexOptions => ({
+ chart: {
+ type: "line",
+ toolbar: { show: false },
+ fontFamily: "Pretendard",
+ zoom: { enabled: false },
+ selection: { enabled: false },
+ },
+ stroke: {
+ show: true,
+ width: [0, 0, 0.01],
+ },
+ markers: {
+ size: [0, 0, 6], // 막대 = 0, 점 = 6
+ strokeWidth: 2,
+ strokeColors: "#fff",
+ hover: { sizeOffset: 2 },
+ },
+ plotOptions: {
+ bar: {
+ columnWidth: "60%",
+ borderRadius: 4,
+ borderRadiusApplication: "end",
+ },
+ },
+ colors: ["#0084fe", "#0a3d91", "#4fc3f7"],
+ xaxis: {
+ categories: categories,
+ labels: {
+ style: {
+ fontSize: "14px",
+ fontWeight: 500,
+ colors: "#212121",
+ },
+ },
+ axisBorder: { show: false },
+ axisTicks: { show: false },
+ },
+ yaxis: [
+ {
+ seriesName: "클릭률",
+ labels: {
+ formatter: (val) => `${val.toFixed(1)}%`,
+ style: {
+ colors: "#8B8B8F",
+ fontSize: "12px",
+ },
+ },
+ },
+ { show: false, seriesName: "전환율" },
+ {
+ opposite: true,
+ seriesName: "노출수",
+ labels: {
+ offsetX: -10,
+ formatter: (val) => val.toLocaleString("ko-KR"),
+ style: {
+ colors: "#8B8B8F",
+ fontSize: "12px",
+ },
+ },
+ },
+ ],
+ tooltip: {
+ shared: true,
+ intersect: false,
+ y: {
+ formatter: (val, { seriesIndex }) => {
+ if (seriesIndex === 0 || seriesIndex === 1) {
+ return `${val.toFixed(2)}%`;
+ }
+ return val.toLocaleString("ko-KR");
+ },
+ },
+ },
+ grid: {
+ borderColor: "#f1f1f1",
+ yaxis: { lines: { show: true } },
+ padding: {
+ bottom: -15,
+ top: -15,
+ },
+ },
+ legend: { show: false },
+});
diff --git a/src/components/dashboard/charts/trafficChart.config.ts b/src/components/dashboard/charts/trafficChart.config.ts
new file mode 100644
index 00000000..f46a1802
--- /dev/null
+++ b/src/components/dashboard/charts/trafficChart.config.ts
@@ -0,0 +1,169 @@
+import type { ApexOptions } from "apexcharts";
+
+import {
+ downloadChartCsv,
+ downloadChartPng,
+ downloadChartSvg,
+} from "@/utils/download";
+
+// 차트 고유 ID
+export const CHART_ID = "traffic-chart";
+
+// 파일 저장 시 이름에 포함
+const TODAY = new Date().toISOString().slice(0, 10);
+
+// SVG 다운로드 시 컨테이너 요소를 직접 참조하기 위한 ID
+export const CHART_CONTAINER_ID = `${CHART_ID}-container`;
+
+const FILENAME = `overview-traffic-chart-${TODAY}`;
+
+// 다운로드 드롭다운 항목
+export const DOWNLOAD_ITEMS = [
+ {
+ label: "PNG 저장",
+ onClick: () => downloadChartPng(CHART_ID, FILENAME),
+ },
+ {
+ label: "SVG 저장",
+ onClick: () => downloadChartSvg(CHART_CONTAINER_ID, FILENAME),
+ },
+ {
+ label: "CSV 다운로드",
+ onClick: () => downloadChartCsv(CHART_ID),
+ },
+];
+
+// 차트 옵션 생성
+export function buildChartOptions(params: {
+ categories: string[];
+ maxCount: number;
+ anomalyCategory?: string; // 이상 징후 x 좌표 ("HH:mm")
+ anomalyY?: number; // 이상 징후 y 좌표
+}): ApexOptions {
+ const { categories, maxCount, anomalyCategory, anomalyY } = params;
+ const yMax = (() => {
+ if (maxCount <= 0) return 1000;
+ const magnitude = Math.pow(10, Math.floor(Math.log10(maxCount)));
+ const unit = magnitude >= 1000 ? magnitude : 1000;
+ return Math.ceil((maxCount * 1.2) / unit) * unit;
+ })();
+
+ return {
+ chart: {
+ id: CHART_ID,
+ type: "area",
+ events: {
+ mounted: (chartContext: { el: Element }) => {
+ chartContext.el.querySelectorAll("title").forEach((el) => {
+ el.remove();
+ });
+ const canvas = chartContext.el.querySelector("canvas");
+ if (canvas) canvas.textContent = "";
+ },
+ },
+ toolbar: {
+ show: true,
+ tools: {
+ download: false,
+ selection: false,
+ zoom: false,
+ zoomin: false,
+ zoomout: false,
+ pan: false,
+ reset: false,
+ },
+ export: {
+ csv: {
+ filename: `overview-traffic-data-${TODAY}`,
+ columnDelimiter: ",",
+ headerCategory: "시간",
+ headerValue: "클릭수",
+ },
+ },
+ },
+ zoom: { enabled: false },
+ fontFamily: "Pretendard",
+ animations: { enabled: false },
+ redrawOnWindowResize: false,
+ },
+
+ dataLabels: { enabled: false },
+
+ stroke: {
+ curve: "smooth",
+ width: 1.5,
+ },
+
+ fill: {
+ type: "solid",
+ opacity: 0.1,
+ },
+
+ colors: ["#0084fe"],
+
+ markers: { size: 0 },
+
+ annotations: {
+ points:
+ anomalyCategory !== undefined && anomalyY !== undefined
+ ? [
+ {
+ x: anomalyCategory,
+ y: anomalyY,
+ marker: {
+ size: 3,
+ fillColor: "#ff4560",
+ strokeColor: "#ff4560",
+ strokeWidth: 1,
+ },
+ },
+ ]
+ : [],
+ },
+
+ xaxis: {
+ type: "category",
+ categories,
+ tickAmount: 6,
+ labels: {
+ formatter: (val: string) => val,
+ style: { colors: "#8b8b8f", fontSize: "12px" },
+ rotate: 0,
+ rotateAlways: false,
+ },
+ axisBorder: { show: false },
+ axisTicks: { show: false },
+ tooltip: { enabled: false },
+ },
+
+ yaxis: {
+ min: 0,
+ max: yMax,
+ tickAmount: 5,
+ labels: {
+ formatter: (val: number) => {
+ if (val === 0) return "";
+ const rounded = Math.round(val);
+ if (rounded < 1000) return rounded.toLocaleString();
+ return `${Math.round(rounded / 1000)}K`;
+ },
+ style: { colors: "#8b8b8f", fontSize: "12px" },
+ },
+ },
+
+ grid: {
+ borderColor: "#f2f4f6",
+ xaxis: { lines: { show: false } },
+ yaxis: { lines: { show: true } },
+ padding: { left: 16, right: 8 },
+ },
+
+ tooltip: {
+ x: { show: false },
+ y: {
+ formatter: (val: number) => val.toLocaleString(),
+ },
+ style: { fontFamily: "Pretendard" },
+ },
+ };
+}
diff --git a/src/components/dashboard/charts/useAnomalyMarkerPos.ts b/src/components/dashboard/charts/useAnomalyMarkerPos.ts
new file mode 100644
index 00000000..b3a702d3
--- /dev/null
+++ b/src/components/dashboard/charts/useAnomalyMarkerPos.ts
@@ -0,0 +1,49 @@
+import { type RefObject, useEffect, useState } from "react";
+
+// 이상 징후 빨간 점(annotation marker)의 컨테이너 기준 좌표를 반환하는 훅
+export function useAnomalyMarkerPos(
+ containerRef: RefObject,
+ dep?: unknown,
+) {
+ const [markerPos, setMarkerPos] = useState<{ x: number; y: number } | null>(
+ null,
+ );
+
+ // 차트 마운트 후(300ms 대기) 및 리사이즈 시 좌표 갱신
+ useEffect(() => {
+ const container = containerRef.current;
+ if (!container) return;
+
+ const updateMarkerPos = () => {
+ // DOM에서 ApexCharts annotation 마커 요소 탐색
+ const marker = container.querySelector(
+ ".apexcharts-point-annotation-marker",
+ );
+ if (!marker) return;
+
+ // getBoundingClientRect으로 뷰포트 기준 위치 계산 후 컨테이너 기준으로 변환
+ const markerRect = marker.getBoundingClientRect();
+ const containerRect = container.getBoundingClientRect();
+ setMarkerPos({
+ x: markerRect.left + markerRect.width / 2 - containerRect.left,
+ y: markerRect.top + markerRect.height / 2 - containerRect.top,
+ });
+ };
+
+ const timer = setTimeout(updateMarkerPos, 300);
+
+ let debounceTimer: ReturnType;
+ const observer = new ResizeObserver(() => {
+ clearTimeout(debounceTimer);
+ debounceTimer = setTimeout(updateMarkerPos, 300);
+ });
+ observer.observe(container);
+ return () => {
+ clearTimeout(timer);
+ clearTimeout(debounceTimer);
+ observer.disconnect();
+ };
+ }, [containerRef, dep]);
+
+ return markerPos;
+}
diff --git a/src/components/dashboard/platform/PlatformDetailCard.tsx b/src/components/dashboard/platform/PlatformDetailCard.tsx
new file mode 100644
index 00000000..ccfd3ddd
--- /dev/null
+++ b/src/components/dashboard/platform/PlatformDetailCard.tsx
@@ -0,0 +1,106 @@
+import React, { memo } from "react";
+
+import type { IPlatformPerformance } from "@/types/dashboard/platform";
+import { PLATFORM_MAP } from "@/types/dashboard/platform";
+
+import Card from "@/components/common/card/Card";
+import StatCard from "@/components/common/card/StatCard";
+
+import GoogleLogo from "@/assets/logo/social-logo/circle/google-circle.svg?react";
+import MetaLogo from "@/assets/logo/social-logo/circle/meta-circle.svg?react";
+import NaverLogo from "@/assets/logo/social-logo/circle/naver-circle.svg?react";
+
+const PLATFORM_LOGOS: Record = {
+ GOOGLE: ,
+ NAVER: ,
+ META: ,
+};
+
+export const PlatformDetailCard = memo(
+ ({ data }: { data: IPlatformPerformance }) => {
+ const {
+ provider,
+ impressions,
+ clicks,
+ conversion,
+ ROAS,
+ impressionChangeRate,
+ clickChangeRate,
+ cvrChangeRate,
+ ROASChangeRate,
+ } = data;
+
+ const innerCardClass =
+ "shadow-none! hover:shadow-none! rounded-component-md! p-2! gap-2!";
+
+ return (
+
+ {/* 로고 + 이름 */}
+
+
{PLATFORM_LOGOS[provider]}
+
+ {PLATFORM_MAP[provider]}
+
+
+
+ {/* 지표 */}
+
+ 0 ? "up" : "down",
+ value: `${Math.abs(impressionChangeRate * 100).toFixed(1)}%`,
+ }
+ : undefined
+ }
+ className={innerCardClass}
+ />
+ 0 ? "up" : "down",
+ value: `${Math.abs(clickChangeRate * 100).toFixed(1)}%`,
+ }
+ : undefined
+ }
+ className={innerCardClass}
+ />
+ 0 ? "up" : "down",
+ value: `${Math.abs(cvrChangeRate * 100).toFixed(1)}%`,
+ }
+ : undefined
+ }
+ className={innerCardClass}
+ />
+ 0 ? "up" : "down",
+ value: `${Math.abs(ROASChangeRate * 100).toFixed(1)}%`,
+ }
+ : undefined
+ }
+ className={innerCardClass}
+ />
+
+
+ );
+ },
+);
+
+export default PlatformDetailCard;
diff --git a/src/components/dashboard/platform/PlatformRoasTable.tsx b/src/components/dashboard/platform/PlatformRoasTable.tsx
new file mode 100644
index 00000000..95569778
--- /dev/null
+++ b/src/components/dashboard/platform/PlatformRoasTable.tsx
@@ -0,0 +1,182 @@
+import { memo } from "react";
+
+import type { IPlatformRankingItem } from "@/types/dashboard/overview";
+
+import { TrendBadge } from "@/components/common/card/StatCard";
+
+import GoogleLogo from "@/assets/logo/social-logo/circle/google-circle.svg?react";
+import KakaoLogo from "@/assets/logo/social-logo/circle/kakao-circle.svg?react";
+import NaverLogo from "@/assets/logo/social-logo/circle/naver-circle.svg?react";
+
+const platformLogoMap = {
+ Google: ,
+ NAVER: ,
+ Kakao: ,
+};
+
+type TPlatformName = keyof typeof platformLogoMap;
+
+const providerDisplayMap: Record = {
+ GOOGLE: "Google",
+ NAVER: "NAVER",
+ KAKAO: "Kakao",
+};
+
+function getDisplayName(provider: string): string {
+ return providerDisplayMap[provider.toUpperCase()] ?? provider;
+}
+
+function getPlatformLogo(provider: string) {
+ const name = getDisplayName(provider);
+ if (name in platformLogoMap) {
+ return platformLogoMap[name as TPlatformName];
+ }
+ return (
+
+ {name[0]}
+
+ );
+}
+
+function roasStatusClass(roas: number) {
+ if (roas >= 200) return "bg-status-green";
+ if (roas >= 100) return "bg-status-blue";
+ return "bg-status-red";
+}
+
+const Delta = memo(function Delta({ value }: { value: number }) {
+ const isPos = value >= 0;
+ return (
+
+ );
+});
+
+const COL =
+ "grid-cols-[32px_1.5fr_2.5fr_1.5fr] @2xl:grid-cols-[32px_1.5fr_2.5fr_1fr_1fr_1.5fr]";
+
+interface IPlatformRoasTableProps {
+ rankings: IPlatformRankingItem[];
+}
+
+const PlatformRoasTable = memo(function PlatformRoasTable({
+ rankings,
+}: IPlatformRoasTableProps) {
+ const maxRoas =
+ rankings.length > 0 ? Math.max(...rankings.map((r) => r.roas)) : 1;
+
+ return (
+
+
+ {/* 헤더 */}
+
+ 순위
+ 플랫폼
+ ROAS(%)
+ CTR(클릭률)
+ CVR(전환율)
+ 매출 / 광고비
+
+
+ {rankings.length === 0 && (
+
+ 플랫폼 데이터가 없습니다.
+
+ )}
+
+ {rankings.map((item) => (
+
+ {/* 순위 */}
+
+ {item.rank}
+
+
+ {/* 플랫폼 이름 */}
+
+
+ {getPlatformLogo(item.provider)}
+
+
+ {getDisplayName(item.provider)}
+
+
+
+ {/* ROAS 수치 + 가로 바 */}
+
+
+ {item.roas.toLocaleString()}%
+
+
+
+
+ {/* CTR */}
+
+ {item.clickRate !== undefined ? (
+ <>
+
+ {item.clickRate.toFixed(1)}%
+
+ {item.ctrDelta !== undefined && (
+
+
+
+ )}
+ >
+ ) : (
+
-
+ )}
+
+
+ {/* CVR */}
+
+ {item.conversionRate !== undefined ? (
+ <>
+
+ {item.conversionRate.toFixed(1)}%
+
+ {item.conversionDelta !== undefined && (
+
+
+
+ )}
+ >
+ ) : (
+
-
+ )}
+
+
+ {/* 매출/광고비 */}
+
+
+ ₩{item.revenue.toLocaleString()}
+
+
+ 광고비
+
+ ₩{item.adSpend.toLocaleString()}
+
+
+
+
+ ))}
+
+
+
+ );
+});
+
+export default PlatformRoasTable;
diff --git a/src/components/dashboard/platform/TopPerformanceList.tsx b/src/components/dashboard/platform/TopPerformanceList.tsx
new file mode 100644
index 00000000..e5159608
--- /dev/null
+++ b/src/components/dashboard/platform/TopPerformanceList.tsx
@@ -0,0 +1,64 @@
+import React, { memo } from "react";
+
+import type { IRoasRanking } from "@/types/dashboard/platform";
+import { PLATFORM_MAP } from "@/types/dashboard/platform";
+
+import { TrendBadge } from "@/components/common/card/StatCard";
+
+import GoogleLogo from "@/assets/logo/social-logo/circle/google-circle.svg?react";
+import MetaLogo from "@/assets/logo/social-logo/circle/meta-circle.svg?react";
+import NaverLogo from "@/assets/logo/social-logo/circle/naver-circle.svg?react";
+
+interface ITopPerformanceListProps {
+ rankings: IRoasRanking[];
+}
+
+const PlatformInfo: Record = {
+ GOOGLE: {
+ name: PLATFORM_MAP.GOOGLE,
+ logo: ,
+ },
+ NAVER: { name: PLATFORM_MAP.NAVER, logo: },
+ META: { name: PLATFORM_MAP.META, logo: },
+};
+
+export const TopPerformanceList = memo(function TopPerformanceList({
+ rankings,
+}: ITopPerformanceListProps) {
+ return (
+
+ {rankings.map((item) => {
+ const info = PlatformInfo[item.provider] || {
+ name: item.provider,
+ logo: null,
+ };
+
+ return (
+
+
+
+ {item.rank}
+
+
{info.logo}
+
+ {info.name}
+
+
+
+
+ {item.roas.toFixed(2)}%
+
+ {item.diffRate !== null && item.diffRate !== 0 && (
+ 0 ? "up" : "down"}
+ value={`${Math.abs(item.diffRate)}%`}
+ />
+ )}
+
+
+ );
+ })}
+
+ );
+});
+export default TopPerformanceList;
diff --git a/src/components/dashboard/platform/skeleton/PlatformSkeleton.tsx b/src/components/dashboard/platform/skeleton/PlatformSkeleton.tsx
new file mode 100644
index 00000000..79670d56
--- /dev/null
+++ b/src/components/dashboard/platform/skeleton/PlatformSkeleton.tsx
@@ -0,0 +1,74 @@
+import { twMerge } from "tailwind-merge";
+
+import {
+ Skeleton,
+ SkeletonCircle,
+} from "@/components/common/skeleton/Skeleton";
+
+// 성과 우수 플랫폼
+export function TopPerformanceListSkeleton() {
+ return (
+
+ {[1, 2, 3].map((i) => (
+
+ {/* 순위 숫자 */}
+ {/* 로고 */}
+ {/* 이름 */}
+ {/* 수치 */}
+
+ ))}
+
+ );
+}
+
+// 개별 플랫폼 상세 카드
+export function PlatformDetailCardSkeleton() {
+ return (
+
+
+
+
+
+
+ {[1, 2, 3, 4].map((i) => (
+
+
+
+
+ ))}
+
+
+ );
+}
+
+// 광고 소재 현황
+export function AdStatusChartSkeleton() {
+ return (
+
+
+
+ );
+}
+
+//플랫폼별 성과 효율
+export function PerformanceEfficiencyChartSkeleton() {
+ return (
+
+
+
+ );
+}
+
+// 실시간 트래픽 변화
+export function TrafficChartSkeleton() {
+ return ;
+}
+
+export function BadgeSkeleton({ className }: { className?: string }) {
+ return (
+
+ );
+}
diff --git a/src/components/landing/GuideOverviewChart.tsx b/src/components/landing/GuideOverviewChart.tsx
new file mode 100644
index 00000000..be1feac3
--- /dev/null
+++ b/src/components/landing/GuideOverviewChart.tsx
@@ -0,0 +1,144 @@
+import { lazy, Suspense } from "react";
+import type { ApexOptions } from "apexcharts";
+
+import Card from "@/components/common/card/Card";
+import ChartLegend from "@/components/common/chart/ChartLegend";
+
+const ReactApexChart = lazy(() => import("react-apexcharts"));
+
+const splitIndex = 12;
+const clicks = [
+ 29600, 31100, 31600, 32100, 33600, 37100, 44600, 46100, 46600, 45600, 49600,
+ 52600, 53600, 51600, 47600, 45600, 43600, 42600, 45100, 40600, 37600, 35600,
+ 41600, 47600, 50600,
+];
+const peak = Math.max(...clicks);
+const targetPeak = 48500;
+const normalizedClicks = clicks.map((value) =>
+ Math.round((value / peak) * targetPeak),
+);
+
+const actualSeries = normalizedClicks.map((y, i) =>
+ i <= splitIndex ? { x: i, y } : { x: i, y: null },
+);
+const projectedSeries = normalizedClicks.map((y, i) =>
+ i >= splitIndex ? { x: i, y } : { x: i, y: null },
+);
+
+const options: ApexOptions = {
+ chart: {
+ type: "line",
+ toolbar: { show: false },
+ zoom: { enabled: false },
+ animations: { enabled: false },
+ fontFamily: "Pretendard",
+ },
+ dataLabels: { enabled: false },
+ stroke: {
+ curve: "smooth",
+ width: [3.5, 3.2],
+ dashArray: [0, 6],
+ lineCap: "round",
+ },
+ colors: ["var(--color-logo-2)", "var(--color-brand-500)"],
+ markers: { size: [0, 0] },
+ tooltip: { enabled: false },
+ xaxis: {
+ type: "numeric",
+ min: 0,
+ max: 24,
+ tickAmount: 24,
+ labels: { show: false },
+ axisBorder: { show: false },
+ axisTicks: { show: false },
+ },
+ yaxis: {
+ min: 0,
+ max: 50000,
+ tickAmount: 6,
+ labels: {
+ formatter: (val: number) =>
+ val === 0 ? "" : `${(val / 1000).toFixed(0)}K`,
+ style: { colors: "var(--color-text-sub)", fontSize: "10px" },
+ offsetX: -2,
+ },
+ },
+ grid: {
+ borderColor: "var(--color-bg-disabled)",
+ strokeDashArray: 5,
+ xaxis: { lines: { show: false } },
+ yaxis: { lines: { show: true } },
+ padding: { left: 12, right: 8 },
+ },
+ legend: { show: false },
+ annotations: {
+ xaxis: [
+ {
+ x: splitIndex,
+ borderColor: "var(--color-brand-500)",
+ strokeDashArray: 0,
+ },
+ ],
+ points: [
+ {
+ x: splitIndex,
+ y: normalizedClicks[splitIndex],
+ marker: {
+ size: 5,
+ fillColor: "var(--color-logo-2)",
+ strokeColor: "var(--color-logo-2)",
+ },
+ },
+ ],
+ },
+};
+
+const series = [
+ { name: "클릭수", data: actualSeries },
+ { name: "예측 클릭수", data: projectedSeries },
+];
+
+export default function GuideOverviewChart() {
+ return (
+
+
+ }
+ >
+
+ }
+ >
+
+
+
+ 광고 클릭수 추이
+
+
+ 오후 12시 기준 클릭수 48,500
+
+
+ 전시간 대비 +1.9%
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/landing/GuidePlatform.tsx b/src/components/landing/GuidePlatform.tsx
new file mode 100644
index 00000000..ec056fd3
--- /dev/null
+++ b/src/components/landing/GuidePlatform.tsx
@@ -0,0 +1,123 @@
+import type { ReactNode } from "react";
+import { useState } from "react";
+
+import ChevronDown from "@/assets/icon/chevron/chevron-down.svg?react";
+import GoogleAdsPlain from "@/assets/logo/social-logo/plain/google_ads.png";
+import MetaPlain from "@/assets/logo/social-logo/plain/meta.svg?react";
+import GoogleWordmark from "@/assets/logo/social-logo/wordmark/google-wordmark.svg?react";
+import KakaoWordmark from "@/assets/logo/social-logo/wordmark/kakao-wordmark.svg?react";
+import NaverWordmarkPng from "@/assets/logo/social-logo/wordmark/naver-wordmark.png";
+
+type TPlatform = {
+ id: string;
+ label: string;
+ content: ReactNode;
+ offsetClass?: string;
+};
+
+const PLATFORMS: TPlatform[] = [
+ {
+ id: "naver",
+ label: "Naver",
+ content: (
+
+ ),
+ },
+ {
+ id: "kakao",
+ label: "Kakao",
+ content: ,
+ },
+ {
+ id: "google",
+ label: "Google",
+ content: ,
+ },
+ {
+ id: "meta",
+ label: "Meta",
+ content: ,
+ offsetClass: "-ml-2",
+ },
+ {
+ id: "googleads",
+ label: "Google Ads",
+ content: (
+
+ ),
+ offsetClass: "-ml-2",
+ },
+];
+
+export default function GuidePlatform() {
+ const [isMenuOpen, setIsMenuOpen] = useState(true);
+ const [selectedIds, setSelectedIds] = useState([
+ "googleads",
+ "meta",
+ "naver",
+ ]);
+
+ function togglePlatform(id: string) {
+ setSelectedIds((prev) =>
+ prev.includes(id) ? prev.filter((value) => value !== id) : [...prev, id],
+ );
+ }
+
+ return (
+
+
+
setIsMenuOpen((prev) => !prev)}
+ aria-expanded={isMenuOpen}
+ className="h-11 w-full rounded-xl px-4 border border-chart-inactive/70 bg-white text-[13px] font-semibold text-text-main flex items-center justify-between hover:bg-brand-300/40 transition-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-logo-2/30"
+ >
+ 플랫폼 선택
+
+
+
+
+
+ {isMenuOpen && (
+
+
+ {PLATFORMS.map((platform) => {
+ const isSelected = selectedIds.includes(platform.id);
+ return (
+
togglePlatform(platform.id)}
+ className={`w-full h-14 px-4 flex items-center justify-start border-b last:border-b-0 transition-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-logo-2/25 focus-visible:ring-inset ${
+ isSelected
+ ? "bg-brand-300/22 border-chart-inactive/40"
+ : "bg-white hover:bg-brand-300/25 border-chart-inactive/40"
+ }`}
+ >
+
+ {platform.content}
+
+ {platform.label}
+
+ );
+ })}
+
+
+ )}
+
+
+ );
+}
diff --git a/src/components/landing/GuideTimeline.tsx b/src/components/landing/GuideTimeline.tsx
new file mode 100644
index 00000000..5ebf4d06
--- /dev/null
+++ b/src/components/landing/GuideTimeline.tsx
@@ -0,0 +1,175 @@
+import ChevronLeftIcon from "@/assets/icon/timeline/chevron-left.svg?react";
+import ChevronRightIcon from "@/assets/icon/timeline/chevron-right.svg?react";
+import FilterIcon from "@/assets/icon/timeline/filter.svg?react";
+import KebabIcon from "@/assets/icon/timeline/kebab.svg?react";
+import SortIcon from "@/assets/icon/timeline/sort.svg?react";
+
+const columns = [
+ { day: "M", date: 30, isWeekend: false },
+ { day: "T", date: 31, isWeekend: false },
+ { day: "W", date: 1, isWeekend: false },
+ { day: "T", date: 2, isWeekend: false, isToday: true },
+ { day: "F", date: 3, isWeekend: false },
+ { day: "S", date: 4, isWeekend: true },
+ { day: "S", date: 5, isWeekend: true },
+ { day: "M", date: 6, isWeekend: false },
+ { day: "T", date: 7, isWeekend: false },
+ { day: "W", date: 8, isWeekend: false },
+ { day: "T", date: 9, isWeekend: false },
+ { day: "F", date: 10, isWeekend: false },
+ { day: "S", date: 11, isWeekend: true },
+ { day: "S", date: 12, isWeekend: true },
+ { day: "M", date: 13, isWeekend: false },
+ { day: "T", date: 14, isWeekend: false },
+ { day: "W", date: 15, isWeekend: false },
+];
+
+const cards = [
+ {
+ id: 1,
+ title: "봄 프로모션 캠페인",
+ subtitle: "Google Ads · 전환",
+ colStart: 3.2,
+ colEnd: 9,
+ row: 1,
+ colorClass: "bg-status-blue",
+ },
+ {
+ id: 2,
+ title: "리타겟팅 캠페인",
+ subtitle: "Meta · 트래픽",
+ colStart: 8.9,
+ colEnd: 15.3,
+ row: 2,
+ colorClass: "bg-logo-2",
+ },
+ {
+ id: 3,
+ title: "브랜드 검색 캠페인",
+ subtitle: "Naver · 검색",
+ colStart: 2.4,
+ colEnd: 8,
+ row: 3,
+ colorClass: "bg-status-green",
+ },
+];
+
+export default function GuideTimeline() {
+ const colWidth = 55;
+ const rowHeight = 92;
+ const rowOffset = 24;
+ const totalWidth = columns.length * colWidth;
+
+ return (
+
+ {/* Top Navigation */}
+
+
+
+ Day
+
+
+ Week
+
+
+ Month
+
+
+
+
+
+
+
+ 27 Dec - 4 Jan
+
+
+
+
+
+
+
+
+ Sort
+
+
+
+ Filter
+
+
+
+
+ {/* Chart Area */}
+
+
+ {/* Header (Dates) */}
+
+ {columns.map((c, i) => (
+
+
+ {c.day} {c.date}
+
+
+ ))}
+
+
+ {/* Timeline Body Grid */}
+
+ {/* Columns Background */}
+ {columns.map((_, i) => (
+
+ ))}
+
+ {/* Today Line removed for cleaner mock */}
+
+ {/* Cards */}
+ {cards.map((card) => {
+ const x = (card.colStart - 1) * colWidth;
+ const width = (card.colEnd - card.colStart) * colWidth;
+ const y = rowOffset + (card.row - 1) * rowHeight;
+
+ return (
+
+ {/* Left Indicator */}
+
+
+ {/* Text */}
+
+
+ {card.title}
+
+
+ {card.subtitle}
+
+
+
+ {/* Menu */}
+
+
+
+
+
+
+ );
+ })}
+
+
+
+
+ );
+}
diff --git a/src/components/landing/LandingFAQ.tsx b/src/components/landing/LandingFAQ.tsx
new file mode 100644
index 00000000..517d339a
--- /dev/null
+++ b/src/components/landing/LandingFAQ.tsx
@@ -0,0 +1,61 @@
+import LandingSectionHeader from "@/components/landing/LandingSectionHeader";
+
+import ChevronDown from "@/assets/icon/chevron/chevron-down.svg?react";
+import ChevronUp from "@/assets/icon/chevron/chevron-up.svg?react";
+
+type TFAQItem = { q: string; a: string };
+
+const FAQ_ITEMS: TFAQItem[] = [
+ {
+ q: "무료로 시작할 수 있나요?",
+ a: "네. 스타터 플랜으로 주요 기능을 바로 체험할 수 있습니다.",
+ },
+ {
+ q: "어떤 광고 채널을 연동할 수 있나요?",
+ a: "Google, Meta, 카카오, 네이버 등 주요 채널을 지원합니다. (추가 채널은 순차 확대 예정입니다.)",
+ },
+ {
+ q: "요금은 언제부터 결제되나요?",
+ a: "프로 플랜은 무료 체험 이후에 결제가 시작됩니다. 자세한 내용은 요금제에서 확인하세요.",
+ },
+ {
+ q: "엔터프라이즈는 어떤 기능이 포함되나요?",
+ a: "조직/권한 관리, 보안 옵션, 전용 지원 등 규모에 맞춘 기능을 제공합니다.",
+ },
+ {
+ q: "데모를 받을 수 있나요?",
+ a: "네. 엔터프라이즈 문의를 통해 데모 일정을 조율할 수 있습니다.",
+ },
+];
+
+export default function LandingFAQ() {
+ return (
+
+
+
+
+
+
+
+ {FAQ_ITEMS.map(({ q, a }) => (
+
+
+ {q}
+
+
+
+
+
+
+ {a}
+
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/components/landing/LandingFeatures.tsx b/src/components/landing/LandingFeatures.tsx
new file mode 100644
index 00000000..b4dcfee9
--- /dev/null
+++ b/src/components/landing/LandingFeatures.tsx
@@ -0,0 +1,256 @@
+import type { ReactNode } from "react";
+import { useEffect, useRef, useState } from "react";
+import { motion, useInView } from "framer-motion";
+
+import LandingSectionHeader from "@/components/landing/LandingSectionHeader";
+
+import SparkleIcon from "@/assets/icon/ai/sparkle.svg?react";
+import ChevronRight from "@/assets/icon/chevron/chevron-right.svg?react";
+import ChevronUp from "@/assets/icon/chevron/chevron-up.svg?react";
+import UserIcon from "@/assets/icon/common/user.svg?react";
+import GoogleAdsLogo from "@/assets/logo/social-logo/circle/googleAds-circle.svg?react";
+import KakaoLogo from "@/assets/logo/social-logo/circle/kakao-circle.svg?react";
+import NaverLogo from "@/assets/logo/social-logo/circle/naver-circle.svg?react";
+
+type TFeatureCardProps = {
+ delay: number;
+ title: string;
+ description: string;
+ Graphic: () => ReactNode;
+};
+
+function IntegrationGraphic() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Google Ads
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+function WorkflowGraphic() {
+ return (
+
+
+
+
+ AI로 요약하기
+
+
+
+
+ 다운로드
+
+
+ );
+}
+
+function WorkspaceGraphic() {
+ const fullText = "WhereYouAd@email.com";
+ const [typedText, setTypedText] = useState("");
+ const [showCursor, setShowCursor] = useState(false);
+ const containerRef = useRef(null);
+ const isInView = useInView(containerRef, { once: true, amount: 0.45 });
+
+ useEffect(() => {
+ if (!isInView) return;
+
+ setShowCursor(true);
+ let index = 0;
+ const timer = setInterval(() => {
+ index += 1;
+ setTypedText(fullText.slice(0, index));
+ if (index >= fullText.length) {
+ clearInterval(timer);
+ setShowCursor(false);
+ }
+ }, 40);
+
+ return () => clearInterval(timer);
+ }, [isInView]);
+
+ return (
+
+
+
+
+
+
+
+ You
+
+ Team JSON
+
+
+
+ 새로운 멤버를 초대하세요!
+
+
+
+
+
+
+ {typedText}
+
+ {showCursor && (
+
|
+ )}
+
+
+
+
+
+ );
+}
+
+export default function LandingFeatures() {
+ const featureCards: Omit[] = [
+ {
+ title: "광고 매체 연동",
+ description:
+ "클릭 한 번으로 모든 광고 매체와 마테크 서비스의 데이터를 간편하게 연동하세요.",
+ Graphic: IntegrationGraphic,
+ },
+ {
+ title: "AI 기반 워크플로우 제안",
+ description:
+ "데이터를 바탕으로 최적의 다음 액션과 워크플로우를 자동으로 제안받으세요.",
+ Graphic: WorkflowGraphic,
+ },
+ {
+ title: "조직을 이어주는 워크스페이스",
+ description:
+ "에이전시 및 팀원들과 캠페인 맥락을 잃지 않고 한 곳에서 효율적으로 소통하세요.",
+ Graphic: WorkspaceGraphic,
+ },
+ ];
+
+ return (
+
+
+
+
+
+
+
+ {featureCards.map(({ title, description, Graphic }, idx) => (
+
+
+
+
+
+ {title}
+
+
+ {description}
+
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/components/landing/LandingFooter.tsx b/src/components/landing/LandingFooter.tsx
new file mode 100644
index 00000000..8de23428
--- /dev/null
+++ b/src/components/landing/LandingFooter.tsx
@@ -0,0 +1,44 @@
+export default function LandingFooter() {
+ return (
+
+
+
+
+
+ © 2026 WhereYouAd. All rights reserved.
+
+
+
+
+ );
+}
diff --git a/src/components/landing/LandingGuide.tsx b/src/components/landing/LandingGuide.tsx
new file mode 100644
index 00000000..47ee5a9b
--- /dev/null
+++ b/src/components/landing/LandingGuide.tsx
@@ -0,0 +1,218 @@
+import { motion } from "framer-motion";
+
+import GuideOverviewChart from "@/components/landing/GuideOverviewChart";
+import GuidePlatform from "@/components/landing/GuidePlatform";
+import GuideTimeline from "@/components/landing/GuideTimeline";
+import LandingSectionHeader from "@/components/landing/LandingSectionHeader";
+
+import TimelineDashboard from "@/assets/mockup/optimized/timeline_dashboard.jpg";
+
+type TGuideStep = { step: number; title: string; text: string };
+
+type TGuidePage = {
+ number: string;
+ label: string;
+ title: string;
+ description: string;
+ steps: TGuideStep[];
+ image?: string;
+ alt?: string;
+ reverse: boolean;
+ useOverview?: boolean;
+ useTimeline?: boolean;
+ usePlatform?: boolean;
+};
+
+const pages: TGuidePage[] = [
+ {
+ number: "01",
+ label: "통합 대시보드",
+ title: "광고 현황을 한눈에 파악하세요",
+ description: `주요 KPI부터 채널별 성과, 실시간 알림까지
+모든 정보를 하나의 화면에서 확인할 수 있습니다.`,
+ steps: [
+ {
+ step: 1,
+ title: "핵심 지표를 즉시 확인",
+ text: "상단 요약 카드에서 노출수·클릭수·전환율 등 핵심 KPI를 빠르게 확인합니다.",
+ },
+ {
+ step: 2,
+ title: "채널별 효율 비교",
+ text: "채널별 성과 차트로 매체 간 효율을 비교하고 예산 재배분을 결정합니다.",
+ },
+ ],
+ useOverview: true,
+ reverse: false,
+ },
+ {
+ number: "02",
+ label: "매체 통합 관리",
+ title: "플랫폼별 캠페인을 한 곳에서 관리하세요",
+ description: `다수의 광고 매체를 별도 로그인 없이 통합 관리하고
+캠페인 설정부터 소재 심사까지 원스톱으로 처리합니다.`,
+ steps: [
+ {
+ step: 1,
+ title: "플랫폼 선택 후 현황 조회",
+ text: "매체사 목록에서 플랫폼을 선택해 캠페인 전체 현황을 확인합니다.",
+ },
+ {
+ step: 2,
+ title: "인라인으로 빠르게 편집",
+ text: "예산·기간·타겟 설정을 인라인 편집으로 빠르게 수정하고 저장합니다.",
+ },
+ ],
+ usePlatform: true,
+ reverse: true,
+ },
+ {
+ number: "03",
+ label: "일정 관리 타임라인",
+ title: "타임라인으로 캠페인 일정을 계획하세요",
+ description: `간트 차트 방식으로 전체 캠페인 기간을 시각화하고
+기간별 성과를 비교합니다.`,
+ steps: [
+ {
+ step: 1,
+ title: "캠페인을 한눈에 파악",
+ text: "타임라인 뷰에서 캠페인 일정을 주·월 단위로 한눈에 확인합니다.",
+ },
+ {
+ step: 2,
+ title: "기간별 성과 세부 확인",
+ text: "타임라인 바를 클릭하면 해당 기간의 클릭수, 전환 등 세부 성과 지표를 확인할 수 있습니다.",
+ },
+ ],
+ image: TimelineDashboard,
+ alt: "Timeline 대시보드 화면",
+ useTimeline: true,
+ reverse: false,
+ },
+];
+
+export default function LandingGuide() {
+ return (
+
+
+
+
+
+
+
+
+ {pages.map((page) => (
+
+
+ {page.useOverview ? (
+
+
+
+ ) : page.useTimeline ? (
+
+
+
+ ) : page.usePlatform ? (
+
+
+
+ ) : (
+
+ )}
+
+
+
+
+
+ {page.number}
+
+
+ {page.label}
+
+
+
+
+ {page.title}
+
+
+
+ {page.description}
+
+
+
+ {page.steps.map((item) => (
+
+
+
+ {item.title}
+
+
+
+ {item.text}
+
+
+ ))}
+
+
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/components/landing/LandingHeader.tsx b/src/components/landing/LandingHeader.tsx
new file mode 100644
index 00000000..5a1d5008
--- /dev/null
+++ b/src/components/landing/LandingHeader.tsx
@@ -0,0 +1,88 @@
+import { useEffect, useState } from "react";
+import { Link } from "react-router-dom";
+
+import logoSvg from "@/assets/logo/service-logo/logo.svg";
+
+const navItems = [
+ { label: "기능", targetId: "features" },
+ { label: "이용방법", targetId: "guide" },
+ { label: "요금제", targetId: "pricing" },
+];
+
+function scrollToSection(id: string) {
+ document.getElementById(id)?.scrollIntoView({ behavior: "smooth" });
+}
+
+export default function LandingHeader() {
+ const [isScrolled, setIsScrolled] = useState(false);
+
+ useEffect(() => {
+ let rafId: number | null = null;
+
+ function update() {
+ rafId = null;
+ const next = window.scrollY > 8;
+ setIsScrolled((prev) => (prev === next ? prev : next));
+ }
+
+ function onScroll() {
+ if (rafId != null) return;
+ rafId = window.requestAnimationFrame(update);
+ }
+
+ update();
+ window.addEventListener("scroll", onScroll, { passive: true });
+ return () => {
+ if (rafId != null) window.cancelAnimationFrame(rafId);
+ window.removeEventListener("scroll", onScroll);
+ };
+ }, []);
+
+ return (
+
+
+
+
+
+
+
+
+ {navItems.map(({ label, targetId }) => (
+ scrollToSection(targetId)}
+ className="text-[15px] font-medium text-text-sub hover:text-text-main transition-colors rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-logo-2/35 focus-visible:ring-offset-2 focus-visible:ring-offset-white"
+ >
+ {label}
+
+ ))}
+
+
+
+
+ 로그인
+
+
+ 회원가입
+
+
+
+ );
+}
diff --git a/src/components/landing/LandingHero.tsx b/src/components/landing/LandingHero.tsx
new file mode 100644
index 00000000..ebfc59e2
--- /dev/null
+++ b/src/components/landing/LandingHero.tsx
@@ -0,0 +1,60 @@
+import { motion } from "framer-motion";
+
+import ChevronDown from "@/assets/icon/chevron/chevron-down.svg?react";
+import MockupTestImage from "@/assets/mockup/optimized/mockup_test.jpg";
+
+export default function LandingHero() {
+ return (
+
+
+
+
+
+
+ WhereYouAd
+
+
+ 광고 통합 대시보드
+
+
+
+ 광고 성과를 실시간으로{"\n"}한 화면에서 관리하세요
+
+
+ Google·Meta 파트너 서비스로 광고 데이터를 한 곳에서 관리하세요.
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/landing/LandingMultiDevice.tsx b/src/components/landing/LandingMultiDevice.tsx
new file mode 100644
index 00000000..e2bd4f43
--- /dev/null
+++ b/src/components/landing/LandingMultiDevice.tsx
@@ -0,0 +1,62 @@
+import IosAppDockImage from "@/assets/mockup/iOS app dock.png";
+import IpadMockupImage from "@/assets/mockup/iPad Air mockup.png";
+import LaptopMockupImage from "@/assets/mockup/laptop_mockup.png";
+
+export default function LandingMultiDevice() {
+ return (
+
+
+
+
Multi-device support
+
+ 모바일·태블릿·데스크탑에서 모두 사용 가능
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/landing/LandingPricing.tsx b/src/components/landing/LandingPricing.tsx
new file mode 100644
index 00000000..9d62d2c2
--- /dev/null
+++ b/src/components/landing/LandingPricing.tsx
@@ -0,0 +1,233 @@
+import { useNavigate } from "react-router-dom";
+import { motion } from "framer-motion";
+
+import LandingSectionHeader from "@/components/landing/LandingSectionHeader";
+
+type TFeature = { text: string; enabled: boolean };
+
+type TPlan = {
+ name: string;
+ target: string;
+ price: string;
+ priceUnit?: string;
+ priceSubText?: string;
+ buttonText: string;
+ featured: boolean;
+ assurance: string;
+ features: TFeature[];
+};
+
+const plans: TPlan[] = [
+ {
+ name: "프리",
+ target: "서비스를 처음 체험하는 누구나",
+ price: "무료",
+ buttonText: "무료로 시작하기",
+ featured: false,
+ assurance: "카드 불필요",
+ features: [
+ { text: "광고 매체 연동 최대 3개", enabled: true },
+ { text: "멤버 1명", enabled: true },
+ { text: "단일 워크스페이스", enabled: true },
+ { text: "AI 성과 리포트", enabled: false },
+ { text: "분석보고서 이메일 전송", enabled: false },
+ ],
+ },
+ {
+ name: "스타터",
+ target: "1인 창업자",
+ price: "₩30,000",
+ priceUnit: "/월",
+ priceSubText: "(부가세 별도)",
+ buttonText: "시작하기",
+ featured: false,
+ assurance: "카드 필요",
+ features: [
+ { text: "광고 매체 연동 최대 10개", enabled: true },
+ { text: "멤버 1명", enabled: true },
+ { text: "워크스페이스 최대 5개", enabled: true },
+ { text: "AI 요약 기능", enabled: true },
+ { text: "분석보고서 이메일 전송", enabled: false },
+ ],
+ },
+ {
+ name: "팀",
+ target: "소규모 팀 (2~10인)",
+ price: "₩150,000",
+ priceUnit: "/월",
+ priceSubText: "(부가세 별도)",
+ buttonText: "14일 무료 체험하기",
+ featured: true,
+ assurance: "무료 체험 가능 · 카드 필요",
+ features: [
+ { text: "광고 매체 연동 최대 30개", enabled: true },
+ { text: "멤버 최대 10명", enabled: true },
+ { text: "워크스페이스 최대 10개", enabled: true },
+ { text: "AI 요약 기능", enabled: true },
+ { text: "분석보고서 이메일 전송", enabled: true },
+ ],
+ },
+ {
+ name: "프로",
+ target: "성장 기업 및 에이전시",
+ price: "₩500,000",
+ priceUnit: "/월",
+ priceSubText: "(부가세 별도)",
+ buttonText: "영업팀에 문의",
+ featured: false,
+ assurance: "맞춤 견적 · 데모 제공",
+ features: [
+ { text: "광고 매체 연동 무제한", enabled: true },
+ { text: "멤버 무제한", enabled: true },
+ { text: "워크스페이스 무제한", enabled: true },
+ { text: "광고 성과 변화 알림 및 실시간 대응", enabled: true },
+ { text: "전담 어카운트 매니저(AM)", enabled: true },
+ ],
+ },
+];
+
+function CheckIcon({ enabled }: { enabled: boolean }) {
+ return (
+
+
+
+ );
+}
+
+export default function LandingPricing() {
+ const navigate = useNavigate();
+
+ function handleCta(planName: string) {
+ if (planName === "프로") {
+ const subject = encodeURIComponent("WhereYouAd 요금제 문의");
+ const body = encodeURIComponent("문의하실 내용을 입력해 주세요.");
+ window.location.href = `mailto:whereyouadofficial@gmail.com?subject=${subject}&body=${body}`;
+ return;
+ }
+
+ navigate("/signup", { replace: false });
+ }
+
+ return (
+
+
+
+
+
+
+
+
+ {plans.map((plan, i) => (
+
+ {plan.featured && (
+
+ 가장 인기
+
+ )}
+
+
+ {plan.name}
+
+
+ {plan.target}
+
+
+
+
+
+ {plan.price}
+
+ {plan.priceUnit && (
+
+ {plan.priceUnit}
+
+ )}
+
+ {plan.priceUnit && plan.priceSubText && (
+
+ {plan.priceSubText}
+
+ )}
+
+
+ handleCta(plan.name)}
+ className={`w-full h-12 rounded-component-md font-semibold transition-colors mb-4 ${
+ plan.featured
+ ? "bg-logo-2 text-white hover:bg-logo-2-dark shadow-[0_10px_24px_rgba(96,136,254,0.28)]"
+ : "bg-white border border-chart-inactive/70 text-text-main hover:bg-brand-300"
+ } focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-logo-2/35 focus-visible:ring-offset-2 focus-visible:ring-offset-white`}
+ >
+ {plan.buttonText}
+
+
+ {plan.assurance}
+
+
+
+
+ {plan.features.map((feature) => (
+
+
+
+ {feature.text}
+
+
+ ))}
+
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/components/landing/LandingSectionHeader.tsx b/src/components/landing/LandingSectionHeader.tsx
new file mode 100644
index 00000000..1c3354fa
--- /dev/null
+++ b/src/components/landing/LandingSectionHeader.tsx
@@ -0,0 +1,28 @@
+type TAlign = "left" | "center";
+
+export default function LandingSectionHeader({
+ title,
+ subtitle,
+ align = "center",
+ className = "",
+}: {
+ title: string;
+ subtitle?: string;
+ align?: TAlign;
+ className?: string;
+}) {
+ const alignClass = align === "left" ? "text-left" : "text-center";
+
+ return (
+
+
+ {title}
+
+ {subtitle && (
+
+ {subtitle}
+
+ )}
+
+ );
+}
diff --git a/src/components/modal/ModalProvider.tsx b/src/components/modal/ModalProvider.tsx
new file mode 100644
index 00000000..7783cd5b
--- /dev/null
+++ b/src/components/modal/ModalProvider.tsx
@@ -0,0 +1,38 @@
+import { useEffect } from "react";
+import { useLocation } from "react-router-dom";
+
+import PrivacyModal from "./privacyModal/PrivacyModal";
+
+import useModalStore, {
+ MODAL_TYPES,
+ type TGlobalModalProps,
+} from "@/store/useModalStore";
+
+function ModalProvider() {
+ const { modalType, closeModal, modalProps } = useModalStore();
+ const location = useLocation();
+
+ useEffect(() => {
+ closeModal();
+ }, [location.pathname, closeModal]);
+
+ if (!modalType) {
+ return null;
+ }
+
+ switch (modalType) {
+ case MODAL_TYPES.PRIVACY: {
+ const props = modalProps as TGlobalModalProps[typeof MODAL_TYPES.PRIVACY];
+ return ;
+ }
+
+ default: {
+ if (import.meta.env.DEV) {
+ console.warn(`Modal component not found for type: ${modalType}`);
+ }
+ return null;
+ }
+ }
+}
+
+export default ModalProvider;
diff --git a/src/components/modal/privacyModal/AgreementItem.tsx b/src/components/modal/privacyModal/AgreementItem.tsx
new file mode 100644
index 00000000..c16ad4aa
--- /dev/null
+++ b/src/components/modal/privacyModal/AgreementItem.tsx
@@ -0,0 +1,100 @@
+import ReactMarkdown, { type Components } from "react-markdown";
+
+type TAgreementItemProps = {
+ label: string;
+ required?: boolean;
+ checked: boolean;
+ expanded: boolean;
+ onToggleCheck: () => void;
+ onToggleExpand: () => void;
+ content: string;
+};
+
+const markdownComponents: Components = {
+ h2: ({ ...props }) => (
+
+ ),
+ h3: ({ ...props }) => (
+
+ ),
+ p: ({ ...props }) => (
+
+ ),
+ ul: ({ ...props }) => (
+
+ ),
+ ol: ({ ...props }) => (
+
+ ),
+ li: ({ ...props }) => (
+
+ ),
+};
+
+export default function AgreementItem({
+ label,
+ required,
+ checked,
+ expanded,
+ onToggleCheck,
+ onToggleExpand,
+ content,
+}: TAgreementItemProps) {
+ return (
+
+
+
{
+ if (e.key === "Enter" || e.key === " ") {
+ e.preventDefault();
+ onToggleCheck();
+ }
+ }}
+ >
+
+
+ {label}
+
+ ({required ? "필수" : "선택"})
+
+
+
+
+ {expanded ? "접기" : "보기"}
+
+
+
+ {expanded && (
+
+
+ {content}
+
+
+ )}
+
+ );
+}
diff --git a/src/components/modal/privacyModal/PrivacyModal.tsx b/src/components/modal/privacyModal/PrivacyModal.tsx
new file mode 100644
index 00000000..c6a44b7e
--- /dev/null
+++ b/src/components/modal/privacyModal/PrivacyModal.tsx
@@ -0,0 +1,129 @@
+import { useState } from "react";
+
+import Button from "@/components/common/button/Button";
+import Modal from "@/components/common/modal/Modal";
+
+import AgreementItem from "./AgreementItem";
+
+import marketingContent from "@/assets/docs/marketing-agreement.md?raw";
+import privacyContent from "@/assets/docs/privacy-collection.md?raw";
+
+type TAgreementType = "privacy" | "marketing";
+
+type TPrivacyModalProps = {
+ onClose: () => void;
+ onAgree?: (agreements: { privacy: boolean; marketing: boolean }) => void;
+ initialState?: { privacy: boolean; marketing: boolean };
+};
+
+export default function PrivacyModal({
+ onClose,
+ onAgree,
+ initialState,
+}: TPrivacyModalProps) {
+ const [agreements, setAgreements] = useState({
+ privacy: initialState?.privacy ?? false,
+ marketing: initialState?.marketing ?? false,
+ });
+
+ const [expanded, setExpanded] = useState>({
+ privacy: false,
+ marketing: false,
+ });
+
+ const toggleAgreement = (key: TAgreementType) => {
+ setAgreements((prev) => ({ ...prev, [key]: !prev[key] }));
+ };
+
+ const toggleExpand = (key: TAgreementType) => {
+ setExpanded((prev) => ({ ...prev, [key]: !prev[key] }));
+ };
+
+ const handleAllAgree = () => {
+ const allChecked = Object.values(agreements).every(Boolean);
+ const newState = !allChecked;
+ setAgreements({
+ privacy: newState,
+ marketing: newState,
+ });
+ };
+
+ const handleConfirm = () => {
+ if (!agreements.privacy) {
+ return;
+ }
+ if (onAgree) {
+ onAgree(agreements);
+ }
+ onClose();
+ };
+
+ const isAllChecked = Object.values(agreements).every(Boolean);
+
+ const isRequiredChecked = agreements.privacy;
+
+ return (
+
+
+
+
개인정보 수집 동의
+
+
+
+
+
+ 전체 동의하기
+
+
+
+
+
toggleAgreement("privacy")}
+ onToggleExpand={() => toggleExpand("privacy")}
+ content={privacyContent}
+ />
+ toggleAgreement("marketing")}
+ onToggleExpand={() => toggleExpand("marketing")}
+ content={marketingContent}
+ />
+
+
+
+
+ 동의하고 계속하기
+
+
+
+
+ );
+}
diff --git a/src/components/sidebar/Sidebar.tsx b/src/components/sidebar/Sidebar.tsx
new file mode 100644
index 00000000..71fba21e
--- /dev/null
+++ b/src/components/sidebar/Sidebar.tsx
@@ -0,0 +1,200 @@
+import type { Dispatch, FocusEvent, SetStateAction } from "react";
+import { AnimatePresence, motion } from "framer-motion";
+import { twMerge } from "tailwind-merge";
+
+import { footerNav, mainNav } from "@/constants/sidebarNav";
+
+import { mainNavSidebar } from "@/utils/navigation/mainNavSidebar";
+import { isPathMatch } from "@/utils/navigation/pathMatch";
+
+import { useSidebar } from "@/hooks/sidebar/useSidebar";
+
+import { SidebarItem } from "./SidebarItem";
+import { SubMenu } from "./SubMenu";
+import { WorkspaceSwitcher } from "./WorkspaceSwitcher";
+
+import CollapseIcon from "@/assets/icon/chevron/chervon-left.svg?react";
+import ChevronIcon from "@/assets/icon/chevron/chevron-up.svg?react";
+
+function getMainItemClass(isActive: boolean, isCollapsed: boolean) {
+ return twMerge(
+ "flex items-center rounded-component-md px-3 text-sm cursor-pointer transition-colors duration-200",
+ isCollapsed
+ ? "h-[55px] w-[55px] mx-auto flex justify-center"
+ : "h-[55px] gap-4 px-3",
+ isActive
+ ? "bg-chart-3 text-white"
+ : "text-text-auth-sub hover:bg-bg-surface",
+ );
+}
+
+function getFooterItemClass(isActive: boolean, isCollapsed: boolean) {
+ return twMerge(
+ "flex w-full h-[55px] items-center rounded-component-md px-3 text-sm cursor-pointer transition-all duration-200",
+ isCollapsed ? "justify-center px-0" : "gap-4 px-3",
+ isActive ? "text-chart-3" : "text-text-auth-sub hover:text-chart-3",
+ );
+}
+
+function collapsedSubmenuInteractionProps(
+ enabled: boolean,
+ itemId: string,
+ setOpenId: Dispatch>,
+) {
+ if (!enabled) return {};
+ return {
+ onMouseEnter: () => setOpenId(itemId),
+ onMouseLeave: () => setOpenId(null),
+ onFocusCapture: () => setOpenId(itemId),
+ onBlurCapture: (e: FocusEvent) => {
+ if (e.currentTarget.contains(e.relatedTarget as Node | null)) return;
+ setOpenId(null);
+ },
+ };
+}
+
+export default function Sidebar() {
+ const {
+ isCollapsed,
+ openId,
+ setOpenId,
+ handleItemClick,
+ pathname,
+ toggleSidebar,
+ toggleOpenId,
+ } = useSidebar();
+
+ return (
+
+
+
+
+
+
+
+ {mainNav.map((item) => {
+ const isOpen = openId === item.id;
+ const { isParentActive } = mainNavSidebar.getItemActiveState(
+ pathname,
+ item,
+ );
+
+ const showChevron =
+ !isCollapsed &&
+ !!item.children?.length &&
+ (isOpen || isParentActive);
+
+ return (
+
+
+
+ {showChevron && (
+ {
+ e.stopPropagation();
+ e.preventDefault();
+ toggleOpenId(item.id);
+ }}
+ className="ml-auto p-2 hover:bg-black/5 rounded-lg transition-colors"
+ >
+
+
+ )}
+
+
+
+ {isOpen && item.children ? (
+
+ ) : null}
+
+
+ );
+ })}
+
+
+
+ {footerNav.map((item) => {
+ const isActive =
+ item.path != null ? isPathMatch(pathname, item.path) : false;
+
+ return (
+
+
+
+ );
+ })}
+
+
+
+
+
+ {isCollapsed ? "사이드바 펼치기" : "사이드바 접기"}
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/sidebar/SidebarItem.tsx b/src/components/sidebar/SidebarItem.tsx
new file mode 100644
index 00000000..a416b570
--- /dev/null
+++ b/src/components/sidebar/SidebarItem.tsx
@@ -0,0 +1,77 @@
+import { memo } from "react";
+import { NavLink } from "react-router-dom";
+import { twMerge } from "tailwind-merge";
+
+import type { INavItem } from "@/types/navigation/navItem";
+
+interface ISidebarItemProps {
+ item: INavItem;
+ isCollapsed: boolean;
+ isOpen?: boolean;
+ className: string;
+ onClick: (id: string, hasChildren: boolean) => void;
+}
+
+export const SidebarItem = memo(function SidebarItem({
+ item,
+ isCollapsed,
+ isOpen,
+ className,
+ onClick,
+}: ISidebarItemProps) {
+ const hasChildren = !!item.children?.length;
+ const Icon = item.icon;
+
+ const content = (
+
+ {Icon && (
+
+ )}
+
+ {item.label}
+
+
+ );
+
+ if (item.path) {
+ return (
+ {
+ if (e.defaultPrevented) return;
+ onClick(item.id, hasChildren);
+ }}
+ >
+ {content}
+
+ );
+ }
+
+ return (
+ {
+ if (e.defaultPrevented) return;
+ onClick(item.id, hasChildren);
+ }}
+ >
+ {content}
+
+ );
+});
diff --git a/src/components/sidebar/SubMenu.tsx b/src/components/sidebar/SubMenu.tsx
new file mode 100644
index 00000000..dc507943
--- /dev/null
+++ b/src/components/sidebar/SubMenu.tsx
@@ -0,0 +1,80 @@
+import { NavLink } from "react-router-dom";
+import { motion } from "framer-motion";
+import { twMerge } from "tailwind-merge";
+
+import type { INavItem } from "@/types/navigation/navItem";
+
+interface ISubMenuProps {
+ items: INavItem[];
+ isCollapsed: boolean;
+ parentLabel?: string;
+}
+
+export function SubMenu({ items, isCollapsed, parentLabel }: ISubMenuProps) {
+ const getSubItemClass = (isActive: boolean) =>
+ twMerge(
+ "flex items-center rounded-component-md px-3 text-sm transition-all duration-200 whitespace-nowrap",
+ isCollapsed ? "h-auto py-2.5" : "h-10 pl-4",
+ isActive
+ ? "bg-chart-3 text-white"
+ : "text-text-auth-sub hover:bg-bg-surface",
+ );
+
+ const menuContainerClass = isCollapsed
+ ? "absolute left-full top-0 pl-2 w-52 flex flex-col gap-1 rounded-component-md bg-white p-2 shadow-Soft z-50 whitespace-nowrap"
+ : "ml-11 mt-1 flex flex-col gap-1 overflow-hidden";
+
+ const expandedMaxHeight = Math.min(640, Math.max(160, items.length * 44 + 8));
+
+ return (
+
+ {items.map((child) => (
+ getSubItemClass(isActive)}
+ >
+ {isCollapsed && parentLabel ? (
+
+
+ {parentLabel}
+
+
+ {child.label}
+
+
+ ) : (
+ child.label
+ )}
+
+ ))}
+
+ );
+}
diff --git a/src/components/sidebar/WorkspaceSwitcher.tsx b/src/components/sidebar/WorkspaceSwitcher.tsx
new file mode 100644
index 00000000..c0fbe1a3
--- /dev/null
+++ b/src/components/sidebar/WorkspaceSwitcher.tsx
@@ -0,0 +1,288 @@
+import { useCallback, useEffect, useMemo, useRef, useState } from "react";
+import { useNavigate } from "react-router-dom";
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+import { AnimatePresence, motion } from "framer-motion";
+import { toast } from "sonner";
+import { twMerge } from "tailwind-merge";
+
+import type { TWorkspace } from "@/types/workspace/workspace";
+
+import { useCoreQuery } from "@/hooks/customQuery";
+
+import { getMyWorkspaces, saveSelectedWorkspace } from "@/api/workspace/org";
+import ChevronIcon from "@/assets/icon/chevron/chevron-up.svg?react";
+import useWorkspaceStore from "@/store/useWorkspaceStore";
+
+export function WorkspaceSwitcher({
+ isCollapsed,
+ className,
+}: {
+ isCollapsed: boolean;
+ className?: string;
+}) {
+ const navigate = useNavigate();
+ const [isOpen, setIsOpen] = useState(false);
+ const rootRef = useRef(null);
+ const queryClient = useQueryClient();
+
+ const selectedOrgId = useWorkspaceStore((s) => s.selectedOrgId);
+ const setSelectedOrgId = useWorkspaceStore((s) => s.setSelectedOrgId);
+
+ const { data: workspaces, isPending } = useCoreQuery(
+ ["my-workspaces"],
+ getMyWorkspaces,
+ );
+
+ const workspaceList = workspaces ?? [];
+
+ const currentWorkspace = useMemo(
+ () =>
+ workspaceList.find((w) => w.orgId === selectedOrgId) ||
+ workspaceList.find((w) => w.isCurrentWorkspace) ||
+ workspaceList[0],
+ [selectedOrgId, workspaceList],
+ );
+
+ useEffect(() => {
+ if (selectedOrgId === null || workspaceList.length === 0) return;
+
+ const exists = workspaceList.some((w) => w.orgId === selectedOrgId);
+ if (exists) return;
+
+ const fallback =
+ workspaceList.find((w) => w.isCurrentWorkspace) || workspaceList[0];
+ setSelectedOrgId(fallback.orgId);
+ }, [selectedOrgId, workspaceList, setSelectedOrgId]);
+
+ const { mutate: saveWorkspace } = useMutation({
+ mutationFn: (orgId: number) => saveSelectedWorkspace(orgId),
+ onSuccess: async (_data, orgId) => {
+ setSelectedOrgId(orgId);
+ setIsOpen(false);
+ await Promise.all([
+ queryClient.invalidateQueries({ queryKey: ["my-workspaces"] }),
+ queryClient.invalidateQueries({ queryKey: ["savedWorkspace"] }),
+ ]);
+ },
+ onError: (error) => {
+ console.error("워크스페이스 저장 실패:", error);
+ toast.error("워크스페이스 변경에 실패했습니다. 다시 시도해 주세요.");
+ },
+ });
+
+ useEffect(() => {
+ if (isCollapsed) {
+ setIsOpen(false);
+ }
+ }, [isCollapsed]);
+
+ useEffect(() => {
+ if (!isOpen) return;
+
+ const onPointerDown = (e: MouseEvent | TouchEvent) => {
+ const root = rootRef.current;
+ if (!root) return;
+ if (!root.contains(e.target as Node)) setIsOpen(false);
+ };
+
+ const onKeyDown = (e: KeyboardEvent) => {
+ if (e.key === "Escape") setIsOpen(false);
+ };
+
+ window.addEventListener("mousedown", onPointerDown);
+ window.addEventListener("touchstart", onPointerDown, { passive: true });
+ window.addEventListener("keydown", onKeyDown);
+
+ return () => {
+ window.removeEventListener("mousedown", onPointerDown);
+ window.removeEventListener("touchstart", onPointerDown);
+ window.removeEventListener("keydown", onKeyDown);
+ };
+ }, [isOpen]);
+
+ const currentWorkspaceId = currentWorkspace?.orgId;
+ const otherWorkspaces = useMemo(
+ () =>
+ currentWorkspaceId
+ ? workspaceList.filter((w) => w.orgId !== currentWorkspaceId)
+ : [],
+ [currentWorkspaceId, workspaceList],
+ );
+
+ const renderImage = useCallback(
+ (workspace: TWorkspace) => (
+
+ {workspace?.logoUrl ? (
+
+ ) : (
+ workspace?.name?.[0] || "W"
+ )}
+
+ ),
+ [],
+ );
+
+ const switcherShellClass = twMerge(
+ "flex items-center rounded-component-md",
+ isCollapsed
+ ? "h-[55px] w-[55px] justify-center py-1.5 px-2 mx-auto"
+ : "w-full py-1.5 px-2 gap-3",
+ );
+
+ if (isPending) {
+ return (
+
+
+
+ {!isCollapsed && (
+
+ )}
+
+
+ );
+ }
+
+ if (!currentWorkspace) {
+ return (
+
+
+
+ —
+
+ {!isCollapsed && (
+
+
+ 워크스페이스 없음
+
+
+ {"\u00A0"}
+
+
+ )}
+
+
+ );
+ }
+
+ return (
+
+
setIsOpen(!isOpen)}
+ className={twMerge(
+ switcherShellClass,
+ "transition-colors hover:bg-bg-surface",
+ )}
+ >
+ {renderImage(currentWorkspace)}
+
+ {!isCollapsed && (
+ <>
+
+
+ {currentWorkspace?.name || "워크스페이스 선택"}
+
+
+ {currentWorkspace?.myRole === "ADMIN" ? "관리자" : "멤버"}
+
+
+
+ >
+ )}
+
+
+
+ {isOpen ? (
+
+
+ {otherWorkspaces.map((org, index) => (
+
+ {index !== 0 && (
+
+ )}
+
{
+ saveWorkspace(org.orgId);
+ }}
+ className="group flex w-full items-center gap-3 rounded-component-md px-2 py-1.5 text-sm text-text-main hover:bg-bg-surface transition-colors"
+ >
+ {renderImage(org)}
+
+
+ {org.name}
+
+
+ {org.myRole === "ADMIN" ? "관리자" : "멤버"}
+
+
+
+
+ ))}
+
+
+
+
{
+ setIsOpen(false);
+ navigate("/workspace");
+ }}
+ className="flex w-full items-center gap-3 rounded-component-md px-2 py-1.5 text-sm text-text-sub hover:bg-bg-surface transition-colors"
+ >
+
+ +
+
+
+ 새 워크스페이스
+
+
+
+
+ ) : null}
+
+
+ );
+}
diff --git a/src/components/workspace/DeleteMemberModal.tsx b/src/components/workspace/DeleteMemberModal.tsx
new file mode 100644
index 00000000..cf74fb7d
--- /dev/null
+++ b/src/components/workspace/DeleteMemberModal.tsx
@@ -0,0 +1,64 @@
+import type { TWorkspaceMember } from "@/types/workspace/workspace";
+
+import Button from "../common/button/Button";
+import Modal from "../common/modal/Modal";
+
+import WarnIcon from "@/assets/icon/common/warn-circle.svg?react";
+
+type TDeleteMemberModalProps = {
+ isOpen: boolean;
+ onClose: () => void;
+ member: TWorkspaceMember | null;
+ onConfirm: (member: TWorkspaceMember) => void;
+ isLoading?: boolean;
+};
+
+export default function DeleteMemberModal({
+ isOpen,
+ onClose,
+ member,
+ onConfirm,
+ isLoading = false,
+}: TDeleteMemberModalProps) {
+ const handleConfirm = () => {
+ if (!member || isLoading) return;
+ onConfirm(member);
+ };
+ return (
+
+
+
+
+
+
+ 팀원을 삭제하시겠습니까?
+
+
+ {member
+ ? `${member.name}님을 팀에서 삭제합니다`
+ : "선택한 팀원을 삭제합니다"}
+ 이 작업은 되돌릴 수 없습니다.
+
+
+
+ {isLoading ? "삭제 중.." : "삭제하기"}
+
+
+
+
+ );
+}
diff --git a/src/components/workspace/InviteMemberModal.tsx b/src/components/workspace/InviteMemberModal.tsx
new file mode 100644
index 00000000..46fac710
--- /dev/null
+++ b/src/components/workspace/InviteMemberModal.tsx
@@ -0,0 +1,219 @@
+import { useMemo, useState } from "react";
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+import { toast } from "sonner";
+
+import type { IApiErrorResponse } from "@/types/common/common";
+import type {
+ TInviteMemberItem,
+ TInviteMemberRequest,
+} from "@/types/workspace/workspace";
+
+import { emailSchema } from "@/utils/validation";
+
+import Badge from "../common/badge/Badge";
+import Button from "../common/button/Button";
+import Input from "../common/input/Input";
+import Modal from "../common/modal/Modal";
+
+import { postInviteEmail } from "@/api/workspace/org";
+import CopyIcon from "@/assets/icon/common/link.svg?react";
+import UserIcon from "@/assets/icon/common/user.svg?react";
+
+type TInviteMemberModalProps = {
+ isOpen: boolean;
+ onClose: () => void;
+ orgId: number;
+ inviteItems: TInviteMemberItem[];
+};
+
+export default function InviteMemberModal({
+ isOpen,
+ onClose,
+ orgId,
+ inviteItems,
+}: TInviteMemberModalProps) {
+ const queryClient = useQueryClient();
+ const [form, setForm] = useState({ email: "" });
+ const trimmedEmail = form.email.trim();
+ const emailValidation = emailSchema.safeParse(trimmedEmail);
+ const isValidEmail = emailValidation.success;
+
+ const inviteMutation = useMutation<
+ unknown,
+ IApiErrorResponse,
+ TInviteMemberRequest
+ >({
+ mutationFn: (body) => postInviteEmail(orgId, body),
+ onSuccess: () => {
+ toast.success("초대 이메일을 발송했습니다");
+ setForm({ email: "" });
+
+ void queryClient.invalidateQueries({
+ queryKey: ["workspacePendingMembers", orgId],
+ });
+ void queryClient.invalidateQueries({
+ queryKey: ["workspaceMembers", orgId],
+ });
+ void queryClient.invalidateQueries({
+ queryKey: ["workspaceMemberCount", orgId],
+ });
+ },
+ onError: (error) => {
+ toast.error(error.message ?? "초대 이메일 발송에 실패했습니다.");
+ },
+ });
+
+ const isInviteDisabled = !isValidEmail || inviteMutation.isPending;
+
+ const inviteLink = useMemo(() => {
+ return `${window.location.origin}/workspace/${orgId}/invite`;
+ }, [orgId]);
+ const handleCopyLink = async () => {
+ try {
+ await navigator.clipboard.writeText(inviteLink);
+ toast.success("초대 링크가 복사되었습니다");
+ } catch (error) {
+ toast.error("초대 링크 복사에 실패했습니다. 다시 시도해주세요");
+ console.log("초대 링크 복사 실패:", error);
+ }
+ };
+ const handleChangeEmail = (value: string) => {
+ setForm({ email: value });
+ };
+
+ const handleInvite = async () => {
+ if (!emailValidation.success) {
+ toast.error(
+ emailValidation.error.issues[0]?.message ??
+ "올바른 이메일을 입력해주세요",
+ );
+ return;
+ }
+ try {
+ await inviteMutation.mutateAsync({
+ email: emailValidation.data,
+ });
+ } catch (error) {
+ console.error("초대 실패", error);
+ }
+ };
+ return (
+ {} : onClose}
+ size="lg"
+ padding="none"
+ title="팀원 초대하기"
+ className="w-full max-w-190 overflow-hidden"
+ >
+
+
+
팀원 초대하기
+
+
+ 링크 복사
+
+
+
+
+
+ handleChangeEmail(e.target.value)}
+ disabled={inviteMutation.isPending}
+ />
+
+
+ {inviteMutation.isPending ? "초대 중..." : "초대"}
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/workspace/MemberItem.tsx b/src/components/workspace/MemberItem.tsx
new file mode 100644
index 00000000..a494da76
--- /dev/null
+++ b/src/components/workspace/MemberItem.tsx
@@ -0,0 +1,72 @@
+import type {
+ TMemberRole,
+ TWorkspaceMember,
+} from "@/types/workspace/workspace";
+
+import MemberRoleSelect from "./MemberRoleSelect";
+
+import MailIcon from "@/assets/icon/common/mail.svg?react";
+import TrashIcon from "@/assets/icon/common/trash.svg?react";
+import UserIcon from "@/assets/icon/common/user.svg?react";
+
+type TProps = {
+ member: TWorkspaceMember;
+ onRoleChange: (newRole: TMemberRole) => void;
+ onDeleteClick: () => void;
+};
+
+export default function MemberItem({
+ member,
+ onRoleChange,
+ onDeleteClick,
+}: TProps) {
+ return (
+
+
+
+ {member.profileImageUrl ? (
+
+ ) : (
+
+ )}
+
+
+
+
+ {member.isMe ? (
+
+ {member.role === "ADMIN" ? "관리자" : "멤버"}
+
+ ) : (
+ <>
+
+
+
+
+ >
+ )}
+
+
+ );
+}
diff --git a/src/components/workspace/MemberList.tsx b/src/components/workspace/MemberList.tsx
new file mode 100644
index 00000000..0e389574
--- /dev/null
+++ b/src/components/workspace/MemberList.tsx
@@ -0,0 +1,125 @@
+import { type RefObject, useState } from "react";
+
+import type {
+ TInviteMemberItem,
+ TMemberRole,
+ TPendingMemberData,
+ TWorkspaceMember,
+} from "@/types/workspace/workspace";
+
+import InviteMemberModal from "./InviteMemberModal";
+import MemberItem from "./MemberItem";
+import Button from "../common/button/Button";
+
+import PlusIcon from "@/assets/icon/common/plus.svg?react";
+
+type TMemberListProps = {
+ orgId: number;
+ members: TWorkspaceMember[];
+ pendingMembers: TPendingMemberData[];
+ totalCount: number;
+ onRoleChange: (targetMemberId: number, newRole: TMemberRole) => void;
+ onDeleteClick: (member: TWorkspaceMember) => void;
+ isFetchingNextPage: boolean;
+ observerRef: RefObject;
+};
+
+export default function MemberList({
+ orgId,
+ members,
+ pendingMembers,
+ totalCount,
+ onRoleChange,
+ onDeleteClick,
+ isFetchingNextPage,
+ observerRef,
+}: TMemberListProps) {
+ const [inviteMemberOpen, setInviteMemberOpen] = useState(false);
+
+ const openInviteMember = () => {
+ setInviteMemberOpen(true);
+ };
+ const closeInviteMember = () => {
+ setInviteMemberOpen(false);
+ };
+
+ const inviteItems: TInviteMemberItem[] = [
+ ...pendingMembers.map((member) => ({
+ invitationId: member.invitationId,
+ email: member.email,
+ invitedAt: member.invitedAt,
+ expireAt: member.expireAt,
+ inviteStatus: "PENDING" as const,
+ })),
+ ...members.map((member) => ({
+ memberId: member.memberId,
+ name: member.name,
+ email: member.email,
+ profileImageUrl: member.profileImageUrl,
+ role: member.role,
+ inviteStatus: "ACTIVE" as const,
+ isMe: member.isMe,
+ })),
+ ];
+
+ const hasVisibleItems = members.length > 0;
+
+ return (
+
+
+
+ {!hasVisibleItems ? (
+
+ 아직 등록된 팀원이 없습니다
+
+ ) : (
+ <>
+
+ {members.map((member) => (
+
+ onRoleChange(member.memberId, newRole)
+ }
+ onDeleteClick={() => onDeleteClick(member)}
+ />
+ ))}
+
+
+ {isFetchingNextPage && (
+
+ 팀원을 더 불러오는 중입니다...
+
+ )}
+ >
+ )}
+
+
+ );
+}
diff --git a/src/components/workspace/MemberManagementLoading.tsx b/src/components/workspace/MemberManagementLoading.tsx
new file mode 100644
index 00000000..a50338a7
--- /dev/null
+++ b/src/components/workspace/MemberManagementLoading.tsx
@@ -0,0 +1,71 @@
+import { Skeleton, SkeletonCircle } from "../common/skeleton/Skeleton";
+
+function MemberRowSkeleton() {
+ return (
+
+ );
+}
+
+function PermissionRowSkeleton() {
+ return (
+
+ );
+}
+
+export default function MemberManagementLoading() {
+ return (
+
+
+
+
+
+
+ {Array.from({ length: 5 }).map((_, i) => (
+
+ ))}
+
+
+
+
+
+
+
+
+
+ {Array.from({ length: 9 }).map((_, i) => (
+
+ ))}
+
+
+
+
+ );
+}
diff --git a/src/components/workspace/MemberRoleSelect.tsx b/src/components/workspace/MemberRoleSelect.tsx
new file mode 100644
index 00000000..ce6300dd
--- /dev/null
+++ b/src/components/workspace/MemberRoleSelect.tsx
@@ -0,0 +1,58 @@
+import type { TMemberRole } from "@/types/workspace/workspace";
+import { ROLE_LABEL_MAP } from "@/constants/workspaceRole";
+
+import {
+ DropdownMenu,
+ type TMenuItem,
+} from "../common/dropdownmenu/DropdownMenu";
+
+import ChevonIcon from "@/assets/icon/chevron/chevron-up.svg?react";
+
+type TProps = {
+ role: TMemberRole;
+ onChange: (newRole: TMemberRole) => void;
+ disabled?: boolean;
+};
+
+const triggerStyleMap: Record = {
+ ADMIN: "bg-status-blue/80 text-white shadow-sm",
+ MEMBER: "bg-chart-3/15 text-text-auth-sub",
+};
+
+export default function MemberRoleSelect({
+ role,
+ onChange,
+ disabled = false,
+}: TProps) {
+ const items: TMenuItem[] = disabled
+ ? []
+ : [
+ {
+ label: ROLE_LABEL_MAP.ADMIN,
+ onClick: () => onChange("ADMIN"),
+ active: role === "ADMIN",
+ },
+ {
+ label: ROLE_LABEL_MAP.MEMBER,
+ onClick: () => onChange("MEMBER"),
+ active: role === "MEMBER",
+ },
+ ];
+ return (
+ (
+
+ {ROLE_LABEL_MAP[role]}
+
+
+ )}
+ />
+ );
+}
diff --git a/src/components/workspace/MemberSearchSelect.tsx b/src/components/workspace/MemberSearchSelect.tsx
new file mode 100644
index 00000000..ab0a8d24
--- /dev/null
+++ b/src/components/workspace/MemberSearchSelect.tsx
@@ -0,0 +1,57 @@
+import type { TWorkspaceMember } from "@/types/workspace/workspace";
+
+import SearchSelect from "../common/select/SearchSelect";
+
+import UserIcon from "@/assets/icon/common/user.svg?react";
+
+type TMemberSearchSelectProps = {
+ candidates: TWorkspaceMember[];
+ selectedMember: TWorkspaceMember | null;
+ onSelect: (member: TWorkspaceMember) => void;
+ isOpen: boolean;
+ onOpenChange: (open: boolean) => void;
+ placeholder?: string;
+};
+
+export default function MemberSearchSelect({
+ candidates,
+ selectedMember,
+ onSelect,
+ isOpen,
+ onOpenChange,
+ placeholder = "권한을 양도할 멤버를 검색하세요",
+}: TMemberSearchSelectProps) {
+ return (
+ member.memberId}
+ getOptionLabel={(member) => member.name}
+ getSearchText={(member) => `${member.name} ${member.email}`}
+ renderOption={(member) => (
+
+
+ {member.profileImageUrl ? (
+
+ ) : (
+
+ )}
+
+
+
{member.name}
+
{member.email}
+
+
+ )}
+ emptyMessage="검색 결과가 없습니다"
+ />
+ );
+}
diff --git a/src/components/workspace/PermissionTable.tsx b/src/components/workspace/PermissionTable.tsx
new file mode 100644
index 00000000..41b0afd3
--- /dev/null
+++ b/src/components/workspace/PermissionTable.tsx
@@ -0,0 +1,193 @@
+import { useMemo, useState } from "react";
+import { toast } from "sonner";
+
+import type { TPermissionRow } from "@/types/workspace/workspace";
+
+import Button from "../common/button/Button";
+import Toggle from "../common/toggle/Toggle";
+
+import CheckIcon from "@/assets/icon/common/check.svg?react";
+
+const permissionRows: TPermissionRow[] = [
+ {
+ key: "campaignView",
+ label: "광고/캠페인 조회",
+ description: "광고 및 캠페인을 조회할 수 있습니다",
+ defaultMemberEnabled: true,
+ },
+ {
+ key: "billingManage",
+ label: "결제 관리",
+ description: "구독 플랜 변경 및 결제 수단을 관리합니다",
+ defaultMemberEnabled: false,
+ },
+ {
+ key: "workspaceView",
+ label: "워크스페이스 조회",
+ description: "워크스페이스에 대한 정보를 조회할 수 있습니다",
+ defaultMemberEnabled: true,
+ },
+ {
+ key: "memberInvite",
+ label: "멤버 초대",
+ description: "새로운 팀원을 워크스페이스에 초대할 수 있습니다",
+ defaultMemberEnabled: true,
+ },
+ {
+ key: "memberRoleEdit",
+ label: "멤버 역할 변경",
+ description:
+ "워크스페이스에 소속되어있는 멤버들의 역할을 변경할 수 있습니다",
+ defaultMemberEnabled: false,
+ },
+ {
+ key: "workspaceEdit",
+ label: "워크스페이스 설정 수정",
+ description: "워크스페이스 이름, 로고 등 기본 정보를 수정합니다",
+ defaultMemberEnabled: false,
+ },
+ {
+ key: "projectDelete",
+ label: "프로젝트 삭제",
+ description: "생성된 프로젝트를 영구적으로 삭제합니다",
+ defaultMemberEnabled: false,
+ },
+];
+
+type TMemberPermissionState = Record;
+
+const initialMemberPermissionState: TMemberPermissionState =
+ permissionRows.reduce((acc, row) => {
+ acc[row.key] = row.defaultMemberEnabled;
+ return acc;
+ }, {} as TMemberPermissionState);
+
+function AdminCheckBadge() {
+ return (
+
+
+ 가능
+
+ );
+}
+
+export default function PermissionTable() {
+ const [savedPermissionState, setSavedPermissionState] = useState(
+ initialMemberPermissionState,
+ );
+ const [draftPermissionState, setDraftPermissionState] = useState(
+ initialMemberPermissionState,
+ );
+ const [isSaving, setIsSaving] = useState(false);
+ const hasChanges = useMemo(() => {
+ return permissionRows.some(
+ (row) => savedPermissionState[row.key] !== draftPermissionState[row.key],
+ );
+ }, [savedPermissionState, draftPermissionState]);
+ const handleToggleMemberPermission = (key: TPermissionRow["key"]) => {
+ setDraftPermissionState((prev) => ({
+ ...prev,
+ [key]: !prev[key],
+ }));
+ };
+ const handleResetChange = () => {
+ setDraftPermissionState(savedPermissionState);
+ };
+ const handleSaveChanges = async () => {
+ if (!hasChanges || isSaving) return;
+ setIsSaving(true);
+ try {
+ // TODO: 권한 저장 API 호출
+ await new Promise((resolve) => setTimeout(resolve, 500));
+ setSavedPermissionState(draftPermissionState);
+ toast.success("권한 설정이 저장되었습니다");
+ } catch (error) {
+ toast.error("권한 설정 저장에 실패했습니다. 다시 시도해주세요");
+ console.error("권한 설정 저장 실패", error);
+ } finally {
+ setIsSaving(false);
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+
+ 기능 및 작업
+
+
+ 관리자
+
+ 멤버
+
+
+
+ {permissionRows.map((row) => (
+
+
+
+
{row.label}
+
+ {row.description}
+
+
+
+
+
+
+
+
+ handleToggleMemberPermission(row.key)}
+ ariaLabel={`${row.label} 권한 토글`}
+ />
+
+
+
+ ))}
+
+
+
+
+
+ 변경 취소
+
+
+ {isSaving ? "저장 중..." : "변경사항 저장하기"}
+
+
+
+ );
+}
diff --git a/src/components/workspace/WorkspaceCard.tsx b/src/components/workspace/WorkspaceCard.tsx
new file mode 100644
index 00000000..6269608e
--- /dev/null
+++ b/src/components/workspace/WorkspaceCard.tsx
@@ -0,0 +1,86 @@
+import React, { useEffect, useState } from "react";
+import { twMerge } from "tailwind-merge";
+
+import type { TWorkspace } from "@/types/workspace/workspace";
+import { ROLE_LABEL_MAP } from "@/constants/workspaceRole";
+
+import BuildingIcon from "@/assets/icon/common/building.svg?react";
+import { getImageUrl } from "@/lib/getImageUrl";
+
+type TProps = {
+ workspace: TWorkspace;
+ isSelected?: boolean;
+ onClick?: () => void;
+};
+
+function WorkspaceCard({ workspace: w, isSelected = false, onClick }: TProps) {
+ const [imageError, setImageError] = useState(false);
+
+ useEffect(() => {
+ setImageError(false);
+ }, [w.logoUrl]);
+
+ const imageSrc = w.logoUrl ? getImageUrl(w.logoUrl) : null;
+ const showPlaceholder = !imageSrc || imageError;
+
+ return (
+
+
+
+
+ {showPlaceholder ? (
+
+
+
+ ) : (
+
{
+ setImageError(true);
+ }}
+ />
+ )}
+
+
+
+
+
+ {w.name}
+
+ {isSelected && (
+
+ 현재 대시보드 기준
+
+ )}
+
+
+
+ {w.description ?? ""}
+
+
+ {ROLE_LABEL_MAP[w.myRole]}
+
+
+
+
+
+ );
+}
+
+export default React.memo(WorkspaceCard);
diff --git a/src/components/workspace/WorkspaceEmptyState.tsx b/src/components/workspace/WorkspaceEmptyState.tsx
new file mode 100644
index 00000000..9826b3ae
--- /dev/null
+++ b/src/components/workspace/WorkspaceEmptyState.tsx
@@ -0,0 +1,13 @@
+interface IWorkspaceEmptyStateProps {
+ message: string;
+}
+
+export default function WorkspaceEmptyState({
+ message,
+}: IWorkspaceEmptyStateProps) {
+ return (
+
+ );
+}
diff --git a/src/components/workspace/WorkspaceListError.tsx b/src/components/workspace/WorkspaceListError.tsx
new file mode 100644
index 00000000..029c2a3a
--- /dev/null
+++ b/src/components/workspace/WorkspaceListError.tsx
@@ -0,0 +1,23 @@
+import Button from "../common/button/Button";
+
+interface IWorkspaceListErrorProps {
+ message: string;
+ onRetry: () => void;
+}
+
+export default function WorkspaceListError({
+ message,
+ onRetry,
+}: IWorkspaceListErrorProps) {
+ return (
+
+
{message}
+
+ 다시 시도
+
+
+ );
+}
diff --git a/src/components/workspace/WorkspaceListLoading.tsx b/src/components/workspace/WorkspaceListLoading.tsx
new file mode 100644
index 00000000..4cfed491
--- /dev/null
+++ b/src/components/workspace/WorkspaceListLoading.tsx
@@ -0,0 +1,42 @@
+import { Skeleton } from "@/components/common/skeleton/Skeleton";
+
+function WorkspaceCardSkeleton() {
+ return (
+ <>
+
+
+
+ >
+ );
+}
+
+export default function WorkspaceListLoading() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ {Array.from({ length: 7 }).map((_, i) => (
+
+ ))}
+
+
+ );
+}
diff --git a/src/components/workspace/WorkspaceSettingLoading.tsx b/src/components/workspace/WorkspaceSettingLoading.tsx
new file mode 100644
index 00000000..4e63f491
--- /dev/null
+++ b/src/components/workspace/WorkspaceSettingLoading.tsx
@@ -0,0 +1,52 @@
+import { Skeleton } from "../common/skeleton/Skeleton";
+
+export default function WorkspaceSettingLoading() {
+ return (
+
+ );
+}
diff --git a/src/constants/sidebarNav.ts b/src/constants/sidebarNav.ts
new file mode 100644
index 00000000..abf66633
--- /dev/null
+++ b/src/constants/sidebarNav.ts
@@ -0,0 +1,77 @@
+import type { INavItem } from "@/types/navigation/navItem";
+
+import AdsIcon from "@/assets/icon/sidebar/ads.svg?react";
+import DashboardIcon from "@/assets/icon/sidebar/dashboard.svg?react";
+import NotificationIcon from "@/assets/icon/sidebar/notification.svg?react";
+import SettingsIcon from "@/assets/icon/sidebar/setting.svg?react";
+import WorkspaceIcon from "@/assets/icon/sidebar/workspace.svg?react";
+
+export const mainNav: INavItem[] = [
+ {
+ id: "dashboard",
+ label: "대시보드",
+ icon: DashboardIcon,
+ path: "/dashboard",
+ children: [
+ {
+ id: "dashboard-integrated",
+ label: "통합 대시보드",
+ path: "/dashboard",
+ },
+ {
+ id: "dashboard-platform",
+ label: "플랫폼별 대시보드",
+ path: "/platform",
+ },
+ {
+ id: "dashboard-timeline",
+ label: "성과 타임라인",
+ path: "/timeline",
+ },
+ ],
+ },
+ {
+ id: "ads",
+ label: "광고",
+ icon: AdsIcon,
+ path: "/ads",
+ children: [
+ {
+ id: "ads-list",
+ label: "광고 목록",
+ path: "/ads",
+ },
+ {
+ id: "ads-campaign-group",
+ label: "캠페인 그룹 정보 설정",
+ path: "/ads/campaignGroup",
+ },
+ ],
+ },
+ {
+ id: "workspace",
+ label: "워크스페이스",
+ icon: WorkspaceIcon,
+ path: "/workspace",
+ children: [
+ {
+ id: "workspace-billing",
+ label: "플랜 및 결제",
+ path: "/workspace/billing",
+ },
+ ],
+ },
+];
+
+export const footerNav: INavItem[] = [
+ {
+ id: "notifications",
+ label: "알림",
+ icon: NotificationIcon,
+ },
+ {
+ id: "settings",
+ label: "설정",
+ icon: SettingsIcon,
+ },
+];
diff --git a/src/constants/workspaceRole.ts b/src/constants/workspaceRole.ts
new file mode 100644
index 00000000..328357fe
--- /dev/null
+++ b/src/constants/workspaceRole.ts
@@ -0,0 +1,6 @@
+import type { TMemberRole } from "@/types/workspace/workspace";
+
+export const ROLE_LABEL_MAP: Record = {
+ ADMIN: "관리자",
+ MEMBER: "멤버",
+};
diff --git a/src/hooks/ads/useAdList.ts b/src/hooks/ads/useAdList.ts
new file mode 100644
index 00000000..8b8676a0
--- /dev/null
+++ b/src/hooks/ads/useAdList.ts
@@ -0,0 +1,33 @@
+import { useEffect, useState } from "react";
+import { toast } from "sonner";
+
+import type { IAd } from "@/types/ads/campaign";
+import type { IApiErrorResponse } from "@/types/common/common";
+
+import { getAdList } from "@/api/ads/ads";
+
+export const useAdList = (orgId: number | null, projectId: number | null) => {
+ const [ads, setAds] = useState([]);
+ const [isAdLoading, setIsAdLoading] = useState(false);
+
+ const fetchAds = async () => {
+ if (!orgId || !projectId) return;
+ try {
+ setIsAdLoading(true);
+ const result = await getAdList(orgId, projectId);
+ setAds(result);
+ } catch (e) {
+ toast.error(
+ (e as IApiErrorResponse).message ?? "광고 목록을 불러오지 못했습니다.",
+ );
+ } finally {
+ setIsAdLoading(false);
+ }
+ };
+
+ useEffect(() => {
+ fetchAds();
+ }, [orgId, projectId]);
+
+ return { ads, isAdLoading, refetchAds: fetchAds };
+};
diff --git a/src/hooks/ads/useCampaignDetail.ts b/src/hooks/ads/useCampaignDetail.ts
new file mode 100644
index 00000000..edd607ea
--- /dev/null
+++ b/src/hooks/ads/useCampaignDetail.ts
@@ -0,0 +1,29 @@
+import { useParams } from "react-router-dom";
+
+import { useCoreQuery } from "@/hooks/customQuery";
+
+import { getCampaignDetail } from "@/api/ads/ads";
+
+export const useCampaignDetail = () => {
+ const { orgId, projectId } = useParams<{
+ orgId: string;
+ projectId: string;
+ }>();
+
+ // URL 파라미터를 숫자로 변환
+ const parsedOrgId = Number(orgId);
+ const parsedProjectId = Number(projectId);
+
+ // 유효한 ID일 때만 요청
+ const isValid =
+ Number.isFinite(parsedOrgId) &&
+ parsedOrgId > 0 &&
+ Number.isFinite(parsedProjectId) &&
+ parsedProjectId > 0;
+
+ return useCoreQuery(
+ ["campaignDetail", parsedOrgId, parsedProjectId],
+ () => getCampaignDetail(parsedOrgId, parsedProjectId),
+ { enabled: isValid },
+ );
+};
diff --git a/src/hooks/ads/useCampaignGroup.ts b/src/hooks/ads/useCampaignGroup.ts
new file mode 100644
index 00000000..3e90b865
--- /dev/null
+++ b/src/hooks/ads/useCampaignGroup.ts
@@ -0,0 +1,134 @@
+import { useState } from "react";
+import { useNavigate } from "react-router-dom";
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
+import { toast } from "sonner";
+
+import type { IPlatformCampaign } from "@/types/ads/campaign";
+import type { IApiErrorResponse } from "@/types/common/common";
+
+import { createCampaignGroup, getPlatformCampaigns } from "@/api/ads/ads";
+import useWorkspaceStore from "@/store/useWorkspaceStore";
+
+const NONE_OPTION: IPlatformCampaign = {
+ adCampaignId: -1,
+ name: "선택 안 함",
+ description: "",
+};
+
+export const useCampaignGroup = () => {
+ const navigate = useNavigate();
+ const queryClient = useQueryClient();
+ const orgId = useWorkspaceStore((s) => s.selectedOrgId);
+
+ const [name, setName] = useState("");
+ const [description, setDescription] = useState("");
+
+ const [googleSelected, setGoogleSelected] =
+ useState(null);
+ const [naverSelected, setNaverSelected] = useState(
+ null,
+ );
+ const [kakaoSelected, setKakaoSelected] = useState(
+ null,
+ );
+
+ const { data: googleData = [] } = useQuery<
+ IPlatformCampaign[],
+ IApiErrorResponse
+ >({
+ queryKey: ["platformCampaigns", orgId, "GOOGLE"],
+ queryFn: () => getPlatformCampaigns(orgId!, "GOOGLE"),
+ enabled: !!orgId,
+ });
+
+ const { data: naverData = [] } = useQuery<
+ IPlatformCampaign[],
+ IApiErrorResponse
+ >({
+ queryKey: ["platformCampaigns", orgId, "NAVER"],
+ queryFn: () => getPlatformCampaigns(orgId!, "NAVER"),
+ enabled: !!orgId,
+ });
+
+ const { data: kakaoData = [] } = useQuery<
+ IPlatformCampaign[],
+ IApiErrorResponse
+ >({
+ queryKey: ["platformCampaigns", orgId, "KAKAO"],
+ queryFn: () => getPlatformCampaigns(orgId!, "KAKAO"),
+ enabled: !!orgId,
+ });
+
+ // '선택 안 함'이 포함된 리스트 생성
+ const googleCampaigns = [NONE_OPTION, ...googleData];
+ const naverCampaigns = [NONE_OPTION, ...naverData];
+ const kakaoCampaigns = [NONE_OPTION, ...kakaoData];
+
+ // 유효성 검사 (실제 캠페인이 하나라도 선택되었는지 확인)
+ const isFormValid =
+ name.trim() !== "" &&
+ [googleSelected, naverSelected, kakaoSelected].some(
+ (sel) => sel !== null && sel.adCampaignId !== -1,
+ );
+
+ const [isSuccessModalOpen, setIsSuccessModalOpen] = useState(false);
+
+ const { mutate: createGroup, isPending: isCreating } = useMutation<
+ unknown,
+ IApiErrorResponse
+ >({
+ mutationFn: () => {
+ const campaignIds: number[] = [
+ googleSelected?.adCampaignId,
+ naverSelected?.adCampaignId,
+ kakaoSelected?.adCampaignId,
+ ].filter(
+ (id): id is number => id !== undefined && id !== null && id !== -1,
+ );
+
+ return createCampaignGroup(orgId!, {
+ name,
+ description,
+ campaignIds,
+ });
+ },
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ["campaigns", orgId] });
+ setIsSuccessModalOpen(true);
+ },
+ onError: (error) => {
+ toast.error(error.message ?? "캠페인 그룹 생성에 실패했습니다.");
+ },
+ });
+
+ const handleComplete = () => {
+ if (!isFormValid) return;
+ createGroup();
+ };
+
+ const handleCloseSuccessModal = () => {
+ setIsSuccessModalOpen(false);
+ navigate("/ads");
+ };
+
+ return {
+ name,
+ setName,
+ description,
+ setDescription,
+ googleSelected,
+ setGoogleSelected,
+ naverSelected,
+ setNaverSelected,
+ kakaoSelected,
+ setKakaoSelected,
+ googleCampaigns,
+ naverCampaigns,
+ kakaoCampaigns,
+ isFormValid,
+ isCreating,
+ handleComplete,
+ isSuccessModalOpen,
+ handleCloseSuccessModal,
+ };
+};
diff --git a/src/hooks/ads/useControlModal.ts b/src/hooks/ads/useControlModal.ts
new file mode 100644
index 00000000..f65debe0
--- /dev/null
+++ b/src/hooks/ads/useControlModal.ts
@@ -0,0 +1,44 @@
+import { useState } from "react";
+import { toast } from "sonner";
+
+import type { IApiErrorResponse } from "@/types/common/common";
+
+interface IUseControlModalProps {
+ onSuccess?: () => void;
+ successMessage: string;
+ errorMessage: string;
+}
+
+export const useControlModal = ({
+ onSuccess,
+ successMessage,
+ errorMessage,
+}: IUseControlModalProps) => {
+ const [isOpen, setIsOpen] = useState(false);
+ const [isLoading, setIsLoading] = useState(false);
+
+ const openModal = () => setIsOpen(true);
+ const closeModal = () => setIsOpen(false);
+
+ const handleConfirm = async (action: () => Promise) => {
+ setIsLoading(true);
+ try {
+ await action();
+ toast.success(successMessage);
+ onSuccess?.();
+ closeModal();
+ } catch (e) {
+ toast.error((e as IApiErrorResponse).message ?? errorMessage);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ return {
+ isOpen,
+ isLoading,
+ openModal,
+ closeModal,
+ handleConfirm,
+ };
+};
diff --git a/src/hooks/alarm/useDeviceToken.ts b/src/hooks/alarm/useDeviceToken.ts
deleted file mode 100644
index 2fd48c0c..00000000
--- a/src/hooks/alarm/useDeviceToken.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-// // src/hooks/alarm/useDeviceToken.ts
-// import { useEffect } from 'react';
-// import { isSupported } from 'firebase/messaging';
-
-// import { postDeviceToken } from '@/api/alarm/alarm'; // 서버에 FCM 토큰 전송하는 API 함수
-// import { generateToken, registerServiceWorker } from '@/firebase/firebase';
-
-// export const useDeviceToken = () => {
-// useEffect(() => {
-// const setupFCM = async () => {
-// if (!(await isSupported())) {
-// console.warn('FCM은 현재 브라우저에서 지원되지 않습니다.');
-// return;
-// }
-
-// await registerServiceWorker();
-// const token = await generateToken();
-
-// if (token) {
-// try {
-// await postDeviceToken({ deviceToken: token }); // 서버에 전송
-// } catch (err) {
-// console.error('디바이스 토큰 서버 전송 실패:', err);
-// }
-// }
-// };
-
-// const handleClick = () => {
-// setupFCM();
-// window.removeEventListener('click', handleClick);
-// };
-
-// window.addEventListener('click', handleClick);
-
-// return () => {
-// window.removeEventListener('click', handleClick);
-// };
-// }, []);
-// };
diff --git a/src/hooks/alarm/useGetAlarm.ts b/src/hooks/alarm/useGetAlarm.ts
deleted file mode 100644
index 14440517..00000000
--- a/src/hooks/alarm/useGetAlarm.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { useInfiniteQuery } from '@tanstack/react-query';
-
-import type { TRequestGetAlarm } from '@/types/alarm/alarm';
-
-import { getAlarm } from '@/api/alarm/alarm';
-import { alarmKeys } from '@/queryKey/queryKey';
-
-export const useGetAlarm = ({ cursor, size }: TRequestGetAlarm) => {
- return useInfiniteQuery({
- queryKey: alarmKeys.getAlarm(size ?? 5, cursor).queryKey,
- queryFn: ({ pageParam = cursor }) => getAlarm({ cursor: pageParam, size: size ?? 5 }),
- initialPageParam: cursor,
- getNextPageParam: (lastPage) => lastPage.result.cursor ?? undefined,
- });
-};
diff --git a/src/hooks/auth/useAccount.ts b/src/hooks/auth/useAccount.ts
deleted file mode 100644
index d7312bde..00000000
--- a/src/hooks/auth/useAccount.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import type {
- TChangeNicknameMutationOptions,
- TChangeNicknameMutationResult,
- TChangeNicknamePayload,
- TChangeNicknameResponse,
- TChangePasswordMutationOptions,
- TChangePasswordMutationResult,
- TChangePasswordPayload,
-} from '@/types/auth/account';
-import type { TUseMutationCustomOptions } from '@/types/common/common';
-import type { TResetPreferencesResponse } from '@/types/dates/preferences';
-
-import { useCoreMutation, useCoreQuery } from '@/hooks/customQuery';
-
-import { changeNickname, changePassword, deleteMember, getMemberGrade, getMemberInfo } from '@/api/auth/account';
-import { resetPreferences } from '@/api/dates/preferences';
-
-export const QUERY_KEYS = {
- memberInfo: ['memberInfo'] as const,
- memberGrade: ['memberGrade'] as const,
-} as const;
-
-export function useAccount() {
- // 비밀번호 변경
- function useChangePassword(options?: TChangePasswordMutationOptions): TChangePasswordMutationResult {
- return useCoreMutation(changePassword, options);
- }
-
- // 닉네임 변경
- function useChangeNickname(options?: TChangeNicknameMutationOptions): TChangeNicknameMutationResult {
- return useCoreMutation(changeNickname, options);
- }
-
- // 회원 탈퇴
- function useDeleteMember(options?: TUseMutationCustomOptions) {
- return useCoreMutation(deleteMember, options);
- }
-
- // 사용자 정보 조회
- function useGetMemberInfo() {
- return useCoreQuery(QUERY_KEYS.memberInfo, getMemberInfo);
- }
-
- // 사용자 등급 조회
- function useGetMemberGrade() {
- return useCoreQuery(QUERY_KEYS.memberGrade, getMemberGrade);
- }
-
- // 취향 데이터 초기화
- function useResetPreferences(options?: TUseMutationCustomOptions) {
- return useCoreMutation(resetPreferences, options);
- }
-
- return { useChangePassword, useChangeNickname, useDeleteMember, useGetMemberInfo, useGetMemberGrade, useResetPreferences };
-}
diff --git a/src/hooks/auth/useAuth.ts b/src/hooks/auth/useAuth.ts
index ce4c2e40..10204a99 100644
--- a/src/hooks/auth/useAuth.ts
+++ b/src/hooks/auth/useAuth.ts
@@ -1,14 +1,41 @@
-import { useCoreMutation } from '../customQuery';
-
-import { checkEmailVerifications, defaultLogin, defaultSignup, emailVerifications, findPassword, logout, socialLogin } from '@/api/auth/auth';
-
-export function useAuth() {
- const useDefaultLogin = useCoreMutation(defaultLogin);
- const useDefaultSignup = useCoreMutation(defaultSignup);
- const useLogout = useCoreMutation(logout);
- const useSendCode = useCoreMutation(emailVerifications);
- const useCheckCode = useCoreMutation(checkEmailVerifications);
- const useSocialLogin = useCoreMutation(socialLogin);
- const useFindPassword = useCoreMutation(findPassword);
- return { useLogout, useFindPassword, useSocialLogin, useCheckCode, useDefaultLogin, useDefaultSignup, useSendCode };
-}
+import { useCoreMutation } from "@/hooks/customQuery";
+
+import {
+ login,
+ requestPasswordReset,
+ resetPassword,
+ sendEmail,
+ sendSMS,
+ signUp,
+ verifyEmail,
+ verifySMS,
+} from "@/api/auth/auth";
+import useAuthStore from "@/store/useAuthStore";
+
+export const useAuth = () => {
+ const { login: loginAction } = useAuthStore();
+
+ const useLogin = useCoreMutation(login, {
+ userOnSuccess: (response, vars) => {
+ loginAction(vars.email, response.data.accessToken);
+ },
+ });
+ const useSignUp = useCoreMutation(signUp);
+ const useSendCode = useCoreMutation(sendEmail);
+ const useCheckCode = useCoreMutation(verifyEmail);
+ const useSendSMS = useCoreMutation(sendSMS);
+ const useVerifySMS = useCoreMutation(verifySMS);
+ const useRequestPasswordReset = useCoreMutation(requestPasswordReset);
+ const useResetPassword = useCoreMutation(resetPassword);
+
+ return {
+ useLogin,
+ useSignUp,
+ useSendCode,
+ useCheckCode,
+ useSendSMS,
+ useVerifySMS,
+ useRequestPasswordReset,
+ useResetPassword,
+ };
+};
diff --git a/src/hooks/auth/useEmailVerification.ts b/src/hooks/auth/useEmailVerification.ts
new file mode 100644
index 00000000..b409f9bf
--- /dev/null
+++ b/src/hooks/auth/useEmailVerification.ts
@@ -0,0 +1,151 @@
+import { useCallback, useEffect, useState } from "react";
+import { useForm, useWatch } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import type { UseMutationResult } from "@tanstack/react-query";
+import { toast } from "sonner";
+import type { z } from "zod";
+
+import type { IEmailSendRequest, IEmailSendResponse } from "@/types/auth/auth";
+import type { IApiErrorResponse, ICommonResponse } from "@/types/common/common";
+
+import { signupEmailSchema } from "@/utils/validation";
+
+import { useAuth } from "@/hooks/auth/useAuth";
+import { useTimer } from "@/hooks/common/useTimer";
+
+import useAuthStore from "@/store/useAuthStore";
+
+export type TSignupEmailFormValues = z.infer;
+
+type TSendCodeMutation = UseMutationResult<
+ ICommonResponse,
+ IApiErrorResponse,
+ IEmailSendRequest
+>;
+
+interface IUseEmailVerificationProps {
+ onNext: () => void;
+ sendMutation?: TSendCodeMutation;
+}
+
+export const useEmailVerification = ({
+ onNext,
+ sendMutation,
+}: IUseEmailVerificationProps) => {
+ const { setEmail } = useAuthStore();
+ const { useSendCode, useCheckCode } = useAuth();
+ const activeSendCode = sendMutation ?? useSendCode;
+
+ const [sendCode, setSendCode] = useState(false);
+ const [codeError, setCodeError] = useState("");
+
+ const form = useForm({
+ mode: "onBlur",
+ resolver: zodResolver(signupEmailSchema),
+ });
+
+ const {
+ control,
+ trigger,
+ handleSubmit,
+ formState: { errors, isValid },
+ } = form;
+
+ const watchedEmail = useWatch({ control, name: "email" });
+ const watchedCode = useWatch({ control, name: "code" });
+
+ const { formattedTime, restart, stop, isExpired } = useTimer(0, {
+ onExpire: () => {
+ toast.error("인증 시간이 만료되었습니다. 다시 시도해주세요.");
+ },
+ });
+
+ const handleEditEmail = useCallback(() => {
+ setSendCode(false);
+ stop();
+ }, [stop]);
+
+ const PROVIDER_NAME: Record = {
+ GOOGLE: "구글",
+ KAKAO: "카카오",
+ NAVER: "네이버",
+ };
+
+ const sendVerificationEmail = (email: string, successMessage: string) => {
+ activeSendCode.mutate(
+ { email },
+ {
+ onSuccess: (data) => {
+ const { isProviderLinked, providerTypes } = data.data;
+
+ if (isProviderLinked) {
+ const providerNames = providerTypes
+ .map((type) => PROVIDER_NAME[type])
+ .join(", ");
+ toast.error("이미 소셜 로그인으로 가입된 이메일입니다.", {
+ description: `${providerNames}계정으로 로그인해주세요`,
+ });
+ return;
+ }
+
+ setSendCode(true);
+ toast.success(successMessage);
+ restart(data.data.expireIn);
+ },
+ onError: (error) => {
+ toast.error(error.message ?? "메일 발송에 실패했습니다.");
+ },
+ },
+ );
+ };
+
+ const handleResendEmail = () => {
+ if (watchedEmail) {
+ sendVerificationEmail(watchedEmail, "인증번호가 재발송되었습니다.");
+ }
+ };
+
+ const postSendCode = async () => {
+ const isEmailValid = await trigger("email");
+ if (isEmailValid && watchedEmail) {
+ sendVerificationEmail(watchedEmail, "인증번호가 발송되었습니다.");
+ }
+ };
+
+ const onSubmit = async (data: TSignupEmailFormValues) => {
+ useCheckCode.mutate(
+ { email: data.email, authCode: data.code },
+ {
+ onSuccess: () => {
+ setEmail(data.email);
+ onNext();
+ },
+ onError: (error) => {
+ setCodeError(error.message ?? "인증번호가 올바르지 않습니다.");
+ },
+ },
+ );
+ };
+
+ useEffect(() => {
+ setCodeError("");
+ }, [watchedCode, watchedEmail]);
+
+ return {
+ form,
+ watchedEmail,
+ sendCode,
+ formattedTime,
+ isExpired,
+ codeError,
+ errors,
+ isValid,
+ isPending: activeSendCode.isPending || useCheckCode.isPending,
+ handlers: {
+ postSendCode,
+ handleResendEmail,
+ handleEditEmail,
+ handleSubmit: handleSubmit(onSubmit),
+ },
+ };
+};
diff --git a/src/hooks/auth/useSocialLogin.ts b/src/hooks/auth/useSocialLogin.ts
new file mode 100644
index 00000000..20a43dc7
--- /dev/null
+++ b/src/hooks/auth/useSocialLogin.ts
@@ -0,0 +1,12 @@
+import { type TSocialLoginPlatform } from "@/types/auth/auth";
+
+export const useSocialLogin = () => {
+ const handleSocialLogin = (platform: TSocialLoginPlatform) => {
+ const API_TARGET_URL =
+ import.meta.env.VITE_API_TARGET_URL || import.meta.env.VITE_API_BASE_URL;
+
+ window.location.href = `${API_TARGET_URL}/oauth2/authorization/${platform}`;
+ };
+
+ return { handleSocialLogin };
+};
diff --git a/src/hooks/auth/useTokenRefresh.ts b/src/hooks/auth/useTokenRefresh.ts
new file mode 100644
index 00000000..5bc4723f
--- /dev/null
+++ b/src/hooks/auth/useTokenRefresh.ts
@@ -0,0 +1,34 @@
+import { useEffect, useRef } from "react";
+
+import { reissueToken } from "@/api/auth/auth";
+import useAuthStore from "@/store/useAuthStore";
+
+export const useTokenRefresh = () => {
+ const { setAccessToken, logout, setTokenInitialized } = useAuthStore();
+ const initialized = useRef(false);
+
+ useEffect(() => {
+ if (initialized.current) return;
+ initialized.current = true;
+
+ if (!localStorage.getItem("hasSession")) {
+ setTokenInitialized();
+ return;
+ }
+
+ const initAuth = async () => {
+ try {
+ const { data } = await reissueToken();
+ if (data.accessToken) {
+ setAccessToken(data.accessToken);
+ }
+ } catch {
+ logout();
+ } finally {
+ setTokenInitialized();
+ }
+ };
+
+ initAuth();
+ }, [setAccessToken, logout, setTokenInitialized]);
+};
diff --git a/src/hooks/common/useIsMounted.ts b/src/hooks/common/useIsMounted.ts
new file mode 100644
index 00000000..fbf35513
--- /dev/null
+++ b/src/hooks/common/useIsMounted.ts
@@ -0,0 +1,12 @@
+import { useEffect, useState } from "react";
+
+// 클라이언트 마운트 여부 반환 (SSR 환경에서 클라이언트 전용 렌더링 제어용)
+export function useIsMounted() {
+ const [isMounted, setIsMounted] = useState(false);
+
+ useEffect(() => {
+ setIsMounted(true);
+ }, []);
+
+ return isMounted;
+}
diff --git a/src/hooks/common/useStepNavigation.ts b/src/hooks/common/useStepNavigation.ts
new file mode 100644
index 00000000..ac94dea7
--- /dev/null
+++ b/src/hooks/common/useStepNavigation.ts
@@ -0,0 +1,11 @@
+import { useCallback, useState } from "react";
+
+export const useStepNavigation = (initialStep: number) => {
+ const [step, setStep] = useState(initialStep);
+
+ const handleNext = useCallback(() => {
+ setStep((prev) => prev + 1);
+ }, []);
+
+ return { step, setStep, handleNext };
+};
diff --git a/src/hooks/common/useTimer.ts b/src/hooks/common/useTimer.ts
new file mode 100644
index 00000000..282694ef
--- /dev/null
+++ b/src/hooks/common/useTimer.ts
@@ -0,0 +1,96 @@
+import { useCallback, useEffect, useMemo, useRef, useState } from "react";
+
+type TUseTimerOptions = {
+ autoStart?: boolean;
+ onExpire?: () => void;
+};
+
+export const useTimer = (
+ initialTime: number,
+ options: TUseTimerOptions = {},
+) => {
+ const { autoStart = false, onExpire } = options;
+
+ const [timeLeft, setTimeLeft] = useState(() => Math.max(0, initialTime));
+ const [isActive, setIsActive] = useState(autoStart);
+
+ const intervalRef = useRef | null>(null);
+ const onExpireRef = useRef(onExpire);
+
+ useEffect(() => {
+ onExpireRef.current = onExpire;
+ }, [onExpire]);
+
+ const clear = useCallback(() => {
+ if (intervalRef.current) {
+ clearInterval(intervalRef.current);
+ intervalRef.current = null;
+ }
+ }, []);
+
+ useEffect(() => {
+ if (!isActive) {
+ clear();
+ return;
+ }
+
+ if (timeLeft <= 0) {
+ setIsActive(false);
+ clear();
+ onExpireRef.current?.();
+ return;
+ }
+
+ intervalRef.current = setInterval(() => {
+ setTimeLeft((prev) => {
+ if (prev <= 1) {
+ return 0;
+ }
+ return prev - 1;
+ });
+ }, 1000);
+
+ return clear;
+ }, [isActive, timeLeft, clear]);
+
+ // 언마운트 시에 정리
+ useEffect(() => clear, [clear]);
+
+ const start = useCallback(() => {
+ setIsActive(true);
+ }, []);
+
+ const stop = useCallback(() => {
+ setIsActive(false);
+ }, []);
+
+ const reset = useCallback(() => {
+ setIsActive(false);
+ setTimeLeft(Math.max(0, initialTime));
+ }, [initialTime]);
+
+ const restart = useCallback(
+ (newTime?: number) => {
+ setTimeLeft(Math.max(0, newTime ?? initialTime));
+ setIsActive(true);
+ },
+ [initialTime],
+ );
+
+ const formattedTime = useMemo(() => {
+ const minutes = Math.floor(timeLeft / 60);
+ const seconds = timeLeft % 60;
+ return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
+ }, [timeLeft]);
+
+ return {
+ timeLeft,
+ formattedTime,
+ isActive,
+ isExpired: timeLeft <= 0,
+ start,
+ stop,
+ reset,
+ restart,
+ };
+};
diff --git a/src/hooks/course/useSearchRegion.tsx b/src/hooks/course/useSearchRegion.tsx
deleted file mode 100644
index 4a7e07ac..00000000
--- a/src/hooks/course/useSearchRegion.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import { useCoreQuery } from '../customQuery';
-
-import { searchRegion } from '@/api/course/course';
-import { regionKeys } from '@/queryKey/queryKey';
-
-export function useSearchRegion({ keyword }: { keyword: string }, options?: { enabled?: boolean }) {
- return useCoreQuery(regionKeys.search(keyword).queryKey, () => searchRegion({ keyword }), {
- enabled: options?.enabled ?? true,
- staleTime: 1000 * 60 * 5,
- });
-}
diff --git a/src/hooks/customQuery.ts b/src/hooks/customQuery.ts
index 6df44614..a0ef0e16 100644
--- a/src/hooks/customQuery.ts
+++ b/src/hooks/customQuery.ts
@@ -1,29 +1,94 @@
-import { type MutationFunction, type QueryFunction, type QueryKey, useMutation, useQuery, type UseQueryResult } from '@tanstack/react-query';
-import type { AxiosError } from 'axios';
-import { toast } from 'sonner';
+import {
+ type MutationFunction,
+ type QueryFunction,
+ type QueryKey,
+ useMutation,
+ useQuery,
+ type UseQueryResult,
+} from "@tanstack/react-query";
-import type { TUseMutationCustomOptions, TUseQueryCustomOptions } from '@/types/common/common';
+import type {
+ IApiErrorResponse,
+ TUseMutationCustomOptions,
+ TUseQueryCustomOptions,
+} from "@/types/common/common";
+
+import { queryClient } from "@/lib/queryClient";
export function useCoreQuery(
- keyName: QueryKey,
- query: QueryFunction,
- options?: TUseQueryCustomOptions,
-): UseQueryResult {
- return useQuery({
- queryKey: keyName,
- queryFn: query,
- ...options,
- staleTime: options?.staleTime ?? 1000 * 60 * 5,
- });
+ keyName: QueryKey,
+ query: QueryFunction,
+ options?: TUseQueryCustomOptions,
+): UseQueryResult {
+ return useQuery({
+ queryKey: keyName,
+ queryFn: query,
+ ...options,
+ });
}
-//options 타입을 제네릭 변경
-export function useCoreMutation(mutation: MutationFunction, options?: TUseMutationCustomOptions) {
- return useMutation({
- mutationFn: mutation,
- onError: (error) => {
- toast.error(error.response?.data.message || 'An error occurred.');
- },
- ...options,
- });
+export function useCoreMutation<
+ TData,
+ TVariables,
+ TError = IApiErrorResponse,
+ TContext extends { prevData?: unknown } = { prevData?: unknown },
+ TCache = unknown,
+>(
+ mutation: MutationFunction,
+ options?: TUseMutationCustomOptions<
+ TData,
+ TVariables,
+ TError,
+ TContext,
+ TCache
+ >,
+) {
+ const {
+ optimisticUpdate,
+ invalidateKeys,
+ userOnError,
+ userOnSuccess,
+ ...rest
+ } = options ?? {};
+
+ return useMutation({
+ mutationFn: mutation,
+ onMutate: async (vars): Promise => {
+ if (!optimisticUpdate) return undefined;
+
+ await queryClient.cancelQueries({ queryKey: optimisticUpdate.key });
+
+ const prevData = queryClient.getQueryData(optimisticUpdate.key);
+
+ queryClient.setQueryData(
+ optimisticUpdate.key,
+ (old: TCache | undefined) =>
+ optimisticUpdate.updateFn(old as TCache | undefined, vars),
+ );
+
+ return { prevData } as TContext;
+ },
+
+ onError: (error, vars, ctx) => {
+ if (optimisticUpdate && ctx?.prevData !== undefined) {
+ queryClient.setQueryData(
+ optimisticUpdate.key,
+ ctx.prevData as TCache,
+ );
+ }
+ userOnError?.(error, vars, ctx);
+ },
+
+ onSuccess: async (data, vars, ctx) => {
+ if (invalidateKeys?.length) {
+ await Promise.all(
+ invalidateKeys.map((key) =>
+ queryClient.invalidateQueries({ queryKey: key }),
+ ),
+ );
+ }
+ userOnSuccess?.(data, vars, ctx);
+ },
+ ...rest,
+ });
}
diff --git a/src/hooks/dashboard/useClickStream.ts b/src/hooks/dashboard/useClickStream.ts
new file mode 100644
index 00000000..a63bb8ea
--- /dev/null
+++ b/src/hooks/dashboard/useClickStream.ts
@@ -0,0 +1,68 @@
+import { useEffect, useRef, useState } from "react";
+import { fetchEventSource } from "@microsoft/fetch-event-source";
+
+import type { IClickStreamItem } from "@/types/dashboard/overview";
+
+import useAuthStore from "@/store/useAuthStore";
+import useWorkspaceStore from "@/store/useWorkspaceStore";
+
+const MAX_RETRIES = 3;
+
+export function useClickStream(mode: "real" | "dummy" = "dummy") {
+ // TODO: 테스트용 - 더미 데이터가 orgId 1에만 있어서 임시 고정, 테스트 후 원래대로 복구할 예정
+ // const orgId = useWorkspaceStore((s) => s.selectedOrgId);
+ useWorkspaceStore((s) => s.selectedOrgId);
+ const orgId = 1;
+ const accessToken = useAuthStore((s) => s.accessToken);
+ const [data, setData] = useState(null);
+ const [suspectDetail, setSuspectDetail] =
+ useState(null);
+ const [isError, setIsError] = useState(false);
+ const retryCountRef = useRef(0);
+
+ useEffect(() => {
+ if (!orgId || !accessToken) return;
+
+ const controller = new AbortController();
+ retryCountRef.current = 0;
+
+ fetchEventSource(`/api/dashboard/${orgId}/clicks/stream?mode=${mode}`, {
+ headers: {
+ Authorization: `Bearer ${accessToken}`,
+ },
+ signal: controller.signal,
+ onopen: async (response) => {
+ if (response.ok) {
+ retryCountRef.current = 0;
+ setIsError(false);
+ }
+ },
+ onmessage(event) {
+ if (event.event === "org-click-update") {
+ try {
+ const wrapper = JSON.parse(event.data);
+ const parsed: IClickStreamItem = wrapper.data ?? wrapper;
+ setData(parsed);
+ if (parsed.suspectDetail) {
+ setSuspectDetail(parsed.suspectDetail);
+ }
+ } catch {
+ // 파싱 실패 시 해당 이벤트 무시하고 스트림 유지
+ }
+ }
+ },
+ onerror(err) {
+ retryCountRef.current += 1;
+ if (retryCountRef.current >= MAX_RETRIES) {
+ setIsError(true);
+ throw err; // 재시도 중단
+ }
+ // MAX_RETRIES 미만이면 기본 재시도 동작 유지
+ },
+ });
+
+ return () => controller.abort();
+ }, [orgId, accessToken, mode]);
+
+ return { data, suspectDetail, isError };
+}
diff --git a/src/hooks/dashboard/useOverviewBudget.ts b/src/hooks/dashboard/useOverviewBudget.ts
new file mode 100644
index 00000000..a8088165
--- /dev/null
+++ b/src/hooks/dashboard/useOverviewBudget.ts
@@ -0,0 +1,26 @@
+import { useCoreQuery } from "@/hooks/customQuery";
+
+import { getBudget } from "@/api/dashboard/overview";
+import useWorkspaceStore from "@/store/useWorkspaceStore";
+
+// 예산 소진율 임계값
+const WARNING_THRESHOLD = 50;
+const DANGER_THRESHOLD = 75;
+
+// 예산 소진 현황 조회
+export function useOverviewBudget() {
+ // TODO: 테스트용 - 예산 데이터가 orgId 2에만 있어서 임시 고정, 테스트 후 원래대로 복구할 예정
+ // const orgId = useWorkspaceStore((s) => s.selectedOrgId);
+ useWorkspaceStore((s) => s.selectedOrgId);
+ const orgId = 2;
+
+ return useCoreQuery(["overview", "budget", orgId], () => getBudget(orgId), {
+ enabled: !!orgId,
+ select: (data) => ({
+ totalBudget: data.totalBudget,
+ spent: data.totalSpend,
+ warningThreshold: WARNING_THRESHOLD,
+ dangerThreshold: DANGER_THRESHOLD,
+ }),
+ });
+}
diff --git a/src/hooks/dashboard/useOverviewMetrics.ts b/src/hooks/dashboard/useOverviewMetrics.ts
new file mode 100644
index 00000000..f61c249b
--- /dev/null
+++ b/src/hooks/dashboard/useOverviewMetrics.ts
@@ -0,0 +1,63 @@
+import type { IMetricsResponse } from "@/types/dashboard/overview";
+
+import { useCoreQuery } from "@/hooks/customQuery";
+
+import type { IStatCardProps } from "@/components/common/card/StatCard";
+
+import { getOverview } from "@/api/dashboard/overview";
+import useWorkspaceStore from "@/store/useWorkspaceStore";
+
+// 변화율 퍼센트 문자열로 변환
+const toRate = (rate: number) => `${Math.abs(rate).toFixed(1)}%`;
+
+// API 응답 KPI 카드 형식으로 변환
+function toKpis(metrics: IMetricsResponse): IStatCardProps[] {
+ return [
+ {
+ title: "클릭수",
+ value: metrics.clicks.toLocaleString(),
+ trend: {
+ direction: metrics.clickChangeRate >= 0 ? "up" : "down",
+ value: toRate(metrics.clickChangeRate),
+ },
+ },
+ {
+ title: "노출수",
+ value: metrics.impressions.toLocaleString(),
+ trend: {
+ direction: metrics.impressionChangeRate >= 0 ? "up" : "down",
+ value: toRate(metrics.impressionChangeRate),
+ },
+ },
+ {
+ title: "전환율",
+ value: `${metrics.conversion.toFixed(1)}%`,
+ trend: {
+ direction: metrics.cvrChangeRate >= 0 ? "up" : "down",
+ value: toRate(metrics.cvrChangeRate),
+ },
+ },
+ {
+ title: "ROAS",
+ value: `${metrics.ROAS.toFixed(1)}%`,
+ trend: {
+ direction: metrics.ROASChangeRate >= 0 ? "up" : "down",
+ value: toRate(metrics.ROASChangeRate),
+ },
+ },
+ ];
+}
+
+// 통합 지표 조회
+export function useOverviewMetrics() {
+ const orgId = useWorkspaceStore((s) => s.selectedOrgId);
+
+ return useCoreQuery(
+ ["overview", "metrics", orgId],
+ () => getOverview(orgId!),
+ {
+ enabled: !!orgId,
+ select: toKpis,
+ },
+ );
+}
diff --git a/src/hooks/dashboard/useOverviewRoasRankings.ts b/src/hooks/dashboard/useOverviewRoasRankings.ts
new file mode 100644
index 00000000..40db7ad9
--- /dev/null
+++ b/src/hooks/dashboard/useOverviewRoasRankings.ts
@@ -0,0 +1,49 @@
+import type {
+ IPlatformRankingItem,
+ TProviderType,
+} from "@/types/dashboard/overview";
+
+import { useCoreQuery } from "@/hooks/customQuery";
+
+import { getOverview, getRoasRankings } from "@/api/dashboard/overview";
+import useWorkspaceStore from "@/store/useWorkspaceStore";
+
+const PROVIDERS: TProviderType[] = ["GOOGLE", "NAVER", "KAKAO"];
+
+// 플랫폼별 ROAS 순위 + CTR/CVR 지표 병렬 조회 후 병합
+export function useOverviewRoasRankings() {
+ const orgId = useWorkspaceStore((s) => s.selectedOrgId);
+
+ return useCoreQuery(
+ ["overview", "roasRankings", orgId],
+ async (): Promise => {
+ // ROAS 순위 + 각 플랫폼 지표 병렬 호출
+ const [rankingsRes, ...metricsResults] = await Promise.all([
+ getRoasRankings(orgId!),
+ ...PROVIDERS.map((p) => getOverview(orgId!, p).catch(() => null)),
+ ]);
+
+ const metricsMap = Object.fromEntries(
+ PROVIDERS.map((p, i) => [p, metricsResults[i]]),
+ );
+
+ return rankingsRes.rankings.map((item) => {
+ const metrics = metricsMap[item.provider.toUpperCase()];
+ // CTR = 클릭수 / 노출수 * 100
+ const clickRate =
+ metrics && metrics.impressions > 0
+ ? (metrics.clicks / metrics.impressions) * 100
+ : undefined;
+
+ return {
+ ...item,
+ clickRate,
+ ctrDelta: metrics ? metrics.clickChangeRate : undefined,
+ conversionRate: metrics ? metrics.conversion : undefined,
+ conversionDelta: metrics ? metrics.cvrChangeRate : undefined,
+ };
+ });
+ },
+ { enabled: !!orgId },
+ );
+}
diff --git a/src/hooks/faq/useFaq.ts b/src/hooks/faq/useFaq.ts
deleted file mode 100644
index 90f67717..00000000
--- a/src/hooks/faq/useFaq.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-// hooks/faq/useFaq.ts
-import { useMemo } from 'react';
-import { keepPreviousData } from '@tanstack/react-query';
-
-import type { TFaqCategory, TFetchFaqsResponse } from '@/types/faq/faq';
-
-import { useCoreQuery } from '@/hooks/customQuery';
-
-import { getFaqs, searchFaqs } from '@/api/faq/faq';
-import { faqKeys } from '@/api/faq/faq.keys';
-
-type TFaqListParams = { category: TFaqCategory; page: number; size: number };
-type TFaqSearchParams = { keyword: string; category?: TFaqCategory; page: number; size: number };
-
-//조회
-export function useGetFaqs(params: TFaqListParams, options?: Parameters>[2]) {
- const stable = useMemo(() => params, [params.category, params.page, params.size]);
-
- return useCoreQuery(faqKeys.list(stable), () => getFaqs(stable), {
- placeholderData: keepPreviousData,
- ...options,
- });
-}
-
-// 검색
-export function useSearchFaqs(params: TFaqSearchParams, options?: Parameters>[2]) {
- const stable = useMemo(() => ({ ...params, keyword: params.keyword.trim() }), [params.keyword, params.category, params.page, params.size]);
- return useCoreQuery(faqKeys.search(stable), () => searchFaqs(stable), {
- enabled: stable.keyword.length > 0,
- placeholderData: keepPreviousData,
- ...options,
- });
-}
diff --git a/src/hooks/home/useDateCourseStates.ts b/src/hooks/home/useDateCourseStates.ts
deleted file mode 100644
index 39e50c26..00000000
--- a/src/hooks/home/useDateCourseStates.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { useCoreQuery } from '@/hooks/customQuery';
-
-import { getDateCourseSavedCount } from '@/api/home/dateCourse';
-import { HomeKeys } from '@/queryKey/queryKey';
-
-// 데이트 코스 저장 횟수 훅
-export const useDateCourseSavedCount = () => {
- return useCoreQuery(HomeKeys.dateCourseSave().queryKey, getDateCourseSavedCount, {
- gcTime: 15 * 60 * 1000, // 15분
- retry: 3,
- });
-};
diff --git a/src/hooks/home/useDatePlaceStates.ts b/src/hooks/home/useDatePlaceStates.ts
deleted file mode 100644
index 35c60df8..00000000
--- a/src/hooks/home/useDatePlaceStates.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { useCoreQuery } from '../customQuery';
-
-import { getMonthlyDatePlaceStates } from '@/api/home/dateTimes';
-import { HomeKeys } from '@/queryKey/queryKey';
-
-export const useMonthlyPlaceStates = () => {
- return useCoreQuery(HomeKeys.monthlyPlaceStates().queryKey, () => getMonthlyDatePlaceStates(), {
- gcTime: 15 * 60 * 1000,
- retry: 3,
- });
-};
diff --git a/src/hooks/home/useDateTimes.ts b/src/hooks/home/useDateTimes.ts
deleted file mode 100644
index 225e46a9..00000000
--- a/src/hooks/home/useDateTimes.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { useCoreQuery } from '@/hooks/customQuery';
-
-import { getDateTimeStates } from '@/api/home/dateTimes';
-import { HomeKeys } from '@/queryKey/queryKey';
-
-export const useDateTimeStates = () => {
- return useCoreQuery(HomeKeys.dateTimes().queryKey, () => getDateTimeStates(), { staleTime: 5 * 60 * 1000, gcTime: 15 * 60 * 1000, retry: 3 });
-};
diff --git a/src/hooks/home/useKeywordStates.ts b/src/hooks/home/useKeywordStates.ts
deleted file mode 100644
index 3cc4d4d7..00000000
--- a/src/hooks/home/useKeywordStates.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { useCoreQuery } from '@/hooks/customQuery';
-
-import { getWeeklyKeywords } from '@/api/home/keyword';
-import { HomeKeys } from '@/queryKey/queryKey';
-
-// 이번 주 인기 키워드 훅
-export const useWeeklyKeywords = () => {
- return useCoreQuery(HomeKeys.keywords().queryKey, getWeeklyKeywords, {
- gcTime: 30 * 60 * 1000,
- retry: 3,
- });
-};
diff --git a/src/hooks/home/useUserGrade.ts b/src/hooks/home/useUserGrade.ts
deleted file mode 100644
index bc79b16a..00000000
--- a/src/hooks/home/useUserGrade.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { useCoreQuery } from '@/hooks/customQuery';
-
-import { getUserGrade } from '@/api/home/level';
-import { HomeKeys } from '@/queryKey/queryKey';
-
-// 사용자 등급 정보 훅
-export const useUserGrade = () => {
- return useCoreQuery(HomeKeys.getUserGrade().queryKey, () => getUserGrade(), {
- gcTime: 15 * 60 * 1000, // 15분
- retry: 3,
- });
-};
diff --git a/src/hooks/home/useUserRegion.ts b/src/hooks/home/useUserRegion.ts
deleted file mode 100644
index bcb7ac99..00000000
--- a/src/hooks/home/useUserRegion.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { useCoreMutation, useCoreQuery } from '../customQuery';
-
-import { getUserRegion, patchUserRegion } from '@/api/home/region';
-import { HomeKeys } from '@/queryKey/queryKey';
-
-export function useUserRegion() {
- return useCoreMutation(patchUserRegion);
-}
-
-export function useGetUserRegion() {
- return useCoreQuery(HomeKeys.userRegion().queryKey, getUserRegion);
-}
diff --git a/src/hooks/home/useWeather.ts b/src/hooks/home/useWeather.ts
deleted file mode 100644
index cb9cc3c9..00000000
--- a/src/hooks/home/useWeather.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { getPrecipitation, getWeeklyWeatherRecommendation } from '../../api/home/weather';
-import { useCoreQuery } from '../customQuery';
-
-import { HomeKeys } from '@/queryKey/queryKey';
-
-// 주간 날씨 추천 훅
-export const useWeatherForecast = ({ startDate, regionId }: { startDate: string; regionId: number }) => {
- return useCoreQuery(HomeKeys.weather(startDate, regionId).queryKey, () => getWeeklyWeatherRecommendation({ startDate, regionId: regionId! }), {
- staleTime: 1000 * 60 * 30,
- enabled: !!startDate && !!regionId,
- });
-};
-
-export const useRainyInfo = ({ startDate, regionId }: { startDate: string; regionId: number }) => {
- return useCoreQuery(HomeKeys.rainyInfo(startDate, regionId).queryKey, () => getPrecipitation({ startDate, regionId: regionId! }), {
- staleTime: 1000 * 60 * 30,
- enabled: !!startDate && !!regionId,
- });
-};
diff --git a/src/hooks/notice/useNotice.ts b/src/hooks/notice/useNotice.ts
deleted file mode 100644
index db2ca05c..00000000
--- a/src/hooks/notice/useNotice.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import { useMemo } from 'react';
-import { keepPreviousData } from '@tanstack/react-query';
-
-import type { TFetchNoticeDetailResponse, TFetchNoticesResponse } from '@/types/notice/notice';
-
-import { useCoreQuery } from '@/hooks/customQuery';
-
-import { getNoticeDetail, getNotices, searchNotices } from '@/api/notice/notice';
-import { noticeKeys } from '@/api/notice/notice.keys';
-
-// 목록 조회 시 넘길 파라미터 타입
-type TListParams = {
- category: 'SERVICE' | 'SYSTEM';
- page: number;
- size: number;
-};
-
-// 검색 시 넘길 파라미터 타입
-type TSearchParams = {
- keyword: string;
- page: number;
- size: number;
- category?: 'SERVICE' | 'SYSTEM';
-};
-
-export function useNotice() {
- // 공지 목록 조회 훅
- const useGetNotices = (params: TListParams, options?: Parameters>[2]) => {
- const stable = useMemo(
- () => ({
- category: params.category,
- page: params.page,
- size: params.size,
- }),
- [params.category, params.page, params.size],
- );
-
- return useCoreQuery(noticeKeys.list(stable), () => getNotices(stable), {
- placeholderData: keepPreviousData,
- ...options,
- });
- };
-
- // 공지 상세
- const useGetNoticeDetail = (id: number, options?: Parameters>[2]) =>
- useCoreQuery(noticeKeys.detail(id), () => getNoticeDetail(id), {
- enabled: Number.isFinite(id) && id > 0,
- ...options,
- });
-
- // 공지 검색
- const useSearchNotices = (params: TSearchParams, options?: Parameters>[2]) => {
- const stable = useMemo(() => ({ ...params, keyword: params.keyword.trim() }), [params.keyword, params.page, params.size, params.category]);
-
- return useCoreQuery(noticeKeys.search(stable), () => searchNotices(stable), {
- enabled: stable.keyword.length > 0,
- placeholderData: keepPreviousData,
- ...options,
- });
- };
-
- return {
- useGetNotices,
- useGetNoticeDetail,
- useSearchNotices,
- };
-}
diff --git a/src/hooks/settingAlarm/useAlarms.ts b/src/hooks/settingAlarm/useAlarms.ts
deleted file mode 100644
index bac45af4..00000000
--- a/src/hooks/settingAlarm/useAlarms.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-// hooks/settingAlarm/useAlarms.ts
-import { useQueryClient } from '@tanstack/react-query';
-
-import type { TAlarmSettings, TGetAlarmSettingsResp, TPatchAlarmSettingsResp } from '@/types/settingAlarm/alarm';
-
-import { useCoreMutation, useCoreQuery } from '@/hooks/customQuery';
-
-import { getAlarmSettings, patchAlarmSettings } from '@/api/settingAlarm/alarm';
-
-// 조회
-export function useGetAlarmSettings() {
- return useCoreQuery(['alarmSettings'], getAlarmSettings, {
- select: (resp) => resp.result,
- refetchOnWindowFocus: false,
- });
-}
-
-// 업데이트
-export function usePatchAlarmSettings() {
- const qc = useQueryClient();
- return useCoreMutation(patchAlarmSettings, {
- onSuccess: () => {
- qc.invalidateQueries({ queryKey: ['alarmSettings'] });
- },
- });
-}
diff --git a/src/hooks/sidebar/useSidebar.ts b/src/hooks/sidebar/useSidebar.ts
new file mode 100644
index 00000000..db4b3ae0
--- /dev/null
+++ b/src/hooks/sidebar/useSidebar.ts
@@ -0,0 +1,61 @@
+import { useCallback, useEffect, useRef, useState } from "react";
+import { useLocation } from "react-router-dom";
+
+import { mainNavSidebar } from "@/utils/navigation/mainNavSidebar";
+import { normalizePathname } from "@/utils/navigation/pathMatch";
+
+import useSidebarStore from "@/store/useSidebarStore";
+
+export const useSidebar = () => {
+ const location = useLocation();
+ const [openId, setOpenId] = useState(null);
+ const isCollapsed = useSidebarStore((s) => s.isCollapsed);
+ const setIsCollapsed = useSidebarStore((s) => s.setIsCollapsed);
+
+ const lastPathRef = useRef("");
+ const pathname = normalizePathname(location.pathname);
+
+ const { childIdToParentId } = mainNavSidebar;
+
+ useEffect(() => {
+ if (isCollapsed) return;
+ const parentId = mainNavSidebar.resolveParentId(pathname);
+
+ if (pathname !== lastPathRef.current) {
+ setOpenId(parentId ?? null);
+ lastPathRef.current = pathname;
+ }
+ }, [pathname, isCollapsed]);
+
+ const toggleSidebar = () => {
+ setIsCollapsed(!isCollapsed);
+ if (!isCollapsed) lastPathRef.current = "";
+ setOpenId(null);
+ };
+
+ const toggleOpenId = useCallback((id: string) => {
+ setOpenId((prev) => (prev === id ? null : id));
+ }, []);
+
+ const handleItemClick = (id: string, hasChildren: boolean) => {
+ if (hasChildren) {
+ toggleOpenId(id);
+ } else {
+ const parentId = childIdToParentId.get(id) ?? null;
+
+ if (!parentId || parentId !== openId) {
+ setOpenId(null);
+ }
+ }
+ };
+
+ return {
+ isCollapsed,
+ openId,
+ setOpenId,
+ pathname,
+ toggleSidebar,
+ handleItemClick,
+ toggleOpenId,
+ };
+};
diff --git a/src/hooks/useDebounce.ts b/src/hooks/useDebounce.ts
deleted file mode 100644
index b05e5f76..00000000
--- a/src/hooks/useDebounce.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { useEffect, useState } from 'react';
-
-const useDebounce = (value: string, delay = 30000) => {
- const [debouncedValue, setDebouncedValue] = useState(value);
-
- useEffect(() => {
- const handler = setTimeout(() => {
- setDebouncedValue(value);
- }, delay);
-
- return () => {
- clearTimeout(handler);
- };
- }, [value, delay]);
-
- return debouncedValue;
-};
-
-export default useDebounce;
diff --git a/src/index.css b/src/index.css
index f1d8c73c..92dc79cd 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1 +1,542 @@
@import "tailwindcss";
+
+@custom-variant tablet (@media (max-width: 1024px));
+
+* {
+ font-family: "Pretendard";
+}
+
+html,
+body,
+#root {
+ height: 100dvh;
+ overflow-x: hidden;
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ min-height: 100dvh;
+ height: 100%;
+}
+
+button {
+ cursor: pointer;
+}
+
+/* Hide horizontal scrollbar for mock timeline */
+.landing-guide-timeline .custom-scrollbar::-webkit-scrollbar {
+ height: 0px;
+}
+.landing-guide-timeline .custom-scrollbar {
+ scrollbar-width: none;
+}
+.landing-guide-timeline .custom-scrollbar::-webkit-scrollbar-thumb {
+ background: transparent;
+}
+
+@theme {
+ --color-logo-1: #2eb4ff;
+ --color-logo-2: #6088fe;
+ /* logo-2와 동일 hue, 살짝만 어두운 톤 (solid CTA 호버용) */
+ --color-logo-2-dark: #4d67e5;
+
+ --color-brand-900: #000000;
+ --color-brand-800: #001f5b;
+ --color-brand-700: #213e68;
+ --color-brand-600: #466a9c;
+ --color-brand-500: #88c1ff;
+ --color-brand-400: #dce7f2;
+ --color-brand-300: #f9fafb;
+ --color-brand-200: #ffffff;
+
+ --color-chart-1: #0a3d91;
+ --color-chart-2: #0056b3;
+ --color-chart-3: #1485ff;
+ --color-chart-4: #00aeef;
+ --color-chart-5: #4fc3f7;
+ --color-chart-inactive: #f2f4f6;
+
+ --color-status-red: #ff2a4b;
+ --color-status-blue: #0084fe;
+ --color-status-green: #22c55e;
+ --color-status-yellow: #facc15;
+
+ --color-text-main: #212121;
+ --color-text-auth-sub: #546171;
+ --color-text-sub: #8b8b8f;
+ --color-text-placeholder: #c3c3c3;
+ --color-text-disabled: #b0b8c1;
+ --color-bg-disabled: #e5e8eb;
+ --color-bg-surface: #f6f6f6;
+
+ /* Landing (legacy 디자인 컬러를 토큰화) */
+ --color-landing-surface: #f5f5f7;
+ --color-landing-section: #f8f9fc;
+ --color-landing-pricing: #fafafa;
+ --color-landing-dark: #1e1e1e;
+ --color-footer-bg: #121212;
+ --color-footer-border: #2a2a2a;
+ --color-landing-muted: #6e6e73;
+
+ --color-social-kakao: #fee500;
+ --color-social-naver: #03c75a;
+ --color-social-google: #ffffff;
+ --color-social-text-kakao: #3a1d1d;
+
+ --height-input: 56px;
+ --height-button-big: 55px;
+ --height-button-small: 40px;
+
+ --radius-component-sm: 0.5rem;
+ --radius-component-md: 1rem;
+ --radius-component-lg: 1.5rem;
+
+ --padding-none: 0;
+ --padding-sm: 1rem;
+ --padding-md: 1.5rem;
+ --padding-lg: 2rem;
+
+ --max-width-sm: 384px;
+ --max-width-md: 512px;
+ --max-width-lg: 672px;
+ --max-width-xl: 896px;
+
+ /* 애니메이션 이징 */
+ --ease-smooth: cubic-bezier(0.25, 0.1, 0.25, 1);
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
+
+ /* 애니메이션 속도 */
+ --duration-fast: 150ms;
+ --duration-normal: 250ms;
+}
+
+@font-face {
+ font-family: "Pretendard";
+ src: url("/fonts/PretendardVariable.woff2") format("font-woff2");
+ font-display: swap;
+ font-weight: 45 920;
+}
+
+@layer utilities {
+ .h-input {
+ height: var(--height-input);
+ }
+ .h-button-big {
+ height: var(--height-button-big);
+ }
+ .h-button-small {
+ height: var(--height-button-small);
+ }
+
+ .rounded-component-sm {
+ border-radius: var(--radius-component-sm);
+ }
+ .rounded-component-md {
+ border-radius: var(--radius-component-md);
+ }
+ .rounded-component-lg {
+ border-radius: var(--radius-component-lg);
+ }
+
+ .max-w-modal-sm {
+ max-width: var(--max-width-sm);
+ }
+ .max-w-modal-md {
+ max-width: var(--max-width-md);
+ }
+ .max-w-modal-lg {
+ max-width: var(--max-width-lg);
+ }
+ .max-w-modal-xl {
+ max-width: var(--max-width-xl);
+ }
+
+ .p-modal-none {
+ padding: var(--padding-none);
+ }
+ .p-modal-sm {
+ padding: var(--padding-sm);
+ }
+ .p-modal-md {
+ padding: var(--padding-md);
+ }
+ .p-modal-lg {
+ padding: var(--padding-lg);
+ }
+
+ /* 기본 트랜지션 */
+ .transition-smooth {
+ transition-property:
+ transform, opacity, background-color, border-color, color, box-shadow;
+ transition-duration: var(--duration-normal);
+ transition-timing-function: var(--ease-smooth);
+ }
+
+ .transition-fast {
+ transition-property:
+ transform, opacity, background-color, border-color, color, box-shadow;
+ transition-duration: var(--duration-fast);
+ transition-timing-function: var(--ease-out);
+ }
+
+ /* 클릭 */
+ .active-scale {
+ transition: transform var(--duration-fast) var(--ease-in-out);
+ }
+ .active-scale:active {
+ transform: scale(0.98);
+ }
+
+ .font-hero {
+ font-size: 54px;
+ font-weight: 700;
+ line-height: 140%;
+ }
+
+ .font-heading1 {
+ font-size: 30px;
+ font-weight: 600;
+ line-height: 130%;
+ }
+
+ .font-heading2 {
+ font-size: 28px;
+ font-weight: 600;
+ line-height: 130%;
+ }
+
+ .font-heading3 {
+ font-size: 24px;
+ font-weight: 500;
+ line-height: 130%;
+ }
+
+ .font-heading4 {
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 130%;
+ }
+
+ .font-body1 {
+ font-size: 16px;
+ font-weight: 500;
+ line-height: 140%;
+ }
+
+ .font-body2 {
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 140%;
+ }
+
+ .font-caption {
+ font-size: 12px;
+ font-weight: 500;
+ line-height: 130%;
+ }
+
+ .font-label {
+ font-size: 14px;
+ font-weight: 600;
+ line-height: 140%;
+ }
+
+ .shadow-Soft {
+ box-shadow: 0px 0px 16px 0px rgba(0, 0, 0, 0.1);
+ }
+
+ .shadow-Medium {
+ box-shadow: 0px 0px 16px 0px rgba(0, 0, 0, 0.2);
+ }
+
+ .shadow-card {
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.03);
+ }
+
+ .shadow-card-hover {
+ box-shadow: 0 12px 40px rgba(0, 0, 0, 0.08);
+ }
+
+ .checkbox {
+ appearance: none;
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+ background-color: #e5e8eb;
+ cursor: pointer;
+ position: relative;
+ transition:
+ background-color 0.2s ease-in-out,
+ border-color 0.2s ease-in-out;
+ flex-shrink: 0;
+ }
+
+ .checkbox:checked {
+ background-color: #0084fe;
+ background-image: url("./assets/icon/common/check-white.svg");
+ background-size: 60% 60%;
+ background-position: center;
+ background-repeat: no-repeat;
+ }
+
+ .checkbox:focus-visible {
+ outline: 2px solid #0084fe;
+ outline-offset: 2px;
+ }
+
+ /* 모달 애니메이션 */
+ @keyframes modal-fade-in {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+ }
+
+ @keyframes modal-fade-out {
+ from {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ }
+ }
+
+ @keyframes modal-scale-in {
+ from {
+ opacity: 0;
+ transform: scale(0.95);
+ }
+ to {
+ opacity: 1;
+ transform: scale(1);
+ }
+ }
+
+ @keyframes modal-scale-out {
+ from {
+ opacity: 1;
+ transform: scale(1);
+ }
+ to {
+ opacity: 0;
+ transform: scale(0.95);
+ }
+ }
+
+ .animate-modal-overlay {
+ animation: modal-fade-in var(--duration-normal) var(--ease-out);
+ }
+
+ .animate-modal-overlay-out {
+ animation: modal-fade-out var(--duration-fast) var(--ease-in) forwards;
+ }
+
+ .animate-modal-content {
+ animation: modal-scale-in var(--duration-normal) var(--ease-out);
+ }
+
+ .animate-modal-content-out {
+ animation: modal-scale-out var(--duration-fast) var(--ease-in) forwards;
+ }
+
+ /* 스크롤 애니메이션 */
+ @keyframes scroll {
+ from {
+ transform: translateX(0);
+ }
+ to {
+ transform: translateX(-50%);
+ }
+ }
+
+ .animate-scroll {
+ animation: scroll 30s linear infinite;
+ }
+
+ /* 슬라이드 텍스트 진입 애니메이션 */
+ @keyframes slide-fade-up {
+ from {
+ opacity: 0;
+ transform: translateY(10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+
+ .animate-slide-fade-up {
+ animation: slide-fade-up 350ms var(--ease-out) both;
+ animation-delay: 100ms;
+ }
+
+ /* 그래프 상승 애니메이션 */
+ @keyframes graph-up {
+ from {
+ transform: scaleY(0);
+ }
+ to {
+ transform: scaleY(1);
+ }
+ }
+
+ .animate-graph-up {
+ animation: graph-up 0.7s ease-out forwards;
+ transform-origin: bottom;
+ }
+
+ /* AI 버블 진입 전환 */
+ .bubble-transition {
+ transition-property: transform, opacity;
+ transition-duration: 300ms;
+ transition-timing-function: cubic-bezier(0.2, 1.05, 0.4, 1);
+ }
+
+ /* 로딩 애니메이션 */
+ @keyframes shimmer {
+ to {
+ transform: translateX(200%);
+ }
+ }
+
+ .animate-shimmer {
+ position: relative;
+ overflow: hidden;
+ }
+
+ .animate-shimmer::after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ transform: translateX(-100%);
+ background: linear-gradient(
+ 90deg,
+ transparent 0%,
+ rgba(255, 255, 255, 0.5) 50%,
+ transparent 100%
+ );
+ animation: shimmer 1.5s infinite linear;
+ }
+
+ /* AI 리포트 인쇄 — 드로어 패널 외 모든 요소 숨김 */
+ @media print {
+ body.ai-report-printing > *:not([data-drawer-portal]) {
+ display: none !important;
+ }
+
+ body.ai-report-printing [data-drawer-portal] {
+ position: static !important;
+ display: block !important;
+ }
+
+ body.ai-report-printing [data-print-hide] {
+ display: none !important;
+ }
+
+ body.ai-report-printing [data-drawer-portal] > div:last-child {
+ box-shadow: none !important;
+ border-radius: 0 !important;
+ max-width: 100% !important;
+ height: auto !important;
+ transform: none !important;
+ }
+
+ @page {
+ margin: 16mm;
+ }
+ }
+
+ /* AI 요약 버튼 스파클 pulse 애니메이션 */
+ @keyframes sparkle-pulse {
+ 0%,
+ 100% {
+ transform: scale(1);
+ opacity: 0.7;
+ }
+ 50% {
+ transform: scale(1.2);
+ opacity: 1;
+ }
+ }
+
+ .animate-sparkle-pulse {
+ animation: sparkle-pulse 2.8s ease-in-out infinite;
+ }
+
+ @media (prefers-reduced-motion: reduce) {
+ /* 스파클 */
+ .animate-sparkle-pulse {
+ animation: none;
+ opacity: 1;
+ }
+
+ /* 인트로 텍스트 진입 — 즉시 표시 */
+ .animate-slide-fade-up {
+ animation: none;
+ opacity: 1;
+ transform: none;
+ }
+
+ /* 인트로 캐러셀 — 위치 이동 중단 */
+ .animate-scroll {
+ animation: none;
+ }
+
+ /* 바 차트 — 즉시 완성 상태로 표시 */
+ .animate-graph-up {
+ animation: none;
+ transform: scaleY(1);
+ }
+
+ /* AI 버블 — transform/opacity 전환 제거 */
+ .bubble-transition {
+ transition: none;
+ }
+
+ /* 모달 — scale 제거, opacity 전환만 유지 */
+ .animate-modal-content {
+ animation: modal-fade-in var(--duration-normal) var(--ease-out);
+ }
+ .animate-modal-content-out {
+ animation: modal-fade-out var(--duration-fast) var(--ease-in) forwards;
+ }
+
+ /* 토스트 — translateY 제거, opacity 전환만 유지 */
+ @keyframes fade-in-up-reduced {
+ from {
+ opacity: 0;
+ transform: translate(-50%, 0);
+ }
+ to {
+ opacity: 1;
+ transform: translate(-50%, 0);
+ }
+ }
+ .animate-fade-in-up {
+ animation: fade-in-up-reduced 200ms var(--ease-out) forwards;
+ }
+ }
+
+ /* 토스트 애니메이션 */
+ @keyframes fade-in-up {
+ from {
+ opacity: 0;
+ transform: translate(-50%, 12px);
+ }
+ to {
+ opacity: 1;
+ transform: translate(-50%, 0);
+ }
+ }
+
+ .animate-fade-in-up {
+ animation: fade-in-up 0.2s var(--ease-out) both;
+ }
+}
+
+/* (removed) react-calendar-timeline overrides — now using custom mock timeline */
diff --git a/src/layout/GlobalLayout.tsx b/src/layout/GlobalLayout.tsx
new file mode 100644
index 00000000..def31135
--- /dev/null
+++ b/src/layout/GlobalLayout.tsx
@@ -0,0 +1,14 @@
+import { Outlet } from "react-router-dom";
+import { Toaster } from "sonner";
+
+import ModalProvider from "@/components/modal/ModalProvider";
+
+export default function GlobalLayout() {
+ return (
+ <>
+
+
+
+ >
+ );
+}
diff --git a/src/layout/auth/AuthLayout.tsx b/src/layout/auth/AuthLayout.tsx
index f25bc1e5..ae13f1b0 100644
--- a/src/layout/auth/AuthLayout.tsx
+++ b/src/layout/auth/AuthLayout.tsx
@@ -1,3 +1,11 @@
+import { Outlet } from "react-router-dom";
+
export default function AuthLayout() {
- return AuthLayout
;
+ return (
+
+ );
}
diff --git a/src/layout/common/Layout.tsx b/src/layout/common/Layout.tsx
deleted file mode 100644
index c779599a..00000000
--- a/src/layout/common/Layout.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function Layout() {
- return Layout
;
-}
diff --git a/src/layout/main/MainLayout.tsx b/src/layout/main/MainLayout.tsx
new file mode 100644
index 00000000..8c8820bb
--- /dev/null
+++ b/src/layout/main/MainLayout.tsx
@@ -0,0 +1,113 @@
+import { type ReactNode, useEffect, useMemo, useState } from "react";
+import { Outlet, useLocation } from "react-router-dom";
+
+import { mainNav } from "@/constants/sidebarNav";
+
+import { isPathMatch, normalizePathname } from "@/utils/navigation/pathMatch";
+
+import { useCoreQuery } from "@/hooks/customQuery";
+
+import Sidebar from "@/components/sidebar/Sidebar";
+
+import { getMyInfo } from "@/api/auth/auth";
+import { getMyWorkspaces, getSavedWorkspace } from "@/api/workspace/org";
+import useWorkspaceStore from "@/store/useWorkspaceStore";
+
+export default function MainLayout() {
+ useCoreQuery(["myInfo"], getMyInfo);
+ const location = useLocation();
+ const [headerRight, setHeaderRight] = useState(null);
+
+ const setSelectedOrgId = useWorkspaceStore((s) => s.setSelectedOrgId);
+
+ const savedWorkspaceQuery = useCoreQuery(
+ ["savedWorkspace"],
+ getSavedWorkspace,
+ );
+ const { data: savedData } = savedWorkspaceQuery;
+ const { data: workspaces } = useCoreQuery(["my-workspaces"], getMyWorkspaces);
+ const selectedOrgId = useWorkspaceStore((s) => s.selectedOrgId);
+
+ useEffect(() => {
+ // 모두 완료되었을 때 시작
+ if (!workspaces?.length || !savedWorkspaceQuery.isFetched) return;
+ if (selectedOrgId !== null) return;
+
+ const savedId = savedData?.orgId;
+ const isExist = workspaces.some((w) => w.orgId === savedId);
+
+ // 1. 현재 워크스페이스 조회 API 데이터
+ if (savedId !== undefined && isExist) {
+ setSelectedOrgId(savedId);
+ }
+ // 2. isCurrentWorkspace 또는 첫 번째
+ else {
+ const currentOrg = workspaces.find((w) => w.isCurrentWorkspace);
+ setSelectedOrgId(currentOrg?.orgId || workspaces[0].orgId);
+ }
+ }, [
+ workspaces,
+ savedWorkspaceQuery.isFetched,
+ savedData,
+ setSelectedOrgId,
+ selectedOrgId,
+ ]);
+
+ const pathname = normalizePathname(location.pathname);
+ const { parentLabel, currentLabel } = useMemo(() => {
+ for (const parent of mainNav) {
+ const children = parent.children ?? [];
+ const exactChild = children.find((c) =>
+ c.path ? normalizePathname(c.path) === pathname : false,
+ );
+ if (exactChild) {
+ return { parentLabel: parent.label, currentLabel: exactChild.label };
+ }
+
+ const matchChild = children.find((c) =>
+ c.path ? isPathMatch(pathname, c.path) : false,
+ );
+ if (matchChild) {
+ return { parentLabel: parent.label, currentLabel: matchChild.label };
+ }
+
+ if (parent.path && isPathMatch(pathname, parent.path)) {
+ return { parentLabel: parent.label, currentLabel: parent.label };
+ }
+ }
+
+ return { parentLabel: "", currentLabel: "" };
+ }, [pathname]);
+
+ return (
+
+ );
+}
diff --git a/src/layout/workspace/WorkspaceManageLayout.tsx b/src/layout/workspace/WorkspaceManageLayout.tsx
new file mode 100644
index 00000000..21dfc395
--- /dev/null
+++ b/src/layout/workspace/WorkspaceManageLayout.tsx
@@ -0,0 +1,33 @@
+import { NavLink, Outlet, useParams } from "react-router-dom";
+
+const tabLinkClass = ({ isActive }: { isActive: boolean }) =>
+ `px-4 py-2 font-body1 border-b-2 -mb-px transition-colors ${
+ isActive
+ ? "border-chart-3 text-chart-3"
+ : "border-transparent text-text-sub hover:text-text-main"
+ }`;
+
+export default function WorkspaceManageLayout() {
+ const { workspaceId } = useParams();
+
+ return (
+
+
+
+ 기본 정보
+
+
+ 멤버 관리
+
+
+
+
+
+ );
+}
diff --git a/src/lib/axiosInstance.ts b/src/lib/axiosInstance.ts
new file mode 100644
index 00000000..b2ae80b8
--- /dev/null
+++ b/src/lib/axiosInstance.ts
@@ -0,0 +1,117 @@
+import axios, { type AxiosRequestConfig } from "axios";
+
+import type { IApiErrorResponse } from "@/types/common/common";
+
+import useAuthStore from "@/store/useAuthStore";
+
+const BASE_URL = import.meta.env.VITE_API_BASE_URL;
+
+// 개발 환경에서는 Vite proxy(`/api` → `VITE_API_TARGET_URL`)를 활용하기 위해
+// baseURL이 없어도 상대경로 요청이 가능하도록 허용합니다.
+if (import.meta.env.PROD && !BASE_URL) {
+ throw new Error("API 서버 주소(VITE_API_BASE_URL)가 설정되지 않았습니다.");
+}
+
+const axiosConfig: AxiosRequestConfig = {
+ baseURL: BASE_URL || undefined,
+ withCredentials: true,
+};
+
+export const axiosInstance = axios.create(axiosConfig);
+export const authInstance = axios.create(axiosConfig);
+
+axiosInstance.interceptors.request.use(
+ (config) => {
+ const token = useAuthStore.getState().accessToken;
+
+ if (token) {
+ config.headers.Authorization = `Bearer ${token}`;
+ }
+ return config;
+ },
+ (error) => {
+ return Promise.reject(error);
+ },
+);
+
+let isRefreshing = false;
+interface IRefreshSubscriber {
+ resolve: (token: string) => void;
+ reject: (error: unknown) => void;
+}
+
+let refreshSubscribers: IRefreshSubscriber[] = [];
+
+const onRefreshed = (accessToken: string) => {
+ refreshSubscribers.forEach(({ resolve }) => resolve(accessToken));
+ refreshSubscribers = [];
+};
+
+const onRefreshFailed = (error: unknown) => {
+ refreshSubscribers.forEach(({ reject }) => reject(error));
+ refreshSubscribers = [];
+};
+
+const addRefreshSubscriber = (
+ resolve: (token: string) => void,
+ reject: (error: unknown) => void,
+) => {
+ refreshSubscribers.push({ resolve, reject });
+};
+
+axiosInstance.interceptors.response.use(
+ (response) => {
+ return response;
+ },
+ async (error) => {
+ const originalRequest = error.config;
+
+ if (error.response?.status === 401) {
+ if (isRefreshing) {
+ return new Promise((resolve, reject) => {
+ addRefreshSubscriber(
+ (accessToken: string) => {
+ originalRequest.headers.Authorization = `Bearer ${accessToken}`;
+ resolve(axiosInstance(originalRequest));
+ },
+ (refreshError: unknown) => {
+ reject(refreshError);
+ },
+ );
+ });
+ }
+
+ if (
+ originalRequest.url?.includes("/api/auth/reissue") ||
+ originalRequest._retry
+ ) {
+ useAuthStore.getState().logout();
+ return Promise.reject(error);
+ }
+
+ originalRequest._retry = true;
+ isRefreshing = true;
+
+ try {
+ const { data } = await authInstance.post("/api/auth/reissue");
+
+ const newAccessToken = data.data.accessToken;
+
+ useAuthStore.getState().setAccessToken(newAccessToken);
+ onRefreshed(newAccessToken);
+
+ originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
+ return axiosInstance(originalRequest);
+ } catch (refreshError) {
+ onRefreshFailed(refreshError);
+ useAuthStore.getState().logout();
+ return Promise.reject(refreshError);
+ } finally {
+ isRefreshing = false;
+ refreshSubscribers = [];
+ }
+ }
+
+ return Promise.reject((error.response?.data as IApiErrorResponse) ?? error);
+ },
+);
diff --git a/src/lib/getImageUrl.ts b/src/lib/getImageUrl.ts
new file mode 100644
index 00000000..f6523eda
--- /dev/null
+++ b/src/lib/getImageUrl.ts
@@ -0,0 +1,9 @@
+export const getImageUrl = (url?: string | null): string | null => {
+ if (!url) return null;
+ if (url.startsWith("http://") || url.startsWith("https://")) {
+ return url;
+ }
+ const BASE_URL = import.meta.env.VITE_API_BASE_URL;
+ if (!BASE_URL) return url;
+ return new URL(url, BASE_URL).toString();
+};
diff --git a/src/lib/queryClient.ts b/src/lib/queryClient.ts
new file mode 100644
index 00000000..18f647a1
--- /dev/null
+++ b/src/lib/queryClient.ts
@@ -0,0 +1,13 @@
+import { QueryClient } from "@tanstack/react-query";
+
+export const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ retry: 1,
+ staleTime: 1000 * 60 * 5,
+ gcTime: 1000 * 60 * 10,
+ refetchOnWindowFocus: false,
+ refetchOnReconnect: true,
+ },
+ },
+});
diff --git a/src/main.tsx b/src/main.tsx
index bef5202a..086c7ba1 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,10 +1,17 @@
-import { StrictMode } from 'react'
-import { createRoot } from 'react-dom/client'
-import './index.css'
-import App from './App.tsx'
+import "./index.css";
-createRoot(document.getElementById('root')!).render(
+import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
+import { QueryClientProvider } from "@tanstack/react-query";
+
+import App from "./App.tsx";
+
+import { queryClient } from "@/lib/queryClient";
+
+createRoot(document.getElementById("root")!).render(
-
+
+
+
,
-)
+);
diff --git a/src/pages/ads/list/AdsListPage.tsx b/src/pages/ads/list/AdsListPage.tsx
new file mode 100644
index 00000000..196953e8
--- /dev/null
+++ b/src/pages/ads/list/AdsListPage.tsx
@@ -0,0 +1,163 @@
+import { useNavigate } from "react-router-dom";
+import { useQueryClient } from "@tanstack/react-query";
+
+import type { ICampaign } from "@/types/ads/campaign";
+
+import { useControlModal } from "@/hooks/ads/useControlModal";
+import { useCoreQuery } from "@/hooks/customQuery";
+
+import CampaignTable from "@/components/ads/CampaignTable";
+import Card from "@/components/common/card/Card";
+import ControlBox from "@/components/common/controlbox/ControlBox";
+import Modal from "@/components/common/modal/Modal";
+import ModalContent from "@/components/common/modal/ModalContent";
+
+import { getCampaignList, updateAllCampaignStatus } from "@/api/ads/ads";
+import WarnCircleIcon from "@/assets/icon/common/warn-circle.svg?react";
+import useWorkspaceStore from "@/store/useWorkspaceStore";
+
+export default function AdsListPage() {
+ const navigate = useNavigate();
+ const queryClient = useQueryClient();
+ const orgId = useWorkspaceStore((s) => s.selectedOrgId);
+
+ const { data: campaigns = [], isLoading } = useCoreQuery(
+ ["campaigns", orgId],
+ () => getCampaignList(orgId!),
+ { enabled: !!orgId },
+ );
+
+ const invalidateCampaigns = () => {
+ queryClient.invalidateQueries({ queryKey: ["campaigns", orgId] });
+ };
+
+ const stopAll = useControlModal({
+ successMessage: "전체 캠페인의 모든 광고 노출이 중단되었습니다.",
+ errorMessage: "중단 처리에 실패하였습니다.",
+ onSuccess: invalidateCampaigns,
+ });
+
+ const resumeAll = useControlModal({
+ successMessage: "전체 캠페인의 광고 노출이 재개되었습니다.",
+ errorMessage: "재개 처리에 실패하였습니다.",
+ onSuccess: invalidateCampaigns,
+ });
+
+ const handleCampaignClick = (id: number) => {
+ navigate(`/ads/${orgId}/${id}`);
+ };
+
+ const handleCampaignGroupClick = () => {
+ navigate("/ads/campaignGroup");
+ };
+
+ const hasCampaigns = campaigns.length > 0;
+ const hasActiveCampaign = campaigns.some((c) => c.status === "ON_GOING");
+
+ if (isLoading) {
+ return (
+
+
+ 데이터를 불러오는 중입니다...
+
+
+ );
+ }
+
+ return (
+
+ {/* 테이블 */}
+
+ handleCampaignClick(id)}
+ />
+
+ {/* 하단 배너 */}
+
+
+ {hasCampaigns &&
+ (hasActiveCampaign ? (
+
+ ) : (
+
+ ))}
+
+
+ {/* 전체 캠페인 중단 모달 */}
+
+ }
+ title="전체 캠페인을 중단하시겠습니까?"
+ description="모든 캠페인의 광고 노출이 즉시 중단됩니다."
+ buttonText="중단하기"
+ onConfirm={() =>
+ stopAll.handleConfirm(() =>
+ updateAllCampaignStatus(orgId!, "PAUSED"),
+ )
+ }
+ isLoading={stopAll.isLoading}
+ variant="danger"
+ />
+
+
+ {/* 전체 캠페인 재개 모달 */}
+
+ }
+ title="전체 캠페인을 재개하시겠습니까?"
+ description="모든 캠페인의 광고 노출이 즉시 재개됩니다."
+ buttonText="시작하기"
+ onConfirm={() =>
+ resumeAll.handleConfirm(() =>
+ updateAllCampaignStatus(orgId!, "ON_GOING"),
+ )
+ }
+ isLoading={resumeAll.isLoading}
+ variant="primary"
+ />
+
+
+ );
+}
diff --git a/src/pages/ads/list/AdsManage.tsx b/src/pages/ads/list/AdsManage.tsx
deleted file mode 100644
index 3273ad39..00000000
--- a/src/pages/ads/list/AdsManage.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function AdsManage() {
- return AdsManage
;
-}
diff --git a/src/pages/ads/list/CampaignDetail.tsx b/src/pages/ads/list/CampaignDetail.tsx
new file mode 100644
index 00000000..02dfd716
--- /dev/null
+++ b/src/pages/ads/list/CampaignDetail.tsx
@@ -0,0 +1,233 @@
+import React from "react";
+import { useNavigate, useParams } from "react-router-dom";
+
+import type { TPlatform } from "@/types/ads/campaign";
+
+import { useAdList } from "@/hooks/ads/useAdList";
+import { useCampaignDetail } from "@/hooks/ads/useCampaignDetail";
+import { useControlModal } from "@/hooks/ads/useControlModal";
+
+import AdListTable from "@/components/ads/AdListTable";
+import Badge from "@/components/common/badge/Badge";
+import ControlBox from "@/components/common/controlbox/ControlBox";
+import Modal from "@/components/common/modal/Modal";
+import ModalContent from "@/components/common/modal/ModalContent";
+
+import { updateCampaignStatus } from "@/api/ads/ads";
+import LeftChevronIcon from "@/assets/icon/chevron/chervon-left.svg?react";
+import WarnCircleIcon from "@/assets/icon/common/warn-circle.svg?react";
+import GoogleLogo from "@/assets/logo/social-logo/circle/google-circle.svg?react";
+import KakaoLogo from "@/assets/logo/social-logo/circle/kakao-circle.svg?react";
+import NaverLogo from "@/assets/logo/social-logo/circle/naver-circle.svg?react";
+
+const LogoMap: Record = {
+ kakao: ,
+ google: ,
+ naver: ,
+};
+
+export default function CampaignDetail() {
+ const { orgId, projectId } = useParams<{
+ orgId: string;
+ projectId: string;
+ }>();
+ const { data, isLoading, refetch } = useCampaignDetail();
+
+ const { ads, isAdLoading, refetchAds } = useAdList(
+ orgId ? Number(orgId) : null,
+ projectId ? Number(projectId) : null,
+ );
+
+ const navigate = useNavigate();
+
+ const stopControl = useControlModal({
+ successMessage: "해당 캠페인의 모든 광고 운영이 중단되었습니다.",
+ errorMessage: "중단 처리에 실패하였습니다.",
+ onSuccess: () => {
+ refetch();
+ refetchAds();
+ },
+ });
+
+ const resumeControl = useControlModal({
+ successMessage: "해당 캠페인의 광고 운영이 재개되었습니다.",
+ errorMessage: "재개 처리에 실패하였습니다.",
+ onSuccess: () => {
+ refetch();
+ refetchAds();
+ },
+ });
+
+ if (isLoading) {
+ return (
+
+
+ 데이터를 불러오는 중입니다...
+
+
+ );
+ }
+
+ if (!data) {
+ return (
+
+ 정보를 불러올 수 없습니다.
+
+ );
+ }
+
+ return (
+
+
+
+ {/* header */}
+
+
+
+ {/* ads list */}
+ {isAdLoading ? (
+
+ 광고 목록을 불러오는 중입니다...
+
+ ) : (
+
+ )}
+
+ {/* campaign controlbox */}
+
+ {data.status === "ON_GOING" ? (
+
+ ) : data.status === "PAUSED" ? (
+
+ ) : null}
+
+
+
+
+
+ {/* 해당 캠페인 중단 */}
+
+ }
+ title="캠페인 운영을 중단하시겠습니까?"
+ description="해당 캠페인의 모든 광고 노출이 중단됩니다."
+ buttonText="중단하기"
+ onConfirm={() =>
+ stopControl.handleConfirm(() =>
+ updateCampaignStatus(Number(orgId), Number(projectId), "PAUSED"),
+ )
+ }
+ isLoading={stopControl.isLoading}
+ variant="danger"
+ />
+
+
+ {/* 해당 캠페인 재개 */}
+
+ }
+ title="캠페인 운영을 재개하시겠습니까?"
+ description="해당 캠페인의 모든 광고 노출이 다시 시작됩니다."
+ buttonText="시작하기"
+ onConfirm={() =>
+ resumeControl.handleConfirm(() =>
+ updateCampaignStatus(
+ Number(orgId),
+ Number(projectId),
+ "ON_GOING",
+ ),
+ )
+ }
+ isLoading={resumeControl.isLoading}
+ variant="primary"
+ />
+
+
+ );
+}
diff --git a/src/pages/ads/new/AdsCreate.tsx b/src/pages/ads/new/AdsCreate.tsx
deleted file mode 100644
index e214ec19..00000000
--- a/src/pages/ads/new/AdsCreate.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function AdsCreate() {
- return AdsCreate
;
-}
diff --git a/src/pages/ads/new/CampaignGroup.tsx b/src/pages/ads/new/CampaignGroup.tsx
new file mode 100644
index 00000000..47ee442a
--- /dev/null
+++ b/src/pages/ads/new/CampaignGroup.tsx
@@ -0,0 +1,170 @@
+import type { IPlatformCampaign } from "@/types/ads/campaign";
+
+import { useCampaignGroup } from "@/hooks/ads/useCampaignGroup";
+
+import Button from "@/components/common/button/Button";
+import Card from "@/components/common/card/Card";
+import Input from "@/components/common/input/Input";
+import Modal from "@/components/common/modal/Modal";
+import ModalContent from "@/components/common/modal/ModalContent";
+import DropdownSelect from "@/components/common/select/DropdownSelect";
+import TextareaField from "@/components/common/textarea/TextareaField";
+
+import WarnCircleIcon from "@/assets/icon/common/warn-circle.svg?react";
+import GoogleIcon from "@/assets/logo/social-logo/circle/google-circle.svg?react";
+import KakaoIcon from "@/assets/logo/social-logo/circle/kakao-circle.svg?react";
+import NaverIcon from "@/assets/logo/social-logo/circle/naver-circle.svg?react";
+
+export default function CampaignGroup() {
+ const {
+ name,
+ setName,
+ description,
+ setDescription,
+ googleSelected,
+ setGoogleSelected,
+ naverSelected,
+ setNaverSelected,
+ kakaoSelected,
+ setKakaoSelected,
+ googleCampaigns,
+ naverCampaigns,
+ kakaoCampaigns,
+ isFormValid,
+ isSuccessModalOpen,
+ handleCloseSuccessModal,
+ isCreating,
+ handleComplete,
+ } = useCampaignGroup();
+
+ return (
+
+
+ {/* 캠페인 기본 정보 */}
+
+
+
캠페인 기본 정보
+
+
+ {/* 캠페인명 */}
+
+
+ 캠페인명
+
+ setName(e.target.value)}
+ />
+
+ {/* 캠페인 설명 */}
+
+
+ 캠페인 설명
+
+ setDescription(e.target.value)}
+ minRows={8}
+ className="bg-white ring-1 ring-logo-1/30 hover:ring-logo-1/40 focus:ring-2 focus:ring-logo-1/50"
+ />
+
+
+
+
+ {/* 플랫폼별 캠페인 연결 */}
+
+
+
+ 플랫폼별 캠페인 연결
+
+
+
+ {/* Google */}
+
+
+
+ Google
+
+
+ placeholder="캠페인 선택"
+ options={googleCampaigns}
+ selectedOption={googleSelected}
+ onSelect={setGoogleSelected}
+ getOptionKey={(opt) => opt.adCampaignId}
+ getOptionLabel={(opt) => opt.name}
+ />
+
+
+ {/* NAVER */}
+
+
+
+ NAVER
+
+
+ placeholder="캠페인 선택"
+ options={naverCampaigns}
+ selectedOption={naverSelected}
+ onSelect={setNaverSelected}
+ getOptionKey={(opt) => opt.adCampaignId}
+ getOptionLabel={(opt) => opt.name}
+ />
+
+
+ {/* Kakao */}
+
+
+
+ Kakao
+
+
+ placeholder="캠페인 선택"
+ options={kakaoCampaigns}
+ selectedOption={kakaoSelected}
+ onSelect={setKakaoSelected}
+ getOptionKey={(opt) => opt.adCampaignId}
+ getOptionLabel={(opt) => opt.name}
+ />
+
+
+
+
+
+
+ {isCreating ? "생성 중..." : "완료"}
+
+
+
+
+ }
+ title="캠페인 생성 완료"
+ description="캠페인 그룹이 성공적으로 생성되었습니다."
+ buttonText="확인"
+ onConfirm={handleCloseSuccessModal}
+ variant="primary"
+ />
+
+
+ );
+}
diff --git a/src/pages/auth/FindEmail.tsx b/src/pages/auth/FindEmail.tsx
new file mode 100644
index 00000000..d7d9e307
--- /dev/null
+++ b/src/pages/auth/FindEmail.tsx
@@ -0,0 +1,15 @@
+import { useStepNavigation } from "@/hooks/common/useStepNavigation";
+
+import Step01Phone from "@/components/auth/flows/find-email/EnterPhoneStep";
+import Step02Email from "@/components/auth/flows/find-email/ShowEmailResultStep";
+
+export default function FindEmail() {
+ const { step, handleNext } = useStepNavigation(1);
+
+ return (
+ <>
+ {step === 1 && }
+ {step === 2 && }
+ >
+ );
+}
diff --git a/src/pages/auth/FindPw.tsx b/src/pages/auth/FindPw.tsx
index ff368250..39091710 100644
--- a/src/pages/auth/FindPw.tsx
+++ b/src/pages/auth/FindPw.tsx
@@ -1,3 +1,15 @@
+import { useStepNavigation } from "@/hooks/common/useStepNavigation";
+
+import Step01VerifyEmail from "@/components/auth/flows/reset-password/EmailVerificationStep";
+import Step02ResetPassword from "@/components/auth/flows/reset-password/NewPasswordStep";
+
export default function FindPw() {
- return FindPw
;
+ const { step, handleNext } = useStepNavigation(1);
+
+ return (
+ <>
+ {step === 1 && }
+ {step === 2 && }
+ >
+ );
}
diff --git a/src/pages/auth/Login.tsx b/src/pages/auth/Login.tsx
index d07a977d..64f57f01 100644
--- a/src/pages/auth/Login.tsx
+++ b/src/pages/auth/Login.tsx
@@ -1,3 +1,131 @@
+import { type SubmitHandler, useForm } from "react-hook-form";
+import { Link, useNavigate } from "react-router-dom";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { toast } from "sonner";
+import type { z } from "zod";
+
+import { loginSchema } from "@/utils/validation";
+
+import { useAuth } from "@/hooks/auth/useAuth";
+import { useSocialLogin } from "@/hooks/auth/useSocialLogin";
+
+import AuthFormShell from "@/components/auth/common/AuthFormShell";
+import CommonAuthInput from "@/components/auth/common/CommonAuthInput";
+import Button from "@/components/common/button/Button";
+
+import GoogleIcon from "@/assets/logo/social-logo/plain/google.svg?react";
+import KakaoIcon from "@/assets/logo/social-logo/plain/kakao.svg?react";
+import NaverIcon from "@/assets/logo/social-logo/plain/naver.svg?react";
+
+type TLoginFormValues = z.infer;
+
export default function Login() {
- return Login
;
+ const {
+ register,
+ handleSubmit,
+ formState: { errors },
+ } = useForm({
+ mode: "onBlur",
+ resolver: zodResolver(loginSchema),
+ });
+
+ const navigate = useNavigate();
+ const { useLogin } = useAuth();
+ const { handleSocialLogin } = useSocialLogin();
+
+ const onSubmit: SubmitHandler = (data) => {
+ useLogin.mutate(data, {
+ onSuccess: () => {
+ navigate("/dashboard", { replace: true });
+ },
+ onError: (error) => {
+ toast.error(error.message ?? "로그인에 실패했습니다.");
+ },
+ });
+ };
+
+ return (
+
+ 로그인
+
+
+
+
+
+ handleSocialLogin("kakao")}
+ >
+
+
+
+ handleSocialLogin("naver")}
+ >
+
+
+
+ toast.error("준비중입니다.")}
+ >
+
+
+
+
+
+
+
+ 이메일로 회원가입
+
+
+
+ );
}
diff --git a/src/pages/auth/RedirectPage.tsx b/src/pages/auth/RedirectPage.tsx
new file mode 100644
index 00000000..2d087b08
--- /dev/null
+++ b/src/pages/auth/RedirectPage.tsx
@@ -0,0 +1,50 @@
+import { useEffect, useRef } from "react";
+import { useNavigate } from "react-router-dom";
+import { toast } from "sonner";
+
+import useAuthStore from "@/store/useAuthStore";
+
+export default function RedirectPage() {
+ const navigate = useNavigate();
+ const { setAccessToken } = useAuthStore();
+ const processed = useRef(false);
+
+ useEffect(() => {
+ if (processed.current) return;
+ processed.current = true;
+
+ const getCookie = (name: string) => {
+ const value = `; ${document.cookie}`;
+ const parts = value.split(`; ${name}=`);
+ if (parts.length === 2) return parts.pop()?.split(";").shift();
+ };
+
+ const deleteCookie = (name: string) => {
+ document.cookie =
+ name + "=; Max-Age=0; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT;";
+ };
+
+ const accessToken = getCookie("access_token");
+
+ if (accessToken) {
+ deleteCookie("access_token");
+ setAccessToken(accessToken);
+
+ toast.success("소셜 로그인되었습니다.");
+ navigate("/dashboard", { replace: true });
+ } else {
+ toast.error("소셜 로그인에 실패했습니다. 다시 시도해주세요.");
+ navigate("/login", { replace: true });
+ }
+ }, [navigate, setAccessToken]);
+
+ return (
+
+ );
+}
diff --git a/src/pages/auth/Signup.tsx b/src/pages/auth/Signup.tsx
index 9bb3734d..4b5c0823 100644
--- a/src/pages/auth/Signup.tsx
+++ b/src/pages/auth/Signup.tsx
@@ -1,3 +1,111 @@
+import { useEffect, useState } from "react";
+import { Link, useLocation } from "react-router-dom";
+
+import { useSocialLogin } from "@/hooks/auth/useSocialLogin";
+import { useStepNavigation } from "@/hooks/common/useStepNavigation";
+
+import AuthFormShell from "@/components/auth/common/AuthFormShell";
+import Step01Email from "@/components/auth/flows/signup/EnterEmailStep";
+import Step02Password from "@/components/auth/flows/signup/PasswordSetupStep";
+import Step03Profile from "@/components/auth/flows/signup/ProfileSetupStep";
+import Button from "@/components/common/button/Button";
+
+import MailIcon from "@/assets/icon/common/mail.svg?react";
+import GoogleIcon from "@/assets/logo/social-logo/plain/google.svg?react";
+import KakaoIcon from "@/assets/logo/social-logo/plain/kakao.svg?react";
+import NaverIcon from "@/assets/logo/social-logo/plain/naver.svg?react";
+import useAuthStore from "@/store/useAuthStore";
+
export default function Signup() {
- return Signup
;
+ const location = useLocation();
+ const { resetAuth } = useAuthStore();
+ const { step, setStep, handleNext } = useStepNavigation(
+ location.state?.step || 0,
+ );
+ const [password, setPassword] = useState("");
+
+ useEffect(() => {
+ return () => {
+ resetAuth();
+ };
+ }, [resetAuth]);
+
+ const { handleSocialLogin } = useSocialLogin();
+
+ if (step === 1) {
+ return ;
+ }
+ if (step === 2) {
+ return (
+ {
+ setPassword(pw);
+ handleNext();
+ }}
+ />
+ );
+ }
+ if (step === 3) {
+ return ;
+ }
+
+ return (
+
+
+ }
+ onClick={() => setStep(1)}
+ className="font-heading4 shadow-Soft hover:shadow-Medium transition-all"
+ >
+ 이메일로 시작하기
+
+
+ }
+ onClick={() => handleSocialLogin("google")}
+ className="bg-white border border-gray-100 text-text-main font-heading4 shadow-Soft hover:bg-gray-50"
+ >
+ 구글 로그인
+
+
+ }
+ onClick={() => handleSocialLogin("kakao")}
+ className="bg-social-kakao text-text-main font-heading4 shadow-Soft hover:opacity-90"
+ >
+ 카카오 로그인
+
+
+ }
+ onClick={() => handleSocialLogin("naver")}
+ className="bg-social-naver text-white font-heading4 shadow-Soft hover:opacity-90"
+ >
+ 네이버 로그인
+
+
+
+
+ 이미 사용자 계정이 있다면?
+
+ 로그인하기
+
+
+
+ );
}
diff --git a/src/pages/dashboard/overview/OverviewAiReportPanel.tsx b/src/pages/dashboard/overview/OverviewAiReportPanel.tsx
new file mode 100644
index 00000000..88acb5a2
--- /dev/null
+++ b/src/pages/dashboard/overview/OverviewAiReportPanel.tsx
@@ -0,0 +1,63 @@
+import { aiReportMockData } from "./aiReport.mock";
+
+import SparkleIcon from "@/assets/icon/ai/sparkle.svg?react";
+import SparkleCircleIcon from "@/assets/icon/ai/sparkle-circle.svg?react";
+import WarnCircleIcon from "@/assets/icon/common/warn-circle.svg?react";
+
+export default function OverviewAiReportPanel() {
+ const data = aiReportMockData;
+
+ return (
+
+
+
+
+
+
+
+ {data.strategySuggestion.title}
+
+
+ {data.strategySuggestion.content}
+
+
+
+
+ {data.sections.map((section) => (
+
+
+ {section.title}
+
+
+ {section.content}
+
+
+ ))}
+
+
+
+
+
+ {data.warning.title}
+
+
+ {data.warning.content}
+
+
+
+
+ );
+}
diff --git a/src/pages/dashboard/overview/OverviewDashboard.tsx b/src/pages/dashboard/overview/OverviewDashboard.tsx
index 925ba2be..47b4d52a 100644
--- a/src/pages/dashboard/overview/OverviewDashboard.tsx
+++ b/src/pages/dashboard/overview/OverviewDashboard.tsx
@@ -1,3 +1,305 @@
+import { lazy, type ReactNode, Suspense, useEffect, useState } from "react";
+import { useNavigate, useOutletContext } from "react-router-dom";
+import { toast } from "sonner";
+
+import { printAsPdf } from "@/utils/download";
+
+import { useOverviewBudget } from "@/hooks/dashboard/useOverviewBudget";
+import { useOverviewMetrics } from "@/hooks/dashboard/useOverviewMetrics";
+import { useOverviewRoasRankings } from "@/hooks/dashboard/useOverviewRoasRankings";
+
+import Badge from "@/components/common/badge/Badge";
+import Button from "@/components/common/button/Button";
+import Card from "@/components/common/card/Card";
+import StatCard from "@/components/common/card/StatCard";
+import ChartLegend from "@/components/common/chart/ChartLegend";
+import Drawer from "@/components/common/drawer/Drawer";
+import {
+ Skeleton,
+ SkeletonCircle,
+} from "@/components/common/skeleton/Skeleton";
+import BudgetGaugeChart, {
+ getBudgetStatus,
+ statusBadgeVariant,
+} from "@/components/dashboard/charts/BudgetGaugeChart";
+import TrafficChart, {
+ TrafficChartDownload,
+} from "@/components/dashboard/charts/TrafficChart";
+import PlatformRoasTable from "@/components/dashboard/platform/PlatformRoasTable";
+
+import SparkleCircleIcon from "@/assets/icon/ai/sparkle-circle.svg?react";
+import ChevronDoubleRightIcon from "@/assets/icon/chevron/chervon-double-right.svg?react";
+import DownloadIcon from "@/assets/icon/common/download.svg?react";
+import LinkIcon from "@/assets/icon/common/link.svg?react";
+import WarnCircleIcon from "@/assets/icon/common/warn-circle.svg?react";
+import AiButtonSvg from "@/assets/logo/service-logo/ai-요약버튼.svg?react";
+
+const OverviewAiReportPanel = lazy(() => import("./OverviewAiReportPanel"));
+
+type TDashboardHeaderContext = {
+ setHeaderRight?: (node: ReactNode | null) => void;
+};
+
export default function OverviewDashboard() {
- return OverviewDashboard
;
+ const navigate = useNavigate();
+ const { setHeaderRight } = useOutletContext();
+ const [isAiPanelOpen, setIsAiPanelOpen] = useState(false);
+ const {
+ data: kpis,
+ isLoading: isKpisLoading,
+ isError: isKpisError,
+ error: kpisError,
+ } = useOverviewMetrics();
+ const {
+ data: budget,
+ isLoading: isBudgetLoading,
+ isError: isBudgetError,
+ error: budgetError,
+ } = useOverviewBudget();
+ const {
+ data: roasRankingsData,
+ isLoading: isRankingsLoading,
+ isError: isRankingsError,
+ error: rankingsError,
+ } = useOverviewRoasRankings();
+
+ // 예산 상태 계산 - 카드 헤더 배지
+ const budgetPct =
+ budget && budget.totalBudget > 0
+ ? Math.round((budget.spent / budget.totalBudget) * 100)
+ : 0;
+ const budgetStatus =
+ budget && !isBudgetLoading
+ ? getBudgetStatus(
+ budgetPct,
+ budget.warningThreshold,
+ budget.dangerThreshold,
+ )
+ : null;
+
+ useEffect(() => {
+ if (!setHeaderRight) return;
+
+ setHeaderRight(
+ setIsAiPanelOpen(true)}
+ className="group relative h-8 px-1 -mr-2 rounded-2xl outline-none cursor-pointer overflow-hidden inline-flex items-center justify-center focus-visible:ring-2 focus-visible:ring-logo-2/35 focus-visible:ring-offset-2 focus-visible:ring-offset-white"
+ aria-label="AI 요약하기"
+ >
+
+
+ ,
+ );
+
+ return () => {
+ setHeaderRight(null);
+ };
+ }, [setHeaderRight]);
+
+ return (
+
+
+ {isKpisError ? (
+
+ {kpisError?.message ??
+ "지표 데이터를 불러오지 못했습니다. 잠시 후 다시 시도해 주세요."}
+
+ ) : isKpisLoading ? (
+ Array.from({ length: 4 }).map((_, i) => (
+
+
+
+
+
+ ))
+ ) : (
+ (kpis ?? []).map((kpi) =>
)
+ )}
+
+
+
+
+ }
+ RightElement={
}
+ >
+
}
+ >
+
+
+
+
+
+ }
+ RightElement={
+ budgetStatus ? (
+
+ {budgetStatus}
+
+ ) : undefined
+ }
+ >
+ {isBudgetError ? (
+
+ {budgetError?.message ?? (
+ <>
+ 예산 데이터를 불러오지 못했습니다.
+
+ 잠시 후 다시 시도해 주세요.
+ >
+ )}
+
+ ) : isBudgetLoading ? (
+
+ ) : budget ? (
+
+ ) : null}
+
+
+
+ navigate("/platform")}
+ className="group flex items-center gap-1 h-8 px-4 bg-bg-surface/60 border-none hover:bg-bg-surface text-text-sub hover:text-text-auth-sub transition-colors rounded-full"
+ >
+
+ 플랫폼 대시보드 살펴보기
+
+
+
+ }
+ description={
+
+
+ ROAS 산출: 매출 ÷ 광고비 × 100
+
+ }
+ >
+ {isRankingsError ? (
+
+ {rankingsError?.message ??
+ "플랫폼 데이터를 불러오지 못했습니다. 잠시 후 다시 시도해 주세요."}
+
+ ) : isRankingsLoading ? (
+
+ {Array.from({ length: 3 }).map((_, i) => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+
+ ) : (
+
+ )}
+
+
+ setIsAiPanelOpen(false)}
+ hideHeader={false}
+ disableScroll={false}
+ className="w-full max-w-160"
+ dropdownItems={[
+ {
+ label: "링크 공유하기",
+ icon: (
+
+ ),
+ onClick: () => {
+ navigator.clipboard
+ .writeText(window.location.href)
+ .then(() => toast.success("링크가 복사되었습니다."))
+ .catch(() => toast.error("링크 복사에 실패했습니다."));
+ },
+ },
+ {
+ label: "PDF로 저장하기",
+ icon: (
+
+ ),
+ onClick: () => printAsPdf("ai-report-printing"),
+ },
+ ]}
+ >
+ {isAiPanelOpen && (
+
+
+
+ )}
+
+
+ );
}
diff --git a/src/pages/dashboard/overview/aiReport.mock.ts b/src/pages/dashboard/overview/aiReport.mock.ts
new file mode 100644
index 00000000..b3cd6851
--- /dev/null
+++ b/src/pages/dashboard/overview/aiReport.mock.ts
@@ -0,0 +1,31 @@
+export const aiReportMockData = {
+ label: "오늘의 데이터 요약",
+ title: "AI가 오늘의 데이터를 중심으로 요약했어요",
+ strategySuggestion: {
+ title: "전략 제안",
+ content:
+ "성과가 안정적으로 유지되고 있는 만큼,\n현재 성과가 좋은 캠페인과 소재를 중심으로 예산 배분 상태를 점검해볼 수 있습니다.\n동시에 전환 효율이 낮았던 시간대에 대해서는\n추가적인 테스트 또는 예산 분산 여부를 검토해보는 것이 도움이 될 수 있습니다.",
+ },
+ sections: [
+ {
+ title: "성과 요약",
+ content:
+ "오늘은 클릭과 노출이 안정적으로 유지되고 있으며,\n일부 시간대에서 전환 효율이 개선되는 흐름을 보이고 있습니다.",
+ },
+ {
+ title: "왜 이렇게 나왔을까?",
+ content:
+ "오늘 클릭수 증가는 상위 성과 캠페인의 노출 비중이 확대된 영향으로 보입니다.\n특히 오후 시간대에 클릭이 집중되면서 전체 트래픽이 증가했으나,\n같은 구간에서 전환수는 상대적으로 완만한 증가세를 보였습니다.\n이는 클릭 대비 전환 효율이 시간대별로 다르게 나타났기 때문으로 추정됩니다.",
+ },
+ {
+ title: "성과 포인트",
+ content:
+ "1월 16일 기준, 클릭수는 전일 대비 약 13% 증가하며 가장 높은 수준을 기록했습니다.\n이 시점에서 전환율 또한 평균 이상을 유지해,\n트래픽 증가가 단순 노출 확대로만 이어지지 않았음을 확인할 수 있습니다.",
+ },
+ ],
+ warning: {
+ title: "주의가 필요한 부분",
+ content:
+ "다만, 일부 매체에서는 클릭 증가 대비 전환 효율이 소폭 하락하는 흐름이 나타났습니다.\n특히 18시 이후 시간대에서는 예산 소진 속도가 빨라졌으나,\n전환 성과는 이에 비례해 증가하지는 않았습니다.\n해당 구간에 대한 추가적인 모니터링이 필요해 보입니다.",
+ },
+};
diff --git a/src/pages/dashboard/platform/PlatformDashboard.tsx b/src/pages/dashboard/platform/PlatformDashboard.tsx
index 66e34adf..62e0e1b0 100644
--- a/src/pages/dashboard/platform/PlatformDashboard.tsx
+++ b/src/pages/dashboard/platform/PlatformDashboard.tsx
@@ -1,3 +1,215 @@
+import { type ReactNode, useEffect, useMemo, useState } from "react";
+import { useOutletContext } from "react-router-dom";
+import { twMerge } from "tailwind-merge";
+
+import Badge from "@/components/common/badge/Badge";
+import Button from "@/components/common/button/Button";
+import Card from "@/components/common/card/Card";
+import ChartLegend from "@/components/common/chart/ChartLegend";
+import { DropdownMenu } from "@/components/common/dropdownmenu/DropdownMenu";
+import AdStatusChart from "@/components/dashboard/charts/AdStatusChart";
+import PerformanceEfficiencyChart from "@/components/dashboard/charts/PerformanceEfficiencyChart";
+import PlatformDetailCard from "@/components/dashboard/platform/PlatformDetailCard";
+import {
+ AdStatusChartSkeleton,
+ BadgeSkeleton,
+ PerformanceEfficiencyChartSkeleton,
+ PlatformDetailCardSkeleton,
+ TopPerformanceListSkeleton,
+ TrafficChartSkeleton,
+} from "@/components/dashboard/platform/skeleton/PlatformSkeleton";
+import TopPerformanceList from "@/components/dashboard/platform/TopPerformanceList";
+
+import {
+ adStatusMock,
+ performanceEfficiencyMock,
+ roasRankingMock,
+} from "./platformDashboard.mock";
+
+import ChevronDownIcon from "@/assets/icon/chevron/chevron-up.svg?react";
+
+type TDashboardHeaderContext = {
+ setHeaderRight?: (node: ReactNode | null) => void;
+};
+
export default function PlatformDashboard() {
- return PlatformDashboard
;
+ const [selectedPlatform, setSelectedPlatform] = useState("전체");
+ const [isLoading, setIsLoading] = useState(true);
+ const { setHeaderRight } = useOutletContext();
+
+ const isAllView = selectedPlatform === "전체";
+
+ const platformItems = useMemo(
+ () => [
+ { label: "Google", onClick: () => setSelectedPlatform("Google") },
+ { label: "NAVER", onClick: () => setSelectedPlatform("NAVER") },
+ { label: "Meta", onClick: () => setSelectedPlatform("Meta") },
+ ],
+ [],
+ );
+
+ useEffect(() => {
+ const timer = setTimeout(() => setIsLoading(false), 1600);
+ return () => clearTimeout(timer);
+ }, []);
+
+ useEffect(() => {
+ if (!setHeaderRight) return;
+
+ setHeaderRight(
+
+ setSelectedPlatform("전체")}
+ className={twMerge(
+ "w-28 py-5 font-body1 rounded-component-md",
+ !isAllView &&
+ "border border-bg-disabled bg-white text-text-sub hover:bg-bg-surface",
+ )}
+ >
+ 전체보기
+
+
+
+ {isAllView ? "플랫폼 선택" : selectedPlatform}
+
+
+
+ }
+ items={platformItems}
+ />
+
,
+ );
+
+ return () => setHeaderRight(null);
+ }, [isAllView, platformItems, selectedPlatform, setHeaderRight]);
+
+ return (
+
+
+
+ {/* 성과 우수 플랫폼 */}
+
+ ) : (
+
+ ROAS 기준 상위 3
+
+ )
+ }
+ className="flex-1 min-h-67 flex flex-col"
+ >
+ {isLoading ? (
+
+ ) : (
+
+ )}
+
+
+ {/* 광고 소재 현황 */}
+
+ }
+ RightElement={
+ isLoading ? (
+
+ ) : (
+
+ 총 {adStatusMock.totalCount}개
+
+ )
+ }
+ className="flex-1 min-h-67 flex flex-col"
+ >
+ {isLoading ? (
+
+ ) : (
+
+ )}
+
+
+ {/* 플랫폼별 성과 효율 비교 */}
+
+ }
+ >
+ {isLoading ? (
+
+ ) : (
+
+ )}
+
+
+
+ {/* 실시간 트래픽 변화 */}
+
+ {isLoading ? : null}
+
+
+ {/* 개별 플랫폼 상세 */}
+
+ {isLoading
+ ? Array.from({ length: 3 }).map((_, i) => (
+
+ ))
+ : performanceEfficiencyMock.map((platform) => (
+
+ ))}
+
+
+
+ );
}
diff --git a/src/pages/dashboard/platform/platformDashboard.mock.ts b/src/pages/dashboard/platform/platformDashboard.mock.ts
new file mode 100644
index 00000000..b2c5e5cf
--- /dev/null
+++ b/src/pages/dashboard/platform/platformDashboard.mock.ts
@@ -0,0 +1,80 @@
+import type {
+ IAdStatusData,
+ IPlatformPerformance,
+ IRoasRanking,
+} from "@/types/dashboard/platform";
+
+// 성과 우수 플랫폼
+export const roasRankingMock: IRoasRanking[] = [
+ {
+ rank: 1,
+ provider: "GOOGLE",
+ roas: 67.08,
+ diffRate: 12,
+ revenue: 12345678,
+ adSpend: 184000,
+ },
+ {
+ rank: 2,
+ provider: "NAVER",
+ roas: 19.11,
+ diffRate: 12,
+ revenue: 8500000,
+ adSpend: 444000,
+ },
+ {
+ rank: 3,
+ provider: "META",
+ roas: 10.98,
+ diffRate: 5.4,
+ revenue: 5200000,
+ adSpend: 472000,
+ },
+];
+
+// 광고 소재 현황
+export const adStatusMock: IAdStatusData = {
+ totalCount: 14,
+ providerCount: [
+ { provider: "GOOGLE", count: 7 },
+ { provider: "NAVER", count: 5 },
+ { provider: "META", count: 2 },
+ ],
+};
+
+// 플랫폼별 성과 효율 비교
+export const performanceEfficiencyMock: IPlatformPerformance[] = [
+ {
+ provider: "GOOGLE",
+ clicks: 12100,
+ clickChangeRate: 0.1,
+ impressions: 450000,
+ impressionChangeRate: 0.05,
+ conversion: 5.8,
+ cvrChangeRate: 0.02,
+ ROAS: 67.08,
+ ROASChangeRate: 0.12,
+ },
+ {
+ provider: "NAVER",
+ clicks: 8500,
+ clickChangeRate: -0.05,
+ impressions: 580000,
+ impressionChangeRate: 0.1,
+ conversion: 3.2,
+ cvrChangeRate: 0.01,
+ ROAS: 19.11,
+ ROASChangeRate: -0.05,
+ },
+ {
+ provider: "META",
+ clicks: 15600,
+ clickChangeRate: 0.15,
+ impressions: 320000,
+ impressionChangeRate: 0.2,
+ conversion: 8.5,
+ cvrChangeRate: 0.08,
+ ROAS: 10.98,
+ ROASChangeRate: 0.05,
+ },
+];
diff --git a/src/pages/dashboard/replay/ReplayDashboard.tsx b/src/pages/dashboard/replay/ReplayDashboard.tsx
deleted file mode 100644
index 147772ed..00000000
--- a/src/pages/dashboard/replay/ReplayDashboard.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function ReplayDashboard() {
- return ReplayDashboard
;
-}
diff --git a/src/pages/dashboard/timeline/Timeline.tsx b/src/pages/dashboard/timeline/Timeline.tsx
new file mode 100644
index 00000000..7bddd521
--- /dev/null
+++ b/src/pages/dashboard/timeline/Timeline.tsx
@@ -0,0 +1,3 @@
+export default function Timeline() {
+ return Timeline
;
+}
diff --git a/src/pages/landing/LandingPage.tsx b/src/pages/landing/LandingPage.tsx
new file mode 100644
index 00000000..931c13b1
--- /dev/null
+++ b/src/pages/landing/LandingPage.tsx
@@ -0,0 +1,46 @@
+import { lazy, Suspense } from "react";
+
+import LandingFooter from "@/components/landing/LandingFooter";
+import LandingHeader from "@/components/landing/LandingHeader";
+import LandingHero from "@/components/landing/LandingHero";
+import LandingMultiDevice from "@/components/landing/LandingMultiDevice";
+
+const LandingFeatures = lazy(
+ () => import("@/components/landing/LandingFeatures"),
+);
+const LandingGuide = lazy(() => import("@/components/landing/LandingGuide"));
+const LandingPricing = lazy(
+ () => import("@/components/landing/LandingPricing"),
+);
+const LandingFAQ = lazy(() => import("@/components/landing/LandingFAQ"));
+
+function SectionFallback({ height = 96 }: { height?: number }) {
+ return
;
+}
+
+export default function LandingPage() {
+ return (
+
+
+
+
+
+ }>
+
+
+ }>
+
+
+ }>
+
+
+ }>
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/pages/workspace/Billing.tsx b/src/pages/workspace/Billing.tsx
new file mode 100644
index 00000000..3a48796c
--- /dev/null
+++ b/src/pages/workspace/Billing.tsx
@@ -0,0 +1,3 @@
+export default function Billing() {
+ return Billing
;
+}
diff --git a/src/pages/workspace/MemberManagement.tsx b/src/pages/workspace/MemberManagement.tsx
new file mode 100644
index 00000000..db7ce94d
--- /dev/null
+++ b/src/pages/workspace/MemberManagement.tsx
@@ -0,0 +1,293 @@
+import { useEffect, useMemo, useRef, useState } from "react";
+import { useParams } from "react-router-dom";
+import {
+ useInfiniteQuery,
+ useMutation,
+ useQuery,
+ useQueryClient,
+} from "@tanstack/react-query";
+import { toast } from "sonner";
+
+import type { IApiErrorResponse } from "@/types/common/common";
+import {
+ type TMemberRole,
+ type TUpdateMemberRoleRequest,
+ type TWorkspaceMember,
+} from "@/types/workspace/workspace";
+
+import DeleteMemberModal from "@/components/workspace/DeleteMemberModal";
+import MemberList from "@/components/workspace/MemberList";
+import MemberManagementLoading from "@/components/workspace/MemberManagementLoading";
+import PermissionTable from "@/components/workspace/PermissionTable";
+
+import {
+ deleteWorkspaceMember,
+ getPendingMember,
+ getWorkspaceMemberCount,
+ getWorkspaceMembers,
+ updateWorkspaceMemberPermission,
+} from "@/api/workspace/org";
+
+const PAGE_SIZE = 20;
+
+export default function MemberManagement() {
+ const { workspaceId } = useParams<{ workspaceId: string }>();
+ const orgId = Number(workspaceId);
+ const queryClient = useQueryClient();
+
+ const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
+ const [selectedDeleteMember, setSelectedDeleteMember] =
+ useState(null);
+
+ const observerRef = useRef(null);
+
+ const memberCountQuery = useQuery<
+ Awaited>,
+ IApiErrorResponse
+ >({
+ queryKey: ["workspaceMemberCount", orgId],
+ queryFn: () => getWorkspaceMemberCount(orgId),
+ enabled: Number.isFinite(orgId) && orgId > 0,
+ });
+ const membersQuery = useInfiniteQuery({
+ queryKey: ["workspaceMembers", orgId, PAGE_SIZE],
+ queryFn: ({ pageParam }: { pageParam: string | null }) =>
+ getWorkspaceMembers(orgId, pageParam, PAGE_SIZE),
+ initialPageParam: null,
+ getNextPageParam: (lastPage) => {
+ if (!lastPage.hasNext) return undefined;
+ return lastPage.nextCursor;
+ },
+ enabled: Number.isFinite(orgId) && orgId > 0,
+ });
+
+ const members = useMemo(() => {
+ return membersQuery.data?.pages.flatMap((page) => page.members) ?? [];
+ }, [membersQuery.data]);
+
+ const totalCount = memberCountQuery?.data?.totalCount ?? 0;
+
+ const adminCount = useMemo(() => {
+ return members.filter((member) => member.role === "ADMIN").length;
+ }, [members]);
+
+ const pendingMembersQuery = useQuery<
+ Awaited>,
+ IApiErrorResponse
+ >({
+ queryKey: ["workspacePendingMembers", orgId],
+ queryFn: () => getPendingMember(orgId),
+ enabled: Number.isFinite(orgId) && orgId > 0,
+ });
+
+ const pendingMembers = useMemo(() => {
+ const items = pendingMembersQuery.data?.pendingMembers ?? [];
+
+ return [...items].sort(
+ (a, b) =>
+ new Date(b.invitedAt).getTime() - new Date(a.invitedAt).getTime(),
+ );
+ }, [pendingMembersQuery.data]);
+
+ const updateMemberRoleMutation = useMutation<
+ unknown,
+ IApiErrorResponse,
+ { memberId: number; body: TUpdateMemberRoleRequest }
+ >({
+ mutationFn: ({ memberId, body }) =>
+ updateWorkspaceMemberPermission(orgId, memberId, body),
+ onSuccess: () => {
+ void queryClient.invalidateQueries({
+ queryKey: ["workspaceMembers", orgId],
+ });
+ },
+ onError: (error) => {
+ toast.error(error.message ?? "권한 변경에 실패했습니다.");
+ },
+ });
+
+ const deleteMemberMutation = useMutation({
+ mutationFn: (memberId) => deleteWorkspaceMember(orgId, memberId),
+ onSuccess: () => {
+ void queryClient.invalidateQueries({
+ queryKey: ["workspaceMembers", orgId],
+ });
+ void queryClient.invalidateQueries({
+ queryKey: ["workspaceMemberCount", orgId],
+ });
+ },
+ onError: (error) => {
+ toast.error(error.message ?? "멤버 삭제에 실패했습니다.");
+ },
+ });
+
+ useEffect(() => {
+ const target = observerRef.current;
+ if (!target) return;
+ if (!membersQuery.hasNextPage) return;
+ const observer = new IntersectionObserver(
+ (entries) => {
+ const firstEntry = entries[0];
+ if (
+ firstEntry?.isIntersecting &&
+ membersQuery.hasNextPage &&
+ !membersQuery.isFetchingNextPage
+ ) {
+ void membersQuery.fetchNextPage();
+ }
+ },
+ {
+ root: null,
+ rootMargin: "120px",
+ threshold: 0,
+ },
+ );
+ observer.observe(target);
+
+ return () => observer.disconnect();
+ }, [
+ membersQuery.hasNextPage,
+ membersQuery.isFetchingNextPage,
+ membersQuery.fetchNextPage,
+ ]);
+
+ const handleRoleChange = async (
+ targetMemberId: number,
+ newRole: TMemberRole,
+ ) => {
+ const targetMember = members.find(
+ (member) => member.memberId === targetMemberId,
+ );
+
+ if (!targetMember) return;
+ if (targetMember.role === newRole) return;
+
+ if (targetMember.isMe) {
+ toast.error("본인 권한은 여기서 변경할 수 없습니다");
+ return;
+ }
+
+ const isLastAdminDemotion =
+ targetMember.role === "ADMIN" && newRole === "MEMBER" && adminCount === 1;
+
+ if (isLastAdminDemotion) {
+ toast.error(
+ "관리자는 최소 1명 이상이어야 합니다. 다른 멤버를 먼저 관리자로 지정한 후 다시 시도해 주세요",
+ );
+ return;
+ }
+ try {
+ await updateMemberRoleMutation.mutateAsync({
+ memberId: targetMemberId,
+ body: { orgRole: newRole },
+ });
+ toast.success(
+ `${targetMember.name}님의 권한이 ${newRole === "ADMIN" ? "관리자" : "멤버"}로 변경되었습니다`,
+ );
+ } catch (error) {
+ console.error("권한 변경 실패", error);
+ }
+ };
+
+ const openDeleteMember = (member: TWorkspaceMember) => {
+ if (member.isMe) {
+ toast.error("본인 계정은 삭제할 수 없습니다");
+ return;
+ }
+
+ const isLastAdmin = member.role === "ADMIN" && adminCount === 1;
+ if (isLastAdmin) {
+ toast.error("마지막 관리자는 삭제할 수 없습니다");
+ return;
+ }
+
+ setSelectedDeleteMember(member);
+ setIsDeleteModalOpen(true);
+ };
+
+ const closeDeleteMember = () => {
+ if (deleteMemberMutation.isPending) return;
+ setIsDeleteModalOpen(false);
+ setSelectedDeleteMember(null);
+ };
+
+ const handleDeleteMember = async (member: TWorkspaceMember) => {
+ try {
+ await deleteMemberMutation.mutateAsync(member.memberId);
+ toast.success(`${member.name}님이 삭제되었습니다`);
+ setIsDeleteModalOpen(false);
+ setSelectedDeleteMember(null);
+ } catch (error) {
+ console.error("팀원 삭제 실패", error);
+ }
+ };
+
+ if (!Number.isFinite(orgId) || orgId <= 0) {
+ return (
+
+
+ 멤버 관리
+
+ 올바르지 않은 워크스페이스입니다.
+
+
+
+ );
+ }
+
+ if (
+ memberCountQuery.isLoading ||
+ membersQuery.isLoading ||
+ pendingMembersQuery.isLoading
+ ) {
+ return ;
+ }
+
+ if (
+ memberCountQuery.isError ||
+ membersQuery.isError ||
+ pendingMembersQuery.isError
+ ) {
+ const errorMessage =
+ memberCountQuery.error?.message ||
+ (membersQuery.error as unknown as IApiErrorResponse)?.message ||
+ pendingMembersQuery.error?.message ||
+ "팀 구성원 정보를 불러오지 못했습니다";
+
+ return (
+
+
+ 멤버 관리
+ {errorMessage}
+
+
+ );
+ }
+
+ return (
+
+ );
+}
diff --git a/src/pages/workspace/Workspace.tsx b/src/pages/workspace/Workspace.tsx
index 9d0ebac3..464027ae 100644
--- a/src/pages/workspace/Workspace.tsx
+++ b/src/pages/workspace/Workspace.tsx
@@ -1,3 +1,285 @@
-export default function Workspace() {
- return Workspace
;
+import React, { useEffect, useMemo, useRef, useState } from "react";
+import { useNavigate } from "react-router-dom";
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
+
+import type { IApiErrorResponse } from "@/types/common/common";
+import type { TWorkspace } from "@/types/workspace/workspace";
+
+import Button from "@/components/common/button/Button";
+import Input from "@/components/common/input/Input";
+import Modal from "@/components/common/modal/Modal";
+import TextareaField from "@/components/common/textarea/TextareaField";
+import WorkspaceCard from "@/components/workspace/WorkspaceCard";
+import WorkspaceEmptyState from "@/components/workspace/WorkspaceEmptyState";
+import WorkspaceListError from "@/components/workspace/WorkspaceListError";
+import WorkspaceListLoading from "@/components/workspace/WorkspaceListLoading";
+
+import { createWorkspace, getMyWorkspaces } from "@/api/workspace/org";
+import PlusIcon from "@/assets/icon/common/plus.svg?react";
+import SearchIcon from "@/assets/icon/common/search.svg?react";
+import UpLoadImgIcon from "@/assets/icon/common/uploadImg.svg?react";
+import useWorkspaceStore from "@/store/useWorkspaceStore";
+
+export default function WorkspacePage() {
+ const navigate = useNavigate();
+
+ const [query, setQuery] = useState("");
+ const [createOpen, setCreateOpen] = useState(false);
+
+ const [newName, setNewName] = useState("");
+ const [newDesc, setNewDesc] = useState("");
+
+ const [logoFile, setLogoFile] = useState(null);
+ const [logoPreview, setLogoPreview] = useState(null);
+
+ const queryClient = useQueryClient();
+ const workspacesQuery = useQuery({
+ queryKey: ["my-workspaces"],
+ queryFn: getMyWorkspaces,
+ });
+
+ const createWorkspaceMutation = useMutation({
+ mutationFn: async () => {
+ const name = newName.trim();
+ const description = newDesc.trim();
+ return createWorkspace({ name, description, imageFile: logoFile });
+ },
+
+ onSuccess: () => {
+ void queryClient.invalidateQueries({ queryKey: ["my-workspaces"] });
+ setCreateOpen(false);
+ },
+ });
+ const isListLoading = workspacesQuery.isLoading;
+ const listErrorMsg = workspacesQuery.isError
+ ? workspacesQuery.error.message
+ : null;
+
+ const isCreating = createWorkspaceMutation.isPending;
+ const createErrorMsg = createWorkspaceMutation.isError
+ ? createWorkspaceMutation.error.message
+ : null;
+
+ const fileRef = useRef(null);
+ const openFile = () => {
+ if (!fileRef.current) return;
+ fileRef.current.value = "";
+ fileRef.current.click();
+ };
+
+ const workspaces = workspacesQuery.data ?? [];
+ const selectedOrgId = useWorkspaceStore((s) => s.selectedOrgId);
+
+ const filtered = useMemo(() => {
+ const q = query.trim().toLowerCase();
+ if (!q) return workspaces;
+ return workspaces.filter((w) => w.name.toLowerCase().includes(q));
+ }, [query, workspaces]);
+
+ const sortedWorkspaces = useMemo(() => {
+ return [...filtered].sort((a, b) => {
+ if (a.orgId === selectedOrgId) return -1;
+ if (b.orgId === selectedOrgId) return 1;
+ return 0;
+ });
+ }, [filtered, selectedOrgId]);
+
+ const onCloseCreate = () => {
+ setLogoPreview(null);
+ setLogoPreview((prev) => {
+ if (prev) URL.revokeObjectURL(prev);
+ return null;
+ });
+ setCreateOpen(false);
+ };
+ const onOpenCreate = () => {
+ setNewName("");
+ setNewDesc("");
+ setLogoFile(null);
+ setLogoPreview((prev) => {
+ if (prev) URL.revokeObjectURL(prev);
+ return null;
+ });
+ createWorkspaceMutation.reset();
+ setCreateOpen(true);
+ };
+
+ const onPickLogo = (e: React.ChangeEvent) => {
+ const file = e.target.files?.[0];
+ if (!file) return;
+ setLogoFile(file);
+ const previewUrl = URL.createObjectURL(file);
+ setLogoPreview((prev) => {
+ if (prev) URL.revokeObjectURL(prev);
+ return previewUrl;
+ });
+ };
+
+ useEffect(() => {
+ return () => {
+ if (logoPreview) URL.revokeObjectURL(logoPreview);
+ };
+ }, [logoPreview]);
+
+ const onSubmitCreate = async () => {
+ if (!newName.trim()) return;
+ createWorkspaceMutation.mutate();
+ };
+
+ const renderWorkspaceContent = () => {
+ if (isListLoading) {
+ return ;
+ }
+ if (listErrorMsg) {
+ return (
+ workspacesQuery.refetch()}
+ />
+ );
+ }
+ if (sortedWorkspaces.length === 0) {
+ return (
+
+ );
+ }
+ return (
+
+ {sortedWorkspaces.map((w) => (
+ {
+ void navigate(`/workspace/${w.orgId}/settings`);
+ }}
+ />
+ ))}
+
+ );
+ };
+
+ return (
+
+
+
+ setQuery(e.target.value)}
+ rightElement={ }
+ />
+
+
+
+ 워크스페이스 생성하기
+ 생성하기
+
+
+
+ {renderWorkspaceContent()}
+
+
+
+
+ 워크스페이스 생성
+
+
+ 워크스페이스를 생성한 사용자는 자동으로 관리자 권한을 갖습니다.
+
+ 로고 이미지와 기본 정보를 입력해 주세요.
+
+
+
+
+
+
+ {logoPreview ? (
+ <>
+
+
+
+
+ 사진 변경
+
+
+ >
+ ) : (
+
+
+
+ 이미지 업로드
+
+
+ )}
+
+
+
+ {/* 입력 폼 */}
+
+
setNewName(e.target.value)}
+ disabled={isCreating}
+ />
+
setNewDesc(e.target.value)}
+ disabled={isCreating}
+ />
+ {createErrorMsg && (
+ {createErrorMsg}
+ )}
+
+
+
+
+ {isCreating ? "생성 중.." : "생성하기"}
+
+
+
+
+
+
+ );
}
diff --git a/src/pages/workspace/WorkspaceSetting.tsx b/src/pages/workspace/WorkspaceSetting.tsx
new file mode 100644
index 00000000..ae524f80
--- /dev/null
+++ b/src/pages/workspace/WorkspaceSetting.tsx
@@ -0,0 +1,345 @@
+import React, { useEffect, useMemo, useRef, useState } from "react";
+import { useNavigate, useParams } from "react-router-dom";
+import { useQueryClient } from "@tanstack/react-query";
+import { toast } from "sonner";
+
+import type { IApiErrorResponse } from "@/types/common/common";
+
+import Button from "@/components/common/button/Button";
+import ControlBox from "@/components/common/controlbox/ControlBox";
+import Input from "@/components/common/input/Input";
+import Modal from "@/components/common/modal/Modal";
+import TextareaField from "@/components/common/textarea/TextareaField";
+import WorkspaceSettingLoading from "@/components/workspace/WorkspaceSettingLoading";
+
+import {
+ deleteWorkspace,
+ getWorkspace,
+ updateWorkspace,
+} from "@/api/workspace/org";
+import BuildingIcon from "@/assets/icon/common/building.svg?react";
+import WarnIcon from "@/assets/icon/common/warn-circle.svg?react";
+import { getImageUrl } from "@/lib/getImageUrl";
+
+export default function WorkspaceSetting() {
+ const navigate = useNavigate();
+ const { workspaceId } = useParams();
+ const queryClient = useQueryClient();
+
+ const orgId = useMemo(() => {
+ if (!workspaceId) return null;
+ const n = Number(workspaceId);
+ return Number.isFinite(n) && n > 0 ? n : null;
+ }, [workspaceId]);
+ const [name, setName] = useState("");
+ const [desc, setDesc] = useState("");
+ const [loading, setLoading] = useState(false);
+
+ const [saving, setSaving] = useState(false);
+ const [errorMsg, setErrorMsg] = useState(null);
+ const [deleteOpen, setDeleteOpen] = useState(false);
+ const [deleting, setDeleting] = useState(false);
+
+ const [serverLogoUrl, setServerLogoUrl] = useState(null);
+ const [logoFile, setLogoFile] = useState(null);
+ const [logoPreview, setLogoPreview] = useState(null);
+ const [imageError, setImageError] = useState(false);
+ const [isImageDeleted, setIsImageDeleted] = useState(false);
+ const fileRef = useRef(null);
+
+ const fetchWorkspaceDetail = async () => {
+ if (orgId === null) {
+ setErrorMsg("잘못된 워크스페이스ID 입니다");
+ return;
+ }
+ setLoading(true);
+ setErrorMsg(null);
+ setImageError(false);
+ try {
+ const detail = await getWorkspace(orgId);
+ setName(detail.name);
+ setDesc(detail.description ?? "");
+ setServerLogoUrl(detail.logoUrl ?? null);
+ setLogoFile(null);
+ setIsImageDeleted(false);
+ setLogoPreview((prev) => {
+ if (prev) URL.revokeObjectURL(prev);
+ return null;
+ });
+ } catch (e) {
+ const message = (e as IApiErrorResponse).message;
+ setErrorMsg(message);
+ toast.error(message);
+ } finally {
+ setLoading(false);
+ }
+ };
+ useEffect(() => {
+ void fetchWorkspaceDetail();
+ }, [orgId]);
+
+ const onSave = async () => {
+ if (orgId === null) {
+ setErrorMsg("잘못된 워크스페이스ID 입니다");
+ return;
+ }
+ const nextName = name.trim();
+ const nextDesc = desc.trim();
+ if (!nextName) return;
+ setSaving(true);
+
+ try {
+ await updateWorkspace(orgId, {
+ name: nextName,
+ description: nextDesc,
+ imageFile: logoFile,
+ isImageDeleted,
+ });
+ await queryClient.invalidateQueries({ queryKey: ["my-workspaces"] });
+ toast.success("변경사항이 저장되었습니다");
+ await fetchWorkspaceDetail();
+ } catch (e) {
+ toast.error(
+ (e as IApiErrorResponse).message ?? "변경사항 저장에 실패했습니다.",
+ );
+ } finally {
+ setSaving(false);
+ }
+ };
+ const onDelete = async () => {
+ if (orgId === null) {
+ setErrorMsg("잘못된 워크스페이스ID 입니다");
+ return;
+ }
+ setDeleting(true);
+ try {
+ await deleteWorkspace(orgId);
+ await queryClient.invalidateQueries({ queryKey: ["my-workspaces"] });
+ toast.success("워크스페이스가 삭제되었습니다");
+ setDeleteOpen(false);
+ navigate("/workspace", { replace: true });
+ } catch (e) {
+ toast.error(
+ (e as IApiErrorResponse).message ?? "워크스페이스 삭제에 실패했습니다.",
+ );
+ } finally {
+ setDeleting(false);
+ }
+ };
+
+ const openDeleteModal = () => {
+ setDeleteOpen(true);
+ };
+
+ const openFilePicker = () => {
+ if (!fileRef.current) return;
+ fileRef.current.value = "";
+ fileRef.current.click();
+ };
+
+ const onPickLogo = (e: React.ChangeEvent) => {
+ const file = e.target.files?.[0];
+ if (!file) return;
+
+ setLogoFile(file);
+ setIsImageDeleted(false);
+
+ const previewUrl = URL.createObjectURL(file);
+ setLogoPreview((prev) => {
+ if (prev) URL.revokeObjectURL(prev);
+ return previewUrl;
+ });
+ };
+
+ useEffect(() => {
+ return () => {
+ if (logoPreview) URL.revokeObjectURL(logoPreview);
+ };
+ }, [logoPreview]);
+
+ const onResetLogo = () => {
+ setLogoFile(null);
+ setIsImageDeleted(true);
+ setImageError(false);
+
+ setLogoPreview((prev) => {
+ if (prev) URL.revokeObjectURL(prev);
+ return null;
+ });
+ setServerLogoUrl(null);
+ };
+
+ const resolvedLogoUrl =
+ !logoPreview && !imageError && serverLogoUrl
+ ? getImageUrl(serverLogoUrl)
+ : null;
+
+ return (
+
+ {loading && }
+ {!loading && errorMsg && (
+
+
{errorMsg}
+
+ 다시 시도
+
+
+ )}
+ {!loading && !errorMsg && (
+ <>
+
+
+
+
+ 로고 이미지
+
+
+
+ {logoPreview ? (
+
+ ) : resolvedLogoUrl ? (
+
{
+ setImageError(true);
+ }}
+ />
+ ) : (
+
+ )}
+
+
+
+ 업로드
+
+
+ 초기화
+
+
+
+
+ setName(e.target.value)}
+ disabled={saving || deleting}
+ />
+ setDesc(e.target.value)}
+ minRows={4}
+ className="min-h-90"
+ disabled={saving || deleting}
+ />
+
+
+
+
+ {saving ? "저장 중.." : "변경사항 저장하기"}
+
+
+
+
+
+ }
+ />
+
+ setDeleteOpen(false)}
+ size="lg"
+ padding="lg"
+ title="워크스페이스 삭제 확인"
+ >
+
+
+
+
+
+ 정말 삭제하시겠습니까?
+
+
+ 삭제된 워크스페이스와 관련된 모든 데이터는 영구 삭제되며 {" "}
+ 절대 되돌릴 수 없습니다.
+
+
+
+ {deleting ? "삭제 중.." : "삭제하기"}
+
+
+
+
+ >
+ )}
+
+ );
+}
diff --git a/src/routes/AuthRoutes.tsx b/src/routes/AuthRoutes.tsx
new file mode 100644
index 00000000..20085356
--- /dev/null
+++ b/src/routes/AuthRoutes.tsx
@@ -0,0 +1,69 @@
+import { lazy, Suspense } from "react";
+import { type RouteObject, useLocation } from "react-router-dom";
+
+import { loadable } from "@/utils/loadable";
+
+import AuthFormSkeleton from "@/components/auth/skeleton/AuthFormSkeleton";
+import LoginPageSkeleton from "@/components/auth/skeleton/LoginPageSkeleton";
+import SignupEmailStepSkeleton from "@/components/auth/skeleton/SignupEmailStepSkeleton";
+import SignupPageSkeleton from "@/components/auth/skeleton/SignupPageSkeleton";
+
+const FindEmail = loadable(
+ lazy(() => import("@/pages/auth/FindEmail")),
+ ,
+);
+const FindPw = loadable(
+ lazy(() => import("@/pages/auth/FindPw")),
+ ,
+);
+const Login = loadable(
+ lazy(() => import("@/pages/auth/Login")),
+ ,
+);
+
+const RedirectPage = loadable(
+ lazy(() => import("@/pages/auth/RedirectPage")),
+ ,
+);
+
+const Signup = lazy(() => import("@/pages/auth/Signup"));
+
+function SignupPage() {
+ const location = useLocation();
+ const step = location.state?.step;
+
+ return (
+ :
+ }
+ >
+
+
+ );
+}
+
+const AuthRoutes: RouteObject[] = [
+ {
+ path: "signup",
+ element: ,
+ },
+ {
+ path: "login",
+ element: ,
+ },
+ {
+ path: "find-email",
+ element: ,
+ },
+ {
+ path: "find-pw",
+ element: ,
+ },
+ {
+ path: "oauth2/redirect",
+ element: ,
+ },
+];
+
+export default AuthRoutes;
diff --git a/src/routes/MainRoutes.tsx b/src/routes/MainRoutes.tsx
new file mode 100644
index 00000000..3f09759a
--- /dev/null
+++ b/src/routes/MainRoutes.tsx
@@ -0,0 +1,85 @@
+import { lazy } from "react";
+import type { RouteObject } from "react-router-dom";
+
+import { loadable } from "@/utils/loadable";
+
+import WorkspaceListLoading from "@/components/workspace/WorkspaceListLoading";
+
+const OverviewDashboard = loadable(
+ lazy(() => import("@/pages/dashboard/overview/OverviewDashboard")),
+);
+const PlatformDashboard = loadable(
+ lazy(() => import("@/pages/dashboard/platform/PlatformDashboard")),
+);
+const Timeline = loadable(
+ lazy(() => import("@/pages/dashboard/timeline/Timeline")),
+);
+const AdsListPage = loadable(
+ lazy(() => import("@/pages/ads/list/AdsListPage")),
+);
+const CampaignDetail = loadable(
+ lazy(() => import("@/pages/ads/list/CampaignDetail")),
+);
+const CampaignGroup = loadable(
+ lazy(() => import("@/pages/ads/new/CampaignGroup")),
+);
+const Workspace = loadable(
+ lazy(() => import("@/pages/workspace/Workspace")),
+ ,
+);
+const WorkspaceManageLayout = loadable(
+ lazy(() => import("@/layout/workspace/WorkspaceManageLayout")),
+);
+const WorkspaceSetting = loadable(
+ lazy(() => import("@/pages/workspace/WorkspaceSetting")),
+);
+const MemberManagement = loadable(
+ lazy(() => import("@/pages/workspace/MemberManagement")),
+);
+const Billing = loadable(lazy(() => import("@/pages/workspace/Billing")));
+
+const MainRoutes: RouteObject[] = [
+ {
+ path: "dashboard",
+ element: ,
+ },
+ {
+ path: "platform",
+ element: ,
+ },
+ {
+ path: "timeline",
+ element: ,
+ },
+ {
+ path: "ads",
+ element: ,
+ },
+ {
+ path: "ads/campaignGroup",
+ element: ,
+ },
+ {
+ path: "ads/:orgId/:projectId",
+ element: ,
+ },
+
+ {
+ path: "workspace",
+ element: ,
+ },
+ {
+ path: "workspace/:workspaceId",
+ element: ,
+ children: [
+ { path: "settings", element: },
+ { path: "members", element: },
+ ],
+ },
+ {
+ path: "workspace/billing",
+ element: ,
+ },
+];
+
+export default MainRoutes;
diff --git a/src/routes/Router.tsx b/src/routes/Router.tsx
new file mode 100644
index 00000000..54bf6897
--- /dev/null
+++ b/src/routes/Router.tsx
@@ -0,0 +1,61 @@
+import React from "react";
+import { createBrowserRouter, Navigate } from "react-router-dom";
+
+import AuthRoutes from "./AuthRoutes";
+import MainRoutes from "./MainRoutes";
+
+import AuthLayout from "@/layout/auth/AuthLayout";
+import GlobalLayout from "@/layout/GlobalLayout";
+import MainLayout from "@/layout/main/MainLayout";
+import Error from "@/pages/common/Error";
+import useAuthStore from "@/store/useAuthStore";
+
+const LandingPage = React.lazy(() => import("@/pages/landing/LandingPage"));
+
+function AuthGuard({ children }: { children: React.ReactNode }) {
+ const isLoggedIn = useAuthStore((state) => state.isLoggedIn);
+ const isTokenInitialized = useAuthStore((state) => state.isTokenInitialized);
+
+ if (!isTokenInitialized) {
+ return null;
+ }
+
+ if (!isLoggedIn) {
+ return ;
+ }
+
+ return <>{children}>;
+}
+
+export const router = createBrowserRouter([
+ {
+ element: ,
+ errorElement: ,
+ children: [
+ {
+ path: "/",
+ element: ,
+ },
+ {
+ path: "/landing",
+ element: (
+
+
+
+ ),
+ },
+ {
+ element: ,
+ children: AuthRoutes,
+ },
+ {
+ element: (
+
+
+
+ ),
+ children: MainRoutes,
+ },
+ ],
+ },
+]);
diff --git a/src/routes/routes.tsx b/src/routes/routes.tsx
deleted file mode 100644
index a4cfeb6b..00000000
--- a/src/routes/routes.tsx
+++ /dev/null
@@ -1,121 +0,0 @@
-import type { PropsWithChildren } from "react";
-import { createBrowserRouter, Navigate } from "react-router-dom";
-
-import AuthLayout from "@/layout/auth/AuthLayout";
-import Layout from "@/layout/common/Layout";
-import FindPw from "@/pages/auth/FindPw";
-import Login from "@/pages/auth/Login";
-import Signup from "@/pages/auth/Signup";
-import Error from "@/pages/common/Error";
-import OverviewDashboard from "@/pages/dashboard/overview/OverviewDashboard";
-import PlatformDashboard from "@/pages/dashboard/platform/PlatformDashboard";
-import ReplayDashboard from "@/pages/dashboard/replay/ReplayDashboard";
-import Setting from "@/pages/setting/Setting";
-import Workspace from "@/pages/workspace/Workspace";
-
-const checkAuth = (): boolean => {
- // 실제 인증 로직으로 교체 필요합니다.
- return true;
-};
-
-function ProtectedRoute({ children }: PropsWithChildren) {
- const isLoggedIn = checkAuth();
-
- if (!isLoggedIn) {
- return ;
- }
-
- return <>{children}>;
-}
-
-function PublicRoute({ children }: PropsWithChildren) {
- const isLoggedIn = checkAuth();
-
- if (isLoggedIn) {
- return ;
- }
-
- return <>{children}>;
-}
-
-const router = createBrowserRouter([
- {
- path: "/",
- element: ,
- },
- {
- path: "/auth",
- element: (
-
-
-
- ),
- errorElement: ,
- children: [
- {
- index: true,
- element: ,
- },
- {
- path: "signup",
- element: ,
- },
- {
- path: "login",
- element: ,
- },
- {
- path: "find-pw",
- element: ,
- },
- ],
- },
- {
- path: "/dashboard",
- element: (
-
-
-
- ),
- errorElement: ,
- children: [
- {
- index: true,
- element: ,
- },
- {
- path: "overview",
- element: ,
- },
- {
- path: "replay",
- element: ,
- },
- {
- path: "platform",
- element: ,
- },
- ],
- },
- {
- path: "/user",
- element: (
-
-
-
- ),
- errorElement: ,
- children: [
- {
- path: "setting",
- element: ,
- },
- {
- path: "workspace",
- element: ,
- },
- ],
- },
-]);
-
-export default router;
diff --git a/src/store/useAuthStore.ts b/src/store/useAuthStore.ts
new file mode 100644
index 00000000..cb53d9fd
--- /dev/null
+++ b/src/store/useAuthStore.ts
@@ -0,0 +1,50 @@
+import { create } from "zustand";
+
+interface IAuthState {
+ isLoggedIn: boolean;
+ isTokenInitialized: boolean;
+ accessToken: string | null;
+ email: string;
+ socialId: number | null;
+
+ login: (email: string, accessToken: string) => void;
+ logout: () => void;
+ setAccessToken: (token: string) => void;
+ setTokenInitialized: () => void;
+ setEmail: (email: string) => void;
+ setSocialId: (socialId: number | null) => void;
+ resetAuth: () => void;
+}
+
+const useAuthStore = create((set) => ({
+ isLoggedIn: false,
+ isTokenInitialized: false,
+ accessToken: null,
+ email: "",
+ socialId: null,
+
+ login: (email, accessToken) => {
+ localStorage.setItem("hasSession", "true");
+ set({ isLoggedIn: true, email, accessToken });
+ },
+ logout: () => {
+ localStorage.removeItem("hasSession");
+ set({
+ isLoggedIn: false,
+ accessToken: null,
+ email: "",
+ socialId: null,
+ });
+ },
+
+ setAccessToken: (token) => {
+ localStorage.setItem("hasSession", "true");
+ set({ accessToken: token, isLoggedIn: true });
+ },
+ setTokenInitialized: () => set({ isTokenInitialized: true }),
+ setEmail: (email) => set({ email }),
+ setSocialId: (socialId) => set({ socialId }),
+ resetAuth: () => set({ email: "", socialId: null }),
+}));
+
+export default useAuthStore;
diff --git a/src/store/useModalStore.ts b/src/store/useModalStore.ts
new file mode 100644
index 00000000..20947bb1
--- /dev/null
+++ b/src/store/useModalStore.ts
@@ -0,0 +1,56 @@
+import { create } from "zustand";
+
+export const MODAL_TYPES = {
+ PRIVACY: "PRIVACY",
+} as const;
+
+export type TModalType = (typeof MODAL_TYPES)[keyof typeof MODAL_TYPES];
+
+export type TGlobalModalProps = {
+ [MODAL_TYPES.PRIVACY]: {
+ onAgree?: (agreements: { privacy: boolean; marketing: boolean }) => void;
+ initialState?: {
+ privacy: boolean;
+ marketing: boolean;
+ };
+ };
+};
+
+type TModalState =
+ | {
+ modalType: null;
+ modalProps: Record;
+ }
+ | {
+ [K in TModalType]: {
+ modalType: K;
+ modalProps: TGlobalModalProps[K];
+ };
+ }[TModalType];
+
+interface IModalStoreActions {
+ openModal: (
+ modalType: T,
+ modalProps: TGlobalModalProps[T],
+ ) => void;
+ closeModal: () => void;
+}
+
+type TModalStoreState = TModalState & IModalStoreActions;
+
+const useModalStore = create((set) => ({
+ modalType: null,
+ modalProps: {},
+ openModal: (modalType, modalProps) =>
+ set({
+ modalType,
+ modalProps,
+ } as TModalState),
+ closeModal: () =>
+ set({
+ modalType: null,
+ modalProps: {},
+ }),
+}));
+
+export default useModalStore;
diff --git a/src/store/useSidebarStore.ts b/src/store/useSidebarStore.ts
new file mode 100644
index 00000000..530093e5
--- /dev/null
+++ b/src/store/useSidebarStore.ts
@@ -0,0 +1,15 @@
+import { create } from "zustand";
+
+interface ISidebarState {
+ isCollapsed: boolean;
+ setIsCollapsed: (next: boolean) => void;
+ toggleSidebar: () => void;
+}
+
+const useSidebarStore = create((set) => ({
+ isCollapsed: true,
+ setIsCollapsed: (next) => set({ isCollapsed: next }),
+ toggleSidebar: () => set((prev) => ({ isCollapsed: !prev.isCollapsed })),
+}));
+
+export default useSidebarStore;
diff --git a/src/store/useWorkspaceStore.ts b/src/store/useWorkspaceStore.ts
new file mode 100644
index 00000000..48bdfbfe
--- /dev/null
+++ b/src/store/useWorkspaceStore.ts
@@ -0,0 +1,13 @@
+import { create } from "zustand";
+
+interface IWorkspaceState {
+ selectedOrgId: number | null;
+ setSelectedOrgId: (orgId: number) => void;
+}
+
+const useWorkspaceStore = create((set) => ({
+ selectedOrgId: null,
+ setSelectedOrgId: (orgId) => set({ selectedOrgId: orgId }),
+}));
+
+export default useWorkspaceStore;
diff --git a/src/stories/BorderRadius.stories.tsx b/src/stories/BorderRadius.stories.tsx
new file mode 100644
index 00000000..646f80fc
--- /dev/null
+++ b/src/stories/BorderRadius.stories.tsx
@@ -0,0 +1,65 @@
+import type { Meta, StoryObj } from "@storybook/react";
+
+const radiusTokens = [
+ {
+ className: "rounded-component-sm",
+ label: "Component SM",
+ value: "0.5rem (8px)",
+ usage: "이미지, 소형 버튼, 뱃지",
+ },
+ {
+ className: "rounded-component-md",
+ label: "Component MD",
+ value: "1rem (16px)",
+ usage: "버튼, 인풋, 모달, 드롭다운, 네비 아이템",
+ },
+ {
+ className: "rounded-component-lg",
+ label: "Component LG",
+ value: "1.5rem (24px)",
+ usage: "카드, 패널, 알럿",
+ },
+ {
+ className: "rounded-full",
+ label: "Full",
+ value: "9999px",
+ usage: "아바타, 소셜 버튼, 뱃지 pill",
+ },
+];
+
+function BorderRadiusDoc() {
+ return (
+
+
+ Token
+ Preview
+ Value
+ Usage
+
+ {radiusTokens.map(({ className, value, usage }) => (
+
+
.{className}
+
+
{value}
+
{usage}
+
+ ))}
+
+ );
+}
+
+const meta: Meta = {
+ title: "Design Tokens/Border Radius",
+ component: BorderRadiusDoc,
+ parameters: { layout: "fullscreen" },
+};
+
+export default meta;
+type TStory = StoryObj;
+
+export const All: TStory = {};
diff --git a/src/stories/Colors.stories.tsx b/src/stories/Colors.stories.tsx
new file mode 100644
index 00000000..d5832856
--- /dev/null
+++ b/src/stories/Colors.stories.tsx
@@ -0,0 +1,111 @@
+import type { Meta, StoryObj } from "@storybook/react";
+
+const colorGroups = [
+ {
+ label: "Brand",
+ colors: [
+ { name: "brand-900", value: "#000000" },
+ { name: "brand-800", value: "#001f5b" },
+ { name: "brand-700", value: "#213e68" },
+ { name: "brand-600", value: "#466a9c" },
+ { name: "brand-500", value: "#88c1ff" },
+ { name: "brand-400", value: "#dce7f2" },
+ { name: "brand-300", value: "#f9fafb" },
+ { name: "brand-200", value: "#ffffff" },
+ ],
+ },
+ {
+ label: "Logo",
+ colors: [
+ { name: "logo-1", value: "#2eb4ff" },
+ { name: "logo-2", value: "#6088fe" },
+ ],
+ },
+ {
+ label: "Status",
+ colors: [
+ { name: "status-red", value: "#ff2a4b" },
+ { name: "status-blue", value: "#0084fe" },
+ { name: "status-green", value: "#22c55e" },
+ { name: "status-yellow", value: "#facc15" },
+ ],
+ },
+ {
+ label: "Text",
+ colors: [
+ { name: "text-main", value: "#212121" },
+ { name: "text-auth-sub", value: "#546171" },
+ { name: "text-sub", value: "#8b8b8f" },
+ { name: "text-placeholder", value: "#c3c3c3" },
+ { name: "text-disabled", value: "#b0b8c1" },
+ { name: "bg-disabled", value: "#e5e8eb" },
+ { name: "bg-surface", value: "#f6f6f6" },
+ ],
+ },
+ {
+ label: "Social",
+ colors: [
+ { name: "social-kakao", value: "#fee500" },
+ { name: "social-naver", value: "#03c75a" },
+ { name: "social-google", value: "#ffffff" },
+ ],
+ },
+ {
+ label: "Chart",
+ colors: [
+ { name: "chart-1", value: "#0a3d91" },
+ { name: "chart-2", value: "#0056b3" },
+ { name: "chart-3", value: "#1485ff" },
+ { name: "chart-4", value: "#00aeef" },
+ { name: "chart-5", value: "#4fc3f7" },
+ { name: "chart-inactive", value: "#f2f4f6" },
+ ],
+ },
+];
+
+function ColorDoc() {
+ return (
+
+ {colorGroups.map(({ label, colors }) => (
+
+
+ {label}
+
+
+ {colors.map(({ name, value }) => (
+
+ ))}
+
+
+ ))}
+
+ );
+}
+
+const meta: Meta = {
+ title: "Design Tokens/Colors",
+ component: ColorDoc,
+ parameters: { layout: "fullscreen" },
+};
+
+export default meta;
+type TStory = StoryObj;
+
+export const All: TStory = {};
diff --git a/src/stories/Shadows.stories.tsx b/src/stories/Shadows.stories.tsx
new file mode 100644
index 00000000..ad62d8e7
--- /dev/null
+++ b/src/stories/Shadows.stories.tsx
@@ -0,0 +1,47 @@
+import type { Meta, StoryObj } from "@storybook/react";
+
+const shadowTokens = [
+ {
+ className: "shadow-Soft",
+ label: "Soft",
+ value: "0px 0px 16px 0px rgba(0, 0, 0, 0.1)",
+ },
+ {
+ className: "shadow-Medium",
+ label: "Medium",
+ value: "0px 0px 16px 0px rgba(0, 0, 0, 0.2)",
+ },
+];
+
+function ShadowDoc() {
+ return (
+
+
+ Token
+ Preview
+ Value
+
+ {shadowTokens.map(({ className, value }) => (
+
+
.{className}
+
+
{value}
+
+ ))}
+
+ );
+}
+
+const meta: Meta = {
+ title: "Design Tokens/Shadows",
+ component: ShadowDoc,
+ parameters: { layout: "fullscreen" },
+};
+
+export default meta;
+type TStory = StoryObj;
+
+export const All: TStory = {};
diff --git a/src/stories/Typography.stories.tsx b/src/stories/Typography.stories.tsx
new file mode 100644
index 00000000..ba32b9b2
--- /dev/null
+++ b/src/stories/Typography.stories.tsx
@@ -0,0 +1,104 @@
+import type { Meta, StoryObj } from "@storybook/react";
+
+const fontTokens = [
+ {
+ className: "font-hero",
+ label: "Hero",
+ size: "54px",
+ weight: "700",
+ lineHeight: "140%",
+ },
+ {
+ className: "font-heading1",
+ label: "Heading 1",
+ size: "30px",
+ weight: "600",
+ lineHeight: "130%",
+ },
+ {
+ className: "font-heading2",
+ label: "Heading 2",
+ size: "28px",
+ weight: "600",
+ lineHeight: "130%",
+ },
+ {
+ className: "font-heading3",
+ label: "Heading 3",
+ size: "24px",
+ weight: "500",
+ lineHeight: "130%",
+ },
+ {
+ className: "font-heading4",
+ label: "Heading 4",
+ size: "18px",
+ weight: "400",
+ lineHeight: "130%",
+ },
+ {
+ className: "font-body1",
+ label: "Body 1",
+ size: "16px",
+ weight: "500",
+ lineHeight: "140%",
+ },
+ {
+ className: "font-body2",
+ label: "Body 2",
+ size: "14px",
+ weight: "500",
+ lineHeight: "140%",
+ },
+ {
+ className: "font-label",
+ label: "Label",
+ size: "14px",
+ weight: "600",
+ lineHeight: "140%",
+ },
+ {
+ className: "font-caption",
+ label: "Caption",
+ size: "12px",
+ weight: "500",
+ lineHeight: "130%",
+ },
+];
+
+function TypographyDoc() {
+ return (
+
+
+ Token
+ Sample
+ Size
+ Weight
+ Leading
+
+ {fontTokens.map(({ className, label, size, weight, lineHeight }) => (
+
+ .{className}
+ {label} — 가나다라마바사
+ {size}
+ {weight}
+ {lineHeight}
+
+ ))}
+
+ );
+}
+
+const meta: Meta = {
+ title: "Design Tokens/Typography",
+ component: TypographyDoc,
+ parameters: { layout: "fullscreen" },
+};
+
+export default meta;
+type TStory = StoryObj;
+
+export const All: TStory = {};
diff --git a/src/types/ads/campaign.ts b/src/types/ads/campaign.ts
new file mode 100644
index 00000000..67a40684
--- /dev/null
+++ b/src/types/ads/campaign.ts
@@ -0,0 +1,49 @@
+export type TPlatform = "kakao" | "google" | "naver"; //UI
+export type TProvider = "KAKAO" | "GOOGLE" | "NAVER"; //API
+export type TStatus = "ON_GOING" | "PAUSED" | "OVER";
+
+// Ad List
+export interface IAd {
+ id: number;
+ name: string;
+ provider: TProvider[];
+ status: TStatus;
+
+ trackingUrl?: string;
+ landingUrl?: string;
+ description?: string;
+ targetInfo?: string;
+
+ platform?: TPlatform;
+ runStatus?: "running" | "stopped";
+ runStatusText?: string;
+}
+
+// Campaign List
+export interface ICampaign {
+ projectId: number;
+ name: string;
+ providers: TPlatform[];
+ status: TStatus;
+ description?: string;
+ budgetUsageRate: number;
+}
+
+// Campaign Detail
+export interface ICampaignDetail extends ICampaign {
+ budget: number;
+ createdAt: string;
+ ads: IAd[];
+}
+
+export interface IPlatformCampaign {
+ adCampaignId: number;
+ name: string;
+ description: string;
+}
+
+export interface ICreateCampaignGroupRequest {
+ name: string;
+ description: string;
+ campaignIds: number[];
+}
diff --git a/src/types/auth/auth.ts b/src/types/auth/auth.ts
new file mode 100644
index 00000000..c3e18f95
--- /dev/null
+++ b/src/types/auth/auth.ts
@@ -0,0 +1,87 @@
+export interface IEmailSendRequest {
+ email: string;
+}
+
+export interface IEmailSendResponse {
+ message: string;
+ email: string;
+ expireIn: number;
+ isProviderLinked: boolean;
+ providerTypes: TLoginProvider[];
+}
+
+export interface IEmailVerifyRequest {
+ email: string;
+ authCode: string;
+}
+
+export interface ISignUpRequest {
+ email: string;
+ password: string;
+ name: string;
+ phone_number: string;
+}
+
+export interface ISignUpResponse {
+ userId: number;
+ createdAt: string;
+}
+
+export interface ILoginRequest {
+ email: string;
+ password: string;
+}
+
+export interface ILoginResponse {
+ grantType: string;
+ accessToken: string;
+ accessTokenExpiresIn: number;
+}
+
+export interface ITokenRefreshResponse {
+ grantType: string;
+ accessToken: string;
+ accessTokenExpiresIn: number;
+}
+
+// 소셜 로그인 OAuth2 경로용
+export type TSocialLoginPlatform = "kakao" | "naver" | "google";
+
+// 서버 응답의 로그인 provider
+export type TLoginProvider = "EMAIL" | "KAKAO" | "NAVER" | "GOOGLE";
+
+export interface ISmsSendRequest {
+ phoneNumber: string;
+}
+
+export interface ISmsSendResponse {
+ message: string;
+ phoneNumber: string;
+ expireIn: number;
+}
+
+export interface ISmsVerifyRequest {
+ phoneNumber: string;
+ verificationCode: string;
+}
+
+export interface ISmsVerifyResponse {
+ isVerified: boolean;
+ verificationMessage: string;
+ email: string;
+}
+
+export interface IPasswordResetRequest {
+ email: string;
+ password: string;
+}
+
+export interface IMyPageInfoResponse {
+ userId: number;
+ email: string;
+ name: string;
+ profileImageUrl: string;
+ phoneNumber: string;
+ isEmailVerified: boolean;
+ providerType: TLoginProvider;
+}
diff --git a/src/types/common/common.ts b/src/types/common/common.ts
new file mode 100644
index 00000000..8e3bb36e
--- /dev/null
+++ b/src/types/common/common.ts
@@ -0,0 +1,55 @@
+import type {
+ QueryKey,
+ UseMutationOptions,
+ UseQueryOptions,
+} from "@tanstack/react-query";
+
+// API 공통 성공 응답 타입
+export interface ICommonResponse {
+ status: string;
+ data: T;
+}
+
+// API 공통 에러 응답 타입
+export interface IApiErrorResponse {
+ status: string;
+ code: string;
+ message: string;
+ method: string;
+ requestURI: string;
+}
+
+export type TUseQueryCustomOptions<
+ TQueryFnData = unknown,
+ TData = TQueryFnData,
+> = Omit<
+ UseQueryOptions,
+ "queryKey" | "queryFn"
+>;
+
+export type TUseMutationCustomOptions<
+ TData = unknown,
+ TVariables = unknown,
+ TError = IApiErrorResponse,
+ TContext = unknown,
+ TCache = unknown,
+> = Omit<
+ UseMutationOptions,
+ "mutationFn" | "onMutate" | "onError" | "onSuccess"
+> & {
+ optimisticUpdate?: {
+ key: QueryKey;
+ updateFn: (oldData: TCache | undefined, newData: TVariables) => TCache;
+ };
+ invalidateKeys?: QueryKey[];
+ userOnError?: (
+ error: TError,
+ variables: TVariables,
+ context: TContext | undefined,
+ ) => Promise | unknown;
+ userOnSuccess?: (
+ data: TData,
+ variables: TVariables,
+ context: TContext | undefined,
+ ) => Promise | unknown;
+};
diff --git a/src/types/dashboard/overview.ts b/src/types/dashboard/overview.ts
new file mode 100644
index 00000000..abe7ee66
--- /dev/null
+++ b/src/types/dashboard/overview.ts
@@ -0,0 +1,68 @@
+// 광고 플랫폼 종류
+export type TProviderType = "KAKAO" | "NAVER" | "GOOGLE";
+
+// 전체 지표 집계 응답
+export interface IMetricsResponse {
+ clicks: number;
+ clickChangeRate: number;
+ impressions: number;
+ impressionChangeRate: number;
+ conversion: number;
+ cvrChangeRate: number;
+ ROAS: number;
+ ROASChangeRate: number;
+}
+
+// 예산 집계 응답
+export interface IBudgetsResponse {
+ providerType: string;
+ usagePercentage: number;
+ totalBudget: number;
+ totalSpend: number;
+ remainingBudget: number;
+}
+
+// ROAS 순위 조회 요청 파라미터
+export interface IRoasRankingsParams {
+ startDate?: string;
+ endDate?: string;
+}
+
+// ROAS 순위 조회 응답
+export interface IRoasRankingsResponse {
+ startDate: string;
+ endDate: string;
+ rankings: IRoasRanking[];
+}
+
+// ROAS 순위 항목
+export interface IRoasRanking {
+ rank: number;
+ provider: string;
+ roas: number;
+ diffRate: number | null;
+ revenue: number;
+ adSpend: number;
+}
+
+// 플랫폼별 ROAS 순위 + 지표(CTR/CVR) 통합 항목
+export interface IPlatformRankingItem extends IRoasRanking {
+ clickRate?: number; // CTR (%)
+ ctrDelta?: number; // CTR 전기 대비 증감 (%)
+ conversionRate?: number; // CVR (%)
+ conversionDelta?: number; // CVR 전기 대비 증감 (%)
+}
+
+// 클릭 스트림 데이터 항목
+export interface IClickStreamItem {
+ timeSeriesData: {
+ minute: string; // 'YYYYMMDDHHmm' 형태
+ count: number;
+ }[];
+ mode: "real" | "dummy";
+ hasSuspect: boolean;
+ suspectDetail: {
+ message: string;
+ timestamp: string;
+ } | null;
+}
diff --git a/src/types/dashboard/platform.ts b/src/types/dashboard/platform.ts
new file mode 100644
index 00000000..d2b87d46
--- /dev/null
+++ b/src/types/dashboard/platform.ts
@@ -0,0 +1,50 @@
+import type { TProviderType } from "./overview";
+
+export type TPlatformProvider = TProviderType | "META";
+
+export const PLATFORM_MAP: Record = {
+ GOOGLE: "Google",
+ NAVER: "NAVER",
+ META: "Meta",
+};
+
+// ROAS 성과 순위
+export interface IRoasRanking {
+ rank: number;
+ provider: string;
+ roas: number;
+ diffRate: number | null;
+ revenue: number;
+ adSpend: number;
+}
+
+// 플랫폼 광고 소재 개수
+export interface IAdCount {
+ provider: TPlatformProvider;
+ count: number;
+}
+
+// 광고 소재 현황
+export interface IAdStatusData {
+ totalCount: number;
+ providerCount: IAdCount[];
+}
+
+// 플랫폼별 성과
+export interface IPlatformPerformance {
+ provider: TPlatformProvider;
+ clicks: number;
+ clickChangeRate: number;
+ impressions: number;
+ impressionChangeRate: number;
+ conversion: number;
+ cvrChangeRate: number;
+ ROAS: number;
+ ROASChangeRate: number;
+}
+
+// 플랫폼별 성과 효율 비교
+export interface IPlatformEfficiencyData {
+ status: string;
+ data: IPlatformPerformance[];
+}
diff --git a/src/types/navigation/navItem.ts b/src/types/navigation/navItem.ts
new file mode 100644
index 00000000..16176c56
--- /dev/null
+++ b/src/types/navigation/navItem.ts
@@ -0,0 +1,9 @@
+import type { ComponentType, SVGProps } from "react";
+
+export interface INavItem {
+ id: string;
+ label: string;
+ icon?: ComponentType>;
+ path?: string;
+ children?: INavItem[];
+}
diff --git a/src/types/workspace/workspace.ts b/src/types/workspace/workspace.ts
new file mode 100644
index 00000000..714a486a
--- /dev/null
+++ b/src/types/workspace/workspace.ts
@@ -0,0 +1,126 @@
+export type TMemberRole = "ADMIN" | "MEMBER";
+
+export type TWorkspace = {
+ orgId: number;
+ name: string;
+ description: string;
+ url?: string | null;
+ logoUrl?: string | null;
+ myRole: TMemberRole;
+ isCurrentWorkspace: boolean;
+};
+
+export type TMyOrgsData = {
+ organizations: TWorkspace[];
+};
+
+export type TCreateOrgRequest = {
+ name: string;
+ description: string;
+ imageFile?: File | null;
+};
+
+export type TCreateOrgResponse = {
+ name: string;
+ description: string;
+ logoUrl: string | null;
+};
+
+export type TGetOrgResponse = {
+ orgId: number;
+ name: string;
+ description: string;
+ logoUrl: string | null;
+ createdAt: string;
+};
+
+export type TWorkspaceDetail = TGetOrgResponse;
+
+export type TUpdateWorkspaceRequest = {
+ name: string;
+ description: string;
+ imageFile?: File | null;
+ isImageDeleted: boolean;
+};
+
+export type TWorkspaceMember = {
+ memberId: number;
+ name: string;
+ email: string;
+ profileImageUrl: string | null;
+ role: TMemberRole;
+ isMe?: boolean;
+};
+
+export type TUpdateMemberRoleRequest = {
+ orgRole: TMemberRole;
+};
+
+export type TUpdateMemberRoleResponse = TWorkspaceMember;
+
+export type TGetWorkspaceMembersData = {
+ hasNext: boolean;
+ nextCursor: string | null;
+ members: TWorkspaceMember[];
+};
+
+export type TWorkspaceMemberCount = {
+ totalCount: number;
+};
+
+export type TDeleteWorkspaceMemberResponse = string;
+
+export type TPermissionKey =
+ | "campaignView"
+ | "billingManage"
+ | "workspaceView"
+ | "memberInvite"
+ | "memberRoleEdit"
+ | "workspaceEdit"
+ | "projectDelete";
+
+export type TPermissionRow = {
+ key: TPermissionKey;
+ label: string;
+ description: string;
+ defaultMemberEnabled: boolean;
+};
+
+export type TInviteMemberRequest = {
+ email: string;
+};
+
+export type TInviteMemberResponse = {
+ orgId: number;
+ message: string;
+ email: string;
+};
+
+export type TInviteMemberItem =
+ | {
+ invitationId: number;
+ email: string;
+ invitedAt: string;
+ expireAt: string;
+ inviteStatus: "PENDING";
+ }
+ | {
+ memberId: number;
+ name: string;
+ email: string;
+ profileImageUrl: string | null;
+ role: TMemberRole;
+ inviteStatus: "ACTIVE";
+ isMe?: boolean;
+ };
+
+export type TPendingMemberData = {
+ invitationId: number;
+ email: string;
+ invitedAt: string;
+ expireAt: string;
+};
+
+export type TPendingMemberResponse = {
+ pendingMembers: TPendingMemberData[];
+};
diff --git a/src/utils/download.ts b/src/utils/download.ts
new file mode 100644
index 00000000..da848e96
--- /dev/null
+++ b/src/utils/download.ts
@@ -0,0 +1,42 @@
+import ApexCharts from "apexcharts";
+
+export async function downloadChartPng(chartId: string, filename: string) {
+ try {
+ const { imgURI } = (await ApexCharts.exec(chartId, "dataURI")) as {
+ imgURI: string;
+ };
+ const a = document.createElement("a");
+ a.href = imgURI;
+ a.download = `${filename}.png`;
+ a.click();
+ } catch (e) {
+ console.error("PNG 저장 실패:", e);
+ }
+}
+
+export function downloadChartSvg(containerId: string, filename: string) {
+ const svgEl = document.getElementById(containerId)?.querySelector("svg");
+ if (!svgEl) return;
+ const svgData = new XMLSerializer().serializeToString(svgEl);
+ const blob = new Blob([svgData], { type: "image/svg+xml" });
+ const url = URL.createObjectURL(blob);
+ const a = document.createElement("a");
+ a.href = url;
+ a.download = `${filename}.svg`;
+ a.click();
+ URL.revokeObjectURL(url);
+}
+
+export function downloadChartCsv(chartId: string) {
+ ApexCharts.exec(chartId, "exportToCSV");
+}
+
+export function printAsPdf(printClass: string) {
+ document.body.classList.add(printClass);
+ const cleanup = () => {
+ document.body.classList.remove(printClass);
+ window.removeEventListener("afterprint", cleanup);
+ };
+ window.addEventListener("afterprint", cleanup);
+ setTimeout(() => window.print(), 150);
+}
diff --git a/src/utils/formatPhoneNumber.ts b/src/utils/formatPhoneNumber.ts
new file mode 100644
index 00000000..50d2b553
--- /dev/null
+++ b/src/utils/formatPhoneNumber.ts
@@ -0,0 +1,17 @@
+export function stripPhoneHyphens(value: string): string {
+ return value.replace(/-/g, "");
+}
+
+export default function formatPhoneNumber(value: string): string {
+ // 1. 숫자만 남기기
+ const digits = value.replace(/\D/g, "").slice(0, 11);
+
+ // 2. 조건부 하이픈 삽입
+ if (digits.length <= 3) {
+ return digits;
+ } else if (digits.length <= 7) {
+ return `${digits.slice(0, 3)}-${digits.slice(3)}`;
+ } else {
+ return `${digits.slice(0, 3)}-${digits.slice(3, 7)}-${digits.slice(7, 11)}`;
+ }
+}
diff --git a/src/utils/loadable.tsx b/src/utils/loadable.tsx
new file mode 100644
index 00000000..8c540947
--- /dev/null
+++ b/src/utils/loadable.tsx
@@ -0,0 +1,19 @@
+import { type ComponentType, type ReactNode, Suspense } from "react";
+
+type TPropsOf = T extends ComponentType ? P : never;
+
+export function loadable>(
+ Component: T,
+ fallback: ReactNode = null,
+) {
+ function Wrapped(props: TPropsOf) {
+ return (
+
+
+
+ );
+ }
+
+ Wrapped.displayName = `Loadable(${Component.displayName || Component.name || "Component"})`;
+ return Wrapped;
+}
diff --git a/src/utils/maskEmail.ts b/src/utils/maskEmail.ts
new file mode 100644
index 00000000..4c6bcc83
--- /dev/null
+++ b/src/utils/maskEmail.ts
@@ -0,0 +1,12 @@
+export function maskEmail(email: string) {
+ if (!email) return "";
+
+ const [local, domain] = email.split("@");
+ if (!local || !domain) return email;
+
+ if (local.length <= 3) {
+ return `${local}****@${domain}`;
+ }
+
+ return `${local.slice(0, 3)}****@${domain}`;
+}
diff --git a/src/utils/navigation/mainNavSidebar.ts b/src/utils/navigation/mainNavSidebar.ts
new file mode 100644
index 00000000..7133d4b2
--- /dev/null
+++ b/src/utils/navigation/mainNavSidebar.ts
@@ -0,0 +1,45 @@
+import type { INavItem } from "@/types/navigation/navItem";
+import { mainNav } from "@/constants/sidebarNav";
+
+import { isPathMatch, normalizePathname } from "./pathMatch";
+
+function createMainNavSidebarHelpers() {
+ const childIdToParentId = new Map();
+ const childPathToParentId = new Map();
+
+ for (const parent of mainNav) {
+ for (const child of parent.children ?? []) {
+ childIdToParentId.set(child.id, parent.id);
+ if (child.path) {
+ childPathToParentId.set(normalizePathname(child.path), parent.id);
+ }
+ }
+ }
+
+ const childPathEntries = Array.from(childPathToParentId.entries()).sort(
+ ([a], [b]) => b.length - a.length,
+ );
+
+ function resolveParentId(pathname: string): string | undefined {
+ return (
+ childPathToParentId.get(pathname) ??
+ childPathEntries.find(([p]) => isPathMatch(pathname, p))?.[1]
+ );
+ }
+
+ function getItemActiveState(pathname: string, item: INavItem) {
+ const isChildActive =
+ item.children?.some((c) =>
+ c.path ? isPathMatch(pathname, c.path) : false,
+ ) ?? false;
+
+ const isParentActive =
+ (item.path ? isPathMatch(pathname, item.path) : false) || isChildActive;
+
+ return { isChildActive, isParentActive };
+ }
+
+ return { childIdToParentId, resolveParentId, getItemActiveState };
+}
+
+export const mainNavSidebar = createMainNavSidebarHelpers();
diff --git a/src/utils/navigation/pathMatch.ts b/src/utils/navigation/pathMatch.ts
new file mode 100644
index 00000000..ec5df745
--- /dev/null
+++ b/src/utils/navigation/pathMatch.ts
@@ -0,0 +1,5 @@
+export const normalizePathname = (pathname: string) =>
+ pathname.replace(/\/+$/, "") || "/";
+
+export const isPathMatch = (currentPath: string, targetPath: string) =>
+ currentPath === targetPath || currentPath.startsWith(`${targetPath}/`);
diff --git a/src/utils/validation.ts b/src/utils/validation.ts
new file mode 100644
index 00000000..f92a10a9
--- /dev/null
+++ b/src/utils/validation.ts
@@ -0,0 +1,71 @@
+import { z } from "zod";
+
+const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
+const phonePattern = /^010-\d{4}-\d{4}$/;
+const realNamePattern = /^[가-힣]+$/;
+const passwordPattern =
+ /^(?=.*[A-Za-z])(?=.*\d)(?=.*[ !"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~]).{8,16}$/;
+
+export const emailSchema = z
+ .string()
+ .trim()
+ .min(1, "이메일은 필수입니다.")
+ .regex(emailRegex, "이메일 형식을 다시 확인해 주세요");
+
+export const nameSchema = z
+ .string()
+ .trim()
+ .min(1, "이름은 필수입니다.")
+ .max(10, "이름은 10자 이내로 입력해주세요.")
+ .regex(realNamePattern, "이름은 한글만 입력할 수 있습니다.")
+ .min(2, "이름은 2자 이상 입력해주세요.");
+
+export const phoneSchema = z
+ .string()
+ .trim()
+ .min(1, "전화번호는 필수입니다.")
+ .regex(phonePattern, "올바른 전화번호를 입력해주세요.");
+
+export const passwordSchema = z
+ .string()
+ .min(1, "비밀번호는 필수입니다.")
+ .regex(passwordPattern, "영문, 숫자, 특수문자가 모두 들어간 8-16글자");
+
+export const codeSchema = z
+ .string()
+ .trim()
+ .min(1, "인증코드를 반드시 입력해주세요.");
+
+export const termsSchema = z.boolean().refine((val) => val === true);
+
+export const loginSchema = z.object({
+ email: emailSchema,
+ password: passwordSchema,
+});
+
+export const signupEmailSchema = z.object({
+ email: emailSchema,
+ code: codeSchema,
+});
+
+export const signupPasswordSchema = z
+ .object({
+ password: passwordSchema,
+ repassword: z.string().min(1, "비밀번호 확인은 필수입니다."),
+ })
+ .refine((data) => data.password === data.repassword, {
+ path: ["repassword"],
+ message: "비밀번호가 일치하지 않습니다.",
+ });
+
+export const signupProfileSchema = z.object({
+ name: nameSchema,
+ phoneNum: phoneSchema,
+ terms: termsSchema,
+ marketing: z.boolean().optional(),
+});
+
+export const findEmailSchema = z.object({
+ phoneNum: phoneSchema,
+ code: codeSchema,
+});
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
new file mode 100644
index 00000000..e1d54387
--- /dev/null
+++ b/src/vite-env.d.ts
@@ -0,0 +1,13 @@
+///
+///
+
+declare module "*.svg?react" {
+ import type { FC, SVGProps } from "react";
+ const ReactComponent: FC>;
+ export default ReactComponent;
+}
+
+declare module "*.md?raw" {
+ const content: string;
+ export default content;
+}
diff --git a/tsconfig.app.json b/tsconfig.app.json
index 18a09f44..4c479e35 100644
--- a/tsconfig.app.json
+++ b/tsconfig.app.json
@@ -5,7 +5,6 @@
"useDefineForClassFields": true,
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
- "types": ["vite/client"],
"skipLibCheck": true,
/* Bundler mode */
@@ -24,11 +23,15 @@
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
- "baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
- "include": ["src"]
+ "include": [
+ "src",
+ ".storybook/**/*.ts",
+ ".storybook/**/*.tsx",
+ "vite-env.d.ts"
+ ]
}
diff --git a/vite.config.ts b/vite.config.ts
index 9a95cc0e..6ed545ba 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,13 +1,71 @@
-import { defineConfig } from "vite";
-import react from "@vitejs/plugin-react-swc";
import tailwindcss from "@tailwindcss/vite";
+import react from "@vitejs/plugin-react-swc";
+import { defineConfig, loadEnv } from "vite";
import svgr from "vite-plugin-svgr";
-export default defineConfig({
- plugins: [react(), tailwindcss(), svgr({ include: "**/*.svg?react" })],
- resolve: {
- alias: {
- "@": "/src",
+export default defineConfig(({ mode }) => {
+ const env = loadEnv(mode, process.cwd(), "");
+
+ return {
+ plugins: [react(), svgr({ include: "**/*.svg?react" }), tailwindcss()],
+
+ // 개발 서버 및 프록시 설정
+ server: {
+ host: "0.0.0.0",
+ port: 5173,
+ proxy: {
+ "/api": {
+ target: env.VITE_API_TARGET_URL,
+ changeOrigin: true,
+ configure(proxy) {
+ proxy.on("proxyReq", (proxyReq) => {
+ // 백엔드가 Origin 기반으로 CORS 차단하는 경우(예: "Invalid CORS request")
+ // 개발 프록시에서는 브라우저의 Origin을 전달하지 않도록 제거합니다.
+ proxyReq.removeHeader("origin");
+ });
+ },
+ },
+ },
+ },
+
+ // 경로 별칭
+ resolve: {
+ alias: {
+ "@": "/src",
+ },
+ dedupe: ["react", "react-dom"],
+ },
+
+ // 사전 번들링 최적화
+ optimizeDeps: {
+ include: ["react-apexcharts", "apexcharts"],
+ },
+
+ // 배포 시 콘솔 로그 제거
+ esbuild: {
+ drop: mode === "production" ? ["console", "debugger"] : [],
+ },
+
+ // 빌드 최적화
+ build: {
+ chunkSizeWarningLimit: 1000, // 청크 크기 경고 한도 상향
+ rollupOptions: {
+ output: {
+ // 라이브러리 및 코드 분할
+ manualChunks(id) {
+ if (id.includes("node_modules")) {
+ if (
+ id.includes("react") ||
+ id.includes("react-dom") ||
+ id.includes("react-router-dom")
+ ) {
+ return "react-vendor"; // 리액트 관련 코어
+ }
+ return "vendor"; // 기타 라이브러리
+ }
+ },
+ },
+ },
},
- },
+ };
});