← back to Angels Flowers
initial snapshot — gitify all builds (CLAUDE.md rule 2026-05-06)
f729216200d3caf261b1b65111a5466dd059a8da · 2026-05-06 10:20:07 -0700 · Steve
Files touched
A .env.local.exampleA .eslintrc.jsonA .gitignoreA CHECKLIST.mdA CLAUDE.mdA DESIGN_SYSTEM.mdA IMPLEMENTATION_GUIDE.mdA PROJECT_OVERVIEW.mdA PROJECT_SUMMARY.mdA QUICKSTART.mdA README.mdA SETUP.mdA SITE_STRUCTURE.mdA USER_RESEARCH.mdA WIREFRAMES.mdA angels_flowers_visual.pngA app/about/page.tsxA app/contact/page.tsxA app/flowers/page.tsxA app/globals.cssA app/icon.svgA app/layout.tsxA app/page.tsxA app/sitemap.tsA components/Footer.tsxA components/Navbar.tsxA components/ThemeProvider.tsxA components/ThemeToggle.tsxA components/__tests__/ThemeProvider.test.tsxA components/__tests__/ThemeToggle.test.tsxA contexts/ThemeContext.tsxA design_philosophy.mdA jest.config.jsA jest.setup.jsA next.config.jsA package-lock.jsonA package.jsonA postcss.config.jsA product_strategy.mdA public/favicon.svgA public/robots.txtA scripts/ralph/prd.jsonA scripts/ralph/progress.txtA tailwind.config.jsA tasks/prd-new-feature-for-angels-flowers.mdA test-utils/index.tsxA test.txtA tsconfig.json
Diff
commit f729216200d3caf261b1b65111a5466dd059a8da
Author: Steve <steve@designerwallcoverings.com>
Date: Wed May 6 10:20:07 2026 -0700
initial snapshot — gitify all builds (CLAUDE.md rule 2026-05-06)
---
.env.local.example | 11 +
.eslintrc.json | 3 +
.gitignore | 35 +
CHECKLIST.md | 180 +
CLAUDE.md | 170 +
DESIGN_SYSTEM.md | 1007 +++
IMPLEMENTATION_GUIDE.md | 1244 +++
PROJECT_OVERVIEW.md | 376 +
PROJECT_SUMMARY.md | 335 +
QUICKSTART.md | 192 +
README.md | 135 +
SETUP.md | 134 +
SITE_STRUCTURE.md | 409 +
USER_RESEARCH.md | 731 ++
WIREFRAMES.md | 912 +++
angels_flowers_visual.png | Bin 0 -> 56819 bytes
app/about/page.tsx | 299 +
app/contact/page.tsx | 392 +
app/flowers/page.tsx | 243 +
app/globals.css | 134 +
app/icon.svg | 4 +
app/layout.tsx | 68 +
app/page.tsx | 244 +
app/sitemap.ts | 32 +
components/Footer.tsx | 154 +
components/Navbar.tsx | 130 +
components/ThemeProvider.tsx | 122 +
components/ThemeToggle.tsx | 29 +
components/__tests__/ThemeProvider.test.tsx | 473 ++
components/__tests__/ThemeToggle.test.tsx | 116 +
contexts/ThemeContext.tsx | 38 +
design_philosophy.md | 15 +
jest.config.js | 20 +
jest.setup.js | 2 +
next.config.js | 9 +
package-lock.json | 10389 ++++++++++++++++++++++++++
package.json | 37 +
postcss.config.js | 6 +
product_strategy.md | 237 +
public/favicon.svg | 4 +
public/robots.txt | 6 +
scripts/ralph/prd.json | 170 +
scripts/ralph/progress.txt | 18 +
tailwind.config.js | 56 +
tasks/prd-new-feature-for-angels-flowers.md | 264 +
test-utils/index.tsx | 36 +
test.txt | 1 +
tsconfig.json | 27 +
48 files changed, 19649 insertions(+)
diff --git a/.env.local.example b/.env.local.example
new file mode 100644
index 0000000..3c6bb09
--- /dev/null
+++ b/.env.local.example
@@ -0,0 +1,11 @@
+# Environment Variables Example
+# Copy this file to .env.local and fill in your values
+
+# Google Maps API (for contact page map)
+NEXT_PUBLIC_GOOGLE_MAPS_API_KEY=your_api_key_here
+
+# Contact Form (if using a service like Formspree)
+NEXT_PUBLIC_FORM_ENDPOINT=your_form_endpoint_here
+
+# Analytics (optional)
+NEXT_PUBLIC_GA_TRACKING_ID=your_google_analytics_id_here
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..bffb357
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+ "extends": "next/core-web-vitals"
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8f322f0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,35 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env*.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
diff --git a/CHECKLIST.md b/CHECKLIST.md
new file mode 100644
index 0000000..0b06f43
--- /dev/null
+++ b/CHECKLIST.md
@@ -0,0 +1,180 @@
+# Angel's Flowers Website - Launch Checklist
+
+## Before Launch
+
+### Content Updates
+- [ ] Update phone number everywhere: `(323) 123-4567` → Your real number
+ - [ ] `/root/WebsitesMisc/angelsflowers/components/Navbar.tsx`
+ - [ ] `/root/WebsitesMisc/angelsflowers/components/Footer.tsx`
+ - [ ] `/root/WebsitesMisc/angelsflowers/app/page.tsx`
+ - [ ] `/root/WebsitesMisc/angelsflowers/app/flowers/page.tsx`
+ - [ ] `/root/WebsitesMisc/angelsflowers/app/contact/page.tsx`
+
+- [ ] Update email address: `info@angelsflowers.com` → Your real email
+ - [ ] `/root/WebsitesMisc/angelsflowers/components/Footer.tsx`
+ - [ ] `/root/WebsitesMisc/angelsflowers/app/contact/page.tsx`
+
+- [ ] Update business address
+ - [ ] `/root/WebsitesMisc/angelsflowers/components/Footer.tsx`
+ - [ ] `/root/WebsitesMisc/angelsflowers/app/contact/page.tsx`
+
+- [ ] Update business hours if different
+ - [ ] `/root/WebsitesMisc/angelsflowers/components/Footer.tsx`
+ - [ ] `/root/WebsitesMisc/angelsflowers/app/contact/page.tsx`
+
+- [ ] Review and customize flower product descriptions
+ - [ ] `/root/WebsitesMisc/angelsflowers/app/flowers/page.tsx`
+
+- [ ] Review and customize family story
+ - [ ] `/root/WebsitesMisc/angelsflowers/app/about/page.tsx`
+
+### Images
+- [ ] Create images directory: `mkdir -p /root/WebsitesMisc/angelsflowers/public/images`
+- [ ] Add hero image (2000x1200px)
+- [ ] Add 14+ flower product photos (800x800px each)
+- [ ] Add family/team photos (600x800px)
+- [ ] Add about page photos
+- [ ] Optimize all images for web (use WebP format, under 500KB each)
+- [ ] Update all image URLs in code
+- [ ] Add favicon.ico to `/root/WebsitesMisc/angelsflowers/public/`
+- [ ] Add apple-touch-icon.png (180x180px)
+
+### SEO
+- [ ] Update domain in `/root/WebsitesMisc/angelsflowers/app/sitemap.ts`
+- [ ] Update robots.txt with actual domain
+- [ ] Add Google Analytics tracking ID (if using)
+- [ ] Add meta descriptions for each page
+- [ ] Verify all alt text on images
+
+### Integrations
+- [ ] Set up Google Maps API
+ - [ ] Get API key
+ - [ ] Add to `.env.local`
+ - [ ] Integrate map in `/root/WebsitesMisc/angelsflowers/app/contact/page.tsx`
+
+- [ ] Set up contact form backend
+ - [ ] Choose service (Formspree, EmailJS, custom API)
+ - [ ] Configure form submission
+ - [ ] Test form submission
+ - [ ] Set up email notifications
+
+- [ ] Set up social media accounts
+ - [ ] Facebook page
+ - [ ] Instagram account
+ - [ ] Update links in `/root/WebsitesMisc/angelsflowers/components/Footer.tsx`
+ - [ ] Update links in `/root/WebsitesMisc/angelsflowers/app/contact/page.tsx`
+
+### Testing
+- [ ] Test on desktop browsers (Chrome, Firefox, Safari, Edge)
+- [ ] Test on mobile devices (iOS Safari, Chrome Mobile)
+- [ ] Test on tablet
+- [ ] Test all navigation links
+- [ ] Test contact form submission
+- [ ] Test phone number links (click-to-call)
+- [ ] Test email links (click-to-email)
+- [ ] Test social media links
+- [ ] Verify responsive design at all breakpoints
+- [ ] Test with screen reader (accessibility)
+- [ ] Test keyboard navigation
+- [ ] Check page load times (should be under 3 seconds)
+
+### Performance
+- [ ] Run Lighthouse audit (aim for 90+ scores)
+- [ ] Optimize images if needed
+- [ ] Test on slow connection
+- [ ] Verify lazy loading works
+- [ ] Check Core Web Vitals
+
+### Legal & Compliance
+- [ ] Add privacy policy (if collecting data)
+- [ ] Add terms of service (if needed)
+- [ ] Verify accessibility compliance (WCAG 2.1 AA)
+- [ ] Add cookie notice (if using cookies/analytics)
+
+## Launch Day
+
+### Deployment
+- [ ] Run `npm run build` and verify no errors
+- [ ] Choose hosting platform (Vercel recommended)
+- [ ] Deploy to production
+- [ ] Set up custom domain
+- [ ] Configure SSL certificate (automatic on Vercel/Netlify)
+- [ ] Test production site thoroughly
+
+### Post-Launch
+- [ ] Submit sitemap to Google Search Console
+- [ ] Submit to Bing Webmaster Tools
+- [ ] Set up Google My Business
+- [ ] Create 301 redirects (if migrating from old site)
+- [ ] Monitor error logs
+- [ ] Check analytics tracking
+
+## Ongoing Maintenance
+
+### Weekly
+- [ ] Check contact form submissions
+- [ ] Review analytics data
+- [ ] Check for broken links
+- [ ] Review error logs
+
+### Monthly
+- [ ] Update flower inventory/prices if needed
+- [ ] Update seasonal offerings
+- [ ] Review and respond to customer feedback
+- [ ] Check and update business hours (holidays)
+- [ ] Review site performance metrics
+
+### Quarterly
+- [ ] Update dependencies (`npm update`)
+- [ ] Review and update content
+- [ ] Add new product photos
+- [ ] Check for outdated information
+- [ ] Run security audit
+
+### Annually
+- [ ] Renew domain registration
+- [ ] Review and update SEO strategy
+- [ ] Analyze site metrics and plan improvements
+- [ ] Update copyright year in footer
+- [ ] Professional photography session
+
+## Quick Reference
+
+### File Locations
+All files located in: `/root/WebsitesMisc/angelsflowers/`
+
+### Key Files to Customize
+1. `/root/WebsitesMisc/angelsflowers/components/Navbar.tsx` - Phone, logo
+2. `/root/WebsitesMisc/angelsflowers/components/Footer.tsx` - Contact info, hours, social
+3. `/root/WebsitesMisc/angelsflowers/app/page.tsx` - Homepage content
+4. `/root/WebsitesMisc/angelsflowers/app/flowers/page.tsx` - Product catalog
+5. `/root/WebsitesMisc/angelsflowers/app/about/page.tsx` - Family story
+6. `/root/WebsitesMisc/angelsflowers/app/contact/page.tsx` - Contact information
+
+### Commands
+```bash
+# Install dependencies
+npm install
+
+# Run development server
+npm run dev
+
+# Build for production
+npm run build
+
+# Start production server
+npm start
+
+# Deploy to Vercel
+vercel
+```
+
+## Support Resources
+- Next.js Docs: https://nextjs.org/docs
+- Tailwind Docs: https://tailwindcss.com/docs
+- React Icons: https://react-icons.github.io/react-icons/
+
+---
+
+**Status**: Ready for customization and launch
+**Last Updated**: 2025-11-10
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..f0fce76
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,170 @@
+# Claude AI Assistant - Angels Flowers Configuration
+
+## Project Overview
+
+- **Name**: Angel's Flowers
+- **Description**: Premium Ecuadorian Flowers in East Los Angeles
+- **Framework**: Next.js 14.0.4 + React 18.2.0
+- **Styling**: Tailwind CSS 3.4.0
+- **Language**: TypeScript 5.3.3
+- **Path**: /root/Projects/angels-flowers
+
+---
+
+## AI Development Guidelines
+
+### Code Conventions
+
+1. **TypeScript**: Always use strict TypeScript. No `any` types unless absolutely necessary.
+2. **Components**: Use functional components with React hooks.
+3. **Naming**:
+ - Components: PascalCase (e.g., `FlowerCard.tsx`)
+ - Utilities: camelCase (e.g., `formatPrice.ts`)
+ - Constants: UPPER_SNAKE_CASE
+4. **Imports**: Use absolute imports with `@/` alias.
+5. **Styling**: Use Tailwind CSS utility classes. Avoid inline styles.
+
+### File Structure
+
+```
+angels-flowers/
+├── app/ # Next.js App Router pages
+│ ├── layout.tsx # Root layout
+│ ├── page.tsx # Home page
+│ ├── globals.css # Global styles
+│ ├── about/ # About page
+│ ├── contact/ # Contact page
+│ └── flowers/ # Flowers catalog
+├── components/ # Reusable React components
+├── public/ # Static assets
+└── scripts/ # Build and automation scripts
+```
+
+---
+
+## Testing Automation
+
+### Running Tests
+
+```bash
+# Type checking
+npm run build
+
+# Linting
+npm run lint
+```
+
+### Pre-Commit Checks
+
+Before committing, always run:
+
+```bash
+npm run build && npm run lint
+```
+
+### Acceptance Criteria Validation
+
+1. **TypeScript**: All files must pass `tsc --noEmit`
+2. **ESLint**: No errors allowed, warnings should be addressed
+3. **Build**: `next build` must complete successfully
+
+---
+
+## Deployment Process
+
+### Local Development
+
+```bash
+# Install dependencies
+npm install
+
+# Start development server
+npm run dev
+```
+
+### Production Build
+
+```bash
+# Create production build
+npm run build
+
+# Start production server
+npm run start
+```
+
+### Environment Variables
+
+Copy `.env.local.example` to `.env.local` and configure:
+
+```bash
+cp .env.local.example .env.local
+```
+
+### PM2 Production Deployment
+
+```bash
+# Start with PM2
+pm2 start npm --name "angels-flowers" -- start
+
+# Monitor
+pm2 monit angels-flowers
+
+# View logs
+pm2 logs angels-flowers
+```
+
+---
+
+## Code Review Standards
+
+### Pull Request Checklist
+
+- [ ] TypeScript compiles without errors (`npm run build`)
+- [ ] ESLint passes (`npm run lint`)
+- [ ] No console.log statements in production code
+- [ ] Components are properly typed
+- [ ] Responsive design tested on mobile and desktop
+- [ ] Accessibility: proper alt tags, ARIA labels where needed
+
+### Commit Message Format
+
+```
+feat(scope): description
+fix(scope): description
+docs(scope): description
+style(scope): description
+refactor(scope): description
+```
+
+Examples:
+- `feat(flowers): add flower detail page`
+- `fix(contact): resolve form validation issue`
+- `docs(readme): update installation instructions`
+
+### Code Quality Rules
+
+1. **No dead code**: Remove unused imports, variables, and functions
+2. **DRY principle**: Extract repeated logic into utilities or components
+3. **Single responsibility**: Each component/function should do one thing well
+4. **Error handling**: Always handle potential errors gracefully
+5. **Performance**: Use React.memo, useMemo, useCallback where appropriate
+
+---
+
+## Quick Reference
+
+### Common Commands
+
+| Command | Description |
+|---------|-------------|
+| `npm run dev` | Start development server |
+| `npm run build` | Create production build |
+| `npm run start` | Start production server |
+| `npm run lint` | Run ESLint |
+
+### Key Files
+
+- `app/layout.tsx` - Root layout with metadata
+- `app/page.tsx` - Home page component
+- `tailwind.config.js` - Tailwind CSS configuration
+- `tsconfig.json` - TypeScript configuration
diff --git a/DESIGN_SYSTEM.md b/DESIGN_SYSTEM.md
new file mode 100644
index 0000000..0127b24
--- /dev/null
+++ b/DESIGN_SYSTEM.md
@@ -0,0 +1,1007 @@
+# Angel's Flowers - UI/UX Design System
+## Family-Run Ecuadorian Flower Shop | East Los Angeles
+
+---
+
+## 1. VISUAL DESIGN DIRECTION
+
+### Color Palette
+
+#### Primary Colors
+```css
+--primary-rose: #D84B6C; /* Ecuadorian Rose Pink - Primary CTA */
+--primary-rose-dark: #B83A56; /* Hover states */
+--primary-rose-light: #F0869D; /* Accents, backgrounds */
+--primary-rose-pale: #FDF2F4; /* Light backgrounds */
+```
+
+#### Secondary Colors (Ecuadorian Flora Inspired)
+```css
+--tropical-green: #2D5F3F; /* Foliage, trust, growth */
+--tropical-green-light: #4A8B5F;/* Secondary elements */
+--sunflower-gold: #F4C430; /* Warmth, celebration */
+--orchid-purple: #8B4789; /* Elegance, premium flowers */
+--sky-blue: #87CEEB; /* Fresh, calming */
+```
+
+#### Neutral Palette
+```css
+--warm-white: #FDFBF7; /* Background */
+--cream: #F5F1E8; /* Section dividers */
+--warm-gray: #6B6B6B; /* Body text */
+--charcoal: #2C2C2C; /* Headlines */
+--soft-shadow: rgba(45, 95, 63, 0.08); /* Card shadows */
+```
+
+#### Semantic Colors
+```css
+--success: #4A8B5F; /* Order confirmation */
+--error: #D84B6C; /* Validation errors */
+--warning: #F4C430; /* Low stock alerts */
+--info: #87CEEB; /* Informational messages */
+```
+
+**Design Rationale**: The palette draws from Ecuador's vibrant flora - roses, tropical foliage, and orchids. The warm neutrals create approachability while maintaining sophistication comparable to 800flowers.
+
+---
+
+### Typography
+
+#### Font Families
+```css
+/* Headings - Elegant yet readable */
+--font-heading: 'Cormorant Garamond', 'Georgia', serif;
+
+/* Body - Modern, clean, accessible */
+--font-body: 'Inter', 'Helvetica Neue', sans-serif;
+
+/* Accent - For special callouts */
+--font-accent: 'Playfair Display', serif;
+```
+
+#### Type Scale
+```css
+/* Desktop */
+--text-5xl: 3.5rem; /* 56px - Hero headlines */
+--text-4xl: 2.5rem; /* 40px - Page titles */
+--text-3xl: 2rem; /* 32px - Section headings */
+--text-2xl: 1.5rem; /* 24px - Card titles */
+--text-xl: 1.25rem; /* 20px - Subheadings */
+--text-lg: 1.125rem; /* 18px - Large body */
+--text-base: 1rem; /* 16px - Body text */
+--text-sm: 0.875rem; /* 14px - Captions, labels */
+--text-xs: 0.75rem; /* 12px - Small print */
+
+/* Line Heights */
+--leading-tight: 1.2;
+--leading-normal: 1.5;
+--leading-relaxed: 1.75;
+```
+
+**Design Rationale**: Serif headings provide elegance and tradition (family business), while sans-serif body text ensures readability across devices. Inter has excellent accessibility characteristics.
+
+---
+
+### Overall Aesthetic
+
+**Design Pillars**:
+1. **Elegant Heritage** - Respect for craftsmanship and Ecuadorian tradition
+2. **Warm Family Connection** - Personal, trustworthy, community-oriented
+3. **Vibrant Freshness** - Celebrating the beauty of living flowers
+4. **Modern Professionalism** - Competitive with major online florists
+5. **Accessible Inclusivity** - Welcoming to all East LA community members
+
+**Visual Language**:
+- Soft, organic shapes (rounded corners 8-16px)
+- Generous whitespace (breathing room like flower arrangements)
+- High-quality photography with natural lighting
+- Subtle animations (gentle fades, smooth transitions)
+- Card-based layouts with gentle shadows
+- Floral accent illustrations (hand-drawn, watercolor style)
+
+---
+
+## 2. WEBSITE STRUCTURE & NAVIGATION
+
+### Main Navigation Menu
+
+#### Desktop Navigation (Sticky Header)
+```
+[Angel's Flowers Logo] | Shop Flowers | Occasions | About Us | Gallery | Contact | [Search Icon] [Cart (0)]
+```
+
+#### Menu Structure
+1. **Shop Flowers** (Mega Menu)
+ - By Type: Roses | Orchids | Lilies | Mixed Bouquets | Tropical Flowers
+ - By Color: Red | Pink | White | Yellow | Purple | Mixed
+ - By Price: Under $50 | $50-$100 | $100-$150 | Premium $150+
+ - Featured: Best Sellers | New Arrivals | Ecuadorian Specialty
+
+2. **Occasions** (Dropdown)
+ - Birthdays
+ - Anniversaries
+ - Weddings & Quinceañeras
+ - Sympathy & Funerals
+ - Just Because
+ - Corporate Events
+
+3. **About Us**
+ - Our Story
+ - Our Family
+ - Ecuador Connection
+ - Community Involvement
+ - Testimonials
+
+4. **Gallery**
+ - Recent Work
+ - Weddings
+ - Events
+ - Daily Arrangements
+
+5. **Contact**
+ - Visit Our Shop
+ - Hours & Location
+ - Request Custom Order
+ - FAQ
+
+#### Mobile Navigation (Hamburger Menu)
+- Same structure, collapsible accordion style
+- Prominent "Call Now" button at top
+- Cart icon always visible in header
+
+---
+
+### Homepage Layout Sections
+
+```
+┌─────────────────────────────────────────┐
+│ STICKY HEADER - Logo, Nav, Cart │
+├─────────────────────────────────────────┤
+│ │
+│ 1. HERO SECTION │
+│ Full-width background image │
+│ Headline + Subheadline + CTA │
+│ "Ecuadorian Flowers, East LA Roots" │
+│ │
+├─────────────────────────────────────────┤
+│ 2. VALUE PROPOSITIONS │
+│ [Icon] Fresh Daily [Icon] Family-Owned │
+│ [Icon] Custom Designs [Icon] Same-Day │
+├─────────────────────────────────────────┤
+│ 3. SHOP BY OCCASION │
+│ Card Grid: Birthdays, Weddings, etc. │
+├─────────────────────────────────────────┤
+│ 4. FEATURED FLOWERS │
+│ Product carousel - Best sellers │
+│ Price, quick view, add to cart │
+├─────────────────────────────────────────┤
+│ 5. FAMILY STORY SECTION │
+│ Split: Family Photo | Story Text │
+│ "From Ecuador to East LA" │
+│ CTA: "Read Our Story" │
+├─────────────────────────────────────────┤
+│ 6. ECUADORIAN DIFFERENCE │
+│ Why Ecuadorian flowers are special │
+│ Image gallery with educational content │
+├─────────────────────────────────────────┤
+│ 7. INSTAGRAM FEED / RECENT WORK │
+│ "See Our Latest Creations" │
+│ 6-8 image grid with social links │
+├─────────────────────────────────────────┤
+│ 8. CUSTOMER TESTIMONIALS │
+│ Carousel of reviews with photos │
+│ Star ratings, names, occasions │
+├─────────────────────────────────────────┤
+│ 9. LOCATION & CONTACT │
+│ Google Map embed │
+│ Hours, Phone, Address, Directions │
+├─────────────────────────────────────────┤
+│ FOOTER │
+│ Links, Social, Newsletter, Legal │
+└─────────────────────────────────────────┘
+```
+
+---
+
+### User Flow: Browsing & Ordering Flowers
+
+#### Primary User Journey
+```
+1. LANDING
+ └─> Homepage Hero
+ ├─> Browse by Occasion (Birthday clicked)
+ └─> Featured Products visible
+
+2. DISCOVERY
+ └─> Birthday Flowers Category Page
+ ├─> Filter by Price/Color
+ ├─> Sort by Popularity/Price
+ └─> View Product Card
+
+3. EVALUATION
+ └─> Product Detail Page
+ ├─> Multiple photos (zoom)
+ ├─> Description, size options
+ ├─> Reviews & ratings
+ ├─> "You may also like"
+ └─> Add to Cart CTA
+
+4. CUSTOMIZATION (Optional)
+ └─> Add to Cart Modal
+ ├─> Select size/upgrade
+ ├─> Add greeting card message
+ ├─> Select delivery date
+ └─> Confirm addition
+
+5. CART REVIEW
+ └─> Shopping Cart
+ ├─> Edit quantities/remove
+ ├─> Apply promo code
+ ├─> View delivery fee
+ └─> Proceed to Checkout
+
+6. CHECKOUT
+ └─> Multi-step form
+ ├─> Step 1: Delivery Info
+ ├─> Step 2: Delivery Date/Time
+ ├─> Step 3: Payment
+ └─> Order Review
+
+7. CONFIRMATION
+ └─> Thank You Page
+ ├─> Order number
+ ├─> Receipt email sent
+ ├─> Expected delivery
+ └─> Share on social CTA
+
+8. POST-PURCHASE
+ └─> Follow-up
+ ├─> Order tracking page
+ ├─> Delivery notification
+ └─> Review request email
+```
+
+#### Alternative User Flows
+- **Quick Shop**: Homepage → Featured Product → Quick View Modal → Add to Cart
+- **Custom Order**: Homepage → Contact → Custom Request Form → Phone Consultation
+- **Phone Order**: Any page → Sticky "Call Now" button → Phone order
+- **Walk-in Coordination**: Location page → Directions → Visit shop
+
+---
+
+## 3. KEY UI COMPONENTS
+
+### Hero Section Design Concept
+
+**Layout**: Full-width, full-viewport height (min-height: 600px)
+
+**Structure**:
+```
+┌────────────────────────────────────────────────────┐
+│ │
+│ [Background: Lush flower arrangement photo] │
+│ │
+│ ┌──────────────────────────────┐ │
+│ │ Angel's Flowers │ │
+│ │ Ecuadorian Blooms, │ │
+│ │ East LA Roots │ │
+│ │ │ │
+│ │ Fresh arrangements crafted │ │
+│ │ with love for over 20 years│ │
+│ │ │ │
+│ │ [Shop Flowers] [Our Story] │ │
+│ └──────────────────────────────┘ │
+│ │
+│ ↓ Scroll indicator │
+└────────────────────────────────────────────────────┘
+```
+
+**Design Specifications**:
+- Background image: 80% opacity overlay with gradient (bottom to top, dark to transparent)
+- Text container: Centered, max-width 700px, padding 2rem
+- Headline: 56px Cormorant Garamond, white, drop shadow for legibility
+- Subheadline: 20px Inter, warm-white, line-height 1.75
+- CTAs: Primary button (rose) + Secondary outline button
+- Subtle parallax scroll effect on background image
+- Mobile: Stack text, reduce font sizes, 70% viewport height
+
+**Photography Direction**:
+- Hero image rotates weekly
+- Should show complete arrangements (not just flowers)
+- Warm, natural lighting
+- Shallow depth of field
+- Include subtle brand elements (ribbon, card)
+
+---
+
+### Flower Product Cards
+
+**Card Design**:
+```
+┌─────────────────────────┐
+│ │
+│ [Product Photo] │
+│ │
+│ ♡ Quick View │ ← Hover overlay
+├─────────────────────────┤
+│ Rose Romance Bouquet │ ← Title
+│ ★★★★★ (24 reviews) │ ← Rating
+│ │
+│ From $65.00 │ ← Price
+│ │
+│ [Add to Cart Button] │
+└─────────────────────────┘
+```
+
+**Specifications**:
+- Card dimensions: 280px x 420px (desktop), responsive
+- Border-radius: 12px
+- Shadow: 0 2px 8px rgba(45, 95, 63, 0.08)
+- Hover: Lift effect (translateY -4px, stronger shadow)
+- Image aspect ratio: 4:5 (portrait)
+- Image hover: Slight zoom (1.05x scale)
+- Quick View: Modal overlay with larger images + details
+- Favorite icon: Save to wishlist functionality
+- Badge system: "Best Seller", "New", "Sale" corner ribbons
+
+**Card States**:
+- Default: Subtle shadow, clear imagery
+- Hover: Elevated, overlay with quick view
+- Loading: Skeleton placeholder with shimmer
+- Out of Stock: Grayscale filter, "Notify Me" button
+
+**Product Grid Layout**:
+- Desktop: 4 columns (with sidebar filters) or 3 columns (full-width)
+- Tablet: 3 columns or 2 columns
+- Mobile: 2 columns (portrait) or 1 column (small devices)
+- Gap: 24px between cards
+
+---
+
+### Family Story Section
+
+**Layout**: Split 50/50 (Image | Content)
+
+```
+┌──────────────────────────────────────────────────────┐
+│ │
+│ ┌─────────────────┐ ┌─────────────────────────┐ │
+│ │ │ │ Our Family Story │ │
+│ │ [Family Photo] │ │ │ │
+│ │ │ │ For over 20 years, │ │
+│ │ Warm, candid │ │ we've brought the │ │
+│ │ shot in shop │ │ beauty of Ecuadorian │ │
+│ │ with flowers │ │ flowers to East LA... │ │
+│ │ │ │ │ │
+│ │ │ │ [Read Full Story →] │ │
+│ └─────────────────┘ └─────────────────────────┘ │
+│ │
+└──────────────────────────────────────────────────────┘
+```
+
+**Design Specifications**:
+- Section background: Warm cream (#F5F1E8)
+- Image: Rounded corners 16px, natural framing
+- Content padding: 4rem (generous whitespace)
+- Heading: 40px Cormorant Garamond, charcoal
+- Body text: 18px Inter, warm-gray, leading-relaxed
+- Decorative element: Subtle watercolor flower illustration behind text
+- CTA: Text link with arrow, primary-rose color
+- Mobile: Stack image on top, full-width
+
+**Content Guidelines**:
+- 150-200 words for homepage version
+- Focus on emotional connection and heritage
+- Mention Ecuador origins and LA community ties
+- Include specific family member names
+- Link to full "About Us" page for complete story
+
+---
+
+### Gallery/Catalog Layout
+
+**Gallery Grid Design**:
+```
+┌─────────────────────────────────────────────────┐
+│ Our Recent Work │
+│ [Filter: All | Weddings | Birthdays | Events] │
+├─────────────────────────────────────────────────┤
+│ │
+│ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │
+│ │ 1 │ │ 2 │ │ 3 │ │ 4 │ ← Masonry │
+│ │ │ └────┘ │ │ │ │ style grid │
+│ └────┘ ┌────┐ │ │ └────┘ │
+│ ┌────┐ │ 5 │ └────┘ ┌────┐ │
+│ │ 6 │ │ │ ┌────┐ │ 7 │ │
+│ │ │ └────┘ │ 8 │ │ │ │
+│ │
+│ [Load More] │
+└─────────────────────────────────────────────────┘
+```
+
+**Specifications**:
+- Layout: Masonry grid (Pinterest-style) using CSS Grid or library
+- Column count: 4 (desktop), 3 (tablet), 2 (mobile)
+- Gap: 16px
+- Image aspect ratios: Variable (natural dimensions)
+- Hover overlay: Dark gradient with arrangement name + occasion
+- Click: Opens lightbox with larger image + details
+- Lazy loading: Images load as user scrolls
+- Filter animation: Smooth fade in/out (300ms)
+
+**Lightbox Features**:
+- Full-screen image viewing
+- Previous/Next navigation
+- Image caption: Occasion, date, description
+- "Request Similar" CTA button
+- Share to social media icons
+- Keyboard navigation (arrow keys, ESC)
+- Touch gestures (swipe) for mobile
+
+---
+
+## 4. ACCESSIBILITY & RESPONSIVENESS
+
+### Accessibility Requirements (WCAG 2.1 AA Compliance)
+
+#### Color & Contrast
+- All text meets 4.5:1 contrast ratio minimum
+- Primary CTA buttons: 7:1 contrast ratio
+- Focus indicators: 3:1 contrast against background
+- No reliance on color alone for information
+- Test with color blindness simulators
+
+#### Keyboard Navigation
+- All interactive elements keyboard accessible
+- Logical tab order throughout site
+- Visible focus indicators (2px solid outline, primary-rose)
+- Skip to main content link
+- Modal dialogs trap focus appropriately
+- Escape key closes modals/overlays
+
+#### Screen Reader Support
+- Semantic HTML5 elements (`<nav>`, `<main>`, `<article>`)
+- ARIA labels for icon buttons
+- ARIA live regions for dynamic content (cart updates, form errors)
+- Alt text for all images (descriptive, not keyword-stuffed)
+- Product images: "Red rose bouquet with 24 long-stem roses in glass vase"
+- Decorative images: `alt=""` (empty alt attribute)
+- Form labels properly associated with inputs
+- Error messages clearly announced
+
+#### Interactive Elements
+- Minimum touch target: 44x44px (Apple/Google guidelines)
+- Button text clearly describes action
+- Links have descriptive text (avoid "click here")
+- Form validation: Real-time, clear error messages
+- Required fields marked with text + asterisk
+- Loading states announced to screen readers
+
+#### Content Structure
+- Proper heading hierarchy (single H1, sequential H2-H6)
+- Landmarks for major page sections
+- Lists use proper `<ul>`, `<ol>`, `<li>` markup
+- Tables (if used) have proper headers and captions
+- Consistent navigation across all pages
+
+#### Media Accessibility
+- All videos have captions
+- Transcripts provided for audio content
+- Avoid auto-playing media (or provide pause control)
+- Animations respect `prefers-reduced-motion`
+
+---
+
+### Responsive Design Breakpoints
+
+```css
+/* Mobile-first approach */
+
+/* Extra small devices (portrait phones) */
+@media (min-width: 320px) {
+ /* Base styles - 1 column layouts */
+ --container-padding: 1rem;
+ --grid-columns: 1;
+}
+
+/* Small devices (landscape phones) */
+@media (min-width: 576px) {
+ /* 2 column product grids possible */
+ --container-padding: 1.5rem;
+ --grid-columns: 2;
+}
+
+/* Medium devices (tablets) */
+@media (min-width: 768px) {
+ /* 3 column layouts, side-by-side content */
+ --container-padding: 2rem;
+ --grid-columns: 3;
+ /* Show expanded navigation */
+}
+
+/* Large devices (desktops) */
+@media (min-width: 1024px) {
+ /* Full desktop experience */
+ --container-padding: 3rem;
+ --grid-columns: 4;
+ /* Mega menus active */
+}
+
+/* Extra large devices (large desktops) */
+@media (min-width: 1440px) {
+ /* Max container width: 1400px */
+ /* Larger hero images */
+ --container-max-width: 1400px;
+}
+```
+
+#### Mobile-Specific Optimizations
+- Hamburger menu with smooth slide-in animation
+- Bottom-fixed "Call Now" button (sticky)
+- Simplified product filters (drawer overlay)
+- Touch-friendly carousels with swipe gestures
+- Single-column checkout flow
+- Large, thumb-friendly form inputs
+- Click-to-call phone numbers (`tel:` links)
+- Click-to-navigate addresses (`maps:` links)
+
+#### Tablet Considerations
+- Hybrid navigation (burger menu or abbreviated nav bar)
+- 2-3 column product grids
+- Sidebar filters can be toggled
+- Side-by-side content sections
+- Larger touch targets maintained
+
+#### Performance Optimizations
+- Images: Modern formats (WebP, AVIF) with fallbacks
+- Responsive images: `srcset` with multiple sizes
+- Lazy loading for below-fold images
+- Critical CSS inlined in `<head>`
+- Deferred JavaScript loading
+- Font subsetting for faster loads
+- CDN delivery for static assets
+- Target: Lighthouse score 90+ on all metrics
+
+---
+
+## 5. DESIGN SYSTEM RECOMMENDATIONS
+
+### Technology Stack
+
+#### Framework & Component Library
+**Recommended: Next.js + Tailwind CSS + shadcn/ui**
+
+**Rationale**:
+1. **Next.js** (React framework)
+ - Server-side rendering for SEO
+ - Image optimization built-in
+ - File-based routing
+ - API routes for backend functionality
+ - Excellent performance out of the box
+
+2. **Tailwind CSS** (Utility-first CSS)
+ - Rapid development
+ - Consistent design tokens
+ - Built-in responsive utilities
+ - Easy customization for brand colors
+ - Smaller CSS bundle (purges unused styles)
+
+3. **shadcn/ui** (Component library)
+ - Accessible by default (Radix UI primitives)
+ - Customizable (not a dependency, copy/paste)
+ - Consistent with modern design practices
+ - TypeScript support
+ - Excellent documentation
+
+#### Alternative Stack (Budget-Friendly)
+**Astro + Tailwind + Alpine.js**
+- Static site generation (faster, cheaper hosting)
+- Partial hydration (only interactive parts use JS)
+- Great for content-heavy sites
+- Can integrate payment forms via embeds
+
+---
+
+### Component Library Structure
+
+```
+/components
+ /ui (shadcn/ui base components)
+ - button.tsx
+ - card.tsx
+ - input.tsx
+ - dialog.tsx
+ - dropdown-menu.tsx
+ - carousel.tsx
+ - badge.tsx
+ - toast.tsx
+
+ /layout
+ - header.tsx
+ - footer.tsx
+ - navigation.tsx
+ - mobile-menu.tsx
+ - container.tsx
+
+ /product
+ - product-card.tsx
+ - product-grid.tsx
+ - product-detail.tsx
+ - product-quick-view.tsx
+ - product-filter.tsx
+ - add-to-cart-button.tsx
+
+ /marketing
+ - hero-section.tsx
+ - value-props.tsx
+ - family-story.tsx
+ - testimonial-carousel.tsx
+ - instagram-feed.tsx
+ - occasion-cards.tsx
+
+ /cart
+ - cart-drawer.tsx
+ - cart-item.tsx
+ - cart-summary.tsx
+
+ /checkout
+ - checkout-form.tsx
+ - delivery-options.tsx
+ - payment-form.tsx
+
+ /shared
+ - logo.tsx
+ - search-bar.tsx
+ - breadcrumbs.tsx
+ - loading-skeleton.tsx
+ - error-boundary.tsx
+```
+
+---
+
+### Design Token Configuration
+
+**Tailwind Config** (`tailwind.config.js`):
+
+```javascript
+module.exports = {
+ theme: {
+ extend: {
+ colors: {
+ // Brand colors
+ primary: {
+ DEFAULT: '#D84B6C',
+ dark: '#B83A56',
+ light: '#F0869D',
+ pale: '#FDF2F4',
+ },
+ secondary: {
+ green: '#2D5F3F',
+ 'green-light': '#4A8B5F',
+ gold: '#F4C430',
+ purple: '#8B4789',
+ blue: '#87CEEB',
+ },
+ neutral: {
+ 'warm-white': '#FDFBF7',
+ cream: '#F5F1E8',
+ 'warm-gray': '#6B6B6B',
+ charcoal: '#2C2C2C',
+ },
+ },
+ fontFamily: {
+ heading: ['Cormorant Garamond', 'Georgia', 'serif'],
+ body: ['Inter', 'Helvetica Neue', 'sans-serif'],
+ accent: ['Playfair Display', 'serif'],
+ },
+ fontSize: {
+ '5xl': '3.5rem',
+ '4xl': '2.5rem',
+ '3xl': '2rem',
+ '2xl': '1.5rem',
+ 'xl': '1.25rem',
+ 'lg': '1.125rem',
+ 'base': '1rem',
+ 'sm': '0.875rem',
+ 'xs': '0.75rem',
+ },
+ borderRadius: {
+ 'soft': '8px',
+ 'medium': '12px',
+ 'large': '16px',
+ },
+ boxShadow: {
+ 'soft': '0 2px 8px rgba(45, 95, 63, 0.08)',
+ 'medium': '0 4px 16px rgba(45, 95, 63, 0.12)',
+ 'large': '0 8px 32px rgba(45, 95, 63, 0.16)',
+ },
+ animation: {
+ 'fade-in': 'fadeIn 0.3s ease-in-out',
+ 'slide-up': 'slideUp 0.4s ease-out',
+ 'slide-in': 'slideIn 0.3s ease-out',
+ },
+ keyframes: {
+ fadeIn: {
+ '0%': { opacity: '0' },
+ '100%': { opacity: '1' },
+ },
+ slideUp: {
+ '0%': { transform: 'translateY(20px)', opacity: '0' },
+ '100%': { transform: 'translateY(0)', opacity: '1' },
+ },
+ slideIn: {
+ '0%': { transform: 'translateX(-100%)' },
+ '100%': { transform: 'translateX(0)' },
+ },
+ },
+ },
+ },
+ plugins: [
+ require('@tailwindcss/forms'),
+ require('@tailwindcss/typography'),
+ require('@tailwindcss/aspect-ratio'),
+ ],
+};
+```
+
+---
+
+### Iconography
+
+**Recommended: Lucide React** (formerly Feather Icons)
+- Clean, consistent style
+- Tree-shakeable (only bundle used icons)
+- React components
+- Accessible by default
+
+**Icon Usage**:
+- Navigation: Menu, Search, ShoppingCart, User, Phone
+- Features: Truck (delivery), Heart (favorites), Star (ratings)
+- Social: Facebook, Instagram, Twitter
+- Actions: Plus, Minus, X (close), ChevronDown, ChevronRight
+- Info: Info, AlertCircle, CheckCircle
+
+**Custom Icons**:
+- Angel's Flowers logo (SVG)
+- Flower type icons (rose, orchid, lily) - custom illustrated
+
+---
+
+### Animation Guidelines
+
+**Principles**:
+- Subtle and purposeful
+- Never block user interaction
+- Respect `prefers-reduced-motion`
+- Smooth transitions (ease-in-out curves)
+
+**Common Animations**:
+```css
+/* Button hover */
+transition: all 0.2s ease-in-out;
+
+/* Card hover */
+transition: transform 0.3s ease, box-shadow 0.3s ease;
+
+/* Modal entrance */
+@keyframes modal {
+ from {
+ opacity: 0;
+ transform: scale(0.95);
+ }
+ to {
+ opacity: 1;
+ transform: scale(1);
+ }
+}
+
+/* Page transitions */
+transition: opacity 0.3s ease-in-out;
+
+/* Loading skeleton shimmer */
+@keyframes shimmer {
+ 0% { background-position: -1000px 0; }
+ 100% { background-position: 1000px 0; }
+}
+```
+
+---
+
+### Photography & Imagery Guidelines
+
+**Product Photography**:
+- Resolution: Minimum 1200x1500px
+- Format: WebP with JPG fallback
+- Aspect ratio: 4:5 (portrait)
+- Background: Clean white or soft neutral
+- Lighting: Bright, natural, diffused
+- Angles: Straight-on and 45-degree options
+- Include size reference (person holding, ruler)
+
+**Lifestyle Photography**:
+- Show flowers in context (events, homes)
+- Feature diverse people and settings
+- Natural, candid moments
+- Warm color grading
+- East LA community representation
+
+**Family & Team Photos**:
+- Candid, authentic moments in shop
+- High-quality but not overly formal
+- Show interaction with flowers/customers
+- Inclusive representation of family members
+
+**Image Optimization**:
+- Compress without quality loss (80-85% quality)
+- Use modern formats (WebP, AVIF)
+- Provide multiple sizes via `srcset`
+- Lazy load below-fold images
+- Use blur-up placeholders while loading
+
+---
+
+## IMPLEMENTATION PRIORITIES
+
+### Phase 1: Foundation (Weeks 1-2)
+- [ ] Set up Next.js + Tailwind + shadcn/ui
+- [ ] Implement design tokens and global styles
+- [ ] Create base layout components (Header, Footer)
+- [ ] Build homepage hero section
+- [ ] Implement responsive navigation
+
+### Phase 2: Core Content (Weeks 3-4)
+- [ ] Product card component
+- [ ] Product grid with filtering
+- [ ] Product detail page
+- [ ] Family story section
+- [ ] About Us page
+- [ ] Gallery/portfolio page
+
+### Phase 3: E-commerce (Weeks 5-6)
+- [ ] Shopping cart functionality
+- [ ] Checkout flow (if applicable)
+- [ ] Payment integration (Stripe/Square)
+- [ ] Order confirmation
+- [ ] Custom order request form
+
+### Phase 4: Polish & Launch (Weeks 7-8)
+- [ ] Accessibility audit and fixes
+- [ ] Performance optimization
+- [ ] SEO optimization
+- [ ] Mobile testing on real devices
+- [ ] Content population
+- [ ] Soft launch and feedback
+- [ ] Official launch
+
+---
+
+## SUCCESS METRICS
+
+**User Experience Metrics**:
+- Time to first interaction < 2 seconds
+- Product page load time < 1.5 seconds
+- Mobile navigation discoverable within 5 seconds
+- Checkout completion rate > 70%
+- Average session duration > 3 minutes
+
+**Accessibility Metrics**:
+- WCAG 2.1 AA compliance: 100%
+- Lighthouse accessibility score: 95+
+- Keyboard navigation: All functions accessible
+- Screen reader testing: Zero critical issues
+
+**Performance Metrics**:
+- Lighthouse performance score: 90+
+- First Contentful Paint: < 1.5s
+- Largest Contentful Paint: < 2.5s
+- Cumulative Layout Shift: < 0.1
+- Mobile page speed: 80+
+
+**Business Metrics**:
+- Inquiry/order form submissions (track increase)
+- Phone call clicks from mobile
+- Time spent on "Our Story" page
+- Gallery engagement rate
+- Returning visitor rate
+
+---
+
+## DESIGN FILES & RESOURCES
+
+**Required Deliverables**:
+1. High-fidelity mockups (Figma)
+ - Homepage (desktop, tablet, mobile)
+ - Product listing page
+ - Product detail page
+ - About Us page
+ - Contact page
+
+2. Component library (Figma)
+ - All UI components documented
+ - Interaction states shown
+ - Spacing and typography specs
+
+3. Style guide documentation
+ - Color palette with hex codes
+ - Typography scale
+ - Icon library
+ - Animation specifications
+
+4. User flow diagrams
+ - Primary user journeys mapped
+ - Decision points identified
+ - Alternative paths documented
+
+5. Content guidelines
+ - Voice and tone guide
+ - Photography specifications
+ - Copy templates for product descriptions
+
+---
+
+## NOTES FOR DEVELOPERS
+
+**Code Quality Standards**:
+- TypeScript for type safety
+- ESLint + Prettier for consistent formatting
+- Component documentation with Storybook
+- Unit tests for critical functions
+- E2E tests for checkout flow
+
+**SEO Considerations**:
+- Semantic HTML throughout
+- Meta tags for all pages
+- Open Graph images for social sharing
+- Schema.org markup for products
+- XML sitemap
+- robots.txt configuration
+
+**Analytics Integration**:
+- Google Analytics 4
+- Facebook Pixel (if using FB ads)
+- Hotjar or similar for heatmaps
+- Custom event tracking for key actions
+
+---
+
+## COMPETITIVE BENCHMARK: 800flowers Comparison
+
+**What to Emulate**:
+- Clean, uncluttered product presentation
+- Clear hierarchy and navigation
+- Robust filtering and search
+- Professional product photography
+- Trust signals (reviews, guarantees)
+- Smooth checkout process
+
+**Where to Differentiate**:
+- Emphasize family story and personal touch
+- Highlight Ecuadorian flower quality/uniqueness
+- Stronger community connection (East LA pride)
+- More intimate, boutique feel vs. corporate
+- Potentially more flexible custom orders
+- Local delivery emphasis vs. national shipping
+
+**Competitive Advantages**:
+- Authentic family business story
+- Unique Ecuadorian flower expertise
+- Local East LA community roots
+- Personal customer service
+- Fresh flowers (not shipped long distances)
+- Custom arrangement flexibility
+
+---
+
+## CONCLUSION
+
+This design system prioritizes creating an emotional connection with visitors while maintaining the professional polish of industry leaders like 800flowers. The warm, family-oriented aesthetic paired with modern, accessible design patterns will position Angel's Flowers as both a trusted local institution and a competitive online florist.
+
+The Ecuadorian heritage should be celebrated throughout the design - in color choices, imagery, and storytelling - making it a unique selling proposition rather than just a backstory.
+
+Every design decision should ask: "Does this make the visitor feel welcome, does it showcase our flowers beautifully, and does it make ordering easy?"
+
+---
+
+**Document Version**: 1.0
+**Last Updated**: 2025-11-10
+**Status**: Ready for Design & Development
diff --git a/IMPLEMENTATION_GUIDE.md b/IMPLEMENTATION_GUIDE.md
new file mode 100644
index 0000000..b71bec9
--- /dev/null
+++ b/IMPLEMENTATION_GUIDE.md
@@ -0,0 +1,1244 @@
+# Angel's Flowers - Implementation Guide
+## From Design to Development: Practical Next Steps
+
+---
+
+## OVERVIEW
+
+This guide provides concrete steps to transform the design strategy into a functional website. It's organized by implementation phase with specific deliverables, timelines, and technical requirements.
+
+---
+
+## PROJECT TEAM STRUCTURE
+
+### Recommended Roles
+
+**Design Team:**
+- UI/UX Designer (Lead)
+- Visual Designer
+- Content Writer/Copywriter
+
+**Development Team:**
+- Frontend Developer (Lead)
+- Backend Developer (if custom checkout/CMS)
+- QA/Testing Specialist
+
+**Business Team:**
+- Project Manager
+- Family Member (stakeholder/content provider)
+- Photographer (product & family photos)
+
+**Optional/Consultants:**
+- SEO Specialist
+- Accessibility Auditor
+- Spanish Translator (for bilingual content)
+
+---
+
+## PHASE 1: FOUNDATION & DESIGN (WEEKS 1-2)
+
+### Week 1: Design System & Assets
+
+#### Deliverables
+- [ ] Figma design system established
+ - Color palette swatches
+ - Typography styles configured
+ - Component library started (buttons, cards, inputs)
+ - Grid system defined
+
+- [ ] Logo refinement/creation
+ - Primary logo
+ - Logo variations (icon only, horizontal, vertical)
+ - Logo usage guidelines
+ - Favicon created
+
+- [ ] Photography planning
+ - Shot list created
+ - Props and styling needs identified
+ - Photo session scheduled
+ - Temporary placeholder images selected
+
+#### Key Activities
+1. **Kickoff Meeting**
+ - Review design strategy documents
+ - Align on timeline and responsibilities
+ - Establish communication channels (Slack, weekly calls)
+ - Set up shared workspace (Figma, Google Drive)
+
+2. **Brand Assets**
+ - Finalize color palette with stakeholders
+ - Test font combinations and readability
+ - Create mood board with reference images
+ - Review and approve design direction
+
+3. **Content Gathering**
+ - Family story interviews (record/transcribe)
+ - Product information collection
+ - Pricing structure finalization
+ - Terms, policies, FAQ content drafted
+
+#### Technical Setup
+```bash
+# Initialize Next.js project
+npx create-next-app@latest angelsflowers --typescript --tailwind --app
+
+# Install shadcn/ui
+npx shadcn-ui@latest init
+
+# Install additional dependencies
+npm install lucide-react
+npm install framer-motion
+npm install @radix-ui/react-*
+npm install react-hook-form zod
+npm install next-seo
+```
+
+---
+
+### Week 2: High-Fidelity Mockups
+
+#### Deliverables
+- [ ] Homepage mockup (desktop & mobile)
+- [ ] Product listing page mockup
+- [ ] Product detail page mockup
+- [ ] Shopping cart mockup
+- [ ] Checkout flow mockups (all steps)
+- [ ] About Us page mockup
+- [ ] Contact page mockup
+
+#### Key Activities
+1. **Design Review Sessions**
+ - Daily design reviews with stakeholder
+ - Iterate based on feedback
+ - Get sign-off on each major page
+
+2. **Component Documentation**
+ - Document interactive states (hover, active, disabled)
+ - Specify animations and transitions
+ - Create spacing and sizing specifications
+ - Export assets for development
+
+3. **Content Finalization**
+ - Write final copy for all pages
+ - Product descriptions template created
+ - SEO metadata planned for each page
+ - Alt text guidelines established
+
+#### Figma Organization
+```
+/Angel's Flowers (Project)
+ /Design System
+ - Colors
+ - Typography
+ - Components
+ - Icons
+ - Spacing
+ /Pages - Desktop
+ - Homepage
+ - Product Listing
+ - Product Detail
+ - Cart
+ - Checkout
+ - About Us
+ - Contact
+ /Pages - Mobile
+ - (Same structure)
+ /Components Library
+ - Buttons
+ - Forms
+ - Cards
+ - Navigation
+ - Modals
+ /Assets
+ - Logos
+ - Photos
+ - Illustrations
+ - Icons
+```
+
+---
+
+## PHASE 2: FRONTEND DEVELOPMENT (WEEKS 3-4)
+
+### Week 3: Core Layout & Components
+
+#### Deliverables
+- [ ] Header/Navigation component (desktop & mobile)
+- [ ] Footer component
+- [ ] Homepage layout and sections
+- [ ] Product card component
+- [ ] Basic routing structure
+- [ ] Responsive breakpoints implemented
+
+#### Technical Implementation
+
+**File Structure:**
+```
+/angelsflowers
+ /app
+ layout.tsx # Root layout with header/footer
+ page.tsx # Homepage
+ /shop
+ page.tsx # Product listing
+ /[product-id]
+ page.tsx # Product detail
+ /about
+ page.tsx # About Us
+ /contact
+ page.tsx # Contact
+ /cart
+ page.tsx # Shopping cart
+ /checkout
+ page.tsx # Checkout flow
+ /components
+ /layout
+ Header.tsx
+ Footer.tsx
+ Navigation.tsx
+ MobileMenu.tsx
+ /ui
+ Button.tsx
+ Card.tsx
+ Input.tsx
+ # (shadcn/ui components)
+ /product
+ ProductCard.tsx
+ ProductGrid.tsx
+ ProductFilter.tsx
+ /sections
+ HeroSection.tsx
+ ValuePropositions.tsx
+ FamilyStory.tsx
+ FeaturedProducts.tsx
+ /lib
+ utils.ts # Utility functions
+ constants.ts # Site-wide constants
+ /public
+ /images
+ /products
+ /family
+ /hero
+ /fonts
+ /styles
+ globals.css
+ tailwind.config.js
+ next.config.js
+```
+
+**Sample Component: Product Card**
+```typescript
+// components/product/ProductCard.tsx
+
+import Image from 'next/image';
+import Link from 'next/link';
+import { Heart, Star } from 'lucide-react';
+import { Button } from '@/components/ui/button';
+
+interface ProductCardProps {
+ id: string;
+ name: string;
+ image: string;
+ price: number;
+ rating: number;
+ reviewCount: number;
+ isNew?: boolean;
+ isBestSeller?: boolean;
+}
+
+export function ProductCard({
+ id,
+ name,
+ image,
+ price,
+ rating,
+ reviewCount,
+ isNew,
+ isBestSeller,
+}: ProductCardProps) {
+ return (
+ <div className="group relative rounded-lg overflow-hidden bg-white shadow-soft hover:shadow-medium transition-all duration-300 hover:-translate-y-1">
+ {/* Badge */}
+ {(isNew || isBestSeller) && (
+ <div className="absolute top-4 left-4 z-10 bg-primary text-white px-3 py-1 rounded-full text-sm font-medium">
+ {isNew ? 'New' : 'Best Seller'}
+ </div>
+ )}
+
+ {/* Favorite Button */}
+ <button
+ className="absolute top-4 right-4 z-10 p-2 rounded-full bg-white/80 backdrop-blur-sm hover:bg-white transition-all"
+ aria-label="Add to favorites"
+ >
+ <Heart className="w-5 h-5 text-primary" />
+ </button>
+
+ {/* Image */}
+ <Link href={`/shop/${id}`}>
+ <div className="relative aspect-[4/5] overflow-hidden bg-neutral-cream">
+ <Image
+ src={image}
+ alt={name}
+ fill
+ className="object-cover group-hover:scale-105 transition-transform duration-300"
+ sizes="(max-width: 768px) 50vw, (max-width: 1200px) 33vw, 25vw"
+ />
+
+ {/* Quick View Overlay */}
+ <div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
+ <Button variant="secondary" size="sm">
+ Quick View
+ </Button>
+ </div>
+ </div>
+ </Link>
+
+ {/* Content */}
+ <div className="p-4">
+ <Link href={`/shop/${id}`}>
+ <h3 className="font-heading text-xl text-charcoal mb-2 hover:text-primary transition-colors">
+ {name}
+ </h3>
+ </Link>
+
+ {/* Rating */}
+ <div className="flex items-center gap-2 mb-3">
+ <div className="flex">
+ {[...Array(5)].map((_, i) => (
+ <Star
+ key={i}
+ className={`w-4 h-4 ${
+ i < Math.floor(rating)
+ ? 'fill-sunflower-gold text-sunflower-gold'
+ : 'text-gray-300'
+ }`}
+ />
+ ))}
+ </div>
+ <span className="text-sm text-warm-gray">({reviewCount})</span>
+ </div>
+
+ {/* Price */}
+ <p className="text-lg font-semibold text-charcoal mb-4">
+ From ${price.toFixed(2)}
+ </p>
+
+ {/* Add to Cart Button */}
+ <Button className="w-full" size="lg">
+ Add to Cart
+ </Button>
+ </div>
+ </div>
+ );
+}
+```
+
+**Tailwind Configuration:**
+```javascript
+// tailwind.config.js
+
+module.exports = {
+ content: [
+ './pages/**/*.{js,ts,jsx,tsx,mdx}',
+ './components/**/*.{js,ts,jsx,tsx,mdx}',
+ './app/**/*.{js,ts,jsx,tsx,mdx}',
+ ],
+ theme: {
+ extend: {
+ colors: {
+ primary: {
+ DEFAULT: '#D84B6C',
+ dark: '#B83A56',
+ light: '#F0869D',
+ pale: '#FDF2F4',
+ },
+ 'tropical-green': '#2D5F3F',
+ 'sunflower-gold': '#F4C430',
+ 'orchid-purple': '#8B4789',
+ 'sky-blue': '#87CEEB',
+ 'warm-white': '#FDFBF7',
+ cream: '#F5F1E8',
+ 'warm-gray': '#6B6B6B',
+ charcoal: '#2C2C2C',
+ },
+ fontFamily: {
+ heading: ['var(--font-cormorant)', 'Georgia', 'serif'],
+ body: ['var(--font-inter)', 'system-ui', 'sans-serif'],
+ accent: ['var(--font-playfair)', 'serif'],
+ },
+ boxShadow: {
+ soft: '0 2px 8px rgba(45, 95, 63, 0.08)',
+ medium: '0 4px 16px rgba(45, 95, 63, 0.12)',
+ large: '0 8px 32px rgba(45, 95, 63, 0.16)',
+ },
+ animation: {
+ 'fade-in': 'fadeIn 0.3s ease-in-out',
+ 'slide-up': 'slideUp 0.4s ease-out',
+ },
+ keyframes: {
+ fadeIn: {
+ '0%': { opacity: '0' },
+ '100%': { opacity: '1' },
+ },
+ slideUp: {
+ '0%': { transform: 'translateY(20px)', opacity: '0' },
+ '100%': { transform: 'translateY(0)', opacity: '1' },
+ },
+ },
+ },
+ },
+ plugins: [
+ require('@tailwindcss/forms'),
+ require('@tailwindcss/typography'),
+ ],
+};
+```
+
+---
+
+### Week 4: Product Pages & Interactivity
+
+#### Deliverables
+- [ ] Product listing page with filtering
+- [ ] Product detail page with image gallery
+- [ ] Add to cart functionality
+- [ ] Shopping cart page
+- [ ] Cart state management (Context API or Zustand)
+- [ ] Search functionality (basic)
+
+#### Key Technical Features
+
+**State Management (Cart Example):**
+```typescript
+// lib/cart-context.tsx
+
+'use client';
+
+import { createContext, useContext, useReducer, ReactNode } from 'react';
+
+interface CartItem {
+ id: string;
+ name: string;
+ price: number;
+ quantity: number;
+ size: string;
+ color: string;
+ image: string;
+}
+
+interface CartState {
+ items: CartItem[];
+ total: number;
+}
+
+type CartAction =
+ | { type: 'ADD_ITEM'; payload: CartItem }
+ | { type: 'REMOVE_ITEM'; payload: string }
+ | { type: 'UPDATE_QUANTITY'; payload: { id: string; quantity: number } }
+ | { type: 'CLEAR_CART' };
+
+const CartContext = createContext<{
+ state: CartState;
+ dispatch: React.Dispatch<CartAction>;
+} | null>(null);
+
+function cartReducer(state: CartState, action: CartAction): CartState {
+ switch (action.type) {
+ case 'ADD_ITEM':
+ const existingItem = state.items.find(
+ item => item.id === action.payload.id
+ );
+
+ if (existingItem) {
+ return {
+ ...state,
+ items: state.items.map(item =>
+ item.id === action.payload.id
+ ? { ...item, quantity: item.quantity + 1 }
+ : item
+ ),
+ total: state.total + action.payload.price,
+ };
+ }
+
+ return {
+ items: [...state.items, action.payload],
+ total: state.total + action.payload.price,
+ };
+
+ case 'REMOVE_ITEM':
+ const itemToRemove = state.items.find(item => item.id === action.payload);
+ return {
+ items: state.items.filter(item => item.id !== action.payload),
+ total: state.total - (itemToRemove?.price || 0) * (itemToRemove?.quantity || 0),
+ };
+
+ case 'UPDATE_QUANTITY':
+ const item = state.items.find(i => i.id === action.payload.id);
+ const priceDiff = item ? item.price * (action.payload.quantity - item.quantity) : 0;
+
+ return {
+ items: state.items.map(i =>
+ i.id === action.payload.id
+ ? { ...i, quantity: action.payload.quantity }
+ : i
+ ),
+ total: state.total + priceDiff,
+ };
+
+ case 'CLEAR_CART':
+ return { items: [], total: 0 };
+
+ default:
+ return state;
+ }
+}
+
+export function CartProvider({ children }: { children: ReactNode }) {
+ const [state, dispatch] = useReducer(cartReducer, { items: [], total: 0 });
+
+ return (
+ <CartContext.Provider value={{ state, dispatch }}>
+ {children}
+ </CartContext.Provider>
+ );
+}
+
+export function useCart() {
+ const context = useContext(CartContext);
+ if (!context) {
+ throw new Error('useCart must be used within CartProvider');
+ }
+ return context;
+}
+```
+
+**Product Filter Component:**
+```typescript
+// components/product/ProductFilter.tsx
+
+'use client';
+
+import { useState } from 'react';
+import { Checkbox } from '@/components/ui/checkbox';
+import { Label } from '@/components/ui/label';
+import { Slider } from '@/components/ui/slider';
+
+interface FilterOptions {
+ priceRange: [number, number];
+ colors: string[];
+ flowerTypes: string[];
+ sizes: string[];
+}
+
+interface ProductFilterProps {
+ onFilterChange: (filters: FilterOptions) => void;
+}
+
+export function ProductFilter({ onFilterChange }: ProductFilterProps) {
+ const [priceRange, setPriceRange] = useState<[number, number]>([0, 200]);
+ const [selectedColors, setSelectedColors] = useState<string[]>([]);
+ const [selectedTypes, setSelectedTypes] = useState<string[]>([]);
+ const [selectedSizes, setSelectedSizes] = useState<string[]>([]);
+
+ const colors = ['Red', 'Pink', 'White', 'Yellow', 'Purple', 'Mixed'];
+ const types = ['Roses', 'Lilies', 'Orchids', 'Sunflowers', 'Mixed Bouquets'];
+ const sizes = ['Small', 'Medium', 'Large', 'Deluxe'];
+
+ const handleApplyFilters = () => {
+ onFilterChange({
+ priceRange,
+ colors: selectedColors,
+ flowerTypes: selectedTypes,
+ sizes: selectedSizes,
+ });
+ };
+
+ return (
+ <div className="space-y-8 p-6 bg-warm-white rounded-lg">
+ <div>
+ <h3 className="font-heading text-2xl mb-4">Filters</h3>
+ </div>
+
+ {/* Price Range */}
+ <div>
+ <Label className="text-lg font-semibold mb-4 block">
+ Price Range
+ </Label>
+ <Slider
+ value={priceRange}
+ onValueChange={(value) => setPriceRange(value as [number, number])}
+ max={200}
+ step={5}
+ className="mb-4"
+ />
+ <div className="flex justify-between text-sm text-warm-gray">
+ <span>${priceRange[0]}</span>
+ <span>${priceRange[1]}</span>
+ </div>
+ </div>
+
+ {/* Colors */}
+ <div>
+ <Label className="text-lg font-semibold mb-4 block">Color</Label>
+ <div className="space-y-3">
+ {colors.map((color) => (
+ <div key={color} className="flex items-center">
+ <Checkbox
+ id={`color-${color}`}
+ checked={selectedColors.includes(color)}
+ onCheckedChange={(checked) => {
+ if (checked) {
+ setSelectedColors([...selectedColors, color]);
+ } else {
+ setSelectedColors(
+ selectedColors.filter((c) => c !== color)
+ );
+ }
+ }}
+ />
+ <Label
+ htmlFor={`color-${color}`}
+ className="ml-3 cursor-pointer"
+ >
+ {color}
+ </Label>
+ </div>
+ ))}
+ </div>
+ </div>
+
+ {/* Flower Types */}
+ <div>
+ <Label className="text-lg font-semibold mb-4 block">Flower Type</Label>
+ <div className="space-y-3">
+ {types.map((type) => (
+ <div key={type} className="flex items-center">
+ <Checkbox
+ id={`type-${type}`}
+ checked={selectedTypes.includes(type)}
+ onCheckedChange={(checked) => {
+ if (checked) {
+ setSelectedTypes([...selectedTypes, type]);
+ } else {
+ setSelectedTypes(selectedTypes.filter((t) => t !== type));
+ }
+ }}
+ />
+ <Label htmlFor={`type-${type}`} className="ml-3 cursor-pointer">
+ {type}
+ </Label>
+ </div>
+ ))}
+ </div>
+ </div>
+
+ {/* Sizes */}
+ <div>
+ <Label className="text-lg font-semibold mb-4 block">Size</Label>
+ <div className="space-y-3">
+ {sizes.map((size) => (
+ <div key={size} className="flex items-center">
+ <Checkbox
+ id={`size-${size}`}
+ checked={selectedSizes.includes(size)}
+ onCheckedChange={(checked) => {
+ if (checked) {
+ setSelectedSizes([...selectedSizes, size]);
+ } else {
+ setSelectedSizes(selectedSizes.filter((s) => s !== size));
+ }
+ }}
+ />
+ <Label htmlFor={`size-${size}`} className="ml-3 cursor-pointer">
+ {size}
+ </Label>
+ </div>
+ ))}
+ </div>
+ </div>
+
+ {/* Apply/Clear Buttons */}
+ <div className="flex gap-3">
+ <Button onClick={handleApplyFilters} className="flex-1">
+ Apply Filters
+ </Button>
+ <Button
+ variant="outline"
+ onClick={() => {
+ setPriceRange([0, 200]);
+ setSelectedColors([]);
+ setSelectedTypes([]);
+ setSelectedSizes([]);
+ onFilterChange({
+ priceRange: [0, 200],
+ colors: [],
+ flowerTypes: [],
+ sizes: [],
+ });
+ }}
+ >
+ Clear
+ </Button>
+ </div>
+ </div>
+ );
+}
+```
+
+---
+
+## PHASE 3: BACKEND & CHECKOUT (WEEKS 5-6)
+
+### Week 5: Content Management & Data
+
+#### Options for Backend
+
+**Option A: Headless CMS (Recommended for MVP)**
+- **Sanity.io** or **Contentful**
+- Pros: Easy for non-technical family to update products
+- Cons: Monthly cost (but free tiers available)
+
+**Option B: Static Data + Git-based Updates**
+- Products in JSON files
+- Updates via code changes
+- Pros: Free, simple
+- Cons: Requires technical knowledge to update
+
+**Option C: Custom Backend (Future scalability)**
+- Next.js API routes + Database (PostgreSQL/MongoDB)
+- Pros: Full control, custom features
+- Cons: More development time
+
+**Recommended: Start with Option A (Sanity.io)**
+
+#### Sanity Schema Example:
+```javascript
+// sanity/schemas/product.js
+
+export default {
+ name: 'product',
+ title: 'Product',
+ type: 'document',
+ fields: [
+ {
+ name: 'name',
+ title: 'Product Name',
+ type: 'string',
+ validation: Rule => Rule.required()
+ },
+ {
+ name: 'slug',
+ title: 'Slug',
+ type: 'slug',
+ options: {
+ source: 'name',
+ maxLength: 96
+ }
+ },
+ {
+ name: 'images',
+ title: 'Product Images',
+ type: 'array',
+ of: [{ type: 'image' }],
+ options: {
+ hotspot: true
+ }
+ },
+ {
+ name: 'description',
+ title: 'Description',
+ type: 'text',
+ rows: 4
+ },
+ {
+ name: 'price',
+ title: 'Base Price',
+ type: 'number',
+ validation: Rule => Rule.required().positive()
+ },
+ {
+ name: 'sizes',
+ title: 'Available Sizes',
+ type: 'array',
+ of: [{
+ type: 'object',
+ fields: [
+ { name: 'name', type: 'string', title: 'Size Name' },
+ { name: 'price', type: 'number', title: 'Price' },
+ { name: 'description', type: 'string', title: 'Description' }
+ ]
+ }]
+ },
+ {
+ name: 'colors',
+ title: 'Available Colors',
+ type: 'array',
+ of: [{ type: 'string' }],
+ options: {
+ list: [
+ { title: 'Red', value: 'red' },
+ { title: 'Pink', value: 'pink' },
+ { title: 'White', value: 'white' },
+ { title: 'Yellow', value: 'yellow' },
+ { title: 'Purple', value: 'purple' },
+ { title: 'Mixed', value: 'mixed' }
+ ]
+ }
+ },
+ {
+ name: 'occasions',
+ title: 'Occasions',
+ type: 'array',
+ of: [{ type: 'reference', to: [{ type: 'occasion' }] }]
+ },
+ {
+ name: 'isFeatured',
+ title: 'Featured Product',
+ type: 'boolean',
+ initialValue: false
+ },
+ {
+ name: 'isBestSeller',
+ title: 'Best Seller',
+ type: 'boolean',
+ initialValue: false
+ },
+ {
+ name: 'isNew',
+ title: 'New Arrival',
+ type: 'boolean',
+ initialValue: false
+ }
+ ]
+};
+```
+
+---
+
+### Week 6: Checkout & Payment Integration
+
+#### Payment Options
+
+**Recommended: Stripe**
+- Industry standard, excellent developer experience
+- PCI compliant out of the box
+- Supports various payment methods
+- Good documentation
+
+**Alternative: Square**
+- Great if already using Square for in-store
+- Unified platform
+- Slightly simpler setup
+
+**Checkout Flow Implementation:**
+
+```typescript
+// app/checkout/page.tsx
+
+'use client';
+
+import { useState } from 'react';
+import { useCart } from '@/lib/cart-context';
+import { loadStripe } from '@stripe/stripe-js';
+import { Elements } from '@stripe/react-stripe-js';
+import CheckoutForm from '@/components/checkout/CheckoutForm';
+
+const stripePromise = loadStripe(
+ process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!
+);
+
+export default function CheckoutPage() {
+ const { state } = useCart();
+ const [step, setStep] = useState(1);
+
+ return (
+ <div className="min-h-screen bg-warm-white py-12">
+ <div className="container mx-auto px-4 max-w-6xl">
+ {/* Progress Steps */}
+ <div className="flex items-center justify-center mb-12">
+ <Step number={1} label="Delivery" active={step === 1} />
+ <StepConnector completed={step > 1} />
+ <Step number={2} label="Date & Time" active={step === 2} />
+ <StepConnector completed={step > 2} />
+ <Step number={3} label="Payment" active={step === 3} />
+ </div>
+
+ {/* Checkout Content */}
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
+ {/* Main Checkout Form */}
+ <div className="lg:col-span-2">
+ {step === 1 && <DeliveryInfoForm onNext={() => setStep(2)} />}
+ {step === 2 && <DeliveryDateForm onNext={() => setStep(3)} onBack={() => setStep(1)} />}
+ {step === 3 && (
+ <Elements stripe={stripePromise}>
+ <CheckoutForm onBack={() => setStep(2)} />
+ </Elements>
+ )}
+ </div>
+
+ {/* Order Summary Sidebar */}
+ <div className="lg:col-span-1">
+ <OrderSummary items={state.items} total={state.total} />
+ </div>
+ </div>
+ </div>
+ </div>
+ );
+}
+```
+
+**Stripe Payment Intent API Route:**
+```typescript
+// app/api/create-payment-intent/route.ts
+
+import { NextResponse } from 'next/server';
+import Stripe from 'stripe';
+
+const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
+ apiVersion: '2023-10-16',
+});
+
+export async function POST(req: Request) {
+ try {
+ const { amount, customerEmail, deliveryDetails } = await req.json();
+
+ const paymentIntent = await stripe.paymentIntents.create({
+ amount: amount * 100, // Convert to cents
+ currency: 'usd',
+ automatic_payment_methods: {
+ enabled: true,
+ },
+ receipt_email: customerEmail,
+ metadata: {
+ deliveryAddress: deliveryDetails.address,
+ recipientName: deliveryDetails.recipientName,
+ deliveryDate: deliveryDetails.date,
+ },
+ });
+
+ return NextResponse.json({
+ clientSecret: paymentIntent.client_secret,
+ });
+ } catch (error) {
+ return NextResponse.json(
+ { error: 'Failed to create payment intent' },
+ { status: 500 }
+ );
+ }
+}
+```
+
+---
+
+## PHASE 4: POLISH & LAUNCH (WEEKS 7-8)
+
+### Week 7: Quality Assurance
+
+#### Testing Checklist
+
+**Functional Testing:**
+- [ ] All navigation links work correctly
+- [ ] Product filtering and sorting functions properly
+- [ ] Add to cart updates cart count and totals
+- [ ] Cart quantity updates recalculate correctly
+- [ ] Checkout flow completes successfully
+- [ ] Payment processing works (use Stripe test mode)
+- [ ] Form validation shows appropriate errors
+- [ ] Search functionality returns relevant results
+- [ ] Contact form sends emails successfully
+
+**Cross-Browser Testing:**
+- [ ] Chrome (latest 2 versions)
+- [ ] Firefox (latest 2 versions)
+- [ ] Safari (latest 2 versions)
+- [ ] Edge (latest 2 versions)
+
+**Device Testing:**
+- [ ] iPhone (Safari)
+- [ ] Android (Chrome)
+- [ ] iPad/Tablet
+- [ ] Desktop (various screen sizes)
+
+**Performance Testing:**
+- [ ] Lighthouse audit (score >90)
+- [ ] GTmetrix grade A/B
+- [ ] WebPageTest results reviewed
+- [ ] Image optimization verified
+- [ ] Lazy loading working correctly
+
+**Accessibility Testing:**
+- [ ] WAVE browser extension audit (0 errors)
+- [ ] Screen reader testing (NVDA or JAWS)
+- [ ] Keyboard navigation complete site
+- [ ] Color contrast checker (WCAG AA minimum)
+- [ ] Focus indicators visible and logical
+
+**SEO Testing:**
+- [ ] Meta tags present on all pages
+- [ ] Open Graph images working
+- [ ] Schema.org markup validated
+- [ ] XML sitemap generated
+- [ ] robots.txt configured
+- [ ] Google Search Console set up
+
+---
+
+### Week 8: Launch Preparation
+
+#### Pre-Launch Checklist
+
+**Technical Setup:**
+- [ ] Domain purchased and DNS configured
+- [ ] SSL certificate installed
+- [ ] Production environment configured
+- [ ] Environment variables set
+- [ ] Database/CMS production instance set up
+- [ ] Payment gateway in live mode (after testing)
+- [ ] Email service configured (SendGrid/Mailgun)
+- [ ] Analytics tracking installed (GA4, Facebook Pixel)
+- [ ] Error monitoring set up (Sentry)
+
+**Content Finalization:**
+- [ ] All product photos edited and uploaded
+- [ ] Product descriptions written and proofread
+- [ ] Family photos taken and processed
+- [ ] About Us content finalized
+- [ ] Legal pages complete (Privacy, Terms, Returns)
+- [ ] Contact information verified
+- [ ] Social media links working
+
+**Business Operations:**
+- [ ] Stripe/Square account verified and active
+- [ ] Delivery fee structure configured
+- [ ] Delivery zone coverage defined
+- [ ] Order notification system tested
+- [ ] Customer service email/phone ready
+- [ ] Inventory management process established
+- [ ] Fulfillment workflow documented
+
+**Marketing Preparation:**
+- [ ] Social media accounts created/updated
+- [ ] Instagram feed populated with content
+- [ ] Google My Business listing claimed
+- [ ] Email list ready (if existing customers)
+- [ ] Launch announcement drafted
+- [ ] Press release prepared (local media)
+- [ ] Soft launch plan for friends/family testing
+
+**Launch Day:**
+1. **Soft Launch (Week 8, Day 1-3)**
+ - Share with friends and family
+ - Monitor for critical bugs
+ - Gather immediate feedback
+ - Test order fulfillment process
+
+2. **Public Launch (Week 8, Day 4+)**
+ - Social media announcement
+ - Email to existing customers
+ - Update Google My Business
+ - Local community outreach
+ - Monitor site performance
+ - Respond to feedback quickly
+
+---
+
+## POST-LAUNCH ROADMAP
+
+### Month 1: Monitor & Optimize
+- Daily monitoring of orders and site performance
+- Address any urgent bugs or issues
+- Collect user feedback through surveys
+- Analyze analytics data
+- Respond to all customer inquiries within 24 hours
+- Post regularly on social media
+
+**Key Metrics to Track:**
+- Orders per day/week
+- Average order value
+- Conversion rate
+- Cart abandonment rate
+- Traffic sources
+- Most viewed products
+- Customer inquiries/questions
+
+### Months 2-3: Iterate & Expand
+
+**Feature Additions:**
+- Customer reviews/ratings system
+- Email newsletter (Mailchimp integration)
+- Loyalty program basics
+- Expanded product catalog
+- Blog with flower care tips
+- Customer account portal
+
+**Content Expansion:**
+- Weekly blog posts
+- Behind-the-scenes Instagram content
+- Customer testimonial collection
+- Video tour of shop/arranging process
+- Seasonal product launches
+
+### Months 4-6: Scale & Grow
+
+**Advanced Features:**
+- Spanish language version
+- Advanced personalization (saved favorites)
+- Subscription service for regular deliveries
+- Corporate account program
+- Virtual consultation booking
+- Expanded delivery zones
+
+**Marketing Initiatives:**
+- Local partnerships (wedding venues, event planners)
+- Influencer collaborations
+- Paid advertising (Google Ads, Instagram Ads)
+- Community event sponsorships
+- Holiday campaign planning
+
+---
+
+## BUDGET BREAKDOWN
+
+### Design & Development (One-Time)
+| Item | Estimated Cost | Notes |
+|------|----------------|-------|
+| UI/UX Design | $3,000 - $5,000 | Includes all mockups, assets |
+| Frontend Development | $5,000 - $8,000 | Next.js, Tailwind, components |
+| Backend/CMS Setup | $2,000 - $3,000 | Sanity.io integration |
+| Payment Integration | $1,000 - $1,500 | Stripe checkout setup |
+| Photography | $500 - $1,500 | Professional product photos |
+| Content Writing | $500 - $1,000 | All page copy |
+| QA/Testing | $1,000 - $2,000 | Comprehensive testing |
+| **Total Development** | **$13,000 - $22,000** | Varies by agency/freelancer |
+
+**Budget-Friendly Option:** $5,000-$8,000 with template customization + freelancer
+
+### Recurring Monthly Costs
+| Service | Monthly Cost | Notes |
+|---------|--------------|-------|
+| Domain + Hosting (Vercel) | $0 - $20 | Free for hobby, Pro for production |
+| CMS (Sanity.io) | $0 - $99 | Free tier adequate to start |
+| Payment Processing | 2.9% + $0.30 | Per transaction (Stripe) |
+| Email Service | $0 - $25 | SendGrid free tier, paid for volume |
+| Analytics | $0 | Google Analytics free |
+| SSL Certificate | $0 | Included with Vercel/Netlify |
+| **Estimated Monthly** | **$25 - $150** | Scales with traffic/orders |
+
+---
+
+## MAINTENANCE PLAN
+
+### Daily
+- Monitor order notifications
+- Check site uptime (UptimeRobot)
+- Respond to customer inquiries
+- Post on social media
+
+### Weekly
+- Review analytics dashboard
+- Update product availability
+- Backup CMS content
+- Check for broken links/images
+- Engage with social media comments
+
+### Monthly
+- Review performance metrics
+- Update seasonal products
+- Security updates (dependencies)
+- Content calendar planning
+- Review and respond to reviews
+
+### Quarterly
+- Comprehensive analytics review
+- User feedback analysis
+- Feature prioritization meeting
+- Photography updates
+- A/B testing new designs
+- Competitor analysis
+
+---
+
+## RISK MITIGATION
+
+### Technical Risks
+
+**Risk: Site downtime during peak hours**
+- Mitigation: Use reliable hosting (Vercel), monitor uptime
+- Contingency: Have phone/in-person ordering as backup
+
+**Risk: Payment processing issues**
+- Mitigation: Thorough testing, Stripe's reliability
+- Contingency: Alternative payment methods (PayPal), phone orders
+
+**Risk: High traffic crashes site**
+- Mitigation: Scalable hosting, image optimization
+- Contingency: Temporary waiting room page during extreme traffic
+
+### Business Risks
+
+**Risk: Online orders cannibalize in-store sales**
+- Mitigation: Emphasize online as convenience, not replacement
+- Strategy: Offer in-store pickup option with small discount
+
+**Risk: Can't fulfill online order volume**
+- Mitigation: Start with conservative delivery zones
+- Strategy: Gradually expand as capacity allows
+
+**Risk: Negative online reviews**
+- Mitigation: Excellent customer service, quality control
+- Strategy: Proactive review requests from happy customers
+
+---
+
+## SUCCESS CRITERIA
+
+### Launch Success (Month 1)
+- [ ] 100+ website visitors per day
+- [ ] 10+ online orders placed
+- [ ] 3%+ conversion rate
+- [ ] Zero critical bugs reported
+- [ ] 4.5+ star average review rating
+- [ ] Social media followers growing
+
+### 6-Month Success
+- [ ] 500+ visitors per day
+- [ ] 30+ online orders per week
+- [ ] 5%+ conversion rate
+- [ ] 50+ customer reviews
+- [ ] 20%+ repeat customer rate
+- [ ] Profitability on online channel
+
+### 1-Year Vision
+- [ ] 1,000+ visitors per day
+- [ ] 100+ online orders per week
+- [ ] Recognized as top online florist in East LA
+- [ ] Featured in local media
+- [ ] Expanded product line
+- [ ] Bilingual site launched
+
+---
+
+## FINAL NOTES
+
+**Key Success Factors:**
+1. **Quality First**: Never compromise on flower quality or customer experience
+2. **Personal Touch**: Technology should enhance, not replace, family connection
+3. **Community Focus**: East LA roots are a competitive advantage
+4. **Consistent Communication**: Keep customers informed throughout order process
+5. **Iterative Improvement**: Launch is just the beginning; continuous refinement
+
+**Remember:**
+- Start simple, iterate based on real user feedback
+- Mobile experience is critical
+- Family story is your unique selling proposition
+- Customer service excellence differentiates you from big competitors
+- Every order is a potential word-of-mouth marketing opportunity
+
+**This is a marathon, not a sprint.** Focus on building a sustainable online presence that complements and amplifies the family business's existing strengths.
+
+---
+
+**Document Version**: 1.0
+**Last Updated**: 2025-11-10
+**Status**: Ready for Project Kickoff
+**Next Action**: Schedule kickoff meeting and begin Phase 1 tasks
diff --git a/PROJECT_OVERVIEW.md b/PROJECT_OVERVIEW.md
new file mode 100644
index 0000000..2456cc9
--- /dev/null
+++ b/PROJECT_OVERVIEW.md
@@ -0,0 +1,376 @@
+# Angel's Flowers - UI/UX Design Documentation
+
+> A comprehensive design strategy for transforming a family-run Ecuadorian flower shop into a premium online experience that rivals 800flowers while maintaining authentic, warm, family-oriented values.
+
+---
+
+## Project Overview
+
+**Business**: Angel's Flowers - Family-run Ecuadorian flower shop in East Los Angeles
+**Goal**: Create a modern, user-friendly e-commerce website that showcases beautiful flowers and the family's heritage
+**Target Audience**: East LA community members, 25-65 years old, celebrating life's special moments
+**Competitive Benchmark**: Match 800flowers.com quality while emphasizing local, family-owned authenticity
+
+---
+
+## Documentation Structure
+
+This project includes comprehensive UI/UX documentation organized into four main files:
+
+### 1. DESIGN_SYSTEM.md
+**Complete visual design and component specifications**
+
+- **Color Palette**: Ecuadorian-inspired (rose pink, tropical green, sunflower gold)
+- **Typography**: Cormorant Garamond (headings) + Inter (body)
+- **Component Library**: Buttons, cards, forms, navigation patterns
+- **Design Tokens**: Tailwind CSS configuration
+- **Photography Guidelines**: Product, lifestyle, and family photo standards
+
+**Key Sections:**
+- Visual Design Direction (colors, fonts, aesthetic)
+- Website Structure & Navigation (site architecture)
+- Key UI Components (hero, product cards, family story)
+- Accessibility & Responsiveness Requirements
+- Design System Recommendations (shadcn/ui + Tailwind)
+
+### 2. WIREFRAMES.md
+**Detailed ASCII wireframes for all major pages**
+
+- Homepage (desktop & mobile)
+- Product Listing Page with filters
+- Product Detail Page with image gallery
+- Shopping Cart
+- Multi-step Checkout Flow
+- About Us Page
+- Interaction patterns (mega menu, quick view modal)
+
+**Use these wireframes to:**
+- Communicate layout concepts to stakeholders
+- Guide frontend development
+- Ensure consistent responsive behavior
+- Plan component hierarchy
+
+### 3. USER_RESEARCH.md
+**Comprehensive user personas and research insights**
+
+**Five Detailed Personas:**
+1. **Maria the Milestone Celebrator** (42, teacher, family-focused)
+2. **David the Romantic Gifter** (34, software engineer, tech-savvy)
+3. **Carmen the Event Coordinator** (54, event planner, business client)
+4. **Robert the Sympathy Sender** (61, retired, community-oriented)
+5. **Sophia the Social Media Influencer** (27, content creator, trendsetter)
+
+**Also Includes:**
+- User journey maps
+- Competitive analysis (800flowers + local competitors)
+- Accessibility considerations
+- Usability testing plan
+- Post-launch analytics strategy
+
+### 4. IMPLEMENTATION_GUIDE.md
+**Practical step-by-step development roadmap**
+
+**8-Week Implementation Plan:**
+- **Phase 1** (Weeks 1-2): Foundation & Design
+- **Phase 2** (Weeks 3-4): Frontend Development
+- **Phase 3** (Weeks 5-6): Backend & Checkout
+- **Phase 4** (Weeks 7-8): Polish & Launch
+
+**Includes:**
+- Technology stack recommendations (Next.js + Tailwind + shadcn/ui)
+- Code examples and file structure
+- Sanity.io CMS schema
+- Stripe payment integration
+- Testing checklists
+- Launch preparation guide
+- Budget breakdown ($13k-$22k for full development)
+- Post-launch roadmap
+
+---
+
+## Quick Start Guide
+
+### For Designers:
+1. Read **DESIGN_SYSTEM.md** for complete visual specifications
+2. Reference **WIREFRAMES.md** for layout guidance
+3. Use **USER_RESEARCH.md** personas to inform design decisions
+4. Create high-fidelity mockups in Figma based on design system
+
+### For Developers:
+1. Review **IMPLEMENTATION_GUIDE.md** for technical setup
+2. Reference **WIREFRAMES.md** for component structure
+3. Follow **DESIGN_SYSTEM.md** for styling specifications
+4. Implement in phases as outlined in implementation guide
+
+### For Project Managers:
+1. Use **IMPLEMENTATION_GUIDE.md** for timeline and budget planning
+2. Reference **USER_RESEARCH.md** for feature prioritization
+3. Track progress against 8-week roadmap
+4. Use testing checklists for quality assurance
+
+### For Stakeholders:
+1. Review **DESIGN_SYSTEM.md** for overall aesthetic and brand direction
+2. Explore **WIREFRAMES.md** to visualize page layouts
+3. Read persona stories in **USER_RESEARCH.md** to understand target customers
+4. Understand timeline and investment via **IMPLEMENTATION_GUIDE.md**
+
+---
+
+## Design Principles
+
+### 1. Elegant Heritage
+Respect for craftsmanship and Ecuadorian tradition through refined design choices.
+
+### 2. Warm Family Connection
+Personal, trustworthy, and community-oriented interactions at every touchpoint.
+
+### 3. Vibrant Freshness
+Celebrating the beauty of living flowers with high-quality imagery and color.
+
+### 4. Modern Professionalism
+Competitive with major online florists in functionality and polish.
+
+### 5. Accessible Inclusivity
+Welcoming to all East LA community members with WCAG AA compliance.
+
+---
+
+## Technology Stack (Recommended)
+
+### Core Framework
+- **Next.js 14+** (React framework with App Router)
+- **TypeScript** (Type safety)
+- **Tailwind CSS** (Utility-first styling)
+
+### Component Library
+- **shadcn/ui** (Accessible, customizable components)
+- **Radix UI** (Headless UI primitives)
+- **Lucide React** (Icon system)
+
+### Backend & CMS
+- **Sanity.io** (Headless CMS for product management)
+- **Next.js API Routes** (Backend functionality)
+
+### E-commerce & Payments
+- **Stripe** (Payment processing)
+- **React Context API or Zustand** (Cart state management)
+
+### Hosting & Deployment
+- **Vercel** (Optimized for Next.js)
+- **Cloudinary or Sanity** (Image optimization)
+
+### Analytics & Monitoring
+- **Google Analytics 4** (User behavior tracking)
+- **Vercel Analytics** (Performance monitoring)
+- **Sentry** (Error tracking)
+
+---
+
+## Key Features
+
+### Must-Have (MVP)
+- Responsive homepage with hero and featured products
+- Product catalog with filtering by occasion, price, color
+- Product detail pages with image gallery
+- Shopping cart with quantity management
+- Multi-step checkout flow
+- Stripe payment integration
+- Mobile-first responsive design
+- Family story and About Us section
+- Contact page with location map
+
+### Phase 2 (Post-Launch)
+- Customer reviews and ratings
+- User accounts and order history
+- Email newsletter integration
+- Instagram feed integration
+- Live chat support
+- Blog with flower care tips
+
+### Phase 3 (Future Enhancements)
+- Spanish language version
+- Loyalty/rewards program
+- Subscription service for regular deliveries
+- Virtual consultation booking
+- Corporate accounts
+- Expanded delivery zones
+
+---
+
+## Success Metrics
+
+### Launch Goals (Month 1)
+- 100+ daily visitors
+- 10+ online orders
+- 3%+ conversion rate
+- 4.5+ star average rating
+- Zero critical bugs
+
+### 6-Month Goals
+- 500+ daily visitors
+- 30+ weekly orders
+- 5%+ conversion rate
+- 50+ customer reviews
+- 20%+ repeat customer rate
+
+### 1-Year Vision
+- 1,000+ daily visitors
+- 100+ weekly orders
+- Recognized as top online florist in East LA
+- Bilingual site launched
+- Featured in local media
+
+---
+
+## Budget Overview
+
+### Development Investment
+- **Full Custom Development**: $13,000 - $22,000
+- **Budget-Friendly Option**: $5,000 - $8,000 (template + freelancer)
+
+### Monthly Operating Costs
+- **Minimal Setup**: $25 - $50/month (hosting, CMS free tiers)
+- **Production Scale**: $100 - $150/month (paid tiers, email service)
+- **Payment Processing**: 2.9% + $0.30 per transaction (Stripe)
+
+---
+
+## Project Timeline
+
+```
+Week 1-2: Design System & Mockups
+Week 3-4: Frontend Development (Layout & Components)
+Week 5-6: Backend & Checkout Integration
+Week 7-8: Testing & Launch Preparation
+Week 8+: Soft Launch → Public Launch
+Month 1-3: Monitor, Iterate, Expand Features
+Month 4-6: Scale and Grow
+```
+
+---
+
+## File Reference
+
+| File | Purpose | Primary Audience |
+|------|---------|------------------|
+| `DESIGN_SYSTEM.md` | Complete visual design specifications | Designers, Developers |
+| `WIREFRAMES.md` | Detailed page layouts and structures | All team members |
+| `USER_RESEARCH.md` | User personas and research insights | UX designers, Product managers |
+| `IMPLEMENTATION_GUIDE.md` | Technical roadmap and code examples | Developers, Project managers |
+| `PROJECT_OVERVIEW.md` (this file) | Project overview and quick reference | All stakeholders |
+
+---
+
+## Next Steps
+
+### Immediate Actions (Week 1):
+1. **Stakeholder Meeting**: Review design strategy with family owners
+2. **Budget Approval**: Confirm development budget and timeline
+3. **Team Assembly**: Hire/assign designers and developers
+4. **Photography Planning**: Schedule product and family photo shoots
+5. **Content Gathering**: Begin collecting product information and family story details
+
+### Design Phase:
+1. Create Figma workspace with design system
+2. Develop high-fidelity mockups for all key pages
+3. Get stakeholder approval on designs
+4. Prepare assets and documentation for developers
+
+### Development Phase:
+1. Set up Next.js project with recommended tech stack
+2. Implement design system in Tailwind config
+3. Build components following wireframes
+4. Integrate Sanity CMS for product management
+5. Connect Stripe for payment processing
+6. Comprehensive testing and QA
+
+### Launch Preparation:
+1. Domain and hosting setup
+2. Content population (products, images, copy)
+3. Payment gateway live mode activation
+4. Analytics and monitoring tools configured
+5. Soft launch with friends/family
+6. Public launch and marketing
+
+---
+
+## Important Notes
+
+### Critical Success Factors:
+1. **Mobile-First**: Most users will discover via smartphone
+2. **Quality Consistency**: Every order must match/exceed expectations
+3. **Personal Touch**: Technology enhances, doesn't replace family connection
+4. **Community Focus**: East LA roots are competitive advantage
+5. **Ecuadorian Story**: Unique heritage differentiates from competitors
+
+### Common Pitfalls to Avoid:
+- Launching without mobile testing
+- Poor product photography
+- Complicated checkout flow
+- Hidden fees or unclear pricing
+- Slow page load times
+- Inaccessible design (WCAG violations)
+- No phone contact option
+- Generic brand voice
+
+### Best Practices:
+- Test on real devices (not just emulators)
+- Use high-quality, well-lit product photos
+- Keep checkout to 3 steps maximum
+- Show all costs upfront
+- Optimize all images (WebP format)
+- Follow WCAG 2.1 AA guidelines
+- Prominently display phone number
+- Let family voice shine through copy
+
+---
+
+## Support & Maintenance
+
+### Daily:
+- Monitor orders and site uptime
+- Respond to customer inquiries
+- Social media engagement
+
+### Weekly:
+- Analytics review
+- Content updates (products, availability)
+- Backups
+
+### Monthly:
+- Performance optimization
+- Security updates
+- Feature planning
+
+### Quarterly:
+- Comprehensive analytics review
+- User feedback analysis
+- A/B testing
+- Competitor analysis
+
+---
+
+## Contact & Collaboration
+
+For questions or clarifications about this design strategy:
+
+- **Design Questions**: Refer to DESIGN_SYSTEM.md and WIREFRAMES.md
+- **User Research**: Refer to USER_RESEARCH.md personas
+- **Technical Implementation**: Refer to IMPLEMENTATION_GUIDE.md
+- **General Overview**: This PROJECT_OVERVIEW.md
+
+---
+
+## Version History
+
+- **v1.0** (2025-11-10): Initial comprehensive design strategy
+ - Complete design system
+ - Detailed wireframes
+ - User research and personas
+ - 8-week implementation roadmap
+
+---
+
+**Ready to bring Angel's Flowers online?** Start with the design system, reference the wireframes, design for the personas, and follow the implementation guide. Every decision should ask: "Does this showcase our beautiful flowers, tell our family story, and make ordering easy?"
+
+From Ecuador to East LA, with love.
diff --git a/PROJECT_SUMMARY.md b/PROJECT_SUMMARY.md
new file mode 100644
index 0000000..3582b1a
--- /dev/null
+++ b/PROJECT_SUMMARY.md
@@ -0,0 +1,335 @@
+# Angel's Flowers - Project Summary
+
+## Overview
+
+A modern, professional website for Angel's Flowers - a family-run flower shop in East Los Angeles specializing in premium Ecuadorian roses and arrangements. Built to rival 800flowers in quality and user experience.
+
+## Technology Stack
+
+- **Framework**: Next.js 14 (App Router)
+- **UI Library**: React 18
+- **Language**: TypeScript
+- **Styling**: Tailwind CSS 3.4
+- **Icons**: React Icons 4.12
+- **Fonts**: Google Fonts (Inter, Playfair Display)
+
+## Project Structure
+
+```
+/root/WebsitesMisc/angelsflowers/
+│
+├── app/ # Next.js App Directory
+│ ├── layout.tsx # Root layout with Navbar/Footer
+│ ├── page.tsx # Homepage
+│ ├── globals.css # Global styles & Tailwind
+│ ├── sitemap.ts # SEO sitemap
+│ ├── about/
+│ │ └── page.tsx # Our Story page
+│ ├── flowers/
+│ │ └── page.tsx # Flowers catalog page
+│ └── contact/
+│ └── page.tsx # Contact page
+│
+├── components/ # Reusable Components
+│ ├── Navbar.tsx # Navigation with mobile menu
+│ └── Footer.tsx # Footer with contact info
+│
+├── public/ # Static Assets
+│ └── robots.txt # SEO robots file
+│
+├── Configuration Files
+│ ├── package.json # Dependencies
+│ ├── tsconfig.json # TypeScript config
+│ ├── tailwind.config.js # Tailwind customization
+│ ├── next.config.js # Next.js config
+│ ├── postcss.config.js # PostCSS config
+│ └── .eslintrc.json # ESLint config
+│
+└── Documentation
+ ├── README.md # Project documentation
+ ├── SETUP.md # Setup instructions
+ └── .env.local.example # Environment variables example
+```
+
+## Pages & Features
+
+### 1. Homepage (`/app/page.tsx`)
+- **Hero Section**: Full-screen hero with gradient overlay and CTA buttons
+- **Why Choose Us**: 4-column feature grid highlighting quality, family, freshness, service
+- **Featured Collections**: 3 featured flower products with images and descriptions
+- **Family Story Preview**: Story section with image and text
+- **Call-to-Action**: Bottom CTA section with contact options
+
+**Key Features**:
+- Responsive design (mobile-first)
+- Animated scroll indicator
+- Hover effects on cards
+- Multiple CTAs for conversion
+
+### 2. Flowers Page (`/app/flowers/page.tsx`)
+- **Hero Section**: Page header with description
+- **Product Categories**:
+ - Ecuadorian Roses (6 varieties: red, white, pink, yellow, rainbow, lavender)
+ - Mixed Arrangements (4 types)
+ - Special Occasions (4 categories: weddings, sympathy, corporate, birthdays)
+- **Product Cards**: Image, name, price, description, features, call-to-order button
+
+**Key Features**:
+- 14 total products/arrangements
+- Detailed product information
+- Feature lists for each item
+- Hover effects with image zoom
+- Direct call-to-action on each card
+
+### 3. About Page (`/app/about/page.tsx`)
+- **Hero Section**: Page introduction
+- **Origin Story**: Two-column layout with story and image
+- **Timeline**: 5-milestone vertical timeline (1995-2025)
+- **Values**: 4-value grid with icons
+- **Ecuador Connection**: Two-column section explaining Ecuadorian flower quality
+- **Team Section**: 3 team members with photos
+
+**Key Features**:
+- Storytelling focus
+- Visual timeline
+- Team member profiles
+- Educational content about Ecuadorian flowers
+
+### 4. Contact Page (`/app/contact/page.tsx`)
+- **Hero Section**: Page header
+- **Contact Information**: 4 contact cards (address, phone, email, hours)
+- **Contact Form**: Full form with validation
+- **Map Section**: Map placeholder with location info
+- **FAQs**: 5 common questions with answers
+
+**Key Features**:
+- Working contact form with state management
+- Success message on submission
+- Social media links
+- Accessibility features
+- Form validation
+
+## Shared Components
+
+### Navbar (`/components/Navbar.tsx`)
+- Sticky navigation with scroll effect
+- Mobile hamburger menu
+- Active page highlighting
+- Logo with gradient background
+- Phone number CTA button
+
+**Accessibility**:
+- ARIA labels
+- Keyboard navigation
+- Focus states
+
+### Footer (`/components/Footer.tsx`)
+- 4-column layout (responsive)
+- Quick links navigation
+- Contact information
+- Business hours
+- Social media links
+- Copyright information
+
+## Design System
+
+### Color Palette
+```css
+Primary (Pink/Rose):
+- 50-900 scale from light to dark
+- Primary-600: Main brand color
+
+Accent (Green):
+- 50-900 scale
+- For foliage/nature elements
+
+Warm (Yellow):
+- 50-900 scale
+- For highlights and warmth
+```
+
+### Typography
+- **Headings**: Playfair Display (serif)
+- **Body**: Inter (sans-serif)
+- **Sizes**: Responsive with Tailwind utility classes
+
+### Components
+- `.btn-primary`: Primary button style
+- `.btn-secondary`: Secondary button style
+- `.card`: Product/content card with hover effect
+- `.section-padding`: Consistent section spacing
+- `.heading-xl/lg/md`: Responsive heading sizes
+
+## Key Features
+
+### Performance
+- Image optimization ready (Next.js Image component setup)
+- Code splitting with App Router
+- Font optimization with next/font
+- CSS purging with Tailwind
+
+### SEO
+- Semantic HTML structure
+- Meta tags in layout
+- Sitemap generation
+- robots.txt configured
+- Descriptive alt text ready
+
+### Accessibility
+- WCAG 2.1 AA compliant structure
+- Keyboard navigation support
+- ARIA labels on interactive elements
+- Focus states on all interactive elements
+- Color contrast ratios meet standards
+
+### Responsive Design
+- Mobile-first approach
+- Breakpoints: sm (640px), md (768px), lg (1024px), xl (1280px)
+- Flexible grid layouts
+- Touch-friendly interactive elements
+- Responsive typography
+
+## Setup Instructions
+
+1. **Install dependencies**:
+ ```bash
+ cd /root/WebsitesMisc/angelsflowers
+ npm install
+ ```
+
+2. **Run development server**:
+ ```bash
+ npm run dev
+ ```
+
+3. **Build for production**:
+ ```bash
+ npm run build
+ npm start
+ ```
+
+## Customization Checklist
+
+- [ ] Update phone number in Navbar, Footer, and Contact page
+- [ ] Update address in Footer and Contact page
+- [ ] Update business hours in Footer and Contact page
+- [ ] Update email addresses throughout
+- [ ] Add real flower images to `/public/images/`
+- [ ] Update image URLs in all pages
+- [ ] Add real team photos in About page
+- [ ] Configure Google Maps API for Contact page
+- [ ] Set up contact form backend
+- [ ] Update social media links
+- [ ] Add Google Analytics tracking ID
+- [ ] Update domain in sitemap.ts
+- [ ] Add favicon and app icons
+- [ ] Test on all devices and browsers
+
+## Deployment Options
+
+### Vercel (Recommended)
+```bash
+npm i -g vercel
+vercel
+```
+
+### Netlify
+- Push to GitHub
+- Connect repository
+- Build command: `npm run build`
+- Publish directory: `.next`
+
+### Traditional Hosting
+- Run `npm run build`
+- Upload build files
+- Run `npm start` on server
+
+## Future Enhancements
+
+### Phase 2
+- [ ] E-commerce integration (Shopify, Stripe)
+- [ ] Online ordering system
+- [ ] Customer account system
+- [ ] Order tracking
+- [ ] Email notifications
+
+### Phase 3
+- [ ] Blog/flower care tips
+- [ ] Newsletter signup
+- [ ] Customer reviews/testimonials
+- [ ] Photo gallery with customer arrangements
+- [ ] Loyalty program
+
+### Phase 4
+- [ ] Mobile app
+- [ ] Subscription service
+- [ ] Live chat support
+- [ ] Virtual consultations
+- [ ] AR flower preview
+
+## Browser Support
+
+- Chrome/Edge (latest 2 versions)
+- Firefox (latest 2 versions)
+- Safari (latest 2 versions)
+- iOS Safari (latest 2 versions)
+- Chrome Mobile (latest 2 versions)
+
+## Dependencies
+
+### Core
+- next: ^14.0.4
+- react: ^18.2.0
+- react-dom: ^18.2.0
+- react-icons: ^4.12.0
+
+### Development
+- typescript: ^5.3.3
+- @types/node: ^20.10.5
+- @types/react: ^18.2.45
+- @types/react-dom: ^18.2.18
+- tailwindcss: ^3.4.0
+- autoprefixer: ^10.4.16
+- postcss: ^8.4.32
+- eslint: ^8.56.0
+- eslint-config-next: ^14.0.4
+
+## File Locations
+
+**All files are located in**: `/root/WebsitesMisc/angelsflowers/`
+
+**Key files**:
+- Homepage: `/root/WebsitesMisc/angelsflowers/app/page.tsx`
+- Flowers page: `/root/WebsitesMisc/angelsflowers/app/flowers/page.tsx`
+- About page: `/root/WebsitesMisc/angelsflowers/app/about/page.tsx`
+- Contact page: `/root/WebsitesMisc/angelsflowers/app/contact/page.tsx`
+- Navbar: `/root/WebsitesMisc/angelsflowers/components/Navbar.tsx`
+- Footer: `/root/WebsitesMisc/angelsflowers/components/Footer.tsx`
+- Global styles: `/root/WebsitesMisc/angelsflowers/app/globals.css`
+- Tailwind config: `/root/WebsitesMisc/angelsflowers/tailwind.config.js`
+
+## Support & Resources
+
+- **Next.js Docs**: https://nextjs.org/docs
+- **React Docs**: https://react.dev
+- **Tailwind CSS**: https://tailwindcss.com/docs
+- **TypeScript**: https://www.typescriptlang.org/docs
+- **React Icons**: https://react-icons.github.io/react-icons/
+
+## Notes
+
+- All images currently use placeholder URLs from Unsplash
+- Contact form needs backend integration for production
+- Google Maps integration requires API key
+- Social media links need to be updated with actual URLs
+- Phone number (323) 123-4567 is placeholder - update everywhere
+
+## License
+
+Copyright 2025 Angel's Flowers. All rights reserved.
+
+---
+
+**Project Status**: ✅ Ready for development server
+**Production Ready**: After customization and real content addition
+**Last Updated**: 2025-11-10
diff --git a/QUICKSTART.md b/QUICKSTART.md
new file mode 100644
index 0000000..fa9f028
--- /dev/null
+++ b/QUICKSTART.md
@@ -0,0 +1,192 @@
+# Angel's Flowers - Quick Start Guide
+
+## Get Running in 3 Steps
+
+### Step 1: Install Dependencies (2-3 minutes)
+
+```bash
+cd /root/WebsitesMisc/angelsflowers
+npm install
+```
+
+This installs Next.js, React, TypeScript, Tailwind CSS, and all dependencies.
+
+### Step 2: Start the Development Server (10 seconds)
+
+```bash
+npm run dev
+```
+
+Open your browser to: **http://localhost:3000**
+
+### Step 3: Explore the Site
+
+You now have a fully functional website with:
+- Homepage with hero and featured flowers
+- Complete flowers catalog (14+ products)
+- About page with family story
+- Contact page with form and info
+
+## What You'll See
+
+### Homepage (/)
+- Beautiful hero section
+- "Why Choose Us" features
+- Featured flower collections
+- Family story preview
+- Call-to-action sections
+
+### Flowers Page (/flowers)
+- 14 different flower products
+- Ecuadorian roses collection
+- Mixed arrangements
+- Special occasion flowers
+- Detailed product cards with pricing
+
+### About Page (/about)
+- Family origin story
+- Company timeline (1995-2025)
+- Core values
+- Ecuador connection explanation
+- Team member profiles
+
+### Contact Page (/contact)
+- Working contact form
+- Business information
+- Map section
+- FAQ section
+- Social media links
+
+## Site Features
+
+### Design
+- Professional, modern design
+- Warm color scheme (pink/rose primary, green accents)
+- Elegant typography (Playfair Display + Inter)
+- High-quality placeholder images
+
+### Responsive
+- Mobile-first design
+- Works on phones, tablets, desktops
+- Touch-friendly navigation
+- Mobile hamburger menu
+
+### Performance
+- Fast loading with Next.js
+- Optimized fonts
+- Image optimization ready
+- Code splitting
+
+### SEO
+- Proper meta tags
+- Semantic HTML
+- Sitemap included
+- robots.txt configured
+
+## Next Steps After Running
+
+### 1. Customize Content
+See `SETUP.md` for detailed customization instructions.
+
+Quick updates needed:
+- Phone number: Search for `(323) 123-4567` and replace
+- Email: Search for `info@angelsflowers.com` and replace
+- Address: Update in Footer and Contact page
+
+### 2. Add Real Images
+- Create folder: `mkdir -p public/images`
+- Add your flower photos
+- Update image URLs in components
+
+### 3. Configure Integrations
+- Google Maps API (for contact page map)
+- Contact form backend (Formspree, EmailJS, or custom)
+- Google Analytics (optional)
+
+## File Structure Overview
+
+```
+/root/WebsitesMisc/angelsflowers/
+├── app/
+│ ├── page.tsx # Homepage
+│ ├── flowers/page.tsx # Flowers catalog
+│ ├── about/page.tsx # Our story
+│ ├── contact/page.tsx # Contact page
+│ ├── layout.tsx # Site layout
+│ └── globals.css # Styles
+├── components/
+│ ├── Navbar.tsx # Navigation
+│ └── Footer.tsx # Footer
+├── package.json # Dependencies
+└── tailwind.config.js # Design system
+```
+
+## Development Commands
+
+```bash
+# Start development server (with hot reload)
+npm run dev
+
+# Build for production
+npm run build
+
+# Start production server
+npm start
+
+# Run linter
+npm run lint
+```
+
+## Deployment
+
+### Quick Deploy to Vercel (Recommended)
+```bash
+npm i -g vercel
+vercel
+```
+
+### Or Deploy to Netlify
+1. Push code to GitHub
+2. Connect to Netlify
+3. Deploy automatically
+
+## Troubleshooting
+
+### Port 3000 Already in Use?
+```bash
+# Kill process on port 3000
+lsof -ti:3000 | xargs kill -9
+npm run dev
+```
+
+### Installation Issues?
+```bash
+# Clear and reinstall
+rm -rf node_modules
+npm install
+```
+
+### Need Help?
+- Check `README.md` for full documentation
+- Check `SETUP.md` for detailed setup
+- Check `PROJECT_SUMMARY.md` for complete overview
+
+## Technologies Used
+
+- **Next.js 14**: React framework with App Router
+- **React 18**: UI library
+- **TypeScript**: Type-safe JavaScript
+- **Tailwind CSS**: Utility-first styling
+- **React Icons**: Icon library
+
+## Contact & Support
+
+Built for Angel's Flowers - East Los Angeles
+
+For technical questions, see documentation files or Next.js docs:
+- https://nextjs.org/docs
+- https://tailwindcss.com/docs
+
+---
+
+**Ready to go!** Just run `npm install` and `npm run dev` to see your site.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8cd7235
--- /dev/null
+++ b/README.md
@@ -0,0 +1,135 @@
+# Angel's Flowers - Premium Ecuadorian Flowers
+
+A modern, professional website for Angel's Flowers - a family-run flower shop in East Los Angeles specializing in premium Ecuadorian roses and arrangements.
+
+## Features
+
+- **Modern Tech Stack**: Built with Next.js 14, React 18, TypeScript, and Tailwind CSS
+- **Responsive Design**: Mobile-first approach ensuring perfect display on all devices
+- **SEO Optimized**: Proper meta tags, semantic HTML, and optimized content
+- **Fast Performance**: Optimized images, code splitting, and modern best practices
+- **Accessible**: WCAG compliant with proper ARIA labels and keyboard navigation
+- **Professional Design**: Elegant color scheme inspired by Ecuadorian flowers
+
+## Pages
+
+1. **Homepage** - Hero section, featured flowers, family story preview, and CTAs
+2. **Flowers** - Complete catalog organized by category (roses, mixed arrangements, special occasions)
+3. **About/Our Story** - Family history, timeline, values, and Ecuadorian connection
+4. **Contact** - Contact form, business information, map, and FAQs
+
+## Getting Started
+
+### Prerequisites
+
+- Node.js 18+
+- npm or yarn
+
+### Installation
+
+1. Install dependencies:
+```bash
+npm install
+```
+
+2. Run the development server:
+```bash
+npm run dev
+```
+
+3. Open [http://localhost:3000](http://localhost:3000) in your browser
+
+### Build for Production
+
+```bash
+npm run build
+npm start
+```
+
+## Project Structure
+
+```
+angelsflowers/
+├── app/ # Next.js app directory
+│ ├── about/ # About page
+│ ├── contact/ # Contact page
+│ ├── flowers/ # Flowers catalog page
+│ ├── layout.tsx # Root layout with Navbar/Footer
+│ ├── page.tsx # Homepage
+│ └── globals.css # Global styles
+├── components/ # Reusable components
+│ ├── Navbar.tsx # Navigation component
+│ └── Footer.tsx # Footer component
+├── public/ # Static assets (add images here)
+└── package.json # Dependencies
+```
+
+## Customization
+
+### Colors
+
+The color scheme is defined in `tailwind.config.js`:
+- **Primary**: Pink/rose tones (customizable)
+- **Accent**: Green tones for foliage
+- **Warm**: Yellow tones for highlights
+
+### Images
+
+Replace placeholder images with real flower photos:
+1. Add high-quality images to `/public/images/`
+2. Update image URLs in page components
+3. Optimize images for web (recommended: WebP format, max 500KB per image)
+
+### Content
+
+Update business information in:
+- `/components/Footer.tsx` - Hours, address, contact info
+- `/app/contact/page.tsx` - Contact details, map coordinates
+- `/components/Navbar.tsx` - Phone number
+
+## Performance Optimizations
+
+- Image optimization with Next.js Image component
+- Code splitting and lazy loading
+- CSS optimization with Tailwind's purge
+- Font optimization with next/font
+
+## Deployment
+
+### Recommended Platforms
+
+1. **Vercel** (Easiest - made by Next.js creators)
+ ```bash
+ npm i -g vercel
+ vercel
+ ```
+
+2. **Netlify**
+ - Connect GitHub repository
+ - Build command: `npm run build`
+ - Publish directory: `.next`
+
+3. **Traditional Hosting**
+ ```bash
+ npm run build
+ # Upload .next, public, and package.json
+ # Run: npm start
+ ```
+
+## Browser Support
+
+- Chrome/Edge (latest 2 versions)
+- Firefox (latest 2 versions)
+- Safari (latest 2 versions)
+- Mobile browsers (iOS Safari, Chrome Mobile)
+
+## License
+
+Copyright 2025 Angel's Flowers. All rights reserved.
+
+## Support
+
+For questions or issues, contact the development team or refer to Next.js documentation:
+- [Next.js Documentation](https://nextjs.org/docs)
+- [React Documentation](https://react.dev)
+- [Tailwind CSS Documentation](https://tailwindcss.com/docs)
diff --git a/SETUP.md b/SETUP.md
new file mode 100644
index 0000000..acd88f6
--- /dev/null
+++ b/SETUP.md
@@ -0,0 +1,134 @@
+# Quick Setup Guide for Angel's Flowers Website
+
+## Step 1: Install Dependencies
+
+```bash
+cd /root/WebsitesMisc/angelsflowers
+npm install
+```
+
+This will install:
+- Next.js 14
+- React 18
+- TypeScript
+- Tailwind CSS
+- React Icons
+
+## Step 2: Start Development Server
+
+```bash
+npm run dev
+```
+
+The website will be available at [http://localhost:3000](http://localhost:3000)
+
+## Step 3: Customize Content
+
+### Update Business Information
+
+1. **Phone Number** (appears throughout the site):
+ - `/components/Navbar.tsx` - Line with phone number
+ - `/components/Footer.tsx` - Contact info section
+ - `/app/contact/page.tsx` - Contact details
+
+2. **Address**:
+ - `/components/Footer.tsx` - Footer address
+ - `/app/contact/page.tsx` - Contact page address
+
+3. **Business Hours**:
+ - `/components/Footer.tsx` - Footer hours
+ - `/app/contact/page.tsx` - Contact page hours
+
+4. **Email**:
+ - `/components/Footer.tsx` - Footer email
+ - `/app/contact/page.tsx` - Contact form
+
+### Add Real Images
+
+Replace placeholder images with your flower photos:
+
+1. Create an images folder:
+ ```bash
+ mkdir -p public/images
+ ```
+
+2. Add your images to `public/images/`
+
+3. Update image URLs in:
+ - `/app/page.tsx` - Homepage hero and featured flowers
+ - `/app/flowers/page.tsx` - Product catalog
+ - `/app/about/page.tsx` - Family photos
+
+### Recommended Image Sizes
+
+- Hero images: 2000x1200px (landscape)
+- Product photos: 800x800px (square)
+- Portrait photos: 600x800px
+- Optimize all images for web (WebP format recommended)
+
+## Step 4: Build for Production
+
+```bash
+npm run build
+npm start
+```
+
+## Step 5: Deploy
+
+### Option A: Vercel (Recommended)
+
+1. Install Vercel CLI:
+ ```bash
+ npm i -g vercel
+ ```
+
+2. Deploy:
+ ```bash
+ vercel
+ ```
+
+3. Follow the prompts
+
+### Option B: Netlify
+
+1. Push code to GitHub
+2. Connect repository to Netlify
+3. Build settings:
+ - Build command: `npm run build`
+ - Publish directory: `.next`
+
+## Troubleshooting
+
+### Port already in use
+```bash
+# Kill process on port 3000
+lsof -ti:3000 | xargs kill -9
+npm run dev
+```
+
+### Clear cache and reinstall
+```bash
+rm -rf node_modules .next
+npm install
+npm run dev
+```
+
+### TypeScript errors
+The project uses TypeScript for type safety. If you see errors:
+- Make sure all dependencies are installed
+- Run `npm run build` to check for issues
+- Check that Node.js version is 18 or higher
+
+## Next Steps
+
+1. Add Google Maps integration to contact page
+2. Set up contact form backend (Formspree, EmailJS, or custom API)
+3. Add Google Analytics for tracking
+4. Set up social media accounts and update links
+5. Consider adding e-commerce functionality (Shopify, Stripe)
+
+## Need Help?
+
+- Next.js docs: https://nextjs.org/docs
+- Tailwind CSS docs: https://tailwindcss.com/docs
+- React Icons: https://react-icons.github.io/react-icons/
diff --git a/SITE_STRUCTURE.md b/SITE_STRUCTURE.md
new file mode 100644
index 0000000..5b2091b
--- /dev/null
+++ b/SITE_STRUCTURE.md
@@ -0,0 +1,409 @@
+# Angel's Flowers - Site Structure
+
+## Navigation Hierarchy
+
+```
+Angel's Flowers Website
+│
+├── Home (/)
+│ ├── Hero Section
+│ ├── Why Choose Us (4 features)
+│ ├── Featured Collections (3 products)
+│ ├── Family Story Preview
+│ └── Call-to-Action
+│
+├── Flowers (/flowers)
+│ ├── Ecuadorian Roses
+│ │ ├── Classic Red Roses
+│ │ ├── White Rose Elegance
+│ │ ├── Pink Perfection
+│ │ ├── Yellow Sunshine
+│ │ ├── Rainbow Rose Collection
+│ │ └── Lavender Dreams
+│ │
+│ ├── Mixed Arrangements
+│ │ ├── Garden Paradise
+│ │ ├── Spring Meadow
+│ │ ├── Tropical Sunset
+│ │ └── Rustic Romance
+│ │
+│ └── Special Occasions
+│ ├── Wedding Collection
+│ ├── Sympathy Arrangements
+│ ├── Corporate Events
+│ └── Birthday Celebration
+│
+├── Our Story (/about)
+│ ├── Origin Story
+│ ├── Timeline (1995-2025)
+│ ├── Our Values (4 core values)
+│ ├── Ecuador Connection
+│ └── Meet the Family
+│
+└── Contact (/contact)
+ ├── Contact Information
+ ├── Contact Form
+ ├── Map & Directions
+ └── FAQs
+
+```
+
+## Component Architecture
+
+```
+Layout (Wrapper for all pages)
+│
+├── Navbar (Sticky)
+│ ├── Logo
+│ ├── Navigation Links
+│ ├── Phone CTA Button
+│ └── Mobile Menu (Hamburger)
+│
+├── Page Content (Dynamic)
+│ └── [Individual page components]
+│
+└── Footer
+ ├── About Section
+ ├── Quick Links
+ ├── Contact Info
+ ├── Business Hours
+ └── Social Media Links
+```
+
+## User Flow Diagram
+
+```
+Landing on Homepage
+│
+├─→ Browse Featured Flowers
+│ ├─→ Click "View All Flowers"
+│ │ └─→ Flowers Page
+│ │ └─→ Call to Order
+│ │
+│ └─→ Click "Call to Order"
+│ └─→ Phone Call
+│
+├─→ Learn About Family Story
+│ └─→ Click "Read Our Full Story"
+│ └─→ About Page
+│ └─→ Contact CTA
+│
+└─→ Contact Directly
+ ├─→ Click "Call Us"
+ │ └─→ Phone Call
+ │
+ └─→ Click "Visit Us"
+ └─→ Contact Page
+ ├─→ Fill Form
+ ├─→ View Map
+ └─→ Get Directions
+```
+
+## Page Component Structure
+
+### Homepage
+```
+Hero Section (Full screen)
+├── Background Image with Overlay
+├── Heading + Tagline
+└── 2 CTA Buttons
+
+Why Choose Us
+├── Section Heading
+└── 4 Feature Cards
+ ├── Icon
+ ├── Title
+ └── Description
+
+Featured Collections
+├── Section Heading
+└── 3 Product Cards
+ ├── Image
+ ├── Name & Price
+ ├── Description
+ └── View Link
+
+Family Story Preview
+├── Image (Left)
+└── Content (Right)
+ ├── Heading
+ ├── Story Text
+ └── CTA Button
+
+Call-to-Action Banner
+├── Heading
+├── Description
+└── 2 CTA Buttons
+```
+
+### Flowers Page
+```
+Hero Section
+├── Page Title
+└── Description
+
+For Each Category:
+├── Category Heading
+└── Product Grid (3 columns)
+ └── Product Card
+ ├── Image (hover zoom effect)
+ ├── Name
+ ├── Price
+ ├── Description
+ ├── Feature List
+ └── Call-to-Order Button
+
+CTA Section
+├── Heading
+├── Description
+└── Phone CTA Button
+```
+
+### About Page
+```
+Hero Section
+├── Page Title
+└── Description
+
+Origin Story
+├── Story Content (Left)
+└── Image (Right)
+
+Timeline
+└── 5 Milestones
+ ├── Year
+ ├── Title
+ └── Description
+
+Values Section
+└── 4 Value Cards
+ ├── Icon
+ ├── Title
+ └── Description
+
+Ecuador Connection
+├── Image (Left)
+└── Content (Right)
+ ├── Heading
+ ├── Explanation
+ └── Bullet Points
+
+Team Section
+└── 3 Team Members
+ ├── Photo
+ ├── Name
+ ├── Role
+ └── Bio
+
+CTA Section
+```
+
+### Contact Page
+```
+Hero Section
+
+Contact Grid
+├── Contact Cards (Left)
+│ ├── Address Card
+│ ├── Phone Card
+│ ├── Email Card
+│ ├── Hours Card
+│ └── Social Links
+│
+└── Contact Form (Right)
+ ├── Name Field
+ ├── Email Field
+ ├── Phone Field
+ ├── Occasion Dropdown
+ ├── Message Textarea
+ └── Submit Button
+
+Map Section
+├── Map Display
+└── 3 Info Cards
+ ├── Parking Info
+ ├── Accessibility
+ └── Transit Info
+
+FAQ Section
+└── 5 Q&A Pairs
+```
+
+## Responsive Breakpoints
+
+```
+Mobile (< 640px)
+├── Single column layouts
+├── Stacked navigation (hamburger menu)
+├── Larger touch targets
+└── Simplified hero
+
+Tablet (640px - 1024px)
+├── 2-column grids
+├── Visible navigation
+└── Optimized images
+
+Desktop (> 1024px)
+├── 3-4 column grids
+├── Full navigation bar
+├── Larger hero sections
+└── Side-by-side content
+```
+
+## Color Coding by Section
+
+```
+Primary Pink/Rose (#d03862)
+├── Used for: Buttons, links, accents
+└── Represents: Roses, love, warmth
+
+Accent Green (#16a34a)
+├── Used for: Secondary elements, foliage
+└── Represents: Growth, nature, freshness
+
+Warm Yellow (#eab308)
+├── Used for: Highlights, special callouts
+└── Represents: Sunshine, Ecuador, energy
+
+Neutral Gray
+├── Used for: Text, backgrounds
+└── Represents: Elegance, sophistication
+```
+
+## Call-to-Action Hierarchy
+
+### Primary CTAs (Conversion Focus)
+1. "Call to Order" buttons (throughout site)
+2. "Browse Our Flowers" (homepage hero)
+3. Contact form submit (contact page)
+
+### Secondary CTAs (Engagement)
+1. "View All Flowers" (homepage)
+2. "Read Our Full Story" (homepage)
+3. "Visit Us in East LA" (multiple pages)
+
+### Tertiary CTAs (Information)
+1. Navigation links
+2. Social media links
+3. Map/directions links
+
+## SEO Structure
+
+```
+Site-wide Elements
+├── Title Tag Template: "[Page] | Angel's Flowers - East LA"
+├── Meta Description Template
+├── Structured Data (JSON-LD)
+│ ├── LocalBusiness
+│ ├── Organization
+│ └── Product (for flowers)
+└── Open Graph Tags
+
+Per-Page Optimization
+├── Homepage: Brand + Location keywords
+├── Flowers: Product + Ecuadorian keywords
+├── About: Story + family + Ecuador keywords
+└── Contact: Location + contact keywords
+```
+
+## Conversion Funnel
+
+```
+Stage 1: Awareness
+├── Landing on homepage
+├── Seeing beautiful flower images
+└── Reading about Ecuadorian quality
+
+Stage 2: Interest
+├── Browsing flower catalog
+├── Reading family story
+└── Understanding unique value
+
+Stage 3: Consideration
+├── Viewing specific products
+├── Checking prices
+└── Reading contact information
+
+Stage 4: Action
+├── Clicking call button
+├── Filling contact form
+└── Visiting physical store
+
+Stage 5: Retention
+├── Social media follow
+├── Newsletter signup (future)
+└── Repeat orders
+```
+
+## Technical Stack Visualization
+
+```
+Frontend Layer
+├── React 18 (UI Components)
+├── Next.js 14 (Framework)
+└── TypeScript (Type Safety)
+
+Styling Layer
+├── Tailwind CSS (Utility Classes)
+├── Custom CSS (Global Styles)
+└── Google Fonts (Typography)
+
+Build Layer
+├── Next.js Compiler
+├── PostCSS (CSS Processing)
+└── TypeScript Compiler
+
+Deployment Layer
+├── Vercel (Recommended)
+├── Netlify (Alternative)
+└── Traditional Hosting (Alternative)
+```
+
+## File Size Targets
+
+```
+Page Load Performance Goals
+├── Homepage: < 500KB total
+├── Flowers Page: < 800KB total
+├── About Page: < 600KB total
+└── Contact Page: < 400KB total
+
+Individual Assets
+├── Hero Images: < 300KB each
+├── Product Images: < 150KB each
+├── Team Photos: < 100KB each
+└── CSS Bundle: < 50KB
+```
+
+## Accessibility Tree
+
+```
+Website (role: document)
+│
+├── Navigation (role: navigation)
+│ ├── Logo (role: link)
+│ ├── Menu Items (role: menuitem)
+│ └── Phone Button (role: button)
+│
+├── Main Content (role: main)
+│ ├── Sections (role: region)
+│ ├── Headings (h1-h6)
+│ ├── Images (alt text)
+│ └── Forms (labels + inputs)
+│
+└── Footer (role: contentinfo)
+ ├── Links (role: link)
+ └── Contact Info (role: list)
+```
+
+---
+
+**All files located in**: `/root/WebsitesMisc/angelsflowers/`
+
+**Quick access**:
+- Homepage: `/root/WebsitesMisc/angelsflowers/app/page.tsx`
+- Flowers: `/root/WebsitesMisc/angelsflowers/app/flowers/page.tsx`
+- About: `/root/WebsitesMisc/angelsflowers/app/about/page.tsx`
+- Contact: `/root/WebsitesMisc/angelsflowers/app/contact/page.tsx`
+- Navbar: `/root/WebsitesMisc/angelsflowers/components/Navbar.tsx`
+- Footer: `/root/WebsitesMisc/angelsflowers/components/Footer.tsx`
diff --git a/USER_RESEARCH.md b/USER_RESEARCH.md
new file mode 100644
index 0000000..17a5c07
--- /dev/null
+++ b/USER_RESEARCH.md
@@ -0,0 +1,731 @@
+# Angel's Flowers - User Research & Personas
+## Understanding Our Community & Customers
+
+---
+
+## RESEARCH METHODOLOGY
+
+### Primary Research Methods
+1. **Customer Interviews** (In-store and phone)
+ - 20-30 existing customers
+ - 10-15 potential customers who've never visited
+ - 5-10 competitors' customers
+
+2. **Observational Studies**
+ - In-store behavior analysis
+ - Peak hours and customer flow
+ - Decision-making process observation
+
+3. **Surveys**
+ - Email survey to existing customer database
+ - Social media surveys (Instagram, Facebook)
+ - Community feedback forms
+
+4. **Competitive Analysis**
+ - 800flowers.com (national leader)
+ - Local competitors in East LA
+ - Online-only flower delivery services
+ - Traditional brick-and-mortar florists
+
+5. **Analytics Review** (Post-Launch)
+ - Website behavior tracking
+ - Heat maps and click tracking
+ - Conversion funnel analysis
+ - Mobile vs desktop usage patterns
+
+---
+
+## TARGET AUDIENCE SEGMENTATION
+
+### Geographic Focus
+- **Primary**: East Los Angeles, CA (5-mile radius)
+- **Secondary**: Greater LA County (10-mile radius)
+- **Tertiary**: Southern California (potential delivery expansion)
+
+### Demographic Breakdown
+- **Age Range**: 25-65 years old (primary), with skew toward 35-55
+- **Gender**: 65% female, 35% male (based on typical floral purchase patterns)
+- **Income**: $40,000 - $100,000+ household income
+- **Cultural Background**: Diverse, with significant Latino/Hispanic community representation
+- **Family Status**: Married, in relationships, or have strong family connections
+
+### Psychographic Traits
+- Value personal connections and family
+- Appreciate quality and authenticity
+- Support local, family-owned businesses
+- Celebrate cultural traditions and milestones
+- Seek meaningful gift-giving experiences
+- Balance price consciousness with quality expectations
+
+---
+
+## USER PERSONAS
+
+### Persona 1: Maria the Milestone Celebrator
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ [Photo: Smiling woman in her 40s] │
+│ │
+│ Maria Garcia │
+│ Age: 42 │
+│ Location: Montebello, CA (near East LA) │
+│ Occupation: Elementary School Teacher │
+│ Family: Married, 2 children (ages 8, 12) │
+│ Tech Comfort: Moderate (uses smartphone daily) │
+└─────────────────────────────────────────────────────────────┘
+
+BACKGROUND
+Maria grew up in East LA and has strong ties to her extended family. She's the unofficial "party planner" for family gatherings and always wants celebrations to feel special and memorable.
+
+GOALS
+• Find beautiful, high-quality flowers for family celebrations
+• Support local businesses in her community
+• Create memorable moments for birthdays, anniversaries, and holidays
+• Get reliable delivery for relatives she can't visit in person
+• Stay within budget while still impressing loved ones
+
+FRUSTRATIONS
+• Online flower sites show pictures that don't match what's delivered
+• Big corporate flower companies feel impersonal
+• Difficult to know if flowers are actually fresh
+• Last-minute needs aren't always accommodated
+• Hard to find unique arrangements (everything looks generic)
+
+MOTIVATIONS
+• Family is everything - celebrations matter
+• Personal touch and relationships with vendors
+• Quality that justifies the price
+• Convenience when life gets busy
+
+BEHAVIORS
+• Plans celebrations 1-2 weeks in advance (but sometimes needs last-minute)
+• Researches online but appreciates being able to call or visit in person
+• Reads reviews before trying new services
+• Shares photos of flowers on Facebook/Instagram
+• Loyal to businesses that treat her well
+• Refers friends and family when she finds quality service
+
+TECHNOLOGY USE
+• Smartphone: iPhone, uses daily for texting, social media, photos
+• Social Media: Active on Facebook, Instagram, WhatsApp groups
+• Shopping: Mix of online and in-person; prefers online for convenience
+• Payment: Credit cards, PayPal, sometimes cash in-store
+• Communication: Prefers text or phone call over email
+
+USER JOURNEY
+1. Realizes daughter's birthday is in 2 weeks
+2. Searches "flower delivery East LA" on phone during lunch break
+3. Finds Angel's Flowers website, browses birthday options
+4. Sees family story, feels connection to local business
+5. Calls to ask about customization options
+6. Places order online after phone consultation
+7. Receives text confirmation and delivery updates
+8. Takes photo of delivered flowers, posts on Instagram
+9. Calls to thank them and saves number for next time
+
+QUOTE
+"I want flowers that show how much I care, not just something generic from a catalog. Supporting a family business makes it even more special."
+```
+
+---
+
+### Persona 2: David the Romantic Gifter
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ [Photo: Professional man in his 30s] │
+│ │
+│ David Chen │
+│ Age: 34 │
+│ Location: Alhambra, CA │
+│ Occupation: Software Engineer │
+│ Relationship: Dating seriously (1.5 years) │
+│ Tech Comfort: High (works in tech) │
+└─────────────────────────────────────────────────────────────┘
+
+BACKGROUND
+David is tech-savvy and busy with work. He wants to be a thoughtful partner but often realizes he needs flowers with short notice. He values quality and presentation and is willing to pay more for premium arrangements.
+
+GOALS
+• Order flowers quickly and easily (mobile-friendly)
+• Impress girlfriend with unique, high-quality arrangements
+• Same-day or next-day delivery options
+• Clear photos and descriptions of what he's buying
+• Reliable delivery to girlfriend's workplace
+• Save favorites/reorder easily
+
+FRUSTRATIONS
+• Generic arrangements that don't feel special
+• Complicated checkout processes on mobile
+• Uncertainty about delivery timing
+• Past experiences with wilted flowers from big companies
+• Feeling like just another transaction
+• Hidden fees at checkout
+
+MOTIVATIONS
+• Expressing love through thoughtful gestures
+• Maintaining relationship through consistent effort
+• Quality matters more than price (within reason)
+• Convenience fits his busy schedule
+
+BEHAVIORS
+• Searches on smartphone (usually at work or commuting)
+• Reads reviews and compares options quickly
+• Appreciates detailed product photos and descriptions
+• Uses Apple Pay or saved credit cards for fast checkout
+• Sets reminders for important dates (but sometimes forgets)
+• Expects business-level service and professionalism
+
+TECHNOLOGY USE
+• Smartphone: iPhone Pro, primary device for everything
+• Desktop: Uses for detailed research or complex tasks
+• Social Media: Instagram, LinkedIn (not much Facebook)
+• Shopping: Heavily online, expects Amazon-level UX
+• Payment: Apple Pay, credit cards saved in password manager
+• Communication: Prefers text, email, or live chat over phone calls
+
+USER JOURNEY
+1. Realizes anniversary is tomorrow (sets reminder but forgot)
+2. Googles "same day flower delivery los angeles" on phone during meeting
+3. Finds Angel's Flowers, sees "same-day delivery available"
+4. Quickly browses options, filters by "premium" and "romantic"
+5. Reads product details and reviews
+6. Uses Apple Pay for one-click checkout
+7. Receives immediate confirmation email and text
+8. Gets text when flowers are delivered with photo proof
+9. Girlfriend sends him photo - she loves them!
+10. Bookmarks site and signs up for anniversary reminders
+
+QUOTE
+"I need flowers that are as impressive as a five-star restaurant experience, but ordered as easily as Uber Eats. Quality and convenience matter."
+```
+
+---
+
+### Persona 3: Carmen the Event Coordinator
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ [Photo: Energetic woman in her 50s] │
+│ │
+│ Carmen Rodriguez │
+│ Age: 54 │
+│ Location: Boyle Heights, CA │
+│ Occupation: Event Planner (weddings/quinceañeras) │
+│ Business: Small business owner, 15 years experience │
+│ Tech Comfort: Moderate-High (business apps, social media) │
+└─────────────────────────────────────────────────────────────┘
+
+BACKGROUND
+Carmen has been planning events in the East LA community for over 15 years. She has high standards and a reputation to maintain. She needs reliable vendors she can trust for her clients' special days.
+
+GOALS
+• Find reliable florist for large event orders
+• Establish business relationship with consistent quality
+• Get wholesale/bulk pricing for events
+• Custom arrangements that match event themes
+• Ability to schedule multiple deliveries to event venues
+• Professional invoicing and business terms
+
+FRUSTRATIONS
+• Florists who can't handle large orders
+• Inconsistent quality between small and large orders
+• Poor communication about order status
+• Inability to see/approve arrangements before delivery
+• Vendors who don't understand cultural event needs (quinceañeras)
+• Hidden costs that affect her budget planning
+
+MOTIVATIONS
+• Maintaining reputation with flawless events
+• Building long-term vendor relationships
+• Supporting local businesses who understand the community
+• Offering unique value to clients
+• Growing her event planning business
+
+BEHAVIORS
+• Needs both online ordering portal and direct phone contact
+• Places orders weeks/months in advance
+• Requires detailed proposals and invoices
+• Brings photos of desired arrangements for reference
+• Needs flexibility for last-minute client changes
+• Recommends vendors to other planners
+• Active on Instagram showcasing events
+
+TECHNOLOGY USE
+• Smartphone & Tablet: iPad for showing clients options on-site
+• Desktop: Uses for detailed planning and proposals
+• Social Media: Instagram (portfolio), Facebook (client groups)
+• Shopping: Mix of in-person consultations and online ordering
+• Payment: Business credit card, sometimes requires NET-30 terms
+• Communication: Phone calls for urgent, email for documentation
+
+USER JOURNEY
+1. Client books quinceañera for December
+2. Searches for florists specializing in cultural events
+3. Finds Angel's Flowers via Instagram, sees similar events
+4. Calls to discuss large order (centerpieces, bouquets, church flowers)
+5. Schedules in-person consultation at shop
+6. Reviews samples and pricing, receives detailed proposal
+7. Makes deposit online, sets up payment plan
+8. Receives regular updates via email and text
+9. Approves mock-up photos of arrangements
+10. Day-of delivery to venue and church on schedule
+11. Posts event photos on Instagram, tags Angel's Flowers
+12. Becomes repeat customer for future events
+
+QUOTE
+"I need a florist who understands our community's celebrations and can deliver consistently beautiful work. When my reputation is on the line, I need a partner I can trust."
+```
+
+---
+
+### Persona 4: Robert the Sympathy Sender
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ [Photo: Thoughtful man in his 60s] │
+│ │
+│ Robert Thompson │
+│ Age: 61 │
+│ Location: Monterey Park, CA │
+│ Occupation: Retired (former postal worker) │
+│ Family: Widower, 3 adult children │
+│ Tech Comfort: Low-Moderate (uses email, basic web) │
+└─────────────────────────────────────────────────────────────┘
+
+BACKGROUND
+Robert is active in his church and community. He often needs to send sympathy flowers to funerals or hospitals for friends and fellow church members. He values dignity, appropriateness, and compassion.
+
+GOALS
+• Send respectful, appropriate sympathy arrangements
+• Easy way to include personal condolence message
+• Direct delivery to funeral homes or homes
+• Confirmation that flowers were delivered respectfully
+• Guidance on what's appropriate for different situations
+• Ability to call and speak with a person for sensitive orders
+
+FRUSTRATIONS
+• Websites that don't explain what's appropriate for funerals
+• Impersonal checkout process for sensitive occasions
+• No one to talk to when he has questions
+• Difficulty typing long messages on smartphone
+• Uncertainty about delivery to funeral homes
+• Generic arrangements that don't feel respectful enough
+
+MOTIVATIONS
+• Honoring the deceased and supporting grieving families
+• Maintaining relationships with community and church
+• Following proper etiquette and showing respect
+• Being a reliable friend in difficult times
+
+BEHAVIORS
+• Prefers to call and speak with someone for sympathy orders
+• May browse website first to see options
+• Wants expert guidance on appropriate choices
+• Reads every detail carefully
+• Appreciates follow-up confirmation call or email
+• Sends handwritten thank-you notes to businesses
+• Tells friends about businesses that treat him with respect
+
+TECHNOLOGY USE
+• Computer: Desktop PC at home, uses for email and basic browsing
+• Smartphone: Android, mostly for calls and texts
+• Social Media: Facebook to stay connected with family
+• Shopping: Prefers in-person or phone orders, but learning online
+• Payment: Credit card (reads numbers over phone) or in-store
+• Communication: Strongly prefers phone calls
+
+USER JOURNEY
+1. Learns of friend's passing through church
+2. Wants to send flowers to funeral home
+3. Looks up local florists online, finds Angel's Flowers
+4. Browses sympathy section on website
+5. Calls shop to ask for guidance on appropriate arrangement
+6. Speaks with staff member who helps select tasteful option
+7. Provides delivery details and dictates card message over phone
+8. Receives email confirmation (also reads it to him over phone)
+9. Gets call confirming delivery to funeral home
+10. Receives thank-you note from family, appreciates the quality
+11. Saves number in phone for future needs
+12. Recommends to church community
+
+QUOTE
+"When someone is grieving, the flowers need to show that you care. I need to work with people who understand that, not just a website."
+```
+
+---
+
+### Persona 5: Sophia the Social Media Influencer
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ [Photo: Stylish young woman in her 20s] │
+│ │
+│ Sophia Martinez │
+│ Age: 27 │
+│ Location: Downtown LA (family in East LA) │
+│ Occupation: Social Media Content Creator / Lifestyle Brand │
+│ Following: 45K Instagram, 20K TikTok │
+│ Tech Comfort: Expert (digital native) │
+└─────────────────────────────────────────────────────────────┘
+
+BACKGROUND
+Sophia creates lifestyle content focused on LA living, supporting local businesses, and celebrating Latino culture. She has influence with younger demographics and can drive significant awareness for businesses she features.
+
+GOALS
+• Discover unique, photogenic flower arrangements
+• Support and showcase local Latino-owned businesses
+• Create engaging content for her followers
+• Partner with brands that align with her values
+• Get flowers for personal use and content creation
+• Build authentic business relationships
+
+FRUSTRATIONS
+• Generic arrangements that don't photograph well
+• Businesses that don't understand influencer partnerships
+• Difficulty finding "hidden gem" local businesses
+• Lack of behind-the-scenes content opportunities
+• Brands that don't value social media exposure
+
+MOTIVATIONS
+• Creating beautiful, authentic content
+• Supporting community and cultural representation
+• Building her personal brand
+• Educating followers about local businesses
+• Being a trendsetter and tastemaker
+
+BEHAVIORS
+• Discovers businesses through Instagram hashtags and geotags
+• Takes extensive photos/videos of products
+• Stories and posts about favorite local spots
+• Engages heavily with brands on social media
+• Expects responsive social media interaction
+• Creates professional-quality content
+• Shares with permission and proper tagging
+
+TECHNOLOGY USE
+• Smartphone: iPhone Pro Max with professional camera
+• Apps: Instagram, TikTok, Lightroom, VSCO
+• Social Media: Multi-platform presence, daily posts
+• Shopping: Exclusively online, mobile-first
+• Payment: Apple Pay, credit cards
+• Communication: Instagram DMs, email for business
+
+USER JOURNEY
+1. Sees Angel's Flowers tagged in friend's Instagram story
+2. Explores Instagram feed, loves the aesthetic and family story
+3. DMs asking about content collaboration
+4. Arranges to visit shop for behind-the-scenes content
+5. Orders arrangement for personal use
+6. Creates Instagram Reel about Ecuadorian flower quality
+7. Posts stories about family business and arranging process
+8. Shares discount code with followers
+9. Tracks engagement and conversion from her posts
+10. Becomes brand ambassador, features regularly
+11. Drives significant young customer traffic to business
+
+QUOTE
+"I love finding authentic local businesses with great stories to share. My followers trust my recommendations, and I only feature brands I genuinely love."
+```
+
+---
+
+## KEY USER INSIGHTS
+
+### Cross-Persona Themes
+
+1. **Trust & Authenticity**
+ - All personas value genuine, family-owned business story
+ - Personal connection matters across demographics
+ - Reviews and social proof are critical for decision-making
+
+2. **Quality Concerns**
+ - Past bad experiences with big corporate flower companies
+ - "What you see is what you get" is essential
+ - Fresh, long-lasting flowers justify higher prices
+
+3. **Convenience Requirements**
+ - Mobile-friendly experience is non-negotiable
+ - Multiple contact methods needed (call, text, online, in-person)
+ - Same-day delivery is a competitive advantage
+
+4. **Cultural Sensitivity**
+ - Understanding Latino/Hispanic cultural celebrations matters
+ - Bilingual support would be beneficial
+ - Community connection is a unique selling proposition
+
+5. **Emotional Significance**
+ - Flowers are never "just flowers" - they carry meaning
+ - Customers want to feel their purchase matters
+ - Personal touches make memorable experiences
+
+---
+
+## USER NEEDS HIERARCHY
+
+### Must-Have (Core Needs)
+- Clear, accurate product photos
+- Transparent pricing (no hidden fees)
+- Reliable delivery with tracking
+- Mobile-responsive website
+- Easy checkout process
+- Phone contact option
+- Same-day delivery availability
+
+### Should-Have (Important but not critical)
+- Customer reviews and ratings
+- Gift message customization
+- Order history and reordering
+- Email/SMS notifications
+- Product filtering (price, color, occasion)
+- Care instructions included
+- Social media integration
+
+### Nice-to-Have (Differentiators)
+- Behind-the-scenes content about Ecuadorian flowers
+- Video of arrangement process
+- Virtual consultation scheduling
+- Subscription services for regular orders
+- Loyalty/rewards program
+- Live chat support
+- Augmented reality preview
+
+---
+
+## ACCESSIBILITY CONSIDERATIONS
+
+### Language
+- **Primary**: English
+- **Secondary**: Spanish (significant portion of East LA community)
+- Consider bilingual option or Spanish version of site
+
+### Literacy Levels
+- Clear, simple language (avoid flowery jargon)
+- Visual-heavy design (rely less on text)
+- Iconography for universal understanding
+
+### Age Range
+- Large, readable fonts for older users (60+)
+- Intuitive navigation for less tech-savvy users
+- But maintain modern aesthetic for younger users
+
+### Economic Diversity
+- Clear price ranges for different budgets
+- "Under $50" options highly visible
+- No judgment in language about budget choices
+
+### Disability Considerations
+- WCAG 2.1 AA compliance minimum
+- Screen reader friendly
+- Keyboard navigation
+- High contrast options
+- Alternative text for all images
+
+---
+
+## COMPETITIVE ANALYSIS SUMMARY
+
+### National Leader: 800flowers.com
+
+**Strengths:**
+- Polished, professional website
+- Extensive product catalog
+- Reliable national delivery network
+- Strong brand recognition
+- Smooth checkout process
+- Clear product filtering
+
+**Weaknesses:**
+- Impersonal, corporate feel
+- Generic arrangements
+- Quality inconsistency (uses local florists)
+- Higher prices
+- No local connection or story
+- Delivery fees and hidden costs
+
+**Opportunities for Angel's Flowers:**
+- Emphasize family story and local roots
+- Highlight Ecuadorian flower quality advantage
+- Offer personalization and customization
+- Build personal relationships with customers
+- Competitive pricing with transparent costs
+- Faster local delivery
+
+---
+
+### Local Competitors Analysis
+
+**Typical Strengths:**
+- Established local presence
+- Personal relationships with regular customers
+- Understanding of community needs
+- Often bilingual staff
+
+**Typical Weaknesses:**
+- Outdated or no website
+- Poor online ordering experience
+- Limited social media presence
+- No same-day online ordering
+- Cash/in-person only payments
+- No delivery tracking
+
+**Opportunities for Angel's Flowers:**
+- Modern, beautiful website (match 800flowers quality)
+- Maintain personal touch (match local competitors)
+- Best of both worlds: tech + personal service
+- Showcase Ecuadorian differentiation (unique position)
+
+---
+
+## USABILITY TESTING PLAN
+
+### Pre-Launch Testing
+
+**Test Objectives:**
+1. Can users find products that match their occasion?
+2. Is the checkout process intuitive and quick?
+3. Do users understand the family story and Ecuadorian advantage?
+4. Are mobile and desktop experiences equally smooth?
+5. Can users easily contact the shop if needed?
+
+**Test Participants:** (5-8 users per round)
+- Mix of personas (at least one from each primary persona)
+- Mix of tech comfort levels
+- Age diversity (25-65)
+- Mix of desktop and mobile testers
+
+**Test Scenarios:**
+1. "Your sister's birthday is next week. Find and order appropriate flowers under $75."
+2. "You need sympathy flowers delivered to a funeral home tomorrow. Complete the order."
+3. "Browse the site and explain what makes this flower shop different from others."
+4. "You want to call the shop to ask a question. How would you find the contact information?"
+5. "Add a greeting card message to your order and schedule delivery."
+
+**Success Metrics:**
+- Task completion rate: >80%
+- Time to complete purchase: <3 minutes
+- User satisfaction rating: >4/5
+- Error rate: <10%
+- Would recommend to friend: >90%
+
+---
+
+### Post-Launch Analytics
+
+**Key Metrics to Track:**
+
+**Engagement Metrics:**
+- Pages per session (target: >4)
+- Average session duration (target: >2 minutes)
+- Bounce rate (target: <40%)
+- Return visitor rate (target: >30% within 3 months)
+
+**Conversion Metrics:**
+- Add to cart rate (target: >15%)
+- Cart abandonment rate (target: <60%)
+- Checkout completion rate (target: >70%)
+- Overall conversion rate (target: >3%)
+
+**User Behavior:**
+- Most viewed products
+- Most popular occasions
+- Price range preferences
+- Peak browsing times
+- Mobile vs desktop conversion rates
+
+**Customer Satisfaction:**
+- Net Promoter Score (target: >50)
+- Customer reviews/ratings (target: >4.5/5)
+- Contact form submissions
+- Phone call conversion rates
+
+---
+
+## RECOMMENDATIONS FOR MVP
+
+### Phase 1 Features (Must-Have for Launch)
+1. Homepage with hero, featured products, family story
+2. Product listing pages with filtering
+3. Product detail pages with add to cart
+4. Shopping cart
+5. Checkout flow (guest checkout enabled)
+6. Mobile responsive design
+7. Contact page with phone/email/location
+8. About Us page with family story
+
+### Phase 2 Features (3-6 months post-launch)
+1. User accounts and order history
+2. Reviews and ratings system
+3. Customer testimonials section
+4. Expanded gallery/portfolio
+5. Blog with flower care tips
+6. Newsletter subscription
+7. Social media integration (Instagram feed)
+8. Live chat support
+
+### Phase 3 Features (6-12 months post-launch)
+1. Loyalty/rewards program
+2. Subscription services
+3. Virtual consultation booking
+4. Spanish language version
+5. Advanced personalization
+6. Corporate accounts program
+7. Event planning services page
+8. Behind-the-scenes video content
+
+---
+
+## CONTENT STRATEGY RECOMMENDATIONS
+
+### Voice & Tone
+- **Warm & Personal**: Like talking to a family friend
+- **Professional but Approachable**: Knowledgeable without being pretentious
+- **Culturally Aware**: Respectful of diverse backgrounds
+- **Authentic**: Honest about story, process, and products
+- **Celebratory**: Emphasis on joy and special moments
+
+### Content Needs
+
+**Product Descriptions:**
+- 100-150 words per product
+- Focus on benefits, not just features
+- Include flower types, colors, sizes
+- Mention vase life and care
+- Suggest appropriate occasions
+- Storytelling element (why special)
+
+**Educational Content:**
+- Flower care guides
+- Occasion-specific recommendations
+- Ecuador flower facts
+- Seasonal availability information
+- Arrangement style explanations
+
+**Brand Storytelling:**
+- Detailed family history page
+- Individual family member profiles
+- Behind-the-scenes content
+- Customer success stories
+- Community involvement highlights
+
+---
+
+## CONCLUSION
+
+Angel's Flowers has a unique opportunity to combine the professional polish of national competitors like 800flowers with the authentic personal touch of local family businesses. The Ecuadorian heritage provides a strong differentiator that should be celebrated throughout the user experience.
+
+Success will depend on:
+1. **Flawless Mobile Experience**: Most users will discover and order via smartphone
+2. **Trust Building**: Family story, reviews, and transparency are critical
+3. **Quality Consistency**: Every order must match or exceed expectations
+4. **Personal Touch**: Technology should enhance, not replace, human connection
+5. **Community Connection**: East LA roots are a competitive advantage
+
+By designing for these diverse personas while maintaining focus on core user needs, Angel's Flowers can build a thriving online presence that complements and amplifies their in-store success.
+
+---
+
+**Document Version**: 1.0
+**Last Updated**: 2025-11-10
+**Status**: Ready for Design Application
diff --git a/WIREFRAMES.md b/WIREFRAMES.md
new file mode 100644
index 0000000..443e675
--- /dev/null
+++ b/WIREFRAMES.md
@@ -0,0 +1,912 @@
+# Angel's Flowers - Detailed Wireframes
+## ASCII Wireframe Documentation
+
+---
+
+## HOMEPAGE - DESKTOP VIEW (1440px)
+
+```
+┌────────────────────────────────────────────────────────────────────────────────────────────────┐
+│ │
+│ [Logo: Angel's Flowers] Shop ▼ Occasions ▼ About Us Gallery Contact [🔍] [🛒 0] │
+│ │
+├────────────────────────────────────────────────────────────────────────────────────────────────┤
+│ │
+│ ╔══════════════════════════════════════════╗ │
+│ ║ ║ │
+│ ║ [Hero Background: Flower Bouquet] ║ │
+│ ║ ║ │
+│ ║ Angel's Flowers ║ │
+│ ║ Ecuadorian Blooms, East LA Roots ║ │
+│ ║ ║ │
+│ ║ Fresh arrangements crafted with love ║ │
+│ ║ for over 20 years ║ │
+│ ║ ║ │
+│ ║ [Shop Flowers] [Our Story →] ║ │
+│ ║ ║ │
+│ ╚══════════════════════════════════════════╝ │
+│ │
+├────────────────────────────────────────────────────────────────────────────────────────────────┤
+│ VALUE PROPOSITIONS │
+│ │
+│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
+│ │ [Icon: 🌹] │ │ [Icon: 👨👩👧] │ │ [Icon: ✂️] │ │ [Icon: 🚚] │ │
+│ │ Fresh Daily │ │ Family-Owned │ │ Custom │ │ Same-Day │ │
+│ │ │ │ │ │ Designs │ │ Delivery │ │
+│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │
+│ │
+├────────────────────────────────────────────────────────────────────────────────────────────────┤
+│ SHOP BY OCCASION │
+│ Celebrate Life's Special Moments │
+│ │
+│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
+│ │ │ │ │ │ │ │ │ │ │ │
+│ │ [Birthday] │ │ [Wedding] │ │ [Anniversary]│ │ [Sympathy] │ │ [Just Because│ │
+│ │ │ │ │ │ │ │ │ │ │ │
+│ │ Birthdays │ │ Weddings & │ │ Anniversary │ │ Sympathy & │ │ Just │ │
+│ │ │ │ Quinceañeras │ │ │ │ Funeral │ │ Because │ │
+│ │ [Browse →] │ │ [Browse →] │ │ [Browse →] │ │ [Browse →] │ │ [Browse →] │ │
+│ │ │ │ │ │ │ │ │ │ │ │
+│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │
+│ │
+├────────────────────────────────────────────────────────────────────────────────────────────────┤
+│ FEATURED FLOWERS │
+│ Our Most Loved Arrangements │
+│ │
+│ [◄] [►] │
+│ │
+│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
+│ │ │ │ │ │ │ │ │ │
+│ │ [Image] │ │ [Image] │ │ [Image] │ │ [Image] │ │
+│ │ │ │ │ │ │ │ │ │
+│ │ │ │ │ │ │ │ │ │
+│ ├──────────────┤ ├──────────────┤ ├──────────────┤ ├──────────────┤ │
+│ │ Rose Romance │ │ Tropical │ │ Elegant │ │ Sunflower │ │
+│ │ Bouquet │ │ Paradise │ │ Orchid │ │ Delight │ │
+│ │ ★★★★★ (24) │ │ ★★★★☆ (18) │ │ ★★★★★ (31) │ │ ★★★★★ (12) │ │
+│ │ │ │ │ │ │ │ │ │
+│ │ From $65.00 │ │ From $85.00 │ │ From $95.00 │ │ From $55.00 │ │
+│ │ │ │ │ │ │ │ │ │
+│ │ [Add to Cart]│ │ [Add to Cart]│ │ [Add to Cart]│ │ [Add to Cart]│ │
+│ │ │ │ │ │ │ │ │ │
+│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │
+│ │
+│ [View All Flowers →] │
+│ │
+├────────────────────────────────────────────────────────────────────────────────────────────────┤
+│ FAMILY STORY SECTION │
+│ [Background: Soft cream color] │
+│ │
+│ ┌───────────────────────────────┐ ┌────────────────────────────────────────────┐ │
+│ │ │ │ │ │
+│ │ │ │ From Ecuador to East LA │ │
+│ │ [Family Photo in Shop] │ │ Our Family Story │ │
+│ │ │ │ │ │
+│ │ (Warm, candid shot with │ │ For over 20 years, the Martinez family │ │
+│ │ family members and │ │ has brought the vibrant beauty of │ │
+│ │ flowers) │ │ Ecuadorian flowers to East Los Angeles. │ │
+│ │ │ │ │ │
+│ │ │ │ Growing up in Quito, we learned the art │ │
+│ │ │ │ of flower arranging from generations │ │
+│ │ │ │ before us. Today, we're proud to serve │ │
+│ │ │ │ our community with that same love and │ │
+│ │ │ │ dedication. │ │
+│ │ │ │ │ │
+│ │ │ │ Every arrangement tells a story. Let us │ │
+│ │ │ │ help tell yours. │ │
+│ │ │ │ │ │
+│ │ │ │ [Read Our Full Story →] │ │
+│ │ │ │ │ │
+│ └───────────────────────────────┘ └────────────────────────────────────────────┘ │
+│ │
+├────────────────────────────────────────────────────────────────────────────────────────────────┤
+│ THE ECUADORIAN DIFFERENCE │
+│ Why Our Flowers Are Simply Better │
+│ │
+│ ┌───────────────────────────┐ ┌────────────────────────────────────────────────┐ │
+│ │ │ │ Ecuador's unique climate and rich volcanic │ │
+│ │ [Image Grid: Ecuadorian │ │ soil create the perfect conditions for │ │
+│ │ flower farms, mountains,│ │ growing the world's finest flowers. │ │
+│ │ roses being picked] │ │ │ │
+│ │ │ │ • Longer stems (up to 6 feet!) │ │
+│ │ [Image 1] [Image 2] │ │ • Larger blooms with vibrant colors │ │
+│ │ [Image 3] [Image 4] │ │ • Longer vase life (2+ weeks) │ │
+│ │ │ │ • Sustainable farming practices │ │
+│ │ │ │ │ │
+│ │ │ │ We import directly from family farms in │ │
+│ │ │ │ Ecuador, ensuring freshness and quality │ │
+│ │ │ │ that local wholesale markets can't match. │ │
+│ │ │ │ │ │
+│ └───────────────────────────┘ └────────────────────────────────────────────────┘ │
+│ │
+├────────────────────────────────────────────────────────────────────────────────────────────────┤
+│ SEE OUR LATEST CREATIONS │
+│ Follow us on Instagram @angelsflowersla │
+│ │
+│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │
+│ │ │ │ │ │ │ │ │ │ │ │ │ │
+│ │[Image] │ │[Image] │ │[Image] │ │[Image] │ │[Image] │ │[Image] │ │
+│ │ │ │ │ │ │ │ │ │ │ │ │ │
+│ │ ♡ 45 │ │ ♡ 62 │ │ ♡ 38 │ │ ♡ 91 │ │ ♡ 27 │ │ ♡ 53 │ │
+│ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │
+│ │
+│ [View More on Instagram →] │
+│ │
+├────────────────────────────────────────────────────────────────────────────────────────────────┤
+│ CUSTOMER TESTIMONIALS │
+│ What Our Community Says About Us │
+│ │
+│ [◄] [►] │
+│ │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ │ │
+│ │ "The most beautiful flowers I've ever received! The │ │
+│ │ Martinez family truly puts love into every │ │
+│ │ arrangement. My mom cried happy tears!" │ │
+│ │ │ │
+│ │ ★★★★★ │ │
+│ │ │ │
+│ │ - Maria G., Birthday Bouquet │ │
+│ │ │ │
+│ └─────────────────────────────────────────────────────────┘ │
+│ │
+│ ● ○ ○ ○ ○ │
+│ │
+├────────────────────────────────────────────────────────────────────────────────────────────────┤
+│ VISIT US IN EAST LOS ANGELES │
+│ │
+│ ┌──────────────────────────────┐ ┌─────────────────────────────────────────┐ │
+│ │ │ │ Angel's Flowers │ │
+│ │ [Google Maps Embed] │ │ 123 Whittier Blvd │ │
+│ │ │ │ East Los Angeles, CA 90022 │ │
+│ │ [Interactive map showing │ │ │ │
+│ │ shop location] │ │ Hours: │ │
+│ │ │ │ Mon-Fri: 9:00 AM - 7:00 PM │ │
+│ │ │ │ Saturday: 9:00 AM - 8:00 PM │ │
+│ │ │ │ Sunday: 10:00 AM - 5:00 PM │ │
+│ │ │ │ │ │
+│ │ │ │ Phone: (323) 555-ROSE │ │
+│ │ │ │ │ │
+│ │ │ │ [Get Directions] [Call Now] │ │
+│ │ │ │ │ │
+│ └──────────────────────────────┘ └─────────────────────────────────────────┘ │
+│ │
+├────────────────────────────────────────────────────────────────────────────────────────────────┤
+│ FOOTER │
+│ │
+│ ┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐ ┌──────────────────┐ │
+│ │ │ │ │ │ │ │ │ │
+│ │ SHOP │ │ ABOUT │ │ CUSTOMER SERVICE │ │ CONNECT │ │
+│ │ │ │ │ │ │ │ │ │
+│ │ • By Occasion │ │ • Our Story │ │ • Contact Us │ │ Instagram │ │
+│ │ • By Flower Type │ │ • Our Family │ │ • FAQ │ │ Facebook │ │
+│ │ • By Price │ │ • Gallery │ │ • Delivery Info │ │ Yelp │ │
+│ │ • Best Sellers │ │ • Testimonials │ │ • Care Guide │ │ │ │
+│ │ │ │ • Blog │ │ • Returns │ │ [Newsletter] │ │
+│ │ │ │ │ │ │ │ [Subscribe] │ │
+│ │ │ │ │ │ │ │ │ │
+│ └───────────────────┘ └───────────────────┘ └───────────────────┘ └──────────────────┘ │
+│ │
+│ ─────────────────────────────────────────────────────────────────────────────────────────── │
+│ │
+│ © 2024 Angel's Flowers | East Los Angeles | Privacy Policy | Terms of Service │
+│ │
+└────────────────────────────────────────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## HOMEPAGE - MOBILE VIEW (375px)
+
+```
+┌─────────────────────────────────────┐
+│ │
+│ ☰ [Logo] 🔍 🛒 0 │
+│ │
+├─────────────────────────────────────┤
+│ │
+│ ╔═════════════════════════════════╗│
+│ ║ ║│
+│ ║ [Hero Background] ║│
+│ ║ ║│
+│ ║ Angel's Flowers ║│
+│ ║ Ecuadorian Blooms, ║│
+│ ║ East LA Roots ║│
+│ ║ ║│
+│ ║ Fresh arrangements ║│
+│ ║ crafted with love ║│
+│ ║ ║│
+│ ║ [Shop Flowers] ║│
+│ ║ [Our Story →] ║│
+│ ║ ║│
+│ ╚═════════════════════════════════╝│
+│ │
+├─────────────────────────────────────┤
+│ VALUE PROPOSITIONS (Carousel) │
+│ │
+│ ┌───────────────────┐ │
+│ │ [Icon: 🌹] │ │
+│ │ Fresh Daily │ │
+│ └───────────────────┘ │
+│ ● ○ ○ ○ │
+│ │
+├─────────────────────────────────────┤
+│ SHOP BY OCCASION │
+│ Celebrate Life's Moments │
+│ │
+│ ┌────────────┐ ┌────────────┐ │
+│ │ │ │ │ │
+│ │ [Birthday] │ │ [Wedding] │ │
+│ │ │ │ │ │
+│ │ Birthdays │ │ Weddings & │ │
+│ │ [Browse →] │ │Quinceañeras│ │
+│ │ │ │ [Browse →] │ │
+│ └────────────┘ └────────────┘ │
+│ │
+│ ┌────────────┐ ┌────────────┐ │
+│ │[Anniversary│ │ [Sympathy] │ │
+│ │ │ │ │ │
+│ │Anniversary │ │ Sympathy & │ │
+│ │ [Browse →] │ │ Funeral │ │
+│ │ │ │ [Browse →] │ │
+│ └────────────┘ └────────────┘ │
+│ │
+├─────────────────────────────────────┤
+│ FEATURED FLOWERS │
+│ Our Most Loved Arrangements │
+│ │
+│ ┌───────────────────────────────┐ │
+│ │ │ │
+│ │ [Image] │ │
+│ │ │ │
+│ │ │ │
+│ ├───────────────────────────────┤ │
+│ │ Rose Romance Bouquet │ │
+│ │ ★★★★★ (24 reviews) │ │
+│ │ │ │
+│ │ From $65.00 │ │
+│ │ │ │
+│ │ [Add to Cart] │ │
+│ │ │ │
+│ └───────────────────────────────┘ │
+│ │
+│ ● ○ ○ ○ │
+│ │
+│ [View All Flowers →] │
+│ │
+├─────────────────────────────────────┤
+│ FAMILY STORY │
+│ [Background: Cream] │
+│ │
+│ ┌───────────────────────────────┐ │
+│ │ │ │
+│ │ [Family Photo in Shop] │ │
+│ │ │ │
+│ └───────────────────────────────┘ │
+│ │
+│ From Ecuador to East LA │
+│ Our Family Story │
+│ │
+│ For over 20 years, the Martinez │
+│ family has brought the vibrant │
+│ beauty of Ecuadorian flowers to │
+│ East Los Angeles... │
+│ │
+│ [Read Our Full Story →] │
+│ │
+├─────────────────────────────────────┤
+│ THE ECUADORIAN DIFFERENCE │
+│ Why Our Flowers Are Better │
+│ │
+│ ┌─────────┐ ┌─────────┐ │
+│ │[Image 1]│ │[Image 2]│ │
+│ └─────────┘ └─────────┘ │
+│ │
+│ • Longer stems (up to 6 feet!) │
+│ • Larger blooms, vibrant colors │
+│ • Longer vase life (2+ weeks) │
+│ • Sustainable farming practices │
+│ │
+│ [Learn More →] │
+│ │
+├─────────────────────────────────────┤
+│ SEE OUR LATEST CREATIONS │
+│ @angelsflowersla │
+│ │
+│ ┌─────┐ ┌─────┐ ┌─────┐ │
+│ │[Img]│ │[Img]│ │[Img]│ │
+│ │ ♡45 │ │ ♡62 │ │ ♡38 │ │
+│ └─────┘ └─────┘ └─────┘ │
+│ │
+│ [View More on Instagram →] │
+│ │
+├─────────────────────────────────────┤
+│ CUSTOMER TESTIMONIALS │
+│ What Our Community Says │
+│ │
+│ ┌───────────────────────────────┐ │
+│ │ │ │
+│ │ "The most beautiful flowers │ │
+│ │ I've ever received!" │ │
+│ │ │ │
+│ │ ★★★★★ │ │
+│ │ - Maria G. │ │
+│ │ │ │
+│ └───────────────────────────────┘ │
+│ │
+│ ● ○ ○ ○ │
+│ │
+├─────────────────────────────────────┤
+│ VISIT US │
+│ │
+│ ┌───────────────────────────────┐ │
+│ │ [Google Maps] │ │
+│ └───────────────────────────────┘ │
+│ │
+│ Angel's Flowers │
+│ 123 Whittier Blvd │
+│ East LA, CA 90022 │
+│ │
+│ Mon-Fri: 9:00 AM - 7:00 PM │
+│ Sat: 9:00 AM - 8:00 PM │
+│ Sun: 10:00 AM - 5:00 PM │
+│ │
+│ [Get Directions] [Call Now] │
+│ │
+├─────────────────────────────────────┤
+│ FOOTER │
+│ │
+│ [Logo] │
+│ │
+│ SHOP │
+│ • By Occasion │
+│ • By Flower Type │
+│ • By Price │
+│ │
+│ ABOUT │
+│ • Our Story │
+│ • Gallery │
+│ • Contact │
+│ │
+│ CONNECT │
+│ [Instagram] [Facebook] [Yelp] │
+│ │
+│ Newsletter: │
+│ [Email] [Subscribe] │
+│ │
+│ © 2024 Angel's Flowers │
+│ Privacy | Terms │
+│ │
+└─────────────────────────────────────┘
+
+[STICKY BOTTOM BAR]
+┌─────────────────────────────────────┐
+│ [Call Now: (323) 555-ROSE] │
+└─────────────────────────────────────┘
+```
+
+---
+
+## PRODUCT LISTING PAGE - DESKTOP
+
+```
+┌────────────────────────────────────────────────────────────────────────────────────────┐
+│ [Header - Same as Homepage] │
+├────────────────────────────────────────────────────────────────────────────────────────┤
+│ │
+│ Home > Shop Flowers > Birthday Flowers │
+│ │
+├────────────────────────────────────────────────────────────────────────────────────────┤
+│ │
+│ ┌──────────────────────────┐ │
+│ │ │ Birthday Flowers │
+│ │ [Hero Image: Birthday │ Make their day extra special │
+│ │ flowers arrangement] │ │
+│ │ │ From vibrant roses to cheerful sunflowers, find the │
+│ │ │ perfect birthday bouquet for your celebration. │
+│ │ │ │
+│ └──────────────────────────┘ │
+│ │
+├──────────┬─────────────────────────────────────────────────────────────────────────────┤
+│ │ │
+│ FILTERS │ Showing 24 of 36 products [Sort by: Most Popular ▼] [Grid ■] [List ☰]│
+│ │ │
+│ Price │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
+│ ☐ Under │ │ │ │ │ │ │ │ │ │
+│ $50 │ │ [Image] │ │ [Image] │ │ [Image] │ │ [Image] │ │
+│ ☑ $50-100│ │ │ │ │ │ │ │ │ │
+│ ☐ $100+ │ │ ♡ │ │ ♡ │ │ ♡ │ │ ♡ │ │
+│ │ ├──────────┤ ├──────────┤ ├──────────┤ ├──────────┤ │
+│ Color │ │ Birthday │ │ Colorful │ │ Happy │ │ Sunshine │ │
+│ ☐ Red │ │ Wishes │ │ Joy │ │ Day │ │ Surprise │ │
+│ ☑ Pink │ │ Bouquet │ │ Blooms │ │ Delight │ │ Bright │ │
+│ ☑ Yellow │ │ ★★★★★ 18 │ │ ★★★★☆ 12 │ │ ★★★★★ 24 │ │ ★★★★★ 9 │ │
+│ ☐ White │ │ │ │ │ │ │ │ │ │
+│ ☐ Mixed │ │ $75.00 │ │ $85.00 │ │ $95.00 │ │ $65.00 │ │
+│ │ │ │ │ │ │ │ │ │ │
+│ Flower │ │[Add Cart]│ │[Add Cart]│ │[Add Cart]│ │[Add Cart]│ │
+│ ☑ Roses │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
+│ ☐ Lilies │ │
+│ ☑ Sunfl. │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
+│ ☐ Orchid │ │ [Image] │ │ [Image] │ │ [Image] │ │ [Image] │ │
+│ ☐ Mixed │ │ ♡ │ │ ♡ │ │ ♡ │ │ ♡ │ │
+│ │ ├──────────┤ ├──────────┤ ├──────────┤ ├──────────┤ │
+│ Size │ │ [Product]│ │ [Product]│ │ [Product]│ │ [Product]│ │
+│ ☐ Small │ │ $xx.00 │ │ $xx.00 │ │ $xx.00 │ │ $xx.00 │ │
+│ ☑ Medium │ │[Add Cart]│ │[Add Cart]│ │[Add Cart]│ │[Add Cart]│ │
+│ ☐ Large │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
+│ ☐ Deluxe │ │
+│ │ [More products continue in grid...] │
+│ │ │
+│ [Clear] │ ┌────────────────────────────────────────┐ │
+│ │ │ [Load More Products] │ │
+│ │ └────────────────────────────────────────┘ │
+│ │ │
+│ │ Page: [1] [2] [3] [Next →] │
+│ │ │
+└──────────┴─────────────────────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## PRODUCT DETAIL PAGE - DESKTOP
+
+```
+┌────────────────────────────────────────────────────────────────────────────────────────┐
+│ [Header - Same as Homepage] │
+├────────────────────────────────────────────────────────────────────────────────────────┤
+│ │
+│ Home > Shop Flowers > Birthday Flowers > Rose Romance Bouquet │
+│ │
+├─────────────────────────────────────┬──────────────────────────────────────────────────┤
+│ │ │
+│ ┌───────────────────────────────┐ │ Rose Romance Bouquet │
+│ │ │ │ ★★★★★ 4.8 (24 reviews) │
+│ │ │ │ │
+│ │ [Main Product Image] │ │ From $65.00 │
+│ │ │ │ │
+│ │ (Zoomable - click to zoom) │ │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━│
+│ │ │ │ │
+│ │ │ │ A stunning arrangement of 24 premium Ecuadorian │
+│ └───────────────────────────────┘ │ roses in a classic glass vase. Perfect for │
+│ │ expressing love, celebration, and joy. │
+│ [Thumb] [Thumb] [Thumb] [Thumb] │ │
+│ (1) (2) (3) (4) │ Select Size: │
+│ │ ○ Standard (12 roses) - $65 │
+│ ♡ Add to Favorites │ ◉ Deluxe (24 roses) - $95 │
+│ │ ○ Premium (36 roses) - $125 │
+│ │ │
+│ │ Select Color: │
+│ │ [Red] [Pink] [White] [Yellow] [Mixed] │
+│ │ │
+│ │ Add Greeting Card? (+$5) │
+│ │ ☑ Yes ☐ No │
+│ │ [Message: _________________________] │
+│ │ │
+│ │ Delivery Date: │
+│ │ [Select Date ▼] Same-day available! │
+│ │ │
+│ │ Quantity: [- 1 +] │
+│ │ │
+│ │ ┌────────────────────────────────────┐ │
+│ │ │ [Add to Cart - $95.00] │ │
+│ │ └────────────────────────────────────┘ │
+│ │ │
+│ │ [Buy Now] or [Request Custom Order] │
+│ │ │
+│ │ ✓ Fresh Daily from Ecuador │
+│ │ ✓ Same-Day Delivery Available │
+│ │ ✓ 100% Satisfaction Guarantee │
+│ │ ✓ Hand-Crafted by Our Family │
+│ │ │
+├─────────────────────────────────────┴──────────────────────────────────────────────────┤
+│ │
+│ ┌─────────────┬─────────────┬─────────────┬─────────────┐ │
+│ │ Description │ Details │ Reviews │ Care Guide │ │
+│ └─────────────┴─────────────┴─────────────┴─────────────┘ │
+│ │
+│ This exquisite Rose Romance Bouquet features premium long-stem Ecuadorian roses │
+│ known for their exceptional size, vibrant color, and extended vase life. │
+│ │
+│ Each rose is hand-selected by our family for quality and freshness. We arrange │
+│ them with care and attention to create a stunning display that will make any │
+│ occasion unforgettable. │
+│ │
+│ Perfect for: Birthdays, Anniversaries, Romantic Gestures, Celebrations │
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━│
+│ │
+│ CUSTOMER REVIEWS [Write a Review] │
+│ │
+│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
+│ │ ★★★★★ Beautiful Beyond Words! │ │
+│ │ │ │
+│ │ "I ordered these for my wife's birthday and she absolutely loved them! The │ │
+│ │ roses were huge and lasted almost three weeks. Will definitely order again."│ │
+│ │ │ │
+│ │ - John M., verified purchase April 15, 2024 │ │
+│ └──────────────────────────────────────────────────────────────────────────────┘ │
+│ │
+│ [Load More Reviews] │
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━│
+│ │
+│ YOU MAY ALSO LIKE │
+│ │
+│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
+│ │ [Image] │ │ [Image] │ │ [Image] │ │ [Image] │ │
+│ │ Product │ │ Product │ │ Product │ │ Product │ │
+│ │ $xx.00 │ │ $xx.00 │ │ $xx.00 │ │ $xx.00 │ │
+│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
+│ │
+└────────────────────────────────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## SHOPPING CART - MOBILE
+
+```
+┌─────────────────────────────────────┐
+│ ← Back Shopping Cart │
+├─────────────────────────────────────┤
+│ │
+│ YOUR CART (2 items) │
+│ │
+│ ┌───────────────────────────────┐ │
+│ │ ┌────┐ Rose Romance Bouquet │ │
+│ │ │img │ Deluxe (24 roses), Red│ │
+│ │ └────┘ With greeting card │ │
+│ │ │ │
+│ │ [- 1 +] $100.00 │ │
+│ │ │ │
+│ │ [Remove] │ │
+│ └───────────────────────────────┘ │
+│ │
+│ ┌───────────────────────────────┐ │
+│ │ ┌────┐ Tropical Paradise │ │
+│ │ │img │ Standard, Mixed │ │
+│ │ └────┘ │ │
+│ │ │ │
+│ │ [- 1 +] $85.00 │ │
+│ │ │ │
+│ │ [Remove] │ │
+│ └───────────────────────────────┘ │
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
+│ │
+│ Promo Code: │
+│ [________________] [Apply] │
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
+│ │
+│ Subtotal: $185.00 │
+│ Delivery Fee: $15.00 │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
+│ Total: $200.00 │
+│ │
+│ ┌───────────────────────────────┐ │
+│ │ Proceed to Checkout │ │
+│ └───────────────────────────────┘ │
+│ │
+│ [Continue Shopping] │
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
+│ │
+│ NEED HELP? │
+│ Call us: (323) 555-ROSE │
+│ or [Request Custom Order] │
+│ │
+└─────────────────────────────────────┘
+```
+
+---
+
+## CHECKOUT FLOW - DESKTOP (3 STEPS)
+
+### Step 1: Delivery Information
+
+```
+┌────────────────────────────────────────────────────────────────────────────────────────┐
+│ [Header - Simplified, no shop links] │
+├────────────────────────────────────────────────────────────────────────────────────────┤
+│ │
+│ ┌──────────────────────────────────────┐ ┌──────────────────────────────────┐ │
+│ │ │ │ ORDER SUMMARY │ │
+│ │ Checkout │ │ │ │
+│ │ │ │ 2 items │ │
+│ │ [1] Delivery → [2] Date → [3] Pay │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━│ │
+│ │ │ │ │ │
+│ │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │ │ Rose Romance Bouquet │ │
+│ │ │ │ Deluxe, Red │ │
+│ │ DELIVERY INFORMATION │ │ Qty: 1 $100.00 │ │
+│ │ │ │ │ │
+│ │ Recipient Name * │ │ Tropical Paradise │ │
+│ │ [_____________________________] │ │ Standard, Mixed │ │
+│ │ │ │ Qty: 1 $85.00 │ │
+│ │ Recipient Phone * │ │ │ │
+│ │ [_____________________________] │ │ ━━━━━━━━━━━━━━━━━━━━━━━━ │ │
+│ │ │ │ │ │
+│ │ Delivery Address * │ │ Subtotal: $185.00 │ │
+│ │ [_____________________________] │ │ Delivery Fee: $15.00 │ │
+│ │ │ │ Tax: $0.00 │ │
+│ │ Apt/Suite │ │ ━━━━━━━━━━━━━━━━━━━━━━━━ │ │
+│ │ [_____________________________] │ │ │ │
+│ │ │ │ TOTAL: $200.00 │ │
+│ │ City State Zip │ │ │ │
+│ │ [______________] [CA ▼] [_____] │ │ ━━━━━━━━━━━━━━━━━━━━━━━━ │ │
+│ │ │ │ │ │
+│ │ ☑ This is a gift │ │ SECURE CHECKOUT │ │
+│ │ │ │ 🔒 SSL Encrypted │ │
+│ │ Your Information (for confirmation) │ │ │ │
+│ │ │ │ We Accept: │ │
+│ │ Your Name * │ │ [Visa] [MC] [AmEx] [Disc] │ │
+│ │ [_____________________________] │ │ │ │
+│ │ │ └──────────────────────────────────┘ │
+│ │ Your Email * │ │
+│ │ [_____________________________] │ │
+│ │ │ │
+│ │ Your Phone * │ │
+│ │ [_____________________________] │ │
+│ │ │ │
+│ │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │ │
+│ │ │ │
+│ │ [← Back to Cart] [Continue →] │ │
+│ │ │ │
+│ └──────────────────────────────────────┘ │
+│ │
+└────────────────────────────────────────────────────────────────────────────────────────┘
+```
+
+### Step 2: Delivery Date & Time
+
+```
+┌──────────────────────────────────────┐
+│ │
+│ [1] Delivery → [2] Date → [3] Pay
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
+│ │
+│ SELECT DELIVERY DATE │
+│ │
+│ [Calendar Widget] │
+│ │
+│ November 2024 │
+│ Su Mo Tu We Th Fr Sa │
+│ 1 2 3 │
+│ 4 5 6 7 8 9 10 │
+│ 11 12 13 14 15 16 17 │
+│ 18 19 20 21 22 23 24 │
+│ 25 26 27 28 29 30 │
+│ │
+│ Selected: November 15, 2024 │
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
+│ │
+│ DELIVERY TIME │
+│ │
+│ ○ Morning (9 AM - 12 PM) │
+│ ◉ Afternoon (12 PM - 5 PM) │
+│ ○ Evening (5 PM - 7 PM) │
+│ ○ Anytime │
+│ │
+│ Special Delivery Instructions: │
+│ [_____________________________] │
+│ [_____________________________] │
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
+│ │
+│ [← Back] [Continue to Payment →] │
+│ │
+└──────────────────────────────────────┘
+```
+
+### Step 3: Payment
+
+```
+┌──────────────────────────────────────┐
+│ │
+│ [1] Delivery → [2] Date → [3] Pay
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
+│ │
+│ PAYMENT METHOD │
+│ │
+│ ◉ Credit/Debit Card │
+│ ○ PayPal │
+│ ○ Venmo │
+│ ○ Pay In Store │
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
+│ │
+│ Card Number * │
+│ [____ ____ ____ ____] │
+│ │
+│ Name on Card * │
+│ [_____________________________] │
+│ │
+│ Expiration CVV │
+│ [MM/YY] [___] │
+│ │
+│ Billing Zip Code * │
+│ [________] │
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
+│ │
+│ ORDER REVIEW │
+│ │
+│ Delivering to: │
+│ Maria Garcia │
+│ 123 Main St, Los Angeles CA 90022 │
+│ Phone: (323) 555-1234 │
+│ │
+│ Delivery Date: │
+│ November 15, 2024 (Afternoon) │
+│ │
+│ Total: $200.00 │
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
+│ │
+│ ☑ I agree to Terms & Conditions │
+│ │
+│ ┌────────────────────────────────┐ │
+│ │ Complete Order ($200.00) │ │
+│ └────────────────────────────────┘ │
+│ │
+│ [← Back] │
+│ │
+│ 🔒 Your payment is secure │
+│ │
+└──────────────────────────────────────┘
+```
+
+---
+
+## ABOUT US PAGE - DESKTOP
+
+```
+┌────────────────────────────────────────────────────────────────────────────────────────┐
+│ [Header] │
+├────────────────────────────────────────────────────────────────────────────────────────┤
+│ │
+│ ┌────────────────────────────────────────────────────────────────────────────────┐ │
+│ │ │ │
+│ │ [Hero Image: Family in flower shop] │ │
+│ │ │ │
+│ │ Our Family Story │ │
+│ │ From Ecuador to East Los Angeles │ │
+│ │ │ │
+│ └────────────────────────────────────────────────────────────────────────────────┘ │
+│ │
+├────────────────────────────────────────────────────────────────────────────────────────┤
+│ │
+│ ┌─────────────────────────────┐ ┌────────────────────────────────────────────┐ │
+│ │ │ │ │ │
+│ │ [Image: Ecuador mountains, │ │ The Beginning: Quito, Ecuador │ │
+│ │ flower farms] │ │ │ │
+│ │ │ │ Our story begins in the highlands of │ │
+│ │ │ │ Ecuador, where the Martinez family has │ │
+│ │ │ │ been cultivating flowers for three │ │
+│ │ │ │ generations. │ │
+│ │ │ │ │ │
+│ │ │ │ Growing up surrounded by roses, orchids, │ │
+│ │ │ │ and lilies, founders Miguel and Rosa │ │
+│ │ │ │ learned the art of floristry from their │ │
+│ │ │ │ parents and grandparents... │ │
+│ │ │ │ │ │
+│ └─────────────────────────────┘ └────────────────────────────────────────────┘ │
+│ │
+│ ┌────────────────────────────────────────────┐ ┌─────────────────────────────┐ │
+│ │ A New Beginning: East Los Angeles │ │ │ │
+│ │ │ │ [Image: Shop front, family │ │
+│ │ In 2004, Miguel and Rosa moved to East LA │ │ standing outside] │ │
+│ │ with a dream: to bring the exceptional │ │ │ │
+│ │ quality of Ecuadorian flowers to their │ │ │ │
+│ │ new community. │ │ │ │
+│ │ │ │ │ │
+│ │ With $5,000 in savings and unwavering │ │ │ │
+│ │ determination, they opened Angel's Flowers│ │ │ │
+│ │ on Whittier Boulevard... │ │ │ │
+│ │ │ │ │ │
+│ └────────────────────────────────────────────┘ └─────────────────────────────┘ │
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━│
+│ │
+│ MEET THE FAMILY │
+│ │
+│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
+│ │ │ │ │ │ │ │ │ │
+│ │ [Photo] │ │ [Photo] │ │ [Photo] │ │ [Photo] │ │
+│ │ │ │ │ │ │ │ │ │
+│ ├──────────────┤ ├──────────────┤ ├──────────────┤ ├──────────────┤ │
+│ │ Miguel │ │ Rosa │ │ Isabella │ │ Carlos │ │
+│ │ Founder │ │ Co-Founder │ │ Manager │ │ Designer │ │
+│ │ │ │ │ │ │ │ │ │
+│ │ "Every │ │ "Flowers are │ │ "Helping our │ │ "Creating │ │
+│ │ flower │ │ love's │ │ community │ │ beauty is │ │
+│ │ tells a │ │ language" │ │ celebrate" │ │ my passion" │ │
+│ │ story" │ │ │ │ │ │ │ │
+│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━│
+│ │
+│ OUR VALUES │
+│ │
+│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
+│ │ [Icon: Heart] │ │ [Icon: Flower] │ │ [Icon: People] │ │
+│ │ │ │ │ │ │ │
+│ │ Quality │ │ Sustainability │ │ Community │ │
+│ │ │ │ │ │ │ │
+│ │ Every flower is │ │ We partner with │ │ East LA is our │ │
+│ │ hand-selected │ │ eco-conscious │ │ home, and we're │ │
+│ │ for freshness │ │ farms in │ │ proud to serve │ │
+│ │ and beauty │ │ Ecuador │ │ our neighbors │ │
+│ │ │ │ │ │ │ │
+│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
+│ │
+│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━│
+│ │
+│ VISIT US TODAY │
+│ │
+│ We'd love to meet you in person at our East LA shop. Stop by to see our fresh │
+│ daily selections, get expert advice, or just say hello! │
+│ │
+│ [Get Directions] [Call Us] [Shop Flowers] │
+│ │
+└────────────────────────────────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## INTERACTION NOTES
+
+### Mega Menu (Desktop - "Shop Flowers" hover)
+
+```
+┌────────────────────────────────────────────────────────────────────────────┐
+│ Shop Flowers ▼ │
+├────────────────────────────────────────────────────────────────────────────┤
+│ │
+│ BY TYPE BY COLOR BY PRICE FEATURED │
+│ │
+│ Roses Red Under $50 [Image] Best Sellers │
+│ Orchids Pink $50 - $100 Popular arrangements │
+│ Lilies White $100 - $150 │
+│ Tulips Yellow Premium $150+ [Image] New Arrivals │
+│ Sunflowers Purple Fresh this week │
+│ Mixed Bouquets Mixed OCCASIONS │
+│ Tropical [Image] Ecuadorian │
+│ SHOP ALL Birthdays Specialty blooms │
+│ [View All →] Weddings │
+│ Sympathy [Shop All →] │
+│ Just Because │
+│ │
+└────────────────────────────────────────────────────────────────────────────┘
+```
+
+### Quick View Modal (Product Card Click)
+
+```
+┌────────────────────────────────────────────────────────────────┐
+│ [X] │
+│ ┌──────────────────┐ Rose Romance Bouquet │
+│ │ │ ★★★★★ (24 reviews) │
+│ │ [Product Img] │ │
+│ │ │ From $65.00 │
+│ │ │ │
+│ │ [◄] [1/4] [►] │ Premium Ecuadorian roses in a classic │
+│ └──────────────────┘ glass vase. Perfect for celebrating... │
+│ │
+│ Size: ○ Standard ◉ Deluxe ○ Premium │
+│ Color: [Red] [Pink] [White] [Yellow] │
+│ │
+│ [Add to Cart] [View Full Details →] │
+│ │
+└────────────────────────────────────────────────────────────────┘
+```
+
+---
+
+**Document Version**: 1.0
+**Last Updated**: 2025-11-10
+**Status**: Ready for Design Review
diff --git a/angels_flowers_visual.png b/angels_flowers_visual.png
new file mode 100644
index 0000000..e06ebdb
Binary files /dev/null and b/angels_flowers_visual.png differ
diff --git a/app/about/page.tsx b/app/about/page.tsx
new file mode 100644
index 0000000..04ee8eb
--- /dev/null
+++ b/app/about/page.tsx
@@ -0,0 +1,299 @@
+import Image from 'next/image'
+import { FaHeart, FaGlobeAmericas, FaUsers, FaAward } from 'react-icons/fa'
+
+export default function AboutPage() {
+ return (
+ <>
+ {/* Hero Section */}
+ <section className="relative py-32 bg-gradient-to-br from-primary-600 to-primary-700 text-white mt-16">
+ <div className="container-custom text-center">
+ <h1 className="heading-xl mb-6 text-white">
+ Our Family Story
+ </h1>
+ <p className="text-xl max-w-3xl mx-auto leading-relaxed text-gray-100">
+ Three generations of passion, tradition, and the finest Ecuadorian flowers
+ </p>
+ </div>
+ </section>
+
+ {/* Origin Story Section */}
+ <section className="section-padding bg-white">
+ <div className="container-custom">
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
+ <div className="space-y-6">
+ <h2 className="heading-md text-gray-900">
+ It All Started with Angel
+ </h2>
+ <div className="space-y-4 text-lg text-gray-600 leading-relaxed">
+ <p>
+ In 1995, our grandmother Angel arrived in East Los Angeles from Quito, Ecuador, carrying with her a deep love for flowers and a dream to share the beauty of her homeland with her new community.
+ </p>
+ <p>
+ Growing up near Ecuador's rose farms in the Andean highlands, Angel understood what made Ecuadorian flowers special: the high altitude, intense sunlight, and rich volcanic soil create roses with larger blooms, longer stems, and more vibrant colors than anywhere else in the world.
+ </p>
+ <p>
+ She opened a small flower shop on East Los Angeles Avenue, determined to bring these exceptional flowers to families celebrating life's most important moments.
+ </p>
+ </div>
+ </div>
+
+ <div className="relative h-[500px] rounded-lg overflow-hidden shadow-xl">
+ <div
+ className="absolute inset-0 bg-cover bg-center"
+ style={{
+ backgroundImage: "url('https://images.unsplash.com/photo-1542838132-92c53300491e?q=80&w=1000')",
+ }}
+ />
+ </div>
+ </div>
+ </div>
+ </section>
+
+ {/* Timeline Section */}
+ <section className="section-padding bg-gray-50">
+ <div className="container-custom">
+ <div className="text-center mb-16">
+ <h2 className="heading-md text-gray-900 mb-4">
+ Our Journey Through the Years
+ </h2>
+ </div>
+
+ <div className="max-w-4xl mx-auto space-y-12">
+ {[
+ {
+ year: '1995',
+ title: 'The Beginning',
+ description: 'Angel opens her first flower shop in East LA, importing roses directly from Ecuador. The community quickly falls in love with the quality and beauty of her flowers.',
+ },
+ {
+ year: '2005',
+ title: 'Second Generation',
+ description: 'Angel\'s daughter Maria joins the business, bringing fresh ideas while honoring traditional values. The shop expands to offer custom arrangements and wedding services.',
+ },
+ {
+ year: '2015',
+ title: 'Building Partnerships',
+ description: 'We establish direct relationships with family-owned farms in Ecuador, ensuring fair trade practices and consistent quality for our customers.',
+ },
+ {
+ year: '2020',
+ title: 'Community Pillars',
+ description: 'Recognized as one of East LA\'s most trusted businesses. We begin serving our customers\' children and grandchildren - true full-circle moments.',
+ },
+ {
+ year: '2025',
+ title: 'Three Generations Strong',
+ description: 'Angel\'s grandchildren now work alongside their mother, continuing the family tradition with the same passion and commitment to excellence that started it all.',
+ },
+ ].map((milestone, index) => (
+ <div key={index} className="flex gap-8 items-start">
+ <div className="flex-shrink-0 w-24 text-right">
+ <span className="text-3xl font-bold text-primary-600">
+ {milestone.year}
+ </span>
+ </div>
+ <div className="relative flex-shrink-0">
+ <div className="w-4 h-4 bg-primary-600 rounded-full" />
+ {index < 4 && (
+ <div className="absolute top-4 left-1/2 w-0.5 h-full bg-primary-200 -translate-x-1/2" />
+ )}
+ </div>
+ <div className="flex-1 pb-12">
+ <h3 className="text-2xl font-bold text-gray-900 mb-2">
+ {milestone.title}
+ </h3>
+ <p className="text-gray-600 leading-relaxed">
+ {milestone.description}
+ </p>
+ </div>
+ </div>
+ ))}
+ </div>
+ </div>
+ </section>
+
+ {/* Values Section */}
+ <section className="section-padding bg-white">
+ <div className="container-custom">
+ <div className="text-center mb-16">
+ <h2 className="heading-md text-gray-900 mb-4">
+ Our Values
+ </h2>
+ <p className="text-lg text-gray-600 max-w-2xl mx-auto">
+ The principles that guide everything we do
+ </p>
+ </div>
+
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
+ {[
+ {
+ icon: <FaHeart className="w-10 h-10" />,
+ title: 'Family First',
+ description: 'We treat every customer like family because that\'s who we are - a family business built on personal relationships and care.',
+ },
+ {
+ icon: <FaGlobeAmericas className="w-10 h-10" />,
+ title: 'Ecuadorian Pride',
+ description: 'We honor our roots by sourcing the finest flowers from Ecuador and supporting family farms that share our values.',
+ },
+ {
+ icon: <FaUsers className="w-10 h-10" />,
+ title: 'Community Focused',
+ description: 'East LA is our home. We\'re committed to serving our neighbors and celebrating our community\'s milestones.',
+ },
+ {
+ icon: <FaAward className="w-10 h-10" />,
+ title: 'Quality Promise',
+ description: 'Three generations of expertise means we never compromise on quality. Every stem meets our family\'s high standards.',
+ },
+ ].map((value, index) => (
+ <div key={index} className="text-center">
+ <div className="inline-flex items-center justify-center w-20 h-20 bg-primary-100 text-primary-600 rounded-full mb-6">
+ {value.icon}
+ </div>
+ <h3 className="text-xl font-bold text-gray-900 mb-3">
+ {value.title}
+ </h3>
+ <p className="text-gray-600 leading-relaxed">
+ {value.description}
+ </p>
+ </div>
+ ))}
+ </div>
+ </div>
+ </section>
+
+ {/* Ecuador Connection Section */}
+ <section className="section-padding bg-gray-50">
+ <div className="container-custom">
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
+ <div className="relative h-[500px] rounded-lg overflow-hidden shadow-xl order-2 lg:order-1">
+ <div
+ className="absolute inset-0 bg-cover bg-center"
+ style={{
+ backgroundImage: "url('https://images.unsplash.com/photo-1490750967868-88aa4486c946?q=80&w=1000')",
+ }}
+ />
+ </div>
+
+ <div className="space-y-6 order-1 lg:order-2">
+ <h2 className="heading-md text-gray-900">
+ The Magic of Ecuadorian Flowers
+ </h2>
+ <div className="space-y-4 text-lg text-gray-600 leading-relaxed">
+ <p>
+ Ecuador isn't just where our family comes from - it's home to the world's finest roses. Located on the equator at high altitude, Ecuador's unique climate creates perfect growing conditions.
+ </p>
+ <p>
+ The intense equatorial sunlight, cool mountain temperatures, and volcanic soil produce roses with:
+ </p>
+ <ul className="space-y-2 ml-6">
+ <li className="flex items-start">
+ <span className="w-2 h-2 bg-primary-500 rounded-full mr-3 mt-2 flex-shrink-0" />
+ <span>Larger blooms (up to twice the size of standard roses)</span>
+ </li>
+ <li className="flex items-start">
+ <span className="w-2 h-2 bg-primary-500 rounded-full mr-3 mt-2 flex-shrink-0" />
+ <span>Longer, stronger stems (60-70cm is standard)</span>
+ </li>
+ <li className="flex items-start">
+ <span className="w-2 h-2 bg-primary-500 rounded-full mr-3 mt-2 flex-shrink-0" />
+ <span>More vibrant, longer-lasting colors</span>
+ </li>
+ <li className="flex items-start">
+ <span className="w-2 h-2 bg-primary-500 rounded-full mr-3 mt-2 flex-shrink-0" />
+ <span>Extended vase life (10-14 days with proper care)</span>
+ </li>
+ </ul>
+ <p>
+ This is why we've maintained our direct connections with Ecuadorian farms for three decades - because nothing else compares.
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ {/* Team Section */}
+ <section className="section-padding bg-white">
+ <div className="container-custom">
+ <div className="text-center mb-16">
+ <h2 className="heading-md text-gray-900 mb-4">
+ Meet the Martinez Family
+ </h2>
+ <p className="text-lg text-gray-600 max-w-2xl mx-auto">
+ Three generations working together to serve our community
+ </p>
+ </div>
+
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-8 max-w-5xl mx-auto">
+ {[
+ {
+ name: 'Angel Martinez',
+ role: 'Founder & Grandmother',
+ image: 'https://images.unsplash.com/photo-1544005313-94ddf0286df2?q=80&w=400',
+ description: 'The heart and soul of our shop, Angel still visits daily to share stories and her love of flowers with customers.',
+ },
+ {
+ name: 'Maria Rodriguez',
+ role: 'Owner & Daughter',
+ image: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?q=80&w=400',
+ description: 'Leading the business for 20 years, Maria combines traditional values with modern service excellence.',
+ },
+ {
+ name: 'Sofia & Carlos',
+ role: 'Third Generation',
+ image: 'https://images.unsplash.com/photo-1529626455594-4ff0802cfb7e?q=80&w=400',
+ description: 'Bringing fresh energy and social media savvy while learning the art of flower arranging from their grandmother.',
+ },
+ ].map((member, index) => (
+ <div key={index} className="text-center">
+ <div className="relative w-48 h-48 mx-auto mb-6 rounded-full overflow-hidden shadow-lg">
+ <div
+ className="absolute inset-0 bg-cover bg-center"
+ style={{ backgroundImage: `url('${member.image}')` }}
+ />
+ </div>
+ <h3 className="text-2xl font-bold text-gray-900 mb-1">
+ {member.name}
+ </h3>
+ <p className="text-primary-600 font-semibold mb-3">
+ {member.role}
+ </p>
+ <p className="text-gray-600 leading-relaxed">
+ {member.description}
+ </p>
+ </div>
+ ))}
+ </div>
+ </div>
+ </section>
+
+ {/* CTA Section */}
+ <section className="section-padding bg-gradient-to-br from-primary-600 to-primary-700 text-white">
+ <div className="container-custom text-center">
+ <h2 className="heading-lg text-white mb-6">
+ Become Part of Our Story
+ </h2>
+ <p className="text-xl mb-8 max-w-2xl mx-auto text-gray-100">
+ Visit us in East LA and experience the warmth of our family tradition. We can't wait to meet you and create something beautiful together.
+ </p>
+ <div className="flex flex-col sm:flex-row gap-4 justify-center">
+ <a
+ href="tel:+13231234567"
+ className="inline-block text-lg px-8 py-4 bg-white text-primary-600 hover:bg-gray-100 rounded-md transition-colors duration-200 font-medium shadow-lg"
+ >
+ Call Us Today
+ </a>
+ <a
+ href="/contact"
+ className="inline-block text-lg px-8 py-4 border-2 border-white text-white hover:bg-white hover:text-primary-600 rounded-md transition-all duration-200 font-medium"
+ >
+ Visit Our Shop
+ </a>
+ </div>
+ </div>
+ </section>
+ </>
+ )
+}
diff --git a/app/contact/page.tsx b/app/contact/page.tsx
new file mode 100644
index 0000000..1bbf787
--- /dev/null
+++ b/app/contact/page.tsx
@@ -0,0 +1,392 @@
+'use client'
+
+import { useState } from 'react'
+import { FaPhone, FaEnvelope, FaMapMarkerAlt, FaClock, FaFacebook, FaInstagram } from 'react-icons/fa'
+
+export default function ContactPage() {
+ const [formData, setFormData] = useState({
+ name: '',
+ email: '',
+ phone: '',
+ occasion: '',
+ message: '',
+ })
+
+ const [submitted, setSubmitted] = useState(false)
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault()
+ // In production, this would send to an API endpoint
+ console.log('Form submitted:', formData)
+ setSubmitted(true)
+ setTimeout(() => setSubmitted(false), 5000)
+ }
+
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
+ setFormData({
+ ...formData,
+ [e.target.name]: e.target.value,
+ })
+ }
+
+ return (
+ <>
+ {/* Hero Section */}
+ <section className="relative py-32 bg-gradient-to-br from-primary-600 to-primary-700 text-white mt-16">
+ <div className="container-custom text-center">
+ <h1 className="heading-xl mb-6 text-white">
+ Get in Touch
+ </h1>
+ <p className="text-xl max-w-3xl mx-auto leading-relaxed text-gray-100">
+ We'd love to hear from you. Visit us in East LA or reach out with any questions about our flowers and services.
+ </p>
+ </div>
+ </section>
+
+ {/* Contact Info & Form Section */}
+ <section className="section-padding bg-white">
+ <div className="container-custom">
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-12">
+ {/* Contact Information */}
+ <div className="space-y-8">
+ <div>
+ <h2 className="heading-md text-gray-900 mb-6">
+ Visit Our Shop
+ </h2>
+ <p className="text-lg text-gray-600 mb-8 leading-relaxed">
+ Come see us in person! We love meeting our customers face-to-face and helping you choose the perfect flowers. Walk-ins are always welcome.
+ </p>
+ </div>
+
+ {/* Contact Cards */}
+ <div className="space-y-6">
+ <div className="flex items-start space-x-4 p-6 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors duration-200">
+ <div className="flex-shrink-0 w-12 h-12 bg-primary-100 text-primary-600 rounded-lg flex items-center justify-center">
+ <FaMapMarkerAlt className="text-xl" />
+ </div>
+ <div>
+ <h3 className="font-bold text-gray-900 mb-2">Address</h3>
+ <p className="text-gray-600">
+ 1234 East Los Angeles Avenue<br />
+ East Los Angeles, CA 90022
+ </p>
+ <a
+ href="https://maps.google.com"
+ target="_blank"
+ rel="noopener noreferrer"
+ className="inline-block mt-2 text-primary-600 hover:text-primary-700 font-medium text-sm"
+ >
+ Get Directions →
+ </a>
+ </div>
+ </div>
+
+ <div className="flex items-start space-x-4 p-6 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors duration-200">
+ <div className="flex-shrink-0 w-12 h-12 bg-primary-100 text-primary-600 rounded-lg flex items-center justify-center">
+ <FaPhone className="text-xl" />
+ </div>
+ <div>
+ <h3 className="font-bold text-gray-900 mb-2">Phone</h3>
+ <a
+ href="tel:+13231234567"
+ className="text-gray-600 hover:text-primary-600 transition-colors duration-200"
+ >
+ (323) 123-4567
+ </a>
+ <p className="text-sm text-gray-500 mt-1">
+ Call us for immediate assistance
+ </p>
+ </div>
+ </div>
+
+ <div className="flex items-start space-x-4 p-6 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors duration-200">
+ <div className="flex-shrink-0 w-12 h-12 bg-primary-100 text-primary-600 rounded-lg flex items-center justify-center">
+ <FaEnvelope className="text-xl" />
+ </div>
+ <div>
+ <h3 className="font-bold text-gray-900 mb-2">Email</h3>
+ <a
+ href="mailto:info@angelsflowers.com"
+ className="text-gray-600 hover:text-primary-600 transition-colors duration-200"
+ >
+ info@angelsflowers.com
+ </a>
+ <p className="text-sm text-gray-500 mt-1">
+ We'll respond within 24 hours
+ </p>
+ </div>
+ </div>
+
+ <div className="flex items-start space-x-4 p-6 bg-gray-50 rounded-lg">
+ <div className="flex-shrink-0 w-12 h-12 bg-primary-100 text-primary-600 rounded-lg flex items-center justify-center">
+ <FaClock className="text-xl" />
+ </div>
+ <div className="flex-1">
+ <h3 className="font-bold text-gray-900 mb-3">Business Hours</h3>
+ <div className="space-y-2 text-sm text-gray-600">
+ <div className="flex justify-between">
+ <span>Monday - Friday:</span>
+ <span className="font-semibold text-gray-900">9:00 AM - 7:00 PM</span>
+ </div>
+ <div className="flex justify-between">
+ <span>Saturday:</span>
+ <span className="font-semibold text-gray-900">9:00 AM - 6:00 PM</span>
+ </div>
+ <div className="flex justify-between">
+ <span>Sunday:</span>
+ <span className="font-semibold text-gray-900">10:00 AM - 4:00 PM</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ {/* Social Media */}
+ <div className="pt-6 border-t border-gray-200">
+ <h3 className="font-bold text-gray-900 mb-4">Follow Us</h3>
+ <div className="flex space-x-4">
+ <a
+ href="https://facebook.com"
+ target="_blank"
+ rel="noopener noreferrer"
+ className="w-12 h-12 bg-primary-600 hover:bg-primary-700 text-white rounded-lg flex items-center justify-center transition-colors duration-200"
+ aria-label="Facebook"
+ >
+ <FaFacebook className="text-xl" />
+ </a>
+ <a
+ href="https://instagram.com"
+ target="_blank"
+ rel="noopener noreferrer"
+ className="w-12 h-12 bg-primary-600 hover:bg-primary-700 text-white rounded-lg flex items-center justify-center transition-colors duration-200"
+ aria-label="Instagram"
+ >
+ <FaInstagram className="text-xl" />
+ </a>
+ </div>
+ </div>
+ </div>
+
+ {/* Contact Form */}
+ <div>
+ <div className="bg-gray-50 rounded-lg p-8">
+ <h2 className="heading-md text-gray-900 mb-6">
+ Send Us a Message
+ </h2>
+ <p className="text-gray-600 mb-6 leading-relaxed">
+ Have a question about our flowers or need help with a custom order? Fill out the form below and we'll get back to you soon.
+ </p>
+
+ {submitted && (
+ <div className="mb-6 p-4 bg-green-50 border border-green-200 rounded-md">
+ <p className="text-green-800 font-medium">
+ Thank you for your message! We'll be in touch shortly.
+ </p>
+ </div>
+ )}
+
+ <form onSubmit={handleSubmit} className="space-y-6">
+ <div>
+ <label htmlFor="name" className="block text-sm font-medium text-gray-700 mb-2">
+ Your Name *
+ </label>
+ <input
+ type="text"
+ id="name"
+ name="name"
+ required
+ value={formData.name}
+ onChange={handleChange}
+ className="w-full px-4 py-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-all duration-200"
+ placeholder="John Doe"
+ />
+ </div>
+
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
+ <div>
+ <label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-2">
+ Email *
+ </label>
+ <input
+ type="email"
+ id="email"
+ name="email"
+ required
+ value={formData.email}
+ onChange={handleChange}
+ className="w-full px-4 py-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-all duration-200"
+ placeholder="john@example.com"
+ />
+ </div>
+
+ <div>
+ <label htmlFor="phone" className="block text-sm font-medium text-gray-700 mb-2">
+ Phone
+ </label>
+ <input
+ type="tel"
+ id="phone"
+ name="phone"
+ value={formData.phone}
+ onChange={handleChange}
+ className="w-full px-4 py-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-all duration-200"
+ placeholder="(323) 123-4567"
+ />
+ </div>
+ </div>
+
+ <div>
+ <label htmlFor="occasion" className="block text-sm font-medium text-gray-700 mb-2">
+ Occasion
+ </label>
+ <select
+ id="occasion"
+ name="occasion"
+ value={formData.occasion}
+ onChange={handleChange}
+ className="w-full px-4 py-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-all duration-200"
+ >
+ <option value="">Select an occasion</option>
+ <option value="birthday">Birthday</option>
+ <option value="anniversary">Anniversary</option>
+ <option value="wedding">Wedding</option>
+ <option value="sympathy">Sympathy</option>
+ <option value="just-because">Just Because</option>
+ <option value="corporate">Corporate Event</option>
+ <option value="other">Other</option>
+ </select>
+ </div>
+
+ <div>
+ <label htmlFor="message" className="block text-sm font-medium text-gray-700 mb-2">
+ Message *
+ </label>
+ <textarea
+ id="message"
+ name="message"
+ required
+ rows={6}
+ value={formData.message}
+ onChange={handleChange}
+ className="w-full px-4 py-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-all duration-200"
+ placeholder="Tell us about what you're looking for..."
+ />
+ </div>
+
+ <button
+ type="submit"
+ className="w-full btn-primary py-4 text-lg"
+ >
+ Send Message
+ </button>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ {/* Map Section */}
+ <section className="section-padding bg-gray-50">
+ <div className="container-custom">
+ <div className="text-center mb-12">
+ <h2 className="heading-md text-gray-900 mb-4">
+ Find Us in East LA
+ </h2>
+ <p className="text-lg text-gray-600">
+ Located in the heart of East Los Angeles, easy to find and free parking available
+ </p>
+ </div>
+
+ {/* Map Placeholder */}
+ <div className="relative h-96 rounded-lg overflow-hidden shadow-lg">
+ <div className="absolute inset-0 bg-gray-300 flex items-center justify-center">
+ <div className="text-center">
+ <FaMapMarkerAlt className="text-6xl text-primary-600 mx-auto mb-4" />
+ <p className="text-gray-700 font-medium">
+ 1234 East Los Angeles Avenue<br />
+ East Los Angeles, CA 90022
+ </p>
+ <a
+ href="https://maps.google.com"
+ target="_blank"
+ rel="noopener noreferrer"
+ className="inline-block mt-4 px-6 py-3 bg-primary-600 text-white rounded-md hover:bg-primary-700 transition-colors duration-200 font-medium"
+ >
+ Open in Google Maps
+ </a>
+ </div>
+ </div>
+ {/* In production, replace with actual Google Maps embed or Mapbox */}
+ </div>
+
+ <div className="mt-8 grid grid-cols-1 md:grid-cols-3 gap-6 text-center">
+ <div className="p-6 bg-white rounded-lg shadow-md">
+ <h3 className="font-bold text-gray-900 mb-2">Free Parking</h3>
+ <p className="text-gray-600 text-sm">
+ Convenient parking lot right in front of our shop
+ </p>
+ </div>
+ <div className="p-6 bg-white rounded-lg shadow-md">
+ <h3 className="font-bold text-gray-900 mb-2">Wheelchair Accessible</h3>
+ <p className="text-gray-600 text-sm">
+ Full accessibility for all customers
+ </p>
+ </div>
+ <div className="p-6 bg-white rounded-lg shadow-md">
+ <h3 className="font-bold text-gray-900 mb-2">Public Transit</h3>
+ <p className="text-gray-600 text-sm">
+ Multiple bus lines stop within 2 blocks
+ </p>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ {/* FAQ Section */}
+ <section className="section-padding bg-white">
+ <div className="container-custom max-w-4xl">
+ <div className="text-center mb-12">
+ <h2 className="heading-md text-gray-900 mb-4">
+ Frequently Asked Questions
+ </h2>
+ </div>
+
+ <div className="space-y-6">
+ {[
+ {
+ question: 'Do you offer same-day delivery?',
+ answer: 'Yes! We offer same-day delivery for orders placed before 2 PM. Call us at (323) 123-4567 to arrange same-day service.',
+ },
+ {
+ question: 'Can I place a custom order?',
+ answer: 'Absolutely! We love creating custom arrangements. Visit us in person or call to discuss your vision with our expert florists.',
+ },
+ {
+ question: 'How long do Ecuadorian roses last?',
+ answer: 'With proper care, our Ecuadorian roses typically last 10-14 days, much longer than standard roses. We provide care instructions with every purchase.',
+ },
+ {
+ question: 'Do you handle wedding flowers?',
+ answer: 'Yes! We offer complete wedding flower services including consultations, custom designs, and day-of coordination. Book a consultation to get started.',
+ },
+ {
+ question: 'What payment methods do you accept?',
+ answer: 'We accept cash, all major credit cards, and contactless payments. We also accept phone orders with card payment.',
+ },
+ ].map((faq, index) => (
+ <div key={index} className="border-b border-gray-200 pb-6 last:border-0">
+ <h3 className="text-xl font-bold text-gray-900 mb-2">
+ {faq.question}
+ </h3>
+ <p className="text-gray-600 leading-relaxed">
+ {faq.answer}
+ </p>
+ </div>
+ ))}
+ </div>
+ </div>
+ </section>
+ </>
+ )
+}
diff --git a/app/flowers/page.tsx b/app/flowers/page.tsx
new file mode 100644
index 0000000..ccf675a
--- /dev/null
+++ b/app/flowers/page.tsx
@@ -0,0 +1,243 @@
+import Image from 'next/image'
+import { FaPhone } from 'react-icons/fa'
+
+const flowerCategories = [
+ {
+ id: 'roses',
+ name: 'Ecuadorian Roses',
+ items: [
+ {
+ name: 'Classic Red Roses',
+ price: '$45 - $120',
+ image: 'https://images.unsplash.com/photo-1582794543139-8ac9cb0f7b11?q=80&w=800',
+ description: 'Premium long-stem red roses with larger blooms, perfect for expressing love and passion. Available in bouquets of 12, 24, or 36 stems.',
+ features: ['60-70cm stems', 'Velvety petals', '10-14 day vase life'],
+ },
+ {
+ name: 'White Rose Elegance',
+ price: '$50 - $125',
+ image: 'https://images.unsplash.com/photo-1518709766631-a6a7f45921c3?q=80&w=800',
+ description: 'Pure white roses symbolizing innocence and new beginnings. Ideal for weddings, sympathy, or as a sophisticated gift.',
+ features: ['60-70cm stems', 'Pure white blooms', 'Elegant presentation'],
+ },
+ {
+ name: 'Pink Perfection',
+ price: '$48 - $115',
+ image: 'https://images.unsplash.com/photo-1464297162577-f5295c892194?q=80&w=800',
+ description: 'Soft pink roses conveying grace, admiration, and joy. Perfect for birthdays, anniversaries, or just because.',
+ features: ['60-70cm stems', 'Delicate pink hues', 'Sweet fragrance'],
+ },
+ {
+ name: 'Yellow Sunshine',
+ price: '$45 - $110',
+ image: 'https://images.unsplash.com/photo-1561181286-d3fee7d55364?q=80&w=800',
+ description: 'Bright yellow roses representing friendship and celebration. Bring sunshine to any occasion.',
+ features: ['60-70cm stems', 'Vibrant yellow', 'Cheerful presentation'],
+ },
+ {
+ name: 'Rainbow Rose Collection',
+ price: '$55 - $135',
+ image: 'https://images.unsplash.com/photo-1563241527-3004b7be0ffd?q=80&w=800',
+ description: 'Stunning assortment of multi-colored Ecuadorian roses creating a vibrant, eye-catching arrangement.',
+ features: ['60-70cm stems', 'Mix of colors', 'Spectacular display'],
+ },
+ {
+ name: 'Lavender Dreams',
+ price: '$52 - $130',
+ image: 'https://images.unsplash.com/photo-1518709594023-6eab9bab7b23?q=80&w=800',
+ description: 'Rare lavender roses offering enchantment and uniqueness. A special choice for those who appreciate the extraordinary.',
+ features: ['60-70cm stems', 'Rare lavender color', 'Unique and elegant'],
+ },
+ ],
+ },
+ {
+ id: 'mixed',
+ name: 'Mixed Arrangements',
+ items: [
+ {
+ name: 'Garden Paradise',
+ price: '$65 - $150',
+ image: 'https://images.unsplash.com/photo-1518709268805-4e9042af9f23?q=80&w=800',
+ description: 'Stunning garden-style arrangement with roses, lilies, and seasonal flowers complemented by fresh greenery.',
+ features: ['Premium mixed flowers', 'Designer vase', 'Eucalyptus accents'],
+ },
+ {
+ name: 'Spring Meadow',
+ price: '$55 - $125',
+ image: 'https://images.unsplash.com/photo-1487070183336-b863922373d4?q=80&w=800',
+ description: 'Fresh and cheerful combination of tulips, daisies, and wildflowers perfect for brightening any space.',
+ features: ['Seasonal flowers', 'Colorful mix', 'Natural style'],
+ },
+ {
+ name: 'Tropical Sunset',
+ price: '$70 - $160',
+ image: 'https://images.unsplash.com/photo-1558442074-2b41e9db72bb?q=80&w=800',
+ description: 'Exotic arrangement featuring birds of paradise, orchids, and vibrant tropical blooms.',
+ features: ['Exotic flowers', 'Bold colors', 'Premium presentation'],
+ },
+ {
+ name: 'Rustic Romance',
+ price: '$60 - $140',
+ image: 'https://images.unsplash.com/photo-1455659817273-f96807779a8a?q=80&w=800',
+ description: 'Charming arrangement with roses, ranunculus, and wildflowers in a rustic wooden container.',
+ features: ['Romantic mix', 'Rustic container', 'Vintage style'],
+ },
+ ],
+ },
+ {
+ id: 'special',
+ name: 'Special Occasions',
+ items: [
+ {
+ name: 'Wedding Collection',
+ price: 'Custom Pricing',
+ image: 'https://images.unsplash.com/photo-1519225421980-715cb0215aed?q=80&w=800',
+ description: 'Complete wedding flower service including bridal bouquets, centerpieces, and ceremony arrangements. Consultation required.',
+ features: ['Custom designs', 'Full service', 'Professional setup'],
+ },
+ {
+ name: 'Sympathy Arrangements',
+ price: '$75 - $200',
+ image: 'https://images.unsplash.com/photo-1498307833015-e7b400441eb8?q=80&w=800',
+ description: 'Elegant and respectful arrangements for expressing condolences and honoring loved ones.',
+ features: ['White and soft colors', 'Elegant design', 'Delivery available'],
+ },
+ {
+ name: 'Corporate Events',
+ price: 'Custom Pricing',
+ image: 'https://images.unsplash.com/photo-1478146896981-b80fe463b330?q=80&w=800',
+ description: 'Professional arrangements for corporate events, grand openings, and business celebrations.',
+ features: ['Bulk pricing', 'Professional design', 'Setup service'],
+ },
+ {
+ name: 'Birthday Celebration',
+ price: '$55 - $135',
+ image: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?q=80&w=800',
+ description: 'Vibrant and festive arrangements perfect for birthday celebrations of all ages.',
+ features: ['Bright colors', 'Festive style', 'Add-on balloons available'],
+ },
+ ],
+ },
+]
+
+export default function FlowersPage() {
+ return (
+ <>
+ {/* Hero Section */}
+ <section className="relative py-32 bg-gradient-to-br from-primary-600 to-primary-700 dark:from-primary-700 dark:to-primary-800 text-white mt-16">
+ <div className="container-custom text-center">
+ <h1 className="heading-xl mb-6 text-white">
+ Our Flower Collection
+ </h1>
+ <p className="text-xl max-w-3xl mx-auto leading-relaxed text-gray-100">
+ Explore our selection of premium Ecuadorian roses and custom arrangements. Each flower is hand-selected for quality, freshness, and beauty.
+ </p>
+ </div>
+ </section>
+
+ {/* Category Sections */}
+ {flowerCategories.map((category, categoryIndex) => (
+ <section
+ key={category.id}
+ className={`section-padding ${
+ categoryIndex % 2 === 0 ? 'bg-white dark:bg-gray-900' : 'bg-gray-50 dark:bg-gray-900/50'
+ }`}
+ >
+ <div className="container-custom">
+ <div className="text-center mb-12">
+ <h2 className="heading-md text-gray-900 dark:text-white mb-4">{category.name}</h2>
+ </div>
+
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
+ {category.items.map((item, index) => (
+ <div key={index} className="card group">
+ <div className="relative h-80 overflow-hidden">
+ <div
+ className="absolute inset-0 bg-cover bg-center transform group-hover:scale-110 transition-transform duration-500"
+ style={{ backgroundImage: `url('${item.image}')` }}
+ />
+ </div>
+ <div className="p-6">
+ <h3 className="text-2xl font-bold text-gray-900 dark:text-white mb-2">
+ {item.name}
+ </h3>
+ <p className="text-primary-600 dark:text-primary-400 font-semibold text-xl mb-3">
+ {item.price}
+ </p>
+ <p className="text-gray-600 dark:text-gray-400 mb-4 leading-relaxed">
+ {item.description}
+ </p>
+ <ul className="space-y-1 mb-4">
+ {item.features.map((feature, featureIndex) => (
+ <li
+ key={featureIndex}
+ className="text-sm text-gray-600 dark:text-gray-400 flex items-center"
+ >
+ <span className="w-1.5 h-1.5 bg-primary-500 dark:bg-primary-400 rounded-full mr-2" />
+ {feature}
+ </li>
+ ))}
+ </ul>
+ <a
+ href="tel:+13231234567"
+ className="inline-flex items-center space-x-2 text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 font-medium transition-colors duration-200"
+ >
+ <FaPhone className="text-sm" />
+ <span>Call to Order</span>
+ </a>
+ </div>
+ </div>
+ ))}
+ </div>
+ </div>
+ </section>
+ ))}
+
+ {/* CTA Section */}
+ <section className="section-padding bg-gradient-to-br from-primary-600 to-primary-700 text-white">
+ <div className="container-custom">
+ <div className="max-w-3xl mx-auto text-center">
+ <h2 className="heading-lg text-white mb-6">
+ Need Help Choosing?
+ </h2>
+ <p className="text-xl mb-8 text-gray-100 leading-relaxed">
+ Our flower experts are here to help you create the perfect arrangement for any occasion. Call us for personalized recommendations and custom orders.
+ </p>
+ <div className="flex flex-col sm:flex-row gap-4 justify-center">
+ <a
+ href="tel:+13231234567"
+ className="inline-flex items-center justify-center space-x-2 text-lg px-8 py-4 bg-white text-primary-600 hover:bg-gray-100 rounded-md transition-colors duration-200 font-medium shadow-lg"
+ >
+ <FaPhone />
+ <span>(323) 123-4567</span>
+ </a>
+ </div>
+ <div className="mt-8 pt-8 border-t border-white/20">
+ <h3 className="text-xl font-bold mb-4">Why Our Flowers Stand Out</h3>
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-6 text-left">
+ <div>
+ <h4 className="font-semibold mb-2">Direct from Ecuador</h4>
+ <p className="text-sm text-gray-100">
+ We source directly from highland farms for unmatched quality
+ </p>
+ </div>
+ <div>
+ <h4 className="font-semibold mb-2">Fresh Daily</h4>
+ <p className="text-sm text-gray-100">
+ New shipments arrive daily ensuring maximum freshness
+ </p>
+ </div>
+ <div>
+ <h4 className="font-semibold mb-2">Expert Care</h4>
+ <p className="text-sm text-gray-100">
+ Each stem is hand-selected and prepared with expertise
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+ </>
+ )
+}
diff --git a/app/globals.css b/app/globals.css
new file mode 100644
index 0000000..4af61ae
--- /dev/null
+++ b/app/globals.css
@@ -0,0 +1,134 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer base {
+ :root {
+ --font-inter: 'Inter', system-ui, -apple-system, sans-serif;
+ --font-playfair: 'Playfair Display', Georgia, serif;
+
+ /* Light theme CSS custom properties */
+ --bg-primary: #ffffff;
+ --bg-secondary: #f9fafb;
+ --bg-tertiary: #f3f4f6;
+ --text-primary: #111827;
+ --text-secondary: #4b5563;
+ --text-muted: #6b7280;
+ --border: #e5e7eb;
+ --border-light: #f3f4f6;
+ --shadow: rgba(0, 0, 0, 0.1);
+ --shadow-lg: rgba(0, 0, 0, 0.15);
+
+ /* Hero overlay for light mode */
+ --hero-overlay-start: rgba(123, 35, 68, 0.9);
+ --hero-overlay-end: rgba(208, 56, 98, 0.8);
+ }
+
+ /* Dark theme CSS custom properties */
+ :root[data-theme="dark"],
+ :root.dark {
+ --bg-primary: #030712;
+ --bg-secondary: #111827;
+ --bg-tertiary: #1f2937;
+ --text-primary: #f9fafb;
+ --text-secondary: #9ca3af;
+ --text-muted: #6b7280;
+ --border: #374151;
+ --border-light: #1f2937;
+ --shadow: rgba(0, 0, 0, 0.5);
+ --shadow-lg: rgba(0, 0, 0, 0.7);
+
+ /* Hero overlay for dark mode - slightly darker for better contrast */
+ --hero-overlay-start: rgba(91, 26, 51, 0.95);
+ --hero-overlay-end: rgba(174, 40, 81, 0.9);
+ }
+
+ body {
+ background-color: var(--bg-primary);
+ color: var(--text-primary);
+ @apply transition-colors duration-300;
+ }
+
+ h1, h2, h3, h4, h5, h6 {
+ @apply font-serif;
+ }
+}
+
+@layer components {
+ .container-custom {
+ @apply max-w-7xl mx-auto px-4 sm:px-6 lg:px-8;
+ }
+
+ .btn-primary {
+ @apply inline-flex items-center justify-center px-6 py-3 border border-transparent text-base font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700 dark:bg-primary-500 dark:hover:bg-primary-600 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 dark:focus:ring-offset-gray-900;
+ }
+
+ .btn-secondary {
+ @apply inline-flex items-center justify-center px-6 py-3 border border-gray-300 dark:border-gray-600 text-base font-medium rounded-md text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 dark:focus:ring-offset-gray-900;
+ }
+
+ .section-padding {
+ @apply py-16 md:py-24;
+ }
+
+ .heading-xl {
+ @apply text-4xl sm:text-5xl md:text-6xl font-bold tracking-tight;
+ }
+
+ .heading-lg {
+ @apply text-3xl sm:text-4xl md:text-5xl font-bold tracking-tight;
+ }
+
+ .heading-md {
+ @apply text-2xl sm:text-3xl md:text-4xl font-bold tracking-tight;
+ }
+
+ .card {
+ @apply bg-white dark:bg-gray-800 rounded-lg shadow-md dark:shadow-gray-900/30 overflow-hidden transition-all duration-300 hover:shadow-xl dark:hover:shadow-gray-900/50 hover:-translate-y-1;
+ }
+}
+
+@layer utilities {
+ .text-balance {
+ text-wrap: balance;
+ }
+}
+
+/* Smooth scrolling */
+html {
+ scroll-behavior: smooth;
+}
+
+/* Image loading animation */
+@keyframes shimmer {
+ 0% {
+ background-position: -1000px 0;
+ }
+ 100% {
+ background-position: 1000px 0;
+ }
+}
+
+.animate-shimmer {
+ animation: shimmer 2s infinite linear;
+ background: linear-gradient(to right, #f6f7f8 0%, #edeef1 20%, #f6f7f8 40%, #f6f7f8 100%);
+ background-size: 1000px 100%;
+}
+
+.dark .animate-shimmer {
+ background: linear-gradient(to right, #1f2937 0%, #374151 20%, #1f2937 40%, #1f2937 100%);
+ background-size: 1000px 100%;
+}
+
+/* Dark mode image overlay for better contrast */
+.dark .dark-image-overlay {
+ position: relative;
+}
+
+.dark .dark-image-overlay::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.1);
+ pointer-events: none;
+}
diff --git a/app/icon.svg b/app/icon.svg
new file mode 100644
index 0000000..0bf53be
--- /dev/null
+++ b/app/icon.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+<rect width="32" height="32" rx="6" fill="#10b981"/>
+<text x="50%" y="55%" text-anchor="middle" dominant-baseline="middle" font-size="20" font-family="Apple Color Emoji, Segoe UI Emoji, sans-serif" fill="white">A</text>
+</svg>
\ No newline at end of file
diff --git a/app/layout.tsx b/app/layout.tsx
new file mode 100644
index 0000000..d7740e5
--- /dev/null
+++ b/app/layout.tsx
@@ -0,0 +1,68 @@
+import type { Metadata } from 'next'
+import { Inter, Playfair_Display } from 'next/font/google'
+import './globals.css'
+import Navbar from '@/components/Navbar'
+import Footer from '@/components/Footer'
+import ThemeProvider from '@/components/ThemeProvider'
+
+const inter = Inter({
+ subsets: ['latin'],
+ variable: '--font-inter',
+ display: 'swap',
+})
+
+const playfair = Playfair_Display({
+ subsets: ['latin'],
+ variable: '--font-playfair',
+ display: 'swap',
+})
+
+export const metadata: Metadata = {
+ title: "Angel's Flowers - Premium Ecuadorian Flowers in East Los Angeles",
+ description: 'Family-run flower shop in East LA specializing in premium Ecuadorian roses and arrangements. Bringing the beauty of Ecuador to Los Angeles since 1995.',
+ keywords: 'flowers, ecuadorian roses, east los angeles, flower shop, floral arrangements, roses, premium flowers',
+ openGraph: {
+ title: "Angel's Flowers",
+ description: 'Premium Ecuadorian Flowers in East Los Angeles',
+ type: 'website',
+ },
+}
+
+const themeScript = `
+(function() {
+ try {
+ var savedTheme = localStorage.getItem('theme');
+ var systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
+ var theme = savedTheme || (systemPrefersDark ? 'dark' : 'light');
+ document.documentElement.setAttribute('data-theme', theme);
+ if (theme === 'dark') {
+ document.documentElement.classList.add('dark');
+ } else {
+ document.documentElement.classList.remove('dark');
+ }
+ } catch (e) {}
+})();
+`;
+
+export default function RootLayout({
+ children,
+}: {
+ children: React.ReactNode
+}) {
+ return (
+ <html lang="en" className={`${inter.variable} ${playfair.variable}`} suppressHydrationWarning>
+ <head>
+ <script dangerouslySetInnerHTML={{ __html: themeScript }} />
+ </head>
+ <body className="font-sans antialiased">
+ <ThemeProvider>
+ <Navbar />
+ <main className="min-h-screen">
+ {children}
+ </main>
+ <Footer />
+ </ThemeProvider>
+ </body>
+ </html>
+ )
+}
diff --git a/app/page.tsx b/app/page.tsx
new file mode 100644
index 0000000..f33298b
--- /dev/null
+++ b/app/page.tsx
@@ -0,0 +1,244 @@
+import Link from 'next/link'
+import Image from 'next/image'
+import { FaHeart, FaLeaf, FaTruck, FaPhone } from 'react-icons/fa'
+
+export default function HomePage() {
+ return (
+ <>
+ {/* Hero Section */}
+ <section className="relative h-screen min-h-[600px] flex items-center justify-center overflow-hidden">
+ {/* Background Image with theme-aware overlay */}
+ <div
+ className="absolute inset-0 z-10"
+ style={{
+ background: 'linear-gradient(to bottom right, var(--hero-overlay-start), var(--hero-overlay-end))',
+ }}
+ />
+ <div
+ className="absolute inset-0 bg-cover bg-center"
+ style={{
+ backgroundImage: "url('https://images.unsplash.com/photo-1490750967868-88aa4486c946?q=80&w=2070')",
+ }}
+ />
+
+ {/* Content */}
+ <div className="relative z-20 container-custom text-center">
+ <h1 className="heading-xl mb-6 text-white animate-fade-in">
+ Premium Ecuadorian Flowers
+ <br />
+ <span className="text-pink-200 dark:text-pink-300">Straight from the Heart</span>
+ </h1>
+ <p className="text-xl md:text-2xl mb-8 max-w-3xl mx-auto leading-relaxed text-white/95 dark:text-white/90">
+ Family-owned since 1995, bringing East Los Angeles the finest roses and arrangements from the highlands of Ecuador
+ </p>
+ <div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
+ <Link href="/flowers" className="btn-primary text-lg px-8 py-4 shadow-lg">
+ Browse Our Flowers
+ </Link>
+ <a
+ href="tel:+13231234567"
+ className="inline-flex items-center space-x-2 text-lg px-8 py-4 border-2 border-white text-white hover:bg-white hover:text-primary-600 dark:hover:text-primary-700 rounded-md transition-all duration-200 font-medium shadow-lg"
+ >
+ <FaPhone />
+ <span>Call to Order</span>
+ </a>
+ </div>
+ </div>
+
+ {/* Scroll Indicator */}
+ <div className="absolute bottom-8 left-1/2 -translate-x-1/2 z-20 animate-bounce">
+ <div className="w-6 h-10 border-2 border-white rounded-full flex justify-center">
+ <div className="w-1 h-3 bg-white rounded-full mt-2" />
+ </div>
+ </div>
+ </section>
+
+ {/* Why Choose Us Section */}
+ <section className="section-padding" style={{ backgroundColor: 'var(--bg-primary)' }}>
+ <div className="container-custom">
+ <div className="text-center mb-16">
+ <h2 className="heading-lg text-gray-900 dark:text-white mb-4">
+ Why Choose Angel's Flowers?
+ </h2>
+ <p className="text-lg text-gray-600 dark:text-gray-400 max-w-2xl mx-auto">
+ Over 25 years of excellence, delivering fresh Ecuadorian blooms to our community
+ </p>
+ </div>
+
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
+ {[
+ {
+ icon: <FaLeaf className="w-8 h-8" />,
+ title: 'Ecuadorian Quality',
+ description: 'Direct from Ecuador\'s highland farms, where perfect conditions produce the world\'s finest roses',
+ },
+ {
+ icon: <FaHeart className="w-8 h-8" />,
+ title: 'Family Tradition',
+ description: 'Three generations of flower expertise, treating every customer like family',
+ },
+ {
+ icon: <FaTruck className="w-8 h-8" />,
+ title: 'Fresh Daily',
+ description: 'New shipments arrive fresh daily, ensuring maximum vase life and vibrant colors',
+ },
+ {
+ icon: <FaPhone className="w-8 h-8" />,
+ title: 'Personal Service',
+ description: 'Expert advice and custom arrangements tailored to your special occasion',
+ },
+ ].map((feature, index) => (
+ <div
+ key={index}
+ className="text-center p-6 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors duration-300"
+ >
+ <div className="inline-flex items-center justify-center w-16 h-16 bg-primary-100 dark:bg-primary-900/30 text-primary-600 dark:text-primary-400 rounded-full mb-4">
+ {feature.icon}
+ </div>
+ <h3 className="text-xl font-bold text-gray-900 dark:text-white mb-2">
+ {feature.title}
+ </h3>
+ <p className="text-gray-600 dark:text-gray-400 leading-relaxed">
+ {feature.description}
+ </p>
+ </div>
+ ))}
+ </div>
+ </div>
+ </section>
+
+ {/* Featured Flowers Section */}
+ <section className="section-padding" style={{ backgroundColor: 'var(--bg-secondary)' }}>
+ <div className="container-custom">
+ <div className="text-center mb-16">
+ <h2 className="heading-lg text-gray-900 dark:text-white mb-4">
+ Featured Collections
+ </h2>
+ <p className="text-lg text-gray-600 dark:text-gray-400 max-w-2xl mx-auto">
+ Handpicked selections from our premium Ecuadorian collection
+ </p>
+ </div>
+
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
+ {[
+ {
+ name: 'Premium Red Roses',
+ price: '$45 - $120',
+ image: 'https://images.unsplash.com/photo-1582794543139-8ac9cb0f7b11?q=80&w=800',
+ description: 'Velvety Ecuadorian roses with larger blooms and longer stems',
+ },
+ {
+ name: 'Rainbow Collection',
+ price: '$55 - $135',
+ image: 'https://images.unsplash.com/photo-1563241527-3004b7be0ffd?q=80&w=800',
+ description: 'Vibrant multi-colored roses in stunning arrangements',
+ },
+ {
+ name: 'Garden Fresh Bouquets',
+ price: '$40 - $95',
+ image: 'https://images.unsplash.com/photo-1518709268805-4e9042af9f23?q=80&w=800',
+ description: 'Mixed seasonal flowers with eucalyptus and greenery',
+ },
+ ].map((flower, index) => (
+ <div key={index} className="card group">
+ <div className="relative h-80 overflow-hidden">
+ <div
+ className="absolute inset-0 bg-cover bg-center transform group-hover:scale-110 transition-transform duration-500"
+ style={{ backgroundImage: `url('${flower.image}')` }}
+ />
+ </div>
+ <div className="p-6">
+ <h3 className="text-2xl font-bold text-gray-900 dark:text-white mb-2">
+ {flower.name}
+ </h3>
+ <p className="text-primary-600 dark:text-primary-400 font-semibold text-lg mb-3">
+ {flower.price}
+ </p>
+ <p className="text-gray-600 dark:text-gray-400 mb-4 leading-relaxed">
+ {flower.description}
+ </p>
+ <Link
+ href="/flowers"
+ className="inline-block text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 font-medium transition-colors duration-200"
+ >
+ View Collection →
+ </Link>
+ </div>
+ </div>
+ ))}
+ </div>
+
+ <div className="text-center mt-12">
+ <Link href="/flowers" className="btn-primary text-lg">
+ View All Flowers
+ </Link>
+ </div>
+ </div>
+ </section>
+
+ {/* Family Story Preview Section */}
+ <section className="section-padding" style={{ backgroundColor: 'var(--bg-primary)' }}>
+ <div className="container-custom">
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
+ <div className="relative h-[400px] lg:h-[500px] rounded-lg overflow-hidden shadow-xl dark:shadow-gray-900/50">
+ <div
+ className="absolute inset-0 bg-cover bg-center"
+ style={{
+ backgroundImage: "url('https://images.unsplash.com/photo-1542838132-92c53300491e?q=80&w=1000')",
+ }}
+ />
+ </div>
+
+ <div className="space-y-6">
+ <h2 className="heading-lg text-gray-900 dark:text-white">
+ Three Generations of Flower Excellence
+ </h2>
+ <div className="space-y-4 text-lg text-gray-600 dark:text-gray-400 leading-relaxed">
+ <p>
+ Angel's Flowers began in 1995 when our grandmother, Angel, brought her love of Ecuadorian roses from Quito to East Los Angeles. What started in a small storefront has blossomed into a beloved family tradition.
+ </p>
+ <p>
+ Today, we continue Angel's vision of bringing the breathtaking beauty of Ecuador's finest flowers to our community. Each rose we offer comes from the same highland farms that inspired our grandmother's passion three decades ago.
+ </p>
+ <p className="text-primary-600 dark:text-primary-400 font-semibold">
+ "Every flower has a story. We're honored to be part of yours."
+ <span className="block text-sm mt-2 text-gray-500 dark:text-gray-500">- The Martinez Family</span>
+ </p>
+ </div>
+ <Link href="/about" className="btn-primary inline-block">
+ Read Our Full Story
+ </Link>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ {/* CTA Section */}
+ <section className="section-padding bg-gradient-to-br from-primary-600 to-primary-700 dark:from-primary-800 dark:to-primary-900 text-white">
+ <div className="container-custom text-center">
+ <h2 className="heading-lg text-white mb-6">
+ Ready to Brighten Someone's Day?
+ </h2>
+ <p className="text-xl mb-8 max-w-2xl mx-auto text-white/95 dark:text-white/90">
+ Call us today or visit our East LA shop to create the perfect arrangement for any occasion
+ </p>
+ <div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
+ <a
+ href="tel:+13231234567"
+ className="inline-flex items-center space-x-2 text-lg px-8 py-4 bg-white text-primary-600 hover:bg-gray-100 dark:hover:bg-gray-200 rounded-md transition-colors duration-200 font-medium shadow-lg"
+ >
+ <FaPhone />
+ <span>(323) 123-4567</span>
+ </a>
+ <Link
+ href="/contact"
+ className="inline-flex items-center space-x-2 text-lg px-8 py-4 border-2 border-white text-white hover:bg-white hover:text-primary-600 dark:hover:text-primary-700 rounded-md transition-all duration-200 font-medium"
+ >
+ Visit Us in East LA
+ </Link>
+ </div>
+ </div>
+ </section>
+ </>
+ )
+}
diff --git a/app/sitemap.ts b/app/sitemap.ts
new file mode 100644
index 0000000..0e05b93
--- /dev/null
+++ b/app/sitemap.ts
@@ -0,0 +1,32 @@
+import { MetadataRoute } from 'next'
+
+export default function sitemap(): MetadataRoute.Sitemap {
+ const baseUrl = 'https://angelsflowers.com' // Update with actual domain
+
+ return [
+ {
+ url: baseUrl,
+ lastModified: new Date(),
+ changeFrequency: 'daily',
+ priority: 1,
+ },
+ {
+ url: `${baseUrl}/flowers`,
+ lastModified: new Date(),
+ changeFrequency: 'daily',
+ priority: 0.9,
+ },
+ {
+ url: `${baseUrl}/about`,
+ lastModified: new Date(),
+ changeFrequency: 'monthly',
+ priority: 0.8,
+ },
+ {
+ url: `${baseUrl}/contact`,
+ lastModified: new Date(),
+ changeFrequency: 'monthly',
+ priority: 0.7,
+ },
+ ]
+}
diff --git a/components/Footer.tsx b/components/Footer.tsx
new file mode 100644
index 0000000..f0f946f
--- /dev/null
+++ b/components/Footer.tsx
@@ -0,0 +1,154 @@
+import Link from 'next/link'
+import { FaPhone, FaEnvelope, FaMapMarkerAlt, FaFacebook, FaInstagram, FaTwitter } from 'react-icons/fa'
+
+export default function Footer() {
+ const currentYear = new Date().getFullYear()
+
+ return (
+ <footer className="bg-gray-900 dark:bg-gray-950 text-gray-300 dark:text-gray-400">
+ <div className="container-custom py-12 md:py-16">
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 md:gap-12">
+ {/* About Section */}
+ <div className="space-y-4">
+ <div className="flex items-center space-x-2">
+ <div className="w-8 h-8 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center">
+ <span className="text-white text-lg font-bold">A</span>
+ </div>
+ <span className="font-serif text-xl font-bold text-white">
+ Angel's Flowers
+ </span>
+ </div>
+ <p className="text-sm leading-relaxed">
+ Family-run flower shop in East Los Angeles, bringing you the finest Ecuadorian flowers since 1995. Every bloom tells a story.
+ </p>
+ <div className="flex space-x-4">
+ <a
+ href="https://facebook.com"
+ target="_blank"
+ rel="noopener noreferrer"
+ className="w-8 h-8 rounded-full bg-gray-800 dark:bg-gray-800 hover:bg-primary-600 dark:hover:bg-primary-500 flex items-center justify-center transition-colors duration-200"
+ aria-label="Facebook"
+ >
+ <FaFacebook className="text-sm" />
+ </a>
+ <a
+ href="https://instagram.com"
+ target="_blank"
+ rel="noopener noreferrer"
+ className="w-8 h-8 rounded-full bg-gray-800 dark:bg-gray-800 hover:bg-primary-600 dark:hover:bg-primary-500 flex items-center justify-center transition-colors duration-200"
+ aria-label="Instagram"
+ >
+ <FaInstagram className="text-sm" />
+ </a>
+ <a
+ href="https://twitter.com"
+ target="_blank"
+ rel="noopener noreferrer"
+ className="w-8 h-8 rounded-full bg-gray-800 dark:bg-gray-800 hover:bg-primary-600 dark:hover:bg-primary-500 flex items-center justify-center transition-colors duration-200"
+ aria-label="Twitter"
+ >
+ <FaTwitter className="text-sm" />
+ </a>
+ </div>
+ </div>
+
+ {/* Quick Links */}
+ <div>
+ <h3 className="text-white dark:text-gray-100 font-semibold text-lg mb-4">Quick Links</h3>
+ <ul className="space-y-2">
+ <li>
+ <Link
+ href="/"
+ className="text-sm hover:text-primary-400 dark:hover:text-primary-300 transition-colors duration-200"
+ >
+ Home
+ </Link>
+ </li>
+ <li>
+ <Link
+ href="/flowers"
+ className="text-sm hover:text-primary-400 dark:hover:text-primary-300 transition-colors duration-200"
+ >
+ Flowers
+ </Link>
+ </li>
+ <li>
+ <Link
+ href="/about"
+ className="text-sm hover:text-primary-400 dark:hover:text-primary-300 transition-colors duration-200"
+ >
+ Our Story
+ </Link>
+ </li>
+ <li>
+ <Link
+ href="/contact"
+ className="text-sm hover:text-primary-400 dark:hover:text-primary-300 transition-colors duration-200"
+ >
+ Contact
+ </Link>
+ </li>
+ </ul>
+ </div>
+
+ {/* Contact Info */}
+ <div>
+ <h3 className="text-white dark:text-gray-100 font-semibold text-lg mb-4">Contact Us</h3>
+ <ul className="space-y-3">
+ <li className="flex items-start space-x-3">
+ <FaMapMarkerAlt className="text-primary-400 dark:text-primary-300 mt-1 flex-shrink-0" />
+ <span className="text-sm">
+ 1234 East Los Angeles Ave<br />
+ East Los Angeles, CA 90022
+ </span>
+ </li>
+ <li className="flex items-center space-x-3">
+ <FaPhone className="text-primary-400 dark:text-primary-300 flex-shrink-0" />
+ <a
+ href="tel:+13231234567"
+ className="text-sm hover:text-primary-400 dark:hover:text-primary-300 transition-colors duration-200"
+ >
+ (323) 123-4567
+ </a>
+ </li>
+ <li className="flex items-center space-x-3">
+ <FaEnvelope className="text-primary-400 dark:text-primary-300 flex-shrink-0" />
+ <a
+ href="mailto:info@angelsflowers.com"
+ className="text-sm hover:text-primary-400 dark:hover:text-primary-300 transition-colors duration-200"
+ >
+ info@angelsflowers.com
+ </a>
+ </li>
+ </ul>
+ </div>
+
+ {/* Business Hours */}
+ <div>
+ <h3 className="text-white dark:text-gray-100 font-semibold text-lg mb-4">Business Hours</h3>
+ <ul className="space-y-2 text-sm">
+ <li className="flex justify-between">
+ <span>Monday - Friday:</span>
+ <span className="text-white dark:text-gray-100">9am - 7pm</span>
+ </li>
+ <li className="flex justify-between">
+ <span>Saturday:</span>
+ <span className="text-white dark:text-gray-100">9am - 6pm</span>
+ </li>
+ <li className="flex justify-between">
+ <span>Sunday:</span>
+ <span className="text-white dark:text-gray-100">10am - 4pm</span>
+ </li>
+ </ul>
+ </div>
+ </div>
+
+ <div className="border-t border-gray-800 dark:border-gray-700 mt-12 pt-8 text-center text-sm">
+ <p>
+ © {currentYear} Angel's Flowers. All rights reserved. | Handcrafted with love in East LA
+ </p>
+ </div>
+ </div>
+ </footer>
+ )
+}
diff --git a/components/Navbar.tsx b/components/Navbar.tsx
new file mode 100644
index 0000000..fff816a
--- /dev/null
+++ b/components/Navbar.tsx
@@ -0,0 +1,130 @@
+'use client'
+
+import { useState, useEffect } from 'react'
+import Link from 'next/link'
+import { usePathname } from 'next/navigation'
+import { FaPhone, FaBars, FaTimes } from 'react-icons/fa'
+import ThemeToggle from './ThemeToggle'
+
+const navigation = [
+ { name: 'Home', href: '/' },
+ { name: 'Flowers', href: '/flowers' },
+ { name: 'Our Story', href: '/about' },
+ { name: 'Contact', href: '/contact' },
+]
+
+export default function Navbar() {
+ const [isScrolled, setIsScrolled] = useState(false)
+ const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false)
+ const pathname = usePathname()
+
+ useEffect(() => {
+ const handleScroll = () => {
+ setIsScrolled(window.scrollY > 10)
+ }
+
+ window.addEventListener('scroll', handleScroll)
+ return () => window.removeEventListener('scroll', handleScroll)
+ }, [])
+
+ const isActive = (path: string) => pathname === path
+
+ return (
+ <nav
+ className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
+ isScrolled
+ ? 'bg-white dark:bg-gray-900 shadow-md dark:shadow-gray-900/50 py-2'
+ : 'bg-white/95 dark:bg-gray-900/95 backdrop-blur-sm py-4'
+ }`}
+ >
+ <div className="container-custom">
+ <div className="flex items-center justify-between">
+ {/* Logo */}
+ <Link href="/" className="flex items-center space-x-2">
+ <div className="w-10 h-10 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center">
+ <span className="text-white text-xl font-bold">A</span>
+ </div>
+ <div className="flex flex-col">
+ <span className="font-serif text-xl font-bold text-gray-900 dark:text-white leading-tight">
+ Angel's Flowers
+ </span>
+ <span className="text-xs text-gray-600 dark:text-gray-400 leading-tight">
+ East Los Angeles
+ </span>
+ </div>
+ </Link>
+
+ {/* Desktop Navigation */}
+ <div className="hidden md:flex items-center space-x-8">
+ {navigation.map((item) => (
+ <Link
+ key={item.name}
+ href={item.href}
+ className={`text-sm font-medium transition-colors duration-200 ${
+ isActive(item.href)
+ ? 'text-primary-600 dark:text-primary-400'
+ : 'text-gray-700 dark:text-gray-300 hover:text-primary-600 dark:hover:text-primary-400'
+ }`}
+ >
+ {item.name}
+ </Link>
+ ))}
+ <ThemeToggle />
+ <a
+ href="tel:+13231234567"
+ className="flex items-center space-x-2 text-sm font-medium text-white bg-primary-600 hover:bg-primary-700 dark:bg-primary-500 dark:hover:bg-primary-600 px-4 py-2 rounded-md transition-colors duration-200"
+ >
+ <FaPhone className="text-xs" />
+ <span>(323) 123-4567</span>
+ </a>
+ </div>
+
+ {/* Mobile Menu Button */}
+ <div className="md:hidden flex items-center space-x-2">
+ <ThemeToggle />
+ <button
+ onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
+ className="p-2 rounded-md text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors duration-200"
+ aria-label="Toggle menu"
+ >
+ {isMobileMenuOpen ? (
+ <FaTimes className="w-6 h-6" />
+ ) : (
+ <FaBars className="w-6 h-6" />
+ )}
+ </button>
+ </div>
+ </div>
+
+ {/* Mobile Menu */}
+ {isMobileMenuOpen && (
+ <div className="md:hidden mt-4 pb-4 border-t border-gray-200 dark:border-gray-700">
+ <div className="pt-4 space-y-3">
+ {navigation.map((item) => (
+ <Link
+ key={item.name}
+ href={item.href}
+ onClick={() => setIsMobileMenuOpen(false)}
+ className={`block px-4 py-2 rounded-md text-base font-medium transition-colors duration-200 ${
+ isActive(item.href)
+ ? 'text-primary-600 dark:text-primary-400 bg-primary-50 dark:bg-primary-900/20'
+ : 'text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800'
+ }`}
+ >
+ {item.name}
+ </Link>
+ ))}
+ <a
+ href="tel:+13231234567"
+ className="flex items-center justify-center space-x-2 px-4 py-3 rounded-md text-base font-medium text-white bg-primary-600 hover:bg-primary-700 dark:bg-primary-500 dark:hover:bg-primary-600 transition-colors duration-200"
+ >
+ <FaPhone className="text-sm" />
+ <span>(323) 123-4567</span>
+ </a>
+ </div>
+ </div>
+ )}
+ </div>
+ </nav>
+ )
+}
diff --git a/components/ThemeProvider.tsx b/components/ThemeProvider.tsx
new file mode 100644
index 0000000..8abbf66
--- /dev/null
+++ b/components/ThemeProvider.tsx
@@ -0,0 +1,122 @@
+'use client'
+
+import { createContext, useContext, useEffect, useState, ReactNode, useCallback } from 'react'
+
+type Theme = 'light' | 'dark'
+
+interface ThemeContextType {
+ theme: Theme
+ toggleTheme: () => void
+}
+
+const ThemeContext = createContext<ThemeContextType | undefined>(undefined)
+
+export function useTheme() {
+ const context = useContext(ThemeContext)
+ if (!context) {
+ throw new Error('useTheme must be used within a ThemeProvider')
+ }
+ return context
+}
+
+interface ThemeProviderProps {
+ children: ReactNode
+}
+
+function getInitialTheme(): Theme {
+ if (typeof window === 'undefined') {
+ return 'light'
+ }
+
+ try {
+ const savedTheme = localStorage.getItem('theme') as Theme | null
+ if (savedTheme === 'light' || savedTheme === 'dark') {
+ return savedTheme
+ }
+
+ if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
+ return 'dark'
+ }
+ } catch {
+ // Handle cases where localStorage is not available (e.g., private browsing)
+ }
+
+ return 'light'
+}
+
+export default function ThemeProvider({ children }: ThemeProviderProps) {
+ const [theme, setTheme] = useState<Theme>(getInitialTheme)
+ const [mounted, setMounted] = useState(false)
+
+ // Apply theme to document
+ const applyTheme = useCallback((newTheme: Theme) => {
+ const root = document.documentElement
+ root.setAttribute('data-theme', newTheme)
+ if (newTheme === 'dark') {
+ root.classList.add('dark')
+ } else {
+ root.classList.remove('dark')
+ }
+ }, [])
+
+ // Initialize on mount
+ useEffect(() => {
+ setMounted(true)
+
+ // Sync with what the inline script may have already set
+ const currentTheme = getInitialTheme()
+ setTheme(currentTheme)
+ applyTheme(currentTheme)
+ }, [applyTheme])
+
+ // Listen for system theme changes
+ useEffect(() => {
+ if (!mounted) return
+
+ const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
+
+ const handleChange = (e: MediaQueryListEvent) => {
+ // Only update if user hasn't set a preference
+ const savedTheme = localStorage.getItem('theme')
+ if (!savedTheme) {
+ const newTheme = e.matches ? 'dark' : 'light'
+ setTheme(newTheme)
+ applyTheme(newTheme)
+ }
+ }
+
+ // Modern browsers
+ if (mediaQuery.addEventListener) {
+ mediaQuery.addEventListener('change', handleChange)
+ return () => mediaQuery.removeEventListener('change', handleChange)
+ }
+
+ // Fallback for older browsers
+ mediaQuery.addListener(handleChange)
+ return () => mediaQuery.removeListener(handleChange)
+ }, [mounted, applyTheme])
+
+ // Persist theme changes
+ useEffect(() => {
+ if (!mounted) return
+
+ applyTheme(theme)
+ try {
+ localStorage.setItem('theme', theme)
+ } catch {
+ // Handle localStorage unavailable
+ }
+ }, [theme, mounted, applyTheme])
+
+ const toggleTheme = useCallback(() => {
+ setTheme((prev) => (prev === 'light' ? 'dark' : 'light'))
+ }, [])
+
+ // Render children even before mount to avoid layout shift
+ // The inline script in layout.tsx handles the initial theme
+ return (
+ <ThemeContext.Provider value={{ theme, toggleTheme }}>
+ {children}
+ </ThemeContext.Provider>
+ )
+}
diff --git a/components/ThemeToggle.tsx b/components/ThemeToggle.tsx
new file mode 100644
index 0000000..345a60c
--- /dev/null
+++ b/components/ThemeToggle.tsx
@@ -0,0 +1,29 @@
+'use client'
+
+import { FaSun, FaMoon } from 'react-icons/fa'
+import { useTheme } from './ThemeProvider'
+
+interface ThemeToggleProps {
+ className?: string
+}
+
+export default function ThemeToggle({ className = '' }: ThemeToggleProps) {
+ const { theme, toggleTheme } = useTheme()
+ const isDark = theme === 'dark'
+
+ return (
+ <button
+ onClick={toggleTheme}
+ className={`p-2 rounded-md text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors duration-200 ${className}`}
+ aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
+ aria-pressed={isDark}
+ type="button"
+ >
+ {isDark ? (
+ <FaSun className="w-5 h-5 text-yellow-500" aria-hidden="true" />
+ ) : (
+ <FaMoon className="w-5 h-5 text-gray-600" aria-hidden="true" />
+ )}
+ </button>
+ )
+}
diff --git a/components/__tests__/ThemeProvider.test.tsx b/components/__tests__/ThemeProvider.test.tsx
new file mode 100644
index 0000000..bf70e85
--- /dev/null
+++ b/components/__tests__/ThemeProvider.test.tsx
@@ -0,0 +1,473 @@
+import { render, screen, act, waitFor } from '@/test-utils';
+import { renderHook } from '@testing-library/react';
+import ThemeProvider, { useTheme } from '../ThemeProvider';
+
+// Mock localStorage
+const localStorageMock = (() => {
+ let store: Record<string, string> = {};
+
+ return {
+ getItem: jest.fn((key: string) => store[key] || null),
+ setItem: jest.fn((key: string, value: string) => {
+ store[key] = value.toString();
+ }),
+ removeItem: jest.fn((key: string) => {
+ delete store[key];
+ }),
+ clear: jest.fn(() => {
+ store = {};
+ }),
+ };
+})();
+
+Object.defineProperty(window, 'localStorage', {
+ value: localStorageMock,
+});
+
+// Mock matchMedia
+const createMatchMediaMock = (matches: boolean) => {
+ return jest.fn().mockImplementation((query: string) => ({
+ matches,
+ media: query,
+ onchange: null,
+ addListener: jest.fn(),
+ removeListener: jest.fn(),
+ addEventListener: jest.fn(),
+ removeEventListener: jest.fn(),
+ dispatchEvent: jest.fn(),
+ }));
+};
+
+describe('ThemeProvider', () => {
+ beforeEach(() => {
+ // Clear and reset localStorage mock completely
+ localStorageMock.clear();
+ localStorageMock.getItem.mockClear();
+ localStorageMock.setItem.mockClear();
+ localStorageMock.removeItem.mockClear();
+ localStorageMock.getItem.mockReturnValue(null); // Reset to default return value
+ jest.clearAllMocks();
+
+ // Default matchMedia mock (light mode)
+ window.matchMedia = createMatchMediaMock(false);
+
+ // Mock document.documentElement
+ document.documentElement.setAttribute = jest.fn();
+ document.documentElement.classList.add = jest.fn();
+ document.documentElement.classList.remove = jest.fn();
+ });
+
+ describe('ThemeProvider renders children correctly', () => {
+ it('should render children without crashing', () => {
+ render(
+ <ThemeProvider>
+ <div>Test Child</div>
+ </ThemeProvider>
+ );
+
+ expect(screen.getByText('Test Child')).toBeInTheDocument();
+ });
+
+ it('should render multiple children', () => {
+ render(
+ <ThemeProvider>
+ <div>First Child</div>
+ <div>Second Child</div>
+ </ThemeProvider>
+ );
+
+ expect(screen.getByText('First Child')).toBeInTheDocument();
+ expect(screen.getByText('Second Child')).toBeInTheDocument();
+ });
+ });
+
+ describe('useTheme hook returns correct initial theme', () => {
+ it('should return light theme by default', () => {
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ expect(result.current.theme).toBe('light');
+ expect(typeof result.current.toggleTheme).toBe('function');
+ });
+
+ it('should throw error when useTheme is used outside ThemeProvider', () => {
+ // Suppress console.error for this test
+ const consoleSpy = jest.spyOn(console, 'error').mockImplementation();
+
+ expect(() => {
+ renderHook(() => useTheme());
+ }).toThrow('useTheme must be used within a ThemeProvider');
+
+ consoleSpy.mockRestore();
+ });
+
+ it('should return saved theme from localStorage', async () => {
+ localStorageMock.getItem.mockReturnValue('dark');
+
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('dark');
+ });
+ });
+
+ it('should ignore invalid localStorage values', async () => {
+ localStorageMock.getItem.mockReturnValueOnce('invalid-theme');
+
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('light');
+ });
+ });
+ });
+
+ describe('toggleTheme function switches between light and dark', () => {
+ it('should toggle from light to dark', async () => {
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ expect(result.current.theme).toBe('light');
+
+ act(() => {
+ result.current.toggleTheme();
+ });
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('dark');
+ });
+ });
+
+ it('should toggle from dark to light', async () => {
+ localStorageMock.getItem.mockReturnValue('dark');
+
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('dark');
+ });
+
+ act(() => {
+ result.current.toggleTheme();
+ });
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('light');
+ });
+ });
+
+ it('should toggle multiple times correctly', async () => {
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ expect(result.current.theme).toBe('light');
+
+ // Toggle to dark
+ act(() => {
+ result.current.toggleTheme();
+ });
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('dark');
+ });
+
+ // Toggle back to light
+ act(() => {
+ result.current.toggleTheme();
+ });
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('light');
+ });
+
+ // Toggle to dark again
+ act(() => {
+ result.current.toggleTheme();
+ });
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('dark');
+ });
+ });
+ });
+
+ describe('localStorage persistence on theme change', () => {
+ it('should persist theme to localStorage on toggle', async () => {
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ act(() => {
+ result.current.toggleTheme();
+ });
+
+ await waitFor(() => {
+ expect(localStorageMock.setItem).toHaveBeenCalledWith('theme', 'dark');
+ });
+ });
+
+ it('should persist light theme to localStorage', async () => {
+ localStorageMock.getItem.mockReturnValue('dark');
+
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('dark');
+ });
+
+ act(() => {
+ result.current.toggleTheme();
+ });
+
+ await waitFor(() => {
+ expect(localStorageMock.setItem).toHaveBeenCalledWith('theme', 'light');
+ });
+ });
+
+ it('should handle localStorage errors gracefully', async () => {
+ localStorageMock.setItem.mockImplementationOnce(() => {
+ throw new Error('localStorage is not available');
+ });
+
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ // Should not throw error
+ expect(() => {
+ act(() => {
+ result.current.toggleTheme();
+ });
+ }).not.toThrow();
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('dark');
+ });
+ });
+ });
+
+ describe('system preference detection', () => {
+ it('should detect dark system preference when no saved theme', async () => {
+ window.matchMedia = createMatchMediaMock(true);
+
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('dark');
+ });
+ });
+
+ it('should detect light system preference when no saved theme', async () => {
+ window.matchMedia = createMatchMediaMock(false);
+
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('light');
+ });
+ });
+
+ it('should prioritize saved theme over system preference', async () => {
+ localStorageMock.getItem.mockReturnValue('light');
+ window.matchMedia = createMatchMediaMock(true); // System prefers dark
+
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('light');
+ });
+ });
+
+ it('should listen for system theme changes when no saved preference', async () => {
+ let changeHandler: ((e: MediaQueryListEvent) => void) | null = null;
+
+ window.matchMedia = jest.fn().mockImplementation((query: string) => ({
+ matches: false,
+ media: query,
+ onchange: null,
+ addListener: jest.fn(),
+ removeListener: jest.fn(),
+ addEventListener: jest.fn((event: string, handler: (e: MediaQueryListEvent) => void) => {
+ if (event === 'change') {
+ changeHandler = handler;
+ }
+ }),
+ removeEventListener: jest.fn(),
+ dispatchEvent: jest.fn(),
+ }));
+
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ // Wait for mount and event listener setup
+ await waitFor(() => {
+ expect(changeHandler).not.toBeNull();
+ });
+
+ expect(result.current.theme).toBe('light');
+
+ // Simulate system theme change to dark
+ if (changeHandler) {
+ act(() => {
+ changeHandler({ matches: true } as MediaQueryListEvent);
+ });
+ }
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('dark');
+ });
+ });
+
+ it('should not update theme on system change if user has saved preference', async () => {
+ localStorageMock.getItem.mockReturnValue('light');
+ let changeHandler: ((e: MediaQueryListEvent) => void) | null = null;
+
+ window.matchMedia = jest.fn().mockImplementation((query: string) => ({
+ matches: false,
+ media: query,
+ onchange: null,
+ addListener: jest.fn(),
+ removeListener: jest.fn(),
+ addEventListener: jest.fn((event: string, handler: (e: MediaQueryListEvent) => void) => {
+ if (event === 'change') {
+ changeHandler = handler;
+ }
+ }),
+ removeEventListener: jest.fn(),
+ dispatchEvent: jest.fn(),
+ }));
+
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('light');
+ });
+
+ // Simulate system theme change to dark
+ if (changeHandler) {
+ act(() => {
+ changeHandler({ matches: true } as MediaQueryListEvent);
+ });
+ }
+
+ // Should remain light because user has saved preference
+ await waitFor(() => {
+ expect(result.current.theme).toBe('light');
+ });
+ });
+ });
+
+ describe('DOM manipulation', () => {
+ it('should apply data-theme attribute to document root', async () => {
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ await waitFor(() => {
+ expect(document.documentElement.setAttribute).toHaveBeenCalledWith(
+ 'data-theme',
+ 'light'
+ );
+ });
+
+ act(() => {
+ result.current.toggleTheme();
+ });
+
+ await waitFor(() => {
+ expect(document.documentElement.setAttribute).toHaveBeenCalledWith(
+ 'data-theme',
+ 'dark'
+ );
+ });
+ });
+
+ it('should add dark class in dark mode', async () => {
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ act(() => {
+ result.current.toggleTheme();
+ });
+
+ await waitFor(() => {
+ expect(document.documentElement.classList.add).toHaveBeenCalledWith('dark');
+ });
+ });
+
+ it('should remove dark class in light mode', async () => {
+ localStorageMock.getItem.mockReturnValue('dark');
+
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
+ <ThemeProvider>{children}</ThemeProvider>
+ );
+
+ const { result } = renderHook(() => useTheme(), { wrapper });
+
+ await waitFor(() => {
+ expect(result.current.theme).toBe('dark');
+ });
+
+ act(() => {
+ result.current.toggleTheme();
+ });
+
+ await waitFor(() => {
+ expect(document.documentElement.classList.remove).toHaveBeenCalledWith('dark');
+ });
+ });
+ });
+});
diff --git a/components/__tests__/ThemeToggle.test.tsx b/components/__tests__/ThemeToggle.test.tsx
new file mode 100644
index 0000000..9c4b734
--- /dev/null
+++ b/components/__tests__/ThemeToggle.test.tsx
@@ -0,0 +1,116 @@
+import { render, screen } from '@/test-utils';
+import ThemeToggle from '../ThemeToggle';
+import { useTheme } from '../ThemeProvider';
+
+// Mock the useTheme hook
+jest.mock('../ThemeProvider', () => ({
+ useTheme: jest.fn(),
+}));
+
+describe('ThemeToggle', () => {
+ const mockToggleTheme = jest.fn();
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('renders the toggle button', () => {
+ (useTheme as jest.Mock).mockReturnValue({
+ theme: 'light',
+ toggleTheme: mockToggleTheme,
+ });
+
+ render(<ThemeToggle />);
+
+ const button = screen.getByRole('button');
+ expect(button).toBeInTheDocument();
+ });
+
+ it('displays sun icon in dark mode', () => {
+ (useTheme as jest.Mock).mockReturnValue({
+ theme: 'dark',
+ toggleTheme: mockToggleTheme,
+ });
+
+ render(<ThemeToggle />);
+
+ const button = screen.getByRole('button');
+ expect(button).toHaveAttribute('aria-label', 'Switch to light mode');
+ expect(button).toHaveAttribute('aria-pressed', 'true');
+ });
+
+ it('displays moon icon in light mode', () => {
+ (useTheme as jest.Mock).mockReturnValue({
+ theme: 'light',
+ toggleTheme: mockToggleTheme,
+ });
+
+ render(<ThemeToggle />);
+
+ const button = screen.getByRole('button');
+ expect(button).toHaveAttribute('aria-label', 'Switch to dark mode');
+ expect(button).toHaveAttribute('aria-pressed', 'false');
+ });
+
+ it('calls toggleTheme when clicked', () => {
+ (useTheme as jest.Mock).mockReturnValue({
+ theme: 'light',
+ toggleTheme: mockToggleTheme,
+ });
+
+ render(<ThemeToggle />);
+
+ const button = screen.getByRole('button');
+ button.click();
+
+ expect(mockToggleTheme).toHaveBeenCalledTimes(1);
+ });
+
+ it('applies custom className', () => {
+ (useTheme as jest.Mock).mockReturnValue({
+ theme: 'light',
+ toggleTheme: mockToggleTheme,
+ });
+
+ render(<ThemeToggle className="custom-class" />);
+
+ const button = screen.getByRole('button');
+ expect(button).toHaveClass('custom-class');
+ });
+
+ it('updates icon when theme prop changes', () => {
+ const { rerender } = render(<ThemeToggle />);
+
+ // Start with light theme
+ (useTheme as jest.Mock).mockReturnValue({
+ theme: 'light',
+ toggleTheme: mockToggleTheme,
+ });
+
+ rerender(<ThemeToggle />);
+ let button = screen.getByRole('button');
+ expect(button).toHaveAttribute('aria-label', 'Switch to dark mode');
+ expect(button).toHaveAttribute('aria-pressed', 'false');
+
+ // Switch to dark theme
+ (useTheme as jest.Mock).mockReturnValue({
+ theme: 'dark',
+ toggleTheme: mockToggleTheme,
+ });
+
+ rerender(<ThemeToggle />);
+ button = screen.getByRole('button');
+ expect(button).toHaveAttribute('aria-label', 'Switch to light mode');
+ expect(button).toHaveAttribute('aria-pressed', 'true');
+ });
+
+ it('handles missing theme context gracefully', () => {
+ // Mock useTheme to throw error (simulating missing provider)
+ (useTheme as jest.Mock).mockImplementation(() => {
+ throw new Error('useTheme must be used within a ThemeProvider');
+ });
+
+ // Expect the component to throw when rendered without provider
+ expect(() => render(<ThemeToggle />)).toThrow('useTheme must be used within a ThemeProvider');
+ });
+});
diff --git a/contexts/ThemeContext.tsx b/contexts/ThemeContext.tsx
new file mode 100644
index 0000000..8dfe99f
--- /dev/null
+++ b/contexts/ThemeContext.tsx
@@ -0,0 +1,38 @@
+'use client';
+
+import React, { createContext, useContext, useState, ReactNode } from 'react';
+
+type Theme = 'light' | 'dark';
+
+interface ThemeContextType {
+ theme: Theme;
+ toggleTheme: () => void;
+}
+
+const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
+
+interface ThemeProviderProps {
+ children: ReactNode;
+}
+
+export function ThemeProvider({ children }: ThemeProviderProps) {
+ const [theme, setTheme] = useState<Theme>('light');
+
+ const toggleTheme = () => {
+ setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
+ };
+
+ return (
+ <ThemeContext.Provider value={{ theme, toggleTheme }}>
+ {children}
+ </ThemeContext.Provider>
+ );
+}
+
+export function useTheme(): ThemeContextType {
+ const context = useContext(ThemeContext);
+ if (context === undefined) {
+ throw new Error('useTheme must be used within a ThemeProvider');
+ }
+ return context;
+}
diff --git a/design_philosophy.md b/design_philosophy.md
new file mode 100644
index 0000000..704a78f
--- /dev/null
+++ b/design_philosophy.md
@@ -0,0 +1,15 @@
+# Altitudinal Bloom
+
+**A Visual Philosophy**
+
+This aesthetic movement emerges from the rarefied air of high-altitude cultivation, where patience and elevation converge to create extraordinary beauty. The philosophy channels the disciplined geometry of terraced mountain agriculture—precise rows ascending volcanic slopes—while honoring the explosive chromatic vitality that only equatorial light can coax from petals. Every compositional choice reflects the paradox of controlled wildness: systematic cultivation that yields blooms of unprecedented vibrancy. The visual language speaks through stratified color fields that reference elevation zones, through radial patterns echoing the architecture of unfurling roses, through the tension between rigid agricultural order and organic flowering chaos. This is design as cultivation, where every element is placed with the meticulous care of a master horticulturist who understands that greatness requires both altitude and patience.
+
+The color system draws from the specific chromatic intensity found only in flowers grown at 9,000 feet—saturated pinks that verge on magenta, greens so deep they approach black, golds that capture equatorial sunlight at its most direct. These hues exist in precise geometric arrangements, never gradients, honoring the distinct microclimates of mountain terraces. Color zones are architectural, bounded, intense—each field carefully calibrated like soil pH levels in a professional greenhouse. The palette refuses pastels and softness; this movement celebrates the almost unnatural vibrancy that elevation and expertise produce. Chromatic relationships are studied with the obsession of someone who has spent decades understanding exactly which varietals thrive at which altitudes, translated into visual compositions where color placement follows invisible rules as strict as agricultural science.
+
+Spatial organization mirrors the vertical logic of mountain cultivation—information and imagery arranged in ascending tiers, creating visual altitude. Negative space functions as breathing room, essential as oxygen at high elevation, never wasted but always purposeful. The composition builds upward, suggesting terraced fields climbing toward peaks, with elements clustered in organic groupings that recall how flowers are bunched for market transport. Scale relationships are dramatic: massive chromatic blocks anchoring the composition like volcanic bedrock, delicate linear details suggesting individual stems. Every spatial decision reflects countless hours of refinement, the work of someone who understands that perfect spacing—between plants, between stems in an arrangement, between visual elements—is the difference between amateur and masterwork.
+
+Typography appears as rare, essential markers—small, precise labels that might identify cultivar names on greenhouse shelves. Words never explain or describe; they anchor and orient. Text is integrated into the visual architecture like wooden stakes marking rows, serving the composition rather than dominating it. Font choices reference both agricultural utility (simple, clear, functional) and the quiet elegance of family-run enterprises that have perfected their craft across generations. Letters are placed with the same precision that commercial growers use when spacing bulbs—measured, intentional, contributing to the overall system. When text does appear, it carries the weight of expertise, suggesting generations of accumulated knowledge compressed into minimal annotation.
+
+The movement insists on forms that balance geometric precision with organic growth patterns. Circles and radials dominate—the architecture of rose blooms viewed from above, the circular motion of binding bouquets, the concentric rings marking a plant's age and maturity. These shapes intersect with strict linear elements: the rows of commercial agriculture, the stems themselves, the ruled lines of professional cultivation plans. The composition rewards sustained viewing, revealing layered complexity that mirrors looking deeply into a flower's structure—discovering stamens, pistils, the precise arrangement of petals that took millions of years to evolve and decades of selective breeding to perfect. This is visual work that appears effortless but reveals, upon examination, the fingerprints of obsessive craftsmanship.
+
+Every aspect of the final work must appear as though created by someone at the absolute pinnacle of their discipline—a master who has devoted years to understanding the subtle relationships between elevation, climate, cultivation technique, and extraordinary beauty. The composition should feel meticulously labored over, with each color boundary, each spatial interval, each typographic placement reflecting deep expertise and painstaking attention to detail. The work announces itself as the product of mastery, where even the simplest elements have been refined through countless iterations until they achieve the quiet perfection that only expertise can produce. Like the flowers themselves—which require specific altitude, precise temperature, exact pH, and generations of breeding to achieve their legendary quality—the visual work must demonstrate that true excellence demands both systematic knowledge and patient craft.
diff --git a/jest.config.js b/jest.config.js
new file mode 100644
index 0000000..d7f06ce
--- /dev/null
+++ b/jest.config.js
@@ -0,0 +1,20 @@
+const nextJest = require('next/jest');
+
+const createJestConfig = nextJest({
+ // Provide the path to your Next.js app to load next.config.js and .env files
+ dir: './',
+});
+
+/** @type {import('jest').Config} */
+const customJestConfig = {
+ setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
+ testEnvironment: 'jest-environment-jsdom',
+ moduleNameMapper: {
+ // Handle module aliases (must match paths in tsconfig.json)
+ '^@/(.*)$': '<rootDir>/$1',
+ },
+ testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/.next/'],
+ moduleDirectories: ['node_modules', '<rootDir>/'],
+};
+
+module.exports = createJestConfig(customJestConfig);
diff --git a/jest.setup.js b/jest.setup.js
new file mode 100644
index 0000000..d15902f
--- /dev/null
+++ b/jest.setup.js
@@ -0,0 +1,2 @@
+// Learn more: https://github.com/testing-library/jest-dom
+import '@testing-library/jest-dom';
diff --git a/next.config.js b/next.config.js
new file mode 100644
index 0000000..b8c158a
--- /dev/null
+++ b/next.config.js
@@ -0,0 +1,9 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ reactStrictMode: true,
+ images: {
+ domains: ['images.unsplash.com', 'via.placeholder.com'],
+ },
+}
+
+module.exports = nextConfig
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..5f759c1
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,10389 @@
+{
+ "name": "angels-flowers",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "angels-flowers",
+ "version": "1.0.0",
+ "dependencies": {
+ "next": "^14.0.4",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-icons": "^4.12.0"
+ },
+ "devDependencies": {
+ "@testing-library/jest-dom": "^6.9.1",
+ "@testing-library/react": "^16.3.1",
+ "@types/jest": "^30.0.0",
+ "@types/node": "^20.10.5",
+ "@types/react": "^18.2.45",
+ "@types/react-dom": "^18.2.18",
+ "autoprefixer": "^10.4.16",
+ "eslint": "^8.56.0",
+ "eslint-config-next": "^14.0.4",
+ "jest": "^30.2.0",
+ "jest-environment-jsdom": "^30.2.0",
+ "postcss": "^8.4.32",
+ "tailwindcss": "^3.4.0",
+ "ts-jest": "^29.4.6",
+ "typescript": "^5.3.3"
+ }
+ },
+ "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/@alloc/quick-lru": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
+ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@asamuzakjp/css-color": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz",
+ "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/css-calc": "^2.1.3",
+ "@csstools/css-color-parser": "^3.0.9",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "lru-cache": "^10.4.3"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz",
+ "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==",
+ "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.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz",
+ "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz",
+ "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.28.6",
+ "@babel/generator": "^7.28.6",
+ "@babel/helper-compilation-targets": "^7.28.6",
+ "@babel/helper-module-transforms": "^7.28.6",
+ "@babel/helpers": "^7.28.6",
+ "@babel/parser": "^7.28.6",
+ "@babel/template": "^7.28.6",
+ "@babel/traverse": "^7.28.6",
+ "@babel/types": "^7.28.6",
+ "@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/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/@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.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.6.tgz",
+ "integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.6",
+ "@babel/types": "^7.28.6",
+ "@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/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/@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-plugin-utils": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
+ "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.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.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz",
+ "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.6"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-static-block": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz",
+ "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz",
+ "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-private-property-in-object": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz",
+ "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.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.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz",
+ "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.28.6",
+ "@babel/generator": "^7.28.6",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.28.6",
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.28.6",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz",
+ "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==",
+ "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/@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@csstools/color-helpers": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz",
+ "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@csstools/css-calc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz",
+ "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-color-parser": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz",
+ "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/color-helpers": "^5.1.0",
+ "@csstools/css-calc": "^2.1.4"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-parser-algorithms": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz",
+ "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-tokenizer": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz",
+ "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@emnapi/core": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.0.tgz",
+ "integrity": "sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.1.0",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.0.tgz",
+ "integrity": "sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz",
+ "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
+ "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
+ "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/eslintrc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+ "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
+ "deprecated": "Use @eslint/config-array instead",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^2.0.3",
+ "debug": "^4.3.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.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/object-schema": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "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-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/@isaacs/cliui/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/@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
+ "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/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/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/console": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.2.0.tgz",
+ "integrity": "sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "jest-message-util": "30.2.0",
+ "jest-util": "30.2.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/core": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.2.0.tgz",
+ "integrity": "sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "30.2.0",
+ "@jest/pattern": "30.0.1",
+ "@jest/reporters": "30.2.0",
+ "@jest/test-result": "30.2.0",
+ "@jest/transform": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "ansi-escapes": "^4.3.2",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "exit-x": "^0.2.2",
+ "graceful-fs": "^4.2.11",
+ "jest-changed-files": "30.2.0",
+ "jest-config": "30.2.0",
+ "jest-haste-map": "30.2.0",
+ "jest-message-util": "30.2.0",
+ "jest-regex-util": "30.0.1",
+ "jest-resolve": "30.2.0",
+ "jest-resolve-dependencies": "30.2.0",
+ "jest-runner": "30.2.0",
+ "jest-runtime": "30.2.0",
+ "jest-snapshot": "30.2.0",
+ "jest-util": "30.2.0",
+ "jest-validate": "30.2.0",
+ "jest-watcher": "30.2.0",
+ "micromatch": "^4.0.8",
+ "pretty-format": "30.2.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/core/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/@jest/core/node_modules/jest-config": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz",
+ "integrity": "sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.27.4",
+ "@jest/get-type": "30.1.0",
+ "@jest/pattern": "30.0.1",
+ "@jest/test-sequencer": "30.2.0",
+ "@jest/types": "30.2.0",
+ "babel-jest": "30.2.0",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "deepmerge": "^4.3.1",
+ "glob": "^10.3.10",
+ "graceful-fs": "^4.2.11",
+ "jest-circus": "30.2.0",
+ "jest-docblock": "30.2.0",
+ "jest-environment-node": "30.2.0",
+ "jest-regex-util": "30.0.1",
+ "jest-resolve": "30.2.0",
+ "jest-runner": "30.2.0",
+ "jest-util": "30.2.0",
+ "jest-validate": "30.2.0",
+ "micromatch": "^4.0.8",
+ "parse-json": "^5.2.0",
+ "pretty-format": "30.2.0",
+ "slash": "^3.0.0",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "@types/node": "*",
+ "esbuild-register": ">=3.4.0",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "esbuild-register": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/core/node_modules/pretty-format": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
+ "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "30.0.5",
+ "ansi-styles": "^5.2.0",
+ "react-is": "^18.3.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/core/node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jest/diff-sequences": {
+ "version": "30.0.1",
+ "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz",
+ "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/environment": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz",
+ "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/fake-timers": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "jest-mock": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/environment-jsdom-abstract": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.2.0.tgz",
+ "integrity": "sha512-kazxw2L9IPuZpQ0mEt9lu9Z98SqR74xcagANmMBU16X0lS23yPc0+S6hGLUz8kVRlomZEs/5S/Zlpqwf5yu6OQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "30.2.0",
+ "@jest/fake-timers": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/jsdom": "^21.1.7",
+ "@types/node": "*",
+ "jest-mock": "30.2.0",
+ "jest-util": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "canvas": "^3.0.0",
+ "jsdom": "*"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/expect": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz",
+ "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expect": "30.2.0",
+ "jest-snapshot": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/expect-utils": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz",
+ "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/get-type": "30.1.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz",
+ "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.2.0",
+ "@sinonjs/fake-timers": "^13.0.0",
+ "@types/node": "*",
+ "jest-message-util": "30.2.0",
+ "jest-mock": "30.2.0",
+ "jest-util": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/get-type": {
+ "version": "30.1.0",
+ "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz",
+ "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/globals": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz",
+ "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "30.2.0",
+ "@jest/expect": "30.2.0",
+ "@jest/types": "30.2.0",
+ "jest-mock": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/pattern": {
+ "version": "30.0.1",
+ "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz",
+ "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "jest-regex-util": "30.0.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/reporters": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz",
+ "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "30.2.0",
+ "@jest/test-result": "30.2.0",
+ "@jest/transform": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "collect-v8-coverage": "^1.0.2",
+ "exit-x": "^0.2.2",
+ "glob": "^10.3.10",
+ "graceful-fs": "^4.2.11",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^6.0.0",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^5.0.0",
+ "istanbul-reports": "^3.1.3",
+ "jest-message-util": "30.2.0",
+ "jest-util": "30.2.0",
+ "jest-worker": "30.2.0",
+ "slash": "^3.0.0",
+ "string-length": "^4.0.2",
+ "v8-to-istanbul": "^9.0.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/schemas": {
+ "version": "30.0.5",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
+ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sinclair/typebox": "^0.34.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/snapshot-utils": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz",
+ "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.2.0",
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "natural-compare": "^1.4.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/source-map": {
+ "version": "30.0.1",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz",
+ "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "callsites": "^3.1.0",
+ "graceful-fs": "^4.2.11"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/test-result": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz",
+ "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/istanbul-lib-coverage": "^2.0.6",
+ "collect-v8-coverage": "^1.0.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/test-sequencer": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz",
+ "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/test-result": "30.2.0",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.2.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/transform": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz",
+ "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.27.4",
+ "@jest/types": "30.2.0",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "babel-plugin-istanbul": "^7.0.1",
+ "chalk": "^4.1.2",
+ "convert-source-map": "^2.0.0",
+ "fast-json-stable-stringify": "^2.1.0",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.2.0",
+ "jest-regex-util": "30.0.1",
+ "jest-util": "30.2.0",
+ "micromatch": "^4.0.8",
+ "pirates": "^4.0.7",
+ "slash": "^3.0.0",
+ "write-file-atomic": "^5.0.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/types": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz",
+ "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/pattern": "30.0.1",
+ "@jest/schemas": "30.0.5",
+ "@types/istanbul-lib-coverage": "^2.0.6",
+ "@types/istanbul-reports": "^3.0.4",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.33",
+ "chalk": "^4.1.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "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==",
+ "dev": true,
+ "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==",
+ "dev": true,
+ "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==",
+ "dev": true,
+ "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==",
+ "dev": true,
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "0.2.12",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz",
+ "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "^1.4.3",
+ "@emnapi/runtime": "^1.4.3",
+ "@tybys/wasm-util": "^0.10.0"
+ }
+ },
+ "node_modules/@next/env": {
+ "version": "14.2.33",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.33.tgz",
+ "integrity": "sha512-CgVHNZ1fRIlxkLhIX22flAZI/HmpDaZ8vwyJ/B0SDPTBuLZ1PJ+DWMjCHhqnExfmSQzA/PbZi8OAc7PAq2w9IA==",
+ "license": "MIT"
+ },
+ "node_modules/@next/eslint-plugin-next": {
+ "version": "14.2.33",
+ "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.33.tgz",
+ "integrity": "sha512-DQTJFSvlB+9JilwqMKJ3VPByBNGxAGFTfJ7BuFj25cVcbBy7jm88KfUN+dngM4D3+UxZ8ER2ft+WH9JccMvxyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "glob": "10.3.10"
+ }
+ },
+ "node_modules/@next/swc-darwin-arm64": {
+ "version": "14.2.33",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.33.tgz",
+ "integrity": "sha512-HqYnb6pxlsshoSTubdXKu15g3iivcbsMXg4bYpjL2iS/V6aQot+iyF4BUc2qA/J/n55YtvE4PHMKWBKGCF/+wA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-darwin-x64": {
+ "version": "14.2.33",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.33.tgz",
+ "integrity": "sha512-8HGBeAE5rX3jzKvF593XTTFg3gxeU4f+UWnswa6JPhzaR6+zblO5+fjltJWIZc4aUalqTclvN2QtTC37LxvZAA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-gnu": {
+ "version": "14.2.33",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.33.tgz",
+ "integrity": "sha512-JXMBka6lNNmqbkvcTtaX8Gu5by9547bukHQvPoLe9VRBx1gHwzf5tdt4AaezW85HAB3pikcvyqBToRTDA4DeLw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-musl": {
+ "version": "14.2.33",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.33.tgz",
+ "integrity": "sha512-Bm+QulsAItD/x6Ih8wGIMfRJy4G73tu1HJsrccPW6AfqdZd0Sfm5Imhgkgq2+kly065rYMnCOxTBvmvFY1BKfg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-x64-gnu": {
+ "version": "14.2.33",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.33.tgz",
+ "integrity": "sha512-FnFn+ZBgsVMbGDsTqo8zsnRzydvsGV8vfiWwUo1LD8FTmPTdV+otGSWKc4LJec0oSexFnCYVO4hX8P8qQKaSlg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-x64-musl": {
+ "version": "14.2.33",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.33.tgz",
+ "integrity": "sha512-345tsIWMzoXaQndUTDv1qypDRiebFxGYx9pYkhwY4hBRaOLt8UGfiWKr9FSSHs25dFIf8ZqIFaPdy5MljdoawA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-arm64-msvc": {
+ "version": "14.2.33",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.33.tgz",
+ "integrity": "sha512-nscpt0G6UCTkrT2ppnJnFsYbPDQwmum4GNXYTeoTIdsmMydSKFz9Iny2jpaRupTb+Wl298+Rh82WKzt9LCcqSQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-ia32-msvc": {
+ "version": "14.2.33",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.33.tgz",
+ "integrity": "sha512-pc9LpGNKhJ0dXQhZ5QMmYxtARwwmWLpeocFmVG5Z0DzWq5Uf0izcI8tLc+qOpqxO1PWqZ5A7J1blrUIKrIFc7Q==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-x64-msvc": {
+ "version": "14.2.33",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.33.tgz",
+ "integrity": "sha512-nOjfZMy8B94MdisuzZo9/57xuFVLHJaDj5e/xrduJp9CV2/HrfxTRH2fbyLe+K9QT41WBLUd4iXX3R7jBp0EUg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nolyfill/is-core-module": {
+ "version": "1.0.39",
+ "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz",
+ "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.4.0"
+ }
+ },
+ "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/@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/@rushstack/eslint-patch": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.14.1.tgz",
+ "integrity": "sha512-jGTk8UD/RdjsNZW8qq10r0RBvxL8OWtoT+kImlzPDFilmozzM+9QmIJsmze9UiSBrFU45ZxhTYBypn9q9z/VfQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@sinclair/typebox": {
+ "version": "0.34.47",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.47.tgz",
+ "integrity": "sha512-ZGIBQ+XDvO5JQku9wmwtabcVTHJsgSWAHYtVuM9pBNNR5E88v6Jcj/llpmsjivig5X8A8HHOb4/mbEKPS5EvAw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
+ "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "13.0.5",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz",
+ "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.1"
+ }
+ },
+ "node_modules/@swc/counter": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz",
+ "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/counter": "^0.1.3",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@testing-library/dom": {
+ "version": "10.4.1",
+ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
+ "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/runtime": "^7.12.5",
+ "@types/aria-query": "^5.0.1",
+ "aria-query": "5.3.0",
+ "dom-accessibility-api": "^0.5.9",
+ "lz-string": "^1.5.0",
+ "picocolors": "1.1.1",
+ "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",
+ "peer": true,
+ "dependencies": {
+ "dequal": "^2.0.3"
+ }
+ },
+ "node_modules/@testing-library/jest-dom": {
+ "version": "6.9.1",
+ "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz",
+ "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@adobe/css-tools": "^4.4.0",
+ "aria-query": "^5.0.0",
+ "css.escape": "^1.5.1",
+ "dom-accessibility-api": "^0.6.3",
+ "picocolors": "^1.1.1",
+ "redent": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14",
+ "npm": ">=6",
+ "yarn": ">=1"
+ }
+ },
+ "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/react": {
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.1.tgz",
+ "integrity": "sha512-gr4KtAWqIOQoucWYD/f6ki+j5chXfcPc74Col/6poTyqTmn7zRmodWahWRCp8tYd+GMqBonw6hstNzqjbs6gjw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@testing-library/dom": "^10.0.0",
+ "@types/react": "^18.0.0 || ^19.0.0",
+ "@types/react-dom": "^18.0.0 || ^19.0.0",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
+ "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "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",
+ "peer": true
+ },
+ "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/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
+ "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
+ "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "node_modules/@types/jest": {
+ "version": "30.0.0",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz",
+ "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expect": "^30.0.0",
+ "pretty-format": "^30.0.0"
+ }
+ },
+ "node_modules/@types/jest/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/@types/jest/node_modules/pretty-format": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
+ "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "30.0.5",
+ "ansi-styles": "^5.2.0",
+ "react-is": "^18.3.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@types/jest/node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/jsdom": {
+ "version": "21.1.7",
+ "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz",
+ "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/tough-cookie": "*",
+ "parse5": "^7.0.0"
+ }
+ },
+ "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/node": {
+ "version": "20.19.24",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.24.tgz",
+ "integrity": "sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.15",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
+ "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/react": {
+ "version": "18.3.26",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.26.tgz",
+ "integrity": "sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.3.7",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
+ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^18.0.0"
+ }
+ },
+ "node_modules/@types/stack-utils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
+ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/tough-cookie": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
+ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/yargs": {
+ "version": "17.0.35",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
+ "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.3",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
+ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.46.4",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.4.tgz",
+ "integrity": "sha512-R48VhmTJqplNyDxCyqqVkFSZIx1qX6PzwqgcXn1olLrzxcSBDlOsbtcnQuQhNtnNiJ4Xe5gREI1foajYaYU2Vg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "8.46.4",
+ "@typescript-eslint/type-utils": "8.46.4",
+ "@typescript-eslint/utils": "8.46.4",
+ "@typescript-eslint/visitor-keys": "8.46.4",
+ "graphemer": "^1.4.0",
+ "ignore": "^7.0.0",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.1.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.46.4",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/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/@typescript-eslint/parser": {
+ "version": "8.46.4",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.4.tgz",
+ "integrity": "sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.46.4",
+ "@typescript-eslint/types": "8.46.4",
+ "@typescript-eslint/typescript-estree": "8.46.4",
+ "@typescript-eslint/visitor-keys": "8.46.4",
+ "debug": "^4.3.4"
+ },
+ "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.46.4",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.4.tgz",
+ "integrity": "sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.46.4",
+ "@typescript-eslint/types": "^8.46.4",
+ "debug": "^4.3.4"
+ },
+ "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.46.4",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.4.tgz",
+ "integrity": "sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.46.4",
+ "@typescript-eslint/visitor-keys": "8.46.4"
+ },
+ "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.46.4",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.4.tgz",
+ "integrity": "sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A==",
+ "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.46.4",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.4.tgz",
+ "integrity": "sha512-V4QC8h3fdT5Wro6vANk6eojqfbv5bpwHuMsBcJUJkqs2z5XnYhJzyz9Y02eUmF9u3PgXEUiOt4w4KHR3P+z0PQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.46.4",
+ "@typescript-eslint/typescript-estree": "8.46.4",
+ "@typescript-eslint/utils": "8.46.4",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^2.1.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.46.4",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.4.tgz",
+ "integrity": "sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==",
+ "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.46.4",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.4.tgz",
+ "integrity": "sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.46.4",
+ "@typescript-eslint/tsconfig-utils": "8.46.4",
+ "@typescript-eslint/types": "8.46.4",
+ "@typescript-eslint/visitor-keys": "8.46.4",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^2.1.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/typescript-estree/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/@typescript-eslint/typescript-estree/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/@typescript-eslint/utils": {
+ "version": "8.46.4",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.4.tgz",
+ "integrity": "sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.7.0",
+ "@typescript-eslint/scope-manager": "8.46.4",
+ "@typescript-eslint/types": "8.46.4",
+ "@typescript-eslint/typescript-estree": "8.46.4"
+ },
+ "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.46.4",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.4.tgz",
+ "integrity": "sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.46.4",
+ "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==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@unrs/resolver-binding-android-arm-eabi": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz",
+ "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-android-arm64": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz",
+ "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-darwin-arm64": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz",
+ "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-darwin-x64": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz",
+ "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-freebsd-x64": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz",
+ "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz",
+ "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz",
+ "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm64-gnu": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz",
+ "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm64-musl": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz",
+ "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz",
+ "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz",
+ "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-riscv64-musl": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz",
+ "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-s390x-gnu": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz",
+ "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-x64-gnu": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz",
+ "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-x64-musl": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz",
+ "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-wasm32-wasi": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz",
+ "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@napi-rs/wasm-runtime": "^0.2.11"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@unrs/resolver-binding-win32-arm64-msvc": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz",
+ "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-win32-ia32-msvc": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz",
+ "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-win32-x64-msvc": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz",
+ "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "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/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "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/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-escapes/node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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/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/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/arg": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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-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/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/autoprefixer": {
+ "version": "10.4.21",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
+ "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.24.4",
+ "caniuse-lite": "^1.0.30001702",
+ "fraction.js": "^4.3.7",
+ "normalize-range": "^0.1.2",
+ "picocolors": "^1.1.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "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.0",
+ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz",
+ "integrity": "sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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/babel-jest": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz",
+ "integrity": "sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/transform": "30.2.0",
+ "@types/babel__core": "^7.20.5",
+ "babel-plugin-istanbul": "^7.0.1",
+ "babel-preset-jest": "30.2.0",
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.11.0 || ^8.0.0-0"
+ }
+ },
+ "node_modules/babel-plugin-istanbul": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz",
+ "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "workspaces": [
+ "test/babel-8"
+ ],
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.3",
+ "istanbul-lib-instrument": "^6.0.2",
+ "test-exclude": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/babel-plugin-jest-hoist": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.2.0.tgz",
+ "integrity": "sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/babel__core": "^7.20.5"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/babel-preset-current-node-syntax": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz",
+ "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
+ "@babel/plugin-syntax-import-attributes": "^7.24.7",
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+ "@babel/plugin-syntax-top-level-await": "^7.14.5"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0 || ^8.0.0-0"
+ }
+ },
+ "node_modules/babel-preset-jest": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.2.0.tgz",
+ "integrity": "sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-plugin-jest-hoist": "30.2.0",
+ "babel-preset-current-node-syntax": "^1.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.11.0 || ^8.0.0-beta.1"
+ }
+ },
+ "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.8.25",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.25.tgz",
+ "integrity": "sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.js"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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/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/browserslist": {
+ "version": "4.27.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz",
+ "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==",
+ "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.8.19",
+ "caniuse-lite": "^1.0.30001751",
+ "electron-to-chromium": "^1.5.238",
+ "node-releases": "^2.0.26",
+ "update-browserslist-db": "^1.1.4"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/bs-logger": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
+ "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-json-stable-stringify": "2.x"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/busboy": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
+ "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
+ "dependencies": {
+ "streamsearch": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=10.16.0"
+ }
+ },
+ "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==",
+ "dev": true,
+ "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": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase-css": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001754",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz",
+ "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==",
+ "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/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/char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/ci-info": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz",
+ "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cjs-module-lexer": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz",
+ "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/client-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
+ "license": "MIT"
+ },
+ "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/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/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/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/co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">= 1.0.0",
+ "node": ">= 0.12.0"
+ }
+ },
+ "node_modules/collect-v8-coverage": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz",
+ "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "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/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/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/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cssstyle": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz",
+ "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@asamuzakjp/css-color": "^3.2.0",
+ "rrweb-cssom": "^0.8.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "dev": true,
+ "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/data-urls": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
+ "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decimal.js": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/dedent": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.1.tgz",
+ "integrity": "sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "babel-plugin-macros": "^3.1.0"
+ },
+ "peerDependenciesMeta": {
+ "babel-plugin-macros": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "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-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/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/didyoumean": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
+ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/dlv": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/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",
+ "peer": true
+ },
+ "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==",
+ "dev": true,
+ "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.249",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.249.tgz",
+ "integrity": "sha512-5vcfL3BBe++qZ5kuFhD/p8WOM1N9m3nwvJPULJx+4xf2usSlZFJ0qoNYO2fOX4hi3ocuDcmDobtA+5SFr4OmBg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emittery": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
+ "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/emittery?sponsor=1"
+ }
+ },
+ "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/entities": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "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.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz",
+ "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==",
+ "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==",
+ "dev": true,
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-iterator-helpers": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz",
+ "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==",
+ "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-set-tostringtag": "^2.0.3",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.6",
+ "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.4",
+ "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==",
+ "dev": true,
+ "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==",
+ "dev": true,
+ "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/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": "8.57.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
+ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.4",
+ "@eslint/js": "8.57.1",
+ "@humanwhocodes/config-array": "^0.13.0",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-config-next": {
+ "version": "14.2.33",
+ "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.2.33.tgz",
+ "integrity": "sha512-e2W+waB+I5KuoALAtKZl3WVDU4Q1MS6gF/gdcwHh0WOAkHf4TZI6dPjd25wKhlZFAsFrVKy24Z7/IwOhn8dHBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@next/eslint-plugin-next": "14.2.33",
+ "@rushstack/eslint-patch": "^1.3.3",
+ "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0",
+ "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0",
+ "eslint-import-resolver-node": "^0.3.6",
+ "eslint-import-resolver-typescript": "^3.5.2",
+ "eslint-plugin-import": "^2.28.1",
+ "eslint-plugin-jsx-a11y": "^6.7.1",
+ "eslint-plugin-react": "^7.33.2",
+ "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705"
+ },
+ "peerDependencies": {
+ "eslint": "^7.23.0 || ^8.0.0",
+ "typescript": ">=3.3.1"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "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-import-resolver-typescript": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz",
+ "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@nolyfill/is-core-module": "1.0.39",
+ "debug": "^4.4.0",
+ "get-tsconfig": "^4.10.0",
+ "is-bun-module": "^2.0.0",
+ "stable-hash": "^0.0.5",
+ "tinyglobby": "^0.2.13",
+ "unrs-resolver": "^1.6.2"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-import-resolver-typescript"
+ },
+ "peerDependencies": {
+ "eslint": "*",
+ "eslint-plugin-import": "*",
+ "eslint-plugin-import-x": "*"
+ },
+ "peerDependenciesMeta": {
+ "eslint-plugin-import": {
+ "optional": true
+ },
+ "eslint-plugin-import-x": {
+ "optional": true
+ }
+ }
+ },
+ "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/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/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/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-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": "5.0.0-canary-7118f5dd7-20230705",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz",
+ "integrity": "sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
+ }
+ },
+ "node_modules/eslint-plugin-react/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/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-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-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/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "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.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "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/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/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/execa/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/exit-x": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz",
+ "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/expect": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz",
+ "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/expect-utils": "30.2.0",
+ "@jest/get-type": "30.1.0",
+ "jest-matcher-utils": "30.2.0",
+ "jest-message-util": "30.2.0",
+ "jest-mock": "30.2.0",
+ "jest-util": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "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-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "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/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fb-watchman": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
+ "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "bser": "2.1.1"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.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": "3.2.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
+ "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.3",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/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/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/fraction.js": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
+ "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "patreon",
+ "url": "https://github.com/sponsors/rawify"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "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==",
+ "dev": true,
+ "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-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dev": true,
+ "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-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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/get-tsconfig": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz",
+ "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.3.10",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
+ "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^2.3.5",
+ "minimatch": "^9.0.1",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
+ "path-scurry": "^1.10.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "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/glob/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/glob/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/globals": {
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "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==",
+ "dev": true,
+ "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/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/handlebars": {
+ "version": "4.7.8",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
+ "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.2",
+ "source-map": "^0.6.1",
+ "wordwrap": "^1.0.0"
+ },
+ "bin": {
+ "handlebars": "bin/handlebars"
+ },
+ "engines": {
+ "node": ">=0.4.7"
+ },
+ "optionalDependencies": {
+ "uglify-js": "^3.1.4"
+ }
+ },
+ "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==",
+ "dev": true,
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/html-encoding-sniffer": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
+ "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-encoding": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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/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-local": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
+ "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "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/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "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-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-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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-bun-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz",
+ "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.7.1"
+ }
+ },
+ "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-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": "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/is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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-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-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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/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/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-instrument": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
+ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/core": "^7.23.9",
+ "@babel/parser": "^7.23.9",
+ "@istanbuljs/schema": "^0.1.3",
+ "istanbul-lib-coverage": "^3.2.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz",
+ "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.23",
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
+ "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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": "2.3.6",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
+ "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/jest": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-30.2.0.tgz",
+ "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/core": "30.2.0",
+ "@jest/types": "30.2.0",
+ "import-local": "^3.2.0",
+ "jest-cli": "30.2.0"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-changed-files": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.2.0.tgz",
+ "integrity": "sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "execa": "^5.1.1",
+ "jest-util": "30.2.0",
+ "p-limit": "^3.1.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-circus": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.2.0.tgz",
+ "integrity": "sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "30.2.0",
+ "@jest/expect": "30.2.0",
+ "@jest/test-result": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "co": "^4.6.0",
+ "dedent": "^1.6.0",
+ "is-generator-fn": "^2.1.0",
+ "jest-each": "30.2.0",
+ "jest-matcher-utils": "30.2.0",
+ "jest-message-util": "30.2.0",
+ "jest-runtime": "30.2.0",
+ "jest-snapshot": "30.2.0",
+ "jest-util": "30.2.0",
+ "p-limit": "^3.1.0",
+ "pretty-format": "30.2.0",
+ "pure-rand": "^7.0.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.6"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-circus/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/jest-circus/node_modules/pretty-format": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
+ "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "30.0.5",
+ "ansi-styles": "^5.2.0",
+ "react-is": "^18.3.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-circus/node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jest-cli": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.2.0.tgz",
+ "integrity": "sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/core": "30.2.0",
+ "@jest/test-result": "30.2.0",
+ "@jest/types": "30.2.0",
+ "chalk": "^4.1.2",
+ "exit-x": "^0.2.2",
+ "import-local": "^3.2.0",
+ "jest-config": "30.2.0",
+ "jest-util": "30.2.0",
+ "jest-validate": "30.2.0",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-cli/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/jest-cli/node_modules/jest-config": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz",
+ "integrity": "sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.27.4",
+ "@jest/get-type": "30.1.0",
+ "@jest/pattern": "30.0.1",
+ "@jest/test-sequencer": "30.2.0",
+ "@jest/types": "30.2.0",
+ "babel-jest": "30.2.0",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "deepmerge": "^4.3.1",
+ "glob": "^10.3.10",
+ "graceful-fs": "^4.2.11",
+ "jest-circus": "30.2.0",
+ "jest-docblock": "30.2.0",
+ "jest-environment-node": "30.2.0",
+ "jest-regex-util": "30.0.1",
+ "jest-resolve": "30.2.0",
+ "jest-runner": "30.2.0",
+ "jest-util": "30.2.0",
+ "jest-validate": "30.2.0",
+ "micromatch": "^4.0.8",
+ "parse-json": "^5.2.0",
+ "pretty-format": "30.2.0",
+ "slash": "^3.0.0",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "@types/node": "*",
+ "esbuild-register": ">=3.4.0",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "esbuild-register": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-cli/node_modules/pretty-format": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
+ "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "30.0.5",
+ "ansi-styles": "^5.2.0",
+ "react-is": "^18.3.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-cli/node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jest-diff": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz",
+ "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/diff-sequences": "30.0.1",
+ "@jest/get-type": "30.1.0",
+ "chalk": "^4.1.2",
+ "pretty-format": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-diff/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/jest-diff/node_modules/pretty-format": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
+ "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "30.0.5",
+ "ansi-styles": "^5.2.0",
+ "react-is": "^18.3.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-diff/node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jest-docblock": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz",
+ "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "detect-newline": "^3.1.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-each": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.2.0.tgz",
+ "integrity": "sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/get-type": "30.1.0",
+ "@jest/types": "30.2.0",
+ "chalk": "^4.1.2",
+ "jest-util": "30.2.0",
+ "pretty-format": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-each/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/jest-each/node_modules/pretty-format": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
+ "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "30.0.5",
+ "ansi-styles": "^5.2.0",
+ "react-is": "^18.3.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-each/node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jest-environment-jsdom": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.2.0.tgz",
+ "integrity": "sha512-zbBTiqr2Vl78pKp/laGBREYzbZx9ZtqPjOK4++lL4BNDhxRnahg51HtoDrk9/VjIy9IthNEWdKVd7H5bqBhiWQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "30.2.0",
+ "@jest/environment-jsdom-abstract": "30.2.0",
+ "@types/jsdom": "^21.1.7",
+ "@types/node": "*",
+ "jsdom": "^26.1.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "canvas": "^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-environment-node": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.2.0.tgz",
+ "integrity": "sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "30.2.0",
+ "@jest/fake-timers": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "jest-mock": "30.2.0",
+ "jest-util": "30.2.0",
+ "jest-validate": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-haste-map": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz",
+ "integrity": "sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "anymatch": "^3.1.3",
+ "fb-watchman": "^2.0.2",
+ "graceful-fs": "^4.2.11",
+ "jest-regex-util": "30.0.1",
+ "jest-util": "30.2.0",
+ "jest-worker": "30.2.0",
+ "micromatch": "^4.0.8",
+ "walker": "^1.0.8"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "^2.3.3"
+ }
+ },
+ "node_modules/jest-leak-detector": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.2.0.tgz",
+ "integrity": "sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/get-type": "30.1.0",
+ "pretty-format": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-leak-detector/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/jest-leak-detector/node_modules/pretty-format": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
+ "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "30.0.5",
+ "ansi-styles": "^5.2.0",
+ "react-is": "^18.3.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-leak-detector/node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jest-matcher-utils": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz",
+ "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/get-type": "30.1.0",
+ "chalk": "^4.1.2",
+ "jest-diff": "30.2.0",
+ "pretty-format": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/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/jest-matcher-utils/node_modules/pretty-format": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
+ "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "30.0.5",
+ "ansi-styles": "^5.2.0",
+ "react-is": "^18.3.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jest-message-util": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz",
+ "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@jest/types": "30.2.0",
+ "@types/stack-utils": "^2.0.3",
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "micromatch": "^4.0.8",
+ "pretty-format": "30.2.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.6"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-message-util/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/jest-message-util/node_modules/pretty-format": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
+ "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "30.0.5",
+ "ansi-styles": "^5.2.0",
+ "react-is": "^18.3.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jest-mock": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz",
+ "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "jest-util": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-pnp-resolver": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
+ "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "peerDependencies": {
+ "jest-resolve": "*"
+ },
+ "peerDependenciesMeta": {
+ "jest-resolve": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-regex-util": {
+ "version": "30.0.1",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz",
+ "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-resolve": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz",
+ "integrity": "sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.2.0",
+ "jest-pnp-resolver": "^1.2.3",
+ "jest-util": "30.2.0",
+ "jest-validate": "30.2.0",
+ "slash": "^3.0.0",
+ "unrs-resolver": "^1.7.11"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-resolve-dependencies": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz",
+ "integrity": "sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jest-regex-util": "30.0.1",
+ "jest-snapshot": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-runner": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.2.0.tgz",
+ "integrity": "sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "30.2.0",
+ "@jest/environment": "30.2.0",
+ "@jest/test-result": "30.2.0",
+ "@jest/transform": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "emittery": "^0.13.1",
+ "exit-x": "^0.2.2",
+ "graceful-fs": "^4.2.11",
+ "jest-docblock": "30.2.0",
+ "jest-environment-node": "30.2.0",
+ "jest-haste-map": "30.2.0",
+ "jest-leak-detector": "30.2.0",
+ "jest-message-util": "30.2.0",
+ "jest-resolve": "30.2.0",
+ "jest-runtime": "30.2.0",
+ "jest-util": "30.2.0",
+ "jest-watcher": "30.2.0",
+ "jest-worker": "30.2.0",
+ "p-limit": "^3.1.0",
+ "source-map-support": "0.5.13"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-runtime": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.2.0.tgz",
+ "integrity": "sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "30.2.0",
+ "@jest/fake-timers": "30.2.0",
+ "@jest/globals": "30.2.0",
+ "@jest/source-map": "30.0.1",
+ "@jest/test-result": "30.2.0",
+ "@jest/transform": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "cjs-module-lexer": "^2.1.0",
+ "collect-v8-coverage": "^1.0.2",
+ "glob": "^10.3.10",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.2.0",
+ "jest-message-util": "30.2.0",
+ "jest-mock": "30.2.0",
+ "jest-regex-util": "30.0.1",
+ "jest-resolve": "30.2.0",
+ "jest-snapshot": "30.2.0",
+ "jest-util": "30.2.0",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-runtime/node_modules/strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-snapshot": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz",
+ "integrity": "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.27.4",
+ "@babel/generator": "^7.27.5",
+ "@babel/plugin-syntax-jsx": "^7.27.1",
+ "@babel/plugin-syntax-typescript": "^7.27.1",
+ "@babel/types": "^7.27.3",
+ "@jest/expect-utils": "30.2.0",
+ "@jest/get-type": "30.1.0",
+ "@jest/snapshot-utils": "30.2.0",
+ "@jest/transform": "30.2.0",
+ "@jest/types": "30.2.0",
+ "babel-preset-current-node-syntax": "^1.2.0",
+ "chalk": "^4.1.2",
+ "expect": "30.2.0",
+ "graceful-fs": "^4.2.11",
+ "jest-diff": "30.2.0",
+ "jest-matcher-utils": "30.2.0",
+ "jest-message-util": "30.2.0",
+ "jest-util": "30.2.0",
+ "pretty-format": "30.2.0",
+ "semver": "^7.7.2",
+ "synckit": "^0.11.8"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/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/jest-snapshot/node_modules/pretty-format": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
+ "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "30.0.5",
+ "ansi-styles": "^5.2.0",
+ "react-is": "^18.3.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jest-util": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz",
+ "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "graceful-fs": "^4.2.11",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-util/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/jest-validate": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.2.0.tgz",
+ "integrity": "sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/get-type": "30.1.0",
+ "@jest/types": "30.2.0",
+ "camelcase": "^6.3.0",
+ "chalk": "^4.1.2",
+ "leven": "^3.1.0",
+ "pretty-format": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-validate/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/jest-validate/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/jest-validate/node_modules/pretty-format": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
+ "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "30.0.5",
+ "ansi-styles": "^5.2.0",
+ "react-is": "^18.3.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jest-watcher": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.2.0.tgz",
+ "integrity": "sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/test-result": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "ansi-escapes": "^4.3.2",
+ "chalk": "^4.1.2",
+ "emittery": "^0.13.1",
+ "jest-util": "30.2.0",
+ "string-length": "^4.0.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz",
+ "integrity": "sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@ungap/structured-clone": "^1.3.0",
+ "jest-util": "30.2.0",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.1.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/jiti": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jiti": "bin/jiti.js"
+ }
+ },
+ "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.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsdom": {
+ "version": "26.1.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz",
+ "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssstyle": "^4.2.1",
+ "data-urls": "^5.0.0",
+ "decimal.js": "^10.5.0",
+ "html-encoding-sniffer": "^4.0.0",
+ "http-proxy-agent": "^7.0.2",
+ "https-proxy-agent": "^7.0.6",
+ "is-potential-custom-element-name": "^1.0.1",
+ "nwsapi": "^2.2.16",
+ "parse5": "^7.2.1",
+ "rrweb-cssom": "^0.8.0",
+ "saxes": "^6.0.0",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^5.1.1",
+ "w3c-xmlserializer": "^5.0.0",
+ "webidl-conversions": "^7.0.0",
+ "whatwg-encoding": "^3.1.1",
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.1.1",
+ "ws": "^8.18.0",
+ "xml-name-validator": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "canvas": "^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
+ }
+ },
+ "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": "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/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": "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/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/leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
+ "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/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/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/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",
+ "peer": true,
+ "bin": {
+ "lz-string": "bin/bin.js"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/makeerror": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tmpl": "1.0.5"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "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/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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/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/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.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "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/napi-postinstall": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz",
+ "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "napi-postinstall": "lib/cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/napi-postinstall"
+ }
+ },
+ "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/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/next": {
+ "version": "14.2.33",
+ "resolved": "https://registry.npmjs.org/next/-/next-14.2.33.tgz",
+ "integrity": "sha512-GiKHLsD00t4ACm1p00VgrI0rUFAC9cRDGReKyERlM57aeEZkOQGcZTpIbsGn0b562FTPJWmYfKwplfO9EaT6ng==",
+ "license": "MIT",
+ "dependencies": {
+ "@next/env": "14.2.33",
+ "@swc/helpers": "0.5.5",
+ "busboy": "1.6.0",
+ "caniuse-lite": "^1.0.30001579",
+ "graceful-fs": "^4.2.11",
+ "postcss": "8.4.31",
+ "styled-jsx": "5.1.1"
+ },
+ "bin": {
+ "next": "dist/bin/next"
+ },
+ "engines": {
+ "node": ">=18.17.0"
+ },
+ "optionalDependencies": {
+ "@next/swc-darwin-arm64": "14.2.33",
+ "@next/swc-darwin-x64": "14.2.33",
+ "@next/swc-linux-arm64-gnu": "14.2.33",
+ "@next/swc-linux-arm64-musl": "14.2.33",
+ "@next/swc-linux-x64-gnu": "14.2.33",
+ "@next/swc-linux-x64-musl": "14.2.33",
+ "@next/swc-win32-arm64-msvc": "14.2.33",
+ "@next/swc-win32-ia32-msvc": "14.2.33",
+ "@next/swc-win32-x64-msvc": "14.2.33"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.1.0",
+ "@playwright/test": "^1.41.2",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "sass": "^1.3.0"
+ },
+ "peerDependenciesMeta": {
+ "@opentelemetry/api": {
+ "optional": true
+ },
+ "@playwright/test": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/next/node_modules/postcss": {
+ "version": "8.4.31",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+ "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+ "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.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nwsapi": {
+ "version": "2.2.23",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz",
+ "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==",
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-hash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "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/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "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/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/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-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/parse5": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^6.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "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/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/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pirates": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
+ "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-import": {
+ "version": "15.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
+ "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.0.0",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.0"
+ }
+ },
+ "node_modules/postcss-js": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz",
+ "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "camelcase-css": "^2.0.1"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >= 16"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.21"
+ }
+ },
+ "node_modules/postcss-load-config": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
+ "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "lilconfig": "^3.1.1"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "jiti": ">=1.21.0",
+ "postcss": ">=8.0.9",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postcss-nested": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
+ "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "postcss-selector-parser": "^6.1.1"
+ },
+ "engines": {
+ "node": ">=12.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.14"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/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",
+ "peer": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/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",
+ "peer": true,
+ "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",
+ "peer": true
+ },
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pure-rand": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz",
+ "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/dubzzz"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fast-check"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/react": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.2"
+ },
+ "peerDependencies": {
+ "react": "^18.3.1"
+ }
+ },
+ "node_modules/react-icons": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz",
+ "integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "*"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pify": "^2.3.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "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/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/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/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-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-cwd/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-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/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rrweb-cssom": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
+ "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.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/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/saxes": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
+ "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "xmlchars": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=v12.22.7"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "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/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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/source-map-support": {
+ "version": "0.5.13",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
+ "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/stable-hash": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz",
+ "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/stack-utils": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+ "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/stack-utils/node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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/streamsearch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
+ "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/string-length": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "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/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/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/string-width/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/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/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": {
+ "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-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-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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/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/styled-jsx": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
+ "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==",
+ "license": "MIT",
+ "dependencies": {
+ "client-only": "0.0.1"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "peerDependencies": {
+ "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "babel-plugin-macros": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/sucrase": {
+ "version": "3.35.0",
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
+ "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "commander": "^4.0.0",
+ "glob": "^10.3.10",
+ "lines-and-columns": "^1.1.6",
+ "mz": "^2.7.0",
+ "pirates": "^4.0.1",
+ "ts-interface-checker": "^0.1.9"
+ },
+ "bin": {
+ "sucrase": "bin/sucrase",
+ "sucrase-node": "bin/sucrase-node"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "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/symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/synckit": {
+ "version": "0.11.11",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz",
+ "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==",
+ "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/tailwindcss": {
+ "version": "3.4.18",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.18.tgz",
+ "integrity": "sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@alloc/quick-lru": "^5.2.0",
+ "arg": "^5.0.2",
+ "chokidar": "^3.6.0",
+ "didyoumean": "^1.2.2",
+ "dlv": "^1.1.3",
+ "fast-glob": "^3.3.2",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "jiti": "^1.21.7",
+ "lilconfig": "^3.1.3",
+ "micromatch": "^4.0.8",
+ "normalize-path": "^3.0.0",
+ "object-hash": "^3.0.0",
+ "picocolors": "^1.1.1",
+ "postcss": "^8.4.47",
+ "postcss-import": "^15.1.0",
+ "postcss-js": "^4.0.1",
+ "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0",
+ "postcss-nested": "^6.2.0",
+ "postcss-selector-parser": "^6.1.2",
+ "resolve": "^1.22.8",
+ "sucrase": "^3.35.0"
+ },
+ "bin": {
+ "tailwind": "lib/cli.js",
+ "tailwindcss": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/test-exclude/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "node_modules/thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "dev": true,
+ "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==",
+ "dev": true,
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/tldts": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz",
+ "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tldts-core": "^6.1.86"
+ },
+ "bin": {
+ "tldts": "bin/cli.js"
+ }
+ },
+ "node_modules/tldts-core": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz",
+ "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tmpl": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "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/tough-cookie": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
+ "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tldts": "^6.1.32"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+ "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/ts-interface-checker": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
+ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/ts-jest": {
+ "version": "29.4.6",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz",
+ "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bs-logger": "^0.2.6",
+ "fast-json-stable-stringify": "^2.1.0",
+ "handlebars": "^4.7.8",
+ "json5": "^2.2.3",
+ "lodash.memoize": "^4.1.2",
+ "make-error": "^1.3.6",
+ "semver": "^7.7.3",
+ "type-fest": "^4.41.0",
+ "yargs-parser": "^21.1.1"
+ },
+ "bin": {
+ "ts-jest": "cli.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": ">=7.0.0-beta.0 <8",
+ "@jest/transform": "^29.0.0 || ^30.0.0",
+ "@jest/types": "^29.0.0 || ^30.0.0",
+ "babel-jest": "^29.0.0 || ^30.0.0",
+ "jest": "^29.0.0 || ^30.0.0",
+ "jest-util": "^29.0.0 || ^30.0.0",
+ "typescript": ">=4.3 <6"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "@jest/transform": {
+ "optional": true
+ },
+ "@jest/types": {
+ "optional": true
+ },
+ "babel-jest": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "jest-util": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-jest/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/ts-jest/node_modules/type-fest": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
+ "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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/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/type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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/uglify-js": {
+ "version": "3.19.3",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
+ "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "optional": true,
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
+ },
+ "engines": {
+ "node": ">=0.8.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": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unrs-resolver": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz",
+ "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "napi-postinstall": "^0.3.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unrs-resolver"
+ },
+ "optionalDependencies": {
+ "@unrs/resolver-binding-android-arm-eabi": "1.11.1",
+ "@unrs/resolver-binding-android-arm64": "1.11.1",
+ "@unrs/resolver-binding-darwin-arm64": "1.11.1",
+ "@unrs/resolver-binding-darwin-x64": "1.11.1",
+ "@unrs/resolver-binding-freebsd-x64": "1.11.1",
+ "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1",
+ "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1",
+ "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1",
+ "@unrs/resolver-binding-linux-arm64-musl": "1.11.1",
+ "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1",
+ "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1",
+ "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1",
+ "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1",
+ "@unrs/resolver-binding-linux-x64-gnu": "1.11.1",
+ "@unrs/resolver-binding-linux-x64-musl": "1.11.1",
+ "@unrs/resolver-binding-wasm32-wasi": "1.11.1",
+ "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1",
+ "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1",
+ "@unrs/resolver-binding-win32-x64-msvc": "1.11.1"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz",
+ "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==",
+ "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/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/v8-to-istanbul": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
+ "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
+ "node_modules/w3c-xmlserializer": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
+ "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xml-name-validator": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/walker": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "makeerror": "1.0.12"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/whatwg-encoding": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "^5.1.0",
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "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.19",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
+ "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
+ "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/wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/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/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/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/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/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/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/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/write-file-atomic": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
+ "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "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/xml-name-validator": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
+ "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/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/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/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/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"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..84be795
--- /dev/null
+++ b/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "angels-flowers",
+ "version": "1.0.0",
+ "description": "Angel's Flowers - Premium Ecuadorian Flowers in East Los Angeles",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start",
+ "lint": "next lint",
+ "test": "jest --passWithNoTests",
+ "test:watch": "jest --watch"
+ },
+ "dependencies": {
+ "next": "^14.0.4",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-icons": "^4.12.0"
+ },
+ "devDependencies": {
+ "@testing-library/jest-dom": "^6.9.1",
+ "@testing-library/react": "^16.3.1",
+ "@types/jest": "^30.0.0",
+ "@types/node": "^20.10.5",
+ "@types/react": "^18.2.45",
+ "@types/react-dom": "^18.2.18",
+ "autoprefixer": "^10.4.16",
+ "eslint": "^8.56.0",
+ "eslint-config-next": "^14.0.4",
+ "jest": "^30.2.0",
+ "jest-environment-jsdom": "^30.2.0",
+ "postcss": "^8.4.32",
+ "tailwindcss": "^3.4.0",
+ "ts-jest": "^29.4.6",
+ "typescript": "^5.3.3"
+ }
+}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000..33ad091
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
diff --git a/product_strategy.md b/product_strategy.md
new file mode 100644
index 0000000..6e30127
--- /dev/null
+++ b/product_strategy.md
@@ -0,0 +1,237 @@
+# Angel's Flowers Product Strategy Document
+
+## Executive Summary
+Angel's Flowers will differentiate as the premier destination for authentic Ecuadorian flowers in Los Angeles, leveraging family heritage, direct sourcing relationships, and deep cultural connections to serve the Latino community and flower enthusiasts seeking superior quality and authenticity.
+
+---
+
+## 🎯 MARKET POSITIONING STRATEGY
+
+### Unique Value Proposition
+**"From Ecuador's highlands to East LA's heart - Premium roses that tell your story"**
+
+### Core Differentiators
+
+| Factor | Angel's Flowers | 800flowers | Local Florists |
+|--------|----------------|------------|----------------|
+| **Sourcing** | Direct from Ecuador farms (family connections) | Mass wholesale | Local wholesalers |
+| **Quality** | 50% longer vase life, larger blooms | Standard commercial | Variable |
+| **Cultural** | Bilingual, Latino traditions expert | Generic | Limited |
+| **Authenticity** | 3rd generation family story | Corporate | Individual |
+| **Specialization** | Ecuadorian rose expert | Everything | General |
+
+### Why Ecuadorian Flowers Matter
+- **World's Best Roses**: Ecuador produces 70% of world's premium roses
+- **Superior Quality**: High altitude (9,000+ ft) creates larger, vibrant blooms
+- **Longevity**: 12-15 day vase life vs. 7-10 days standard
+- **Year-Round Excellence**: Equatorial climate ensures consistent quality
+- **Variety**: 500+ rose varieties, rare colors unavailable elsewhere
+
+---
+
+## 📍 COMPETITIVE POSITIONING CANVAS
+
+### Market Category Definition
+- **Primary**: Premium Online Florist (competing on quality, not price)
+- **Secondary**: Cultural Celebration Specialist (quinceañeras, bodas, baptisms)
+- **Emerging**: Farm-to-Vase Direct Sourcing Pioneer
+
+### Strategic Position
+```
+Price Premium ↑
+ Angel's Flowers
+ (Premium Quality,
+ Cultural Expert)
+
+Local Shops 800flowers
+(Personal, (Convenient,
+Limited) Mass Market)
+
+Generic ← → Specialized
+```
+
+---
+
+## 🛍️ KEY WEBSITE FEATURES ROADMAP
+
+### Phase 1: Core MVP (Months 0-3)
+**Essential Features**
+- Online catalog with Ecuadorian flower showcase
+- Shopping cart with same-day/next-day delivery options
+- Bilingual interface (English/Spanish toggle)
+- WhatsApp integration for customer service
+- Mobile-first responsive design
+- Secure payment processing (including Afterpay/Klarna)
+
+### Phase 2: Differentiation (Months 3-6)
+**Growth Features**
+- Virtual arrangement builder with AR preview
+- Subscription service ("Rosa del Mes" - Rose of the Month)
+- Event planning tool for quinceañeras/weddings
+- Flower care video tutorials in English/Spanish
+- Customer photo gallery and testimonials
+- SMS order updates and delivery tracking
+
+### Phase 3: Platform Expansion (Months 6-12)
+**Advanced Features**
+- Corporate/B2B portal with volume pricing
+- Loyalty program with tiered benefits
+- Gift reminder calendar with cultural holidays
+- Live chat with flower experts
+- Instagram shopping integration
+- Wholesale portal for event planners
+
+---
+
+## 👥 TARGET AUDIENCE SEGMENTATION
+
+### Primary Segments
+
+| Segment | Demographics | Needs | Value Drivers |
+|---------|-------------|-------|---------------|
+| **Latino Families** | 25-55, East LA/Greater LA, $40-80K HH income | Cultural celebrations, family traditions | Authenticity, bilingual service, payment plans |
+| **Celebration Planners** | Event planners, quinceañera coordinators | Bulk orders, unique arrangements | Quality, reliability, cultural expertise |
+| **Premium Gift Givers** | 30-50, $60K+ income, quality-conscious | Impressive gifts, special occasions | Superior quality, exclusivity, story |
+| **Romantic Partners** | 25-45, relationship-focused | Anniversary, apology, romance | Flower longevity, presentation, delivery |
+
+### Customer Journey Map
+1. **Discovery**: Social media, local community, word-of-mouth
+2. **Consideration**: Website browsing, WhatsApp questions
+3. **Purchase**: Online order or phone consultation
+4. **Delivery**: Real-time tracking, surprise element
+5. **Follow-up**: Care instructions, loyalty program
+6. **Advocacy**: Social sharing, reviews, referrals
+
+---
+
+## 📝 CONTENT STRATEGY
+
+### Essential Website Pages
+
+#### 1. Homepage
+- Hero: "Ecuador's Finest Roses, East LA's Family Touch"
+- Featured: Seasonal arrangements, bestsellers
+- Trust signals: Family story preview, reviews
+- Clear CTAs: Shop Now, Learn Our Story
+
+#### 2. Our Story / Nuestra Historia
+- 3-generation family journey
+- Ecuador farm partnerships with photos
+- East LA community involvement
+- Behind-the-scenes import process
+
+#### 3. Why Ecuadorian Flowers
+- Educational content on quality difference
+- Altitude and climate advantages
+- Comparison chart with photos
+- Care instructions for longevity
+
+#### 4. Collections
+- **By Occasion**: Quinceañeras, Bodas, Funerals, Romance
+- **By Flower Type**: Roses (30+ varieties), Gypsophila, Carnations
+- **By Price**: Under $50, $50-100, Premium $100+
+- **Subscriptions**: Weekly, Bi-weekly, Monthly
+
+#### 5. Cultural Celebrations Guide
+- Quinceañera flower traditions
+- Day of the Dead arrangements
+- Valentine's Day in Latino culture
+- Mother's Day specials
+
+#### 6. Flower Care Center
+- Video tutorials (bilingual)
+- PDF care guides
+- Troubleshooting tips
+- Vase life guarantee
+
+---
+
+## 🚀 GO-TO-MARKET STRATEGY
+
+### Launch Strategy (Soft Launch → Full Launch)
+
+**Phase 1: Community Beta (Month 1)**
+- 50 select East LA families
+- 20% discount for feedback
+- WhatsApp group for input
+
+**Phase 2: Local Market Entry (Months 2-3)**
+- East LA + adjacent neighborhoods
+- Partner with 3 event planners
+- Pop-ups at local markets
+
+**Phase 3: Greater LA Expansion (Months 4-6)**
+- Full LA County delivery
+- Corporate partnerships
+- Influencer collaborations
+
+### Channel Strategy
+
+| Channel | Purpose | Investment |
+|---------|---------|------------|
+| **Website** | Primary sales platform | 40% |
+| **Instagram** | Visual storytelling, younger audience | 20% |
+| **WhatsApp Business** | Customer service, orders | 10% |
+| **Local SEO** | "Flores cerca de mi" searches | 15% |
+| **Community Events** | Trust building, sampling | 15% |
+
+### Pricing Strategy
+- **Premium Positioning**: 15-20% above standard florists
+- **Value Justification**: Superior quality, longevity, authenticity
+- **Payment Options**: Afterpay, Klarna for large orders
+- **Subscription Discount**: 15% off for monthly subscribers
+
+---
+
+## 📊 SUCCESS METRICS
+
+### Key Performance Indicators
+
+**Year 1 Targets**
+- Monthly Active Customers: 500 by month 12
+- Average Order Value: $75
+- Customer Retention Rate: 40%
+- Subscription Customers: 100
+- NPS Score: 70+
+
+**Leading Indicators**
+- Website conversion rate: 3.5%
+- Cart abandonment rate: <65%
+- Repeat purchase rate: 35%
+- Social engagement rate: 5%
+- Delivery satisfaction: 95%
+
+---
+
+## 💡 STRATEGIC RECOMMENDATIONS
+
+### Immediate Actions (Next 30 Days)
+1. Secure domain and brand identity
+2. Photograph signature arrangements
+3. Build relationships with 3 Ecuador farms
+4. Create bilingual content library
+5. Set up WhatsApp Business account
+
+### Competitive Advantages to Leverage
+1. **Direct Sourcing**: "From our family farms in Ecuador"
+2. **Cultural Expertise**: Only florist that truly understands Latino celebrations
+3. **Quality Guarantee**: "2-week vase life or money back"
+4. **Community Roots**: "Serving East LA families for 3 generations"
+5. **Bilingual Service**: Full Spanish support at every touchpoint
+
+### Risk Mitigation
+- **Supply Chain**: Maintain 2-3 farm partnerships
+- **Seasonality**: Develop corporate/subscription base
+- **Competition**: Focus on authenticity over price wars
+- **Operations**: Partner with reliable last-mile delivery
+
+---
+
+## 🌹 UNIQUE BRAND POSITIONING STATEMENT
+
+"Angel's Flowers brings Ecuador's world-renowned roses directly to Los Angeles, combining three generations of floral expertise with deep cultural understanding. We're not just delivering flowers – we're delivering tradition, quality, and the authentic beauty that only comes from Ecuador's perfect growing conditions. When your celebration matters, trust the family that knows flowers and knows our community."
+
+---
+
+*Strategy Document Version 1.0*
+*Prepared for Angel's Flowers Website Development*
\ No newline at end of file
diff --git a/public/favicon.svg b/public/favicon.svg
new file mode 100644
index 0000000..0bf53be
--- /dev/null
+++ b/public/favicon.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+<rect width="32" height="32" rx="6" fill="#10b981"/>
+<text x="50%" y="55%" text-anchor="middle" dominant-baseline="middle" font-size="20" font-family="Apple Color Emoji, Segoe UI Emoji, sans-serif" fill="white">A</text>
+</svg>
\ No newline at end of file
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..28c1b63
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,6 @@
+# Allow all crawlers
+User-agent: *
+Allow: /
+
+# Sitemap location
+Sitemap: https://angelsflowers.com/sitemap.xml
diff --git a/scripts/ralph/prd.json b/scripts/ralph/prd.json
new file mode 100644
index 0000000..d508c99
--- /dev/null
+++ b/scripts/ralph/prd.json
@@ -0,0 +1,170 @@
+{
+ "project": "angels-flowers",
+ "branchName": "ralph/dark-mode-testing-infrastructure",
+ "description": "Dark Mode Support & Unit Testing Framework implementation for premium Ecuadorian flower retailer",
+ "userStories": [
+ {
+ "id": "US-002",
+ "title": "System Theme Detection",
+ "description": "As a user, I want the website to automatically detect my system's dark mode preference so that the site matches my device settings.",
+ "acceptanceCriteria": [
+ "Detect prefers-color-scheme: dark media query on load",
+ "Set initial theme state based on system preference",
+ "Handle cases where system preference is not available",
+ "No flash of incorrect theme on page load",
+ "Typecheck passes",
+ "Run npm run build to verify no errors"
+ ],
+ "priority": 1,
+ "passes": false,
+ "notes": ""
+ },
+ {
+ "id": "US-003",
+ "title": "Theme State Persistence",
+ "description": "As a user, I want my theme preference to persist across browser sessions so that I don't need to reselect it each visit.",
+ "acceptanceCriteria": [
+ "Save theme preference to localStorage on change",
+ "Load saved theme preference on app initialization",
+ "Override system preference when manual selection exists",
+ "Handle localStorage not available gracefully",
+ "Typecheck passes"
+ ],
+ "priority": 2,
+ "passes": false,
+ "notes": ""
+ },
+ {
+ "id": "US-007",
+ "title": "Jest Testing Framework Setup",
+ "description": "As a developer, I want Jest configured for the project so that I can write and run unit tests.",
+ "acceptanceCriteria": [
+ "Install jest, @types/jest, and related dependencies",
+ "Create jest.config.js with TypeScript and Next.js support",
+ "Add test script to package.json",
+ "Configure path mapping for Next.js aliases",
+ "Test script runs without errors on empty test suite",
+ "Typecheck passes"
+ ],
+ "priority": 3,
+ "passes": false,
+ "notes": ""
+ },
+ {
+ "id": "US-001",
+ "title": "Theme Context Provider Setup",
+ "description": "As a developer, I want a theme context provider so that theme state is accessible throughout the component tree.",
+ "acceptanceCriteria": [
+ "Create ThemeContext with React.createContext",
+ "ThemeProvider component wraps app with theme state",
+ "Custom useTheme hook returns theme and toggleTheme function",
+ "Context provides 'light' and 'dark' theme values",
+ "Typecheck passes",
+ "Run npm run build to verify no errors"
+ ],
+ "priority": 4,
+ "passes": false,
+ "notes": ""
+ },
+ {
+ "id": "US-004",
+ "title": "CSS Variables for Dark Theme",
+ "description": "As a developer, I want CSS custom properties for dark theme colors so that components can adapt to theme changes.",
+ "acceptanceCriteria": [
+ "Define --bg-primary, --bg-secondary CSS variables for backgrounds",
+ "Define --text-primary, --text-secondary for text colors",
+ "Define --border, --shadow variables for UI elements",
+ "Root element applies data-theme attribute based on context",
+ "Variables update automatically when theme changes",
+ "Typecheck passes",
+ "Run npm run build to verify no errors"
+ ],
+ "priority": 5,
+ "passes": false,
+ "notes": ""
+ },
+ {
+ "id": "US-005",
+ "title": "Dark Mode Toggle Component",
+ "description": "As a user, I want a toggle button to manually switch between light and dark themes so that I can override system preference.",
+ "acceptanceCriteria": [
+ "ThemeToggle component with sun/moon icon",
+ "Button shows current theme state visually",
+ "Clicking button calls toggleTheme from context",
+ "Component uses proper ARIA labels for accessibility",
+ "Typecheck passes",
+ "Run npm run build to verify no errors"
+ ],
+ "priority": 6,
+ "passes": false,
+ "notes": ""
+ },
+ {
+ "id": "US-006",
+ "title": "Homepage Dark Theme Styling",
+ "description": "As a user, I want the homepage to display properly in dark mode so that I can browse comfortably in low-light conditions.",
+ "acceptanceCriteria": [
+ "Homepage uses CSS variables for background and text colors",
+ "Hero section adapts to dark theme with proper contrast",
+ "Navigation elements use dark theme colors",
+ "All text maintains minimum 4.5:1 contrast ratio",
+ "Typecheck passes",
+ "Run npm run build to verify no errors"
+ ],
+ "priority": 7,
+ "passes": false,
+ "notes": ""
+ },
+ {
+ "id": "US-008",
+ "title": "React Testing Library Configuration",
+ "description": "As a developer, I want React Testing Library configured so that I can test React components effectively.",
+ "acceptanceCriteria": [
+ "Install @testing-library/react and @testing-library/jest-dom",
+ "Create jest.setup.js with testing library configuration",
+ "Configure custom render function with theme providers",
+ "Add @testing-library/jest-dom matchers to Jest config",
+ "Sample component test runs successfully",
+ "Typecheck passes",
+ "Run npm run build to verify no errors"
+ ],
+ "priority": 8,
+ "passes": false,
+ "notes": ""
+ },
+ {
+ "id": "US-009",
+ "title": "Theme Context Component Tests",
+ "description": "As a developer, I want tests for the theme context so that theme functionality is verified.",
+ "acceptanceCriteria": [
+ "Test ThemeProvider renders children correctly",
+ "Test useTheme hook returns correct initial theme",
+ "Test toggleTheme function switches between light and dark",
+ "Test localStorage persistence on theme change",
+ "Test system preference detection",
+ "Typecheck passes",
+ "Run npm run build to verify no errors"
+ ],
+ "priority": 9,
+ "passes": false,
+ "notes": ""
+ },
+ {
+ "id": "US-010",
+ "title": "Theme Toggle Component Tests",
+ "description": "As a developer, I want tests for the theme toggle component so that user interaction is verified.",
+ "acceptanceCriteria": [
+ "Test component renders with correct initial icon",
+ "Test click handler calls toggleTheme function",
+ "Test icon changes when theme prop changes",
+ "Test ARIA attributes are set correctly",
+ "Test component handles missing theme context gracefully",
+ "Typecheck passes",
+ "Run npm run build to verify no errors"
+ ],
+ "priority": 10,
+ "passes": false,
+ "notes": ""
+ }
+ ]
+}
\ No newline at end of file
diff --git a/scripts/ralph/progress.txt b/scripts/ralph/progress.txt
new file mode 100644
index 0000000..ef33bb7
--- /dev/null
+++ b/scripts/ralph/progress.txt
@@ -0,0 +1,18 @@
+# Ralph Progress
+# Project: angels-flowers
+# Branch: ralph/dark-mode-testing-infrastructure
+# Started: 2026-01-14T02:22:08.829Z
+
+## Stories
+US-002: DONE - System Theme Detection
+US-003: DONE - Theme State Persistence
+US-007: DONE - Jest Testing Framework Setup
+US-001: DONE - Theme Context Provider Setup
+US-004: DONE - CSS Variables for Dark Theme
+US-005: DONE - Dark Mode Toggle Component
+US-006: DONE - Homepage Dark Theme Styling
+US-008: DONE - React Testing Library Configuration
+US-009: DONE - Theme Context Component Tests
+US-010: DONE - Theme Toggle Component Tests
+
+## Log
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 0000000..418326c
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,56 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: [
+ './pages/**/*.{js,ts,jsx,tsx,mdx}',
+ './components/**/*.{js,ts,jsx,tsx,mdx}',
+ './app/**/*.{js,ts,jsx,tsx,mdx}',
+ ],
+ darkMode: 'class',
+ theme: {
+ extend: {
+ colors: {
+ primary: {
+ 50: '#fdf4f5',
+ 100: '#fce7ea',
+ 200: '#fad4db',
+ 300: '#f6b1bd',
+ 400: '#f08399',
+ 500: '#e5567a',
+ 600: '#d03862',
+ 700: '#ae2851',
+ 800: '#91244a',
+ 900: '#7b2344',
+ },
+ accent: {
+ 50: '#f0fdf4',
+ 100: '#dcfce7',
+ 200: '#bbf7d0',
+ 300: '#86efac',
+ 400: '#4ade80',
+ 500: '#22c55e',
+ 600: '#16a34a',
+ 700: '#15803d',
+ 800: '#166534',
+ 900: '#14532d',
+ },
+ warm: {
+ 50: '#fefce8',
+ 100: '#fef9c3',
+ 200: '#fef08a',
+ 300: '#fde047',
+ 400: '#facc15',
+ 500: '#eab308',
+ 600: '#ca8a04',
+ 700: '#a16207',
+ 800: '#854d0e',
+ 900: '#713f12',
+ },
+ },
+ fontFamily: {
+ sans: ['var(--font-inter)', 'system-ui', 'sans-serif'],
+ serif: ['var(--font-playfair)', 'Georgia', 'serif'],
+ },
+ },
+ },
+ plugins: [],
+}
diff --git a/tasks/prd-new-feature-for-angels-flowers.md b/tasks/prd-new-feature-for-angels-flowers.md
new file mode 100644
index 0000000..0449cce
--- /dev/null
+++ b/tasks/prd-new-feature-for-angels-flowers.md
@@ -0,0 +1,264 @@
+# Product Requirements Document: Dark Mode & Testing Infrastructure
+
+## 1. Introduction/Overview
+
+This PRD outlines the implementation of dark mode support and unit testing framework for Angel's Flowers, a premium Ecuadorian flower retailer serving East Los Angeles. The website will be enhanced to provide a better user experience across different lighting conditions while ensuring code quality through comprehensive testing.
+
+**Project**: angels-flowers
+**Feature**: Dark Mode Support & Unit Testing Framework
+**Priority**: High
+**Target Users**: All website visitors and internal development team
+**Tech Stack**: Next.js 16 + React 19
+
+## 2. Goals
+
+• Implement system-aware dark mode with manual toggle override
+• Reduce eye strain for users browsing in low-light environments
+• Optimize flower product images for dark mode viewing
+• Establish comprehensive unit testing framework with 80%+ coverage
+• Improve code reliability and maintainability
+• Enable confident feature development and deployment
+• Increase user engagement through improved user experience
+
+## 3. User Stories
+
+### US-001: Dark Mode Theme Detection
+**Description**: As a user, I want the website to automatically detect my system's dark mode preference so that the site matches my device settings.
+**Acceptance Criteria**:
+- [ ] System automatically detects `prefers-color-scheme: dark` media query
+- [ ] Website applies dark theme when system preference is dark
+- [ ] Website applies light theme when system preference is light or not set
+- [ ] Theme detection works on page load without flash of incorrect theme
+- [ ] Typecheck passes
+- [ ] Verify in browser using dev-browser skill
+
+### US-002: Manual Dark Mode Toggle
+**Description**: As a user, I want to manually toggle between light and dark mode so that I can override my system preference.
+**Acceptance Criteria**:
+- [ ] Toggle button is visible in website header/navigation
+- [ ] Clicking toggle switches between light and dark themes
+- [ ] Toggle state persists across page navigation
+- [ ] Toggle state persists across browser sessions using localStorage
+- [ ] Toggle shows current theme state (sun/moon icon or similar)
+- [ ] Typecheck passes
+- [ ] Verify in browser using dev-browser skill
+
+### US-003: Homepage Dark Mode Styling
+**Description**: As a user, I want the homepage to display properly in dark mode so that I can browse comfortably in low-light conditions.
+**Acceptance Criteria**:
+- [ ] Background color changes to dark theme (#1a1a1a or similar)
+- [ ] Text color changes to light color (#ffffff or #f0f0f0)
+- [ ] All buttons maintain proper contrast ratio (minimum 4.5:1)
+- [ ] Hero section adapts to dark theme
+- [ ] Navigation elements use appropriate dark theme colors
+- [ ] Typecheck passes
+- [ ] Verify in browser using dev-browser skill
+
+### US-004: Product Catalog Dark Mode Styling
+**Description**: As a user, I want the product catalog page to display properly in dark mode so that I can browse flower products without eye strain.
+**Acceptance Criteria**:
+- [ ] Product grid maintains proper spacing and contrast in dark mode
+- [ ] Product cards have dark background with light text
+- [ ] Price text remains clearly visible with proper contrast
+- [ ] Filter/search controls adapt to dark theme
+- [ ] Pagination controls use dark theme styling
+- [ ] Typecheck passes
+- [ ] Verify in browser using dev-browser skill
+
+### US-005: Product Details Dark Mode Styling
+**Description**: As a user, I want product detail pages to display properly in dark mode so that I can view flower details comfortably.
+**Acceptance Criteria**:
+- [ ] Product title and description text use light colors on dark background
+- [ ] Add to cart button maintains brand colors with proper contrast
+- [ ] Product specifications/details are clearly readable
+- [ ] Related products section adapts to dark theme
+- [ ] Breadcrumb navigation uses dark theme colors
+- [ ] Typecheck passes
+- [ ] Verify in browser using dev-browser skill
+
+### US-006: Image Optimization for Dark Mode
+**Description**: As a user, I want flower product images to be optimized for dark mode so that they don't appear too bright or harsh.
+**Acceptance Criteria**:
+- [ ] Product images have subtle brightness reduction (10-15%) in dark mode
+- [ ] Image containers have appropriate dark backgrounds
+- [ ] Image loading states use dark theme colors
+- [ ] Hero images apply subtle overlay or filter in dark mode
+- [ ] Image zoom functionality works properly in both themes
+- [ ] Typecheck passes
+- [ ] Verify in browser using dev-browser skill
+
+### US-007: Jest Testing Framework Setup
+**Description**: As a developer, I want Jest configured for the project so that I can write and run unit tests.
+**Acceptance Criteria**:
+- [ ] Jest is installed and configured in package.json
+- [ ] Jest config file supports TypeScript files (.ts, .tsx)
+- [ ] Jest config includes path mapping for Next.js aliases
+- [ ] Test script added to package.json (`npm test`)
+- [ ] Jest can run without errors on empty test suite
+- [ ] Coverage reporting is configured and functional
+- [ ] Typecheck passes
+
+### US-008: React Testing Library Setup
+**Description**: As a developer, I want React Testing Library configured so that I can test React components effectively.
+**Acceptance Criteria**:
+- [ ] @testing-library/react is installed and configured
+- [ ] @testing-library/jest-dom is set up for custom matchers
+- [ ] Test utilities are configured for Next.js environment
+- [ ] Sample component test runs successfully
+- [ ] Setup file is configured for global test setup
+- [ ] Cleanup happens automatically after each test
+- [ ] Typecheck passes
+
+### US-009: Component Testing Suite
+**Description**: As a developer, I want comprehensive tests for React components so that I can ensure UI reliability.
+**Acceptance Criteria**:
+- [ ] All customer-facing components have test files (*.test.tsx)
+- [ ] Component rendering tests pass without errors
+- [ ] Props handling is tested for each component
+- [ ] User interaction tests cover click/form events
+- [ ] Error boundary behavior is tested where applicable
+- [ ] Test coverage for components is above 80%
+- [ ] Typecheck passes
+
+### US-010: Utility Functions Testing
+**Description**: As a developer, I want tests for utility functions so that business logic is verified.
+**Acceptance Criteria**:
+- [ ] All utility functions have corresponding test files
+- [ ] Edge cases are covered in utility tests
+- [ ] Input validation is tested for each function
+- [ ] Error handling scenarios are tested
+- [ ] Pure function behavior is verified
+- [ ] Test coverage for utilities is above 90%
+- [ ] Typecheck passes
+
+## 4. Functional Requirements
+
+**FR-1**: Theme Management System
+- Implement theme context provider using React Context API
+- Support system preference detection via CSS media queries
+- Provide manual override functionality with localStorage persistence
+- Ensure theme state is accessible throughout component tree
+
+**FR-2**: CSS Variables Architecture
+- Define comprehensive CSS custom properties for colors
+- Implement light and dark theme variable sets
+- Ensure consistent color usage across all components
+- Maintain proper contrast ratios for accessibility compliance
+
+**FR-3**: Image Enhancement System
+- Apply subtle filters to product images in dark mode
+- Implement automatic brightness adjustment for hero images
+- Ensure image quality is maintained across both themes
+- Optimize loading performance for dual-theme images
+
+**FR-4**: Testing Infrastructure
+- Configure Jest with TypeScript support for Next.js 16
+- Set up React Testing Library with custom render utilities
+- Implement code coverage reporting with 80%+ target
+- Create testing utilities for common scenarios
+
+**FR-5**: Component Test Coverage
+- Test all customer-facing page components
+- Verify theme switching functionality
+- Test user interactions and form submissions
+- Validate error handling and edge cases
+
+## 5. Non-Goals
+
+• Admin/dashboard pages dark mode support (customer-facing only)
+• Mobile app dark mode implementation
+• Email template dark mode support
+• Third-party widget/plugin dark mode integration
+• Backend API testing (unit tests for frontend only)
+• End-to-end testing implementation
+• Performance testing framework
+• Integration testing setup
+
+## 6. Design Considerations
+
+**Color Palette**:
+- Dark theme primary background: #1a1a1a
+- Dark theme secondary background: #2d2d2d
+- Dark theme text: #ffffff / #f0f0f0
+- Maintain brand colors for accents with adjusted opacity
+- Ensure WCAG AA compliance (4.5:1 contrast ratio minimum)
+
+**User Experience**:
+- Smooth transitions between themes (0.3s ease-in-out)
+- Persistent theme preference across sessions
+- Clear visual indication of current theme state
+- No flash of unstyled content during theme switching
+
+**Image Handling**:
+- Apply CSS filter: brightness(0.9) for dark mode images
+- Use background overlays for hero sections
+- Maintain image aspect ratios and quality
+- Consider loading separate optimized images for dark mode
+
+## 7. Technical Considerations
+
+**Theme Implementation**:
+- Use CSS-in-JS solution or CSS custom properties
+- Implement theme provider at app root level
+- Use Next.js theme detection to prevent hydration mismatch
+- Consider using next-themes library for robust implementation
+
+**Testing Architecture**:
+- Jest 29+ with TypeScript support
+- React Testing Library for component testing
+- Mock Next.js router and image components
+- Set up custom render function with theme providers
+
+**Performance**:
+- Minimize bundle size impact of theme switching
+- Optimize CSS custom property updates
+- Lazy load theme-specific assets
+- Ensure smooth transitions without layout shift
+
+**Browser Support**:
+- Modern browsers with CSS custom properties support
+- Graceful degradation for older browsers
+- Test across Chrome, Firefox, Safari, Edge
+- Ensure mobile browser compatibility
+
+## 8. Success Metrics
+
+**User Engagement**:
+- Track dark mode adoption rate (target: 30% of users)
+- Monitor session duration increase (target: 15% improvement)
+- Measure page views per session (target: 10% increase)
+- Track bounce rate reduction (target: 5% decrease)
+
+**Code Quality**:
+- Achieve 80%+ test coverage for components and utilities
+- Zero failing tests in CI/CD pipeline
+- Reduce bug reports related to UI inconsistencies
+- Improve developer confidence scores in team surveys
+
+**Performance**:
+- Maintain current page load speeds (<3s on 3G)
+- Theme switching completes within 300ms
+- No increase in cumulative layout shift (CLS)
+- Lighthouse accessibility score maintains 90+
+
+**Business Impact**:
+- Track conversion rate changes post-implementation
+- Monitor customer support tickets for usability issues
+- Measure development velocity improvement
+- Track deployment confidence and rollback frequency
+
+## 9. Open Questions
+
+1. **Image Strategy**: Should we pre-generate dark mode optimized images or apply filters dynamically? Consider CDN bandwidth and processing costs.
+
+2. **Testing Scope**: Should we include visual regression testing for dark mode, or is unit/integration testing sufficient for initial release?
+
+3. **Theme Customization**: Do we need to support additional themes beyond light/dark, or should we focus on these two options initially?
+
+4. **Legacy Browser Support**: What is our minimum browser support requirement for CSS custom properties and prefers-color-scheme?
+
+5. **Marketing Integration**: How should we communicate the new dark mode feature to existing customers? Newsletter, banner, social media?
+
+6. **Analytics Tracking**: What specific events should we track for dark mode usage to measure success beyond the defined metrics?
+
+7. **Maintenance Strategy**: How often should we review and update test coverage? Who is responsible for maintaining test quality standards?
\ No newline at end of file
diff --git a/test-utils/index.tsx b/test-utils/index.tsx
new file mode 100644
index 0000000..4e8b739
--- /dev/null
+++ b/test-utils/index.tsx
@@ -0,0 +1,36 @@
+import { ReactElement, ReactNode } from 'react';
+import { render, RenderOptions } from '@testing-library/react';
+
+interface AllTheProvidersProps {
+ children: ReactNode;
+}
+
+/**
+ * Wrapper component that can be extended with providers as needed.
+ * Currently returns children directly, but can be extended to include
+ * ThemeProvider or other context providers when testing components
+ * that require them.
+ */
+function AllTheProviders({ children }: AllTheProvidersProps) {
+ return <>{children}</>;
+}
+
+/**
+ * Custom render function that wraps components with necessary providers
+ * for testing. This can be extended to include ThemeProvider or other
+ * context providers as needed.
+ *
+ * Usage:
+ * import { render } from '@/test-utils';
+ * render(<MyComponent />);
+ */
+const customRender = (
+ ui: ReactElement,
+ options?: Omit<RenderOptions, 'wrapper'>
+) => render(ui, { wrapper: AllTheProviders, ...options });
+
+// Re-export everything from React Testing Library
+export * from '@testing-library/react';
+
+// Override render with our custom version
+export { customRender as render };
diff --git a/test.txt b/test.txt
new file mode 100644
index 0000000..3b18e51
--- /dev/null
+++ b/test.txt
@@ -0,0 +1 @@
+hello world
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..c714696
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
+ "paths": {
+ "@/*": ["./*"]
+ }
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+ "exclude": ["node_modules"]
+}
(oldest)
·
back to Angels Flowers
·
tighten .gitignore: add missing standing-rule patterns (tmp/ 6bd8617 →