diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index c6c8b36..0000000 --- a/.editorconfig +++ /dev/null @@ -1,9 +0,0 @@ -root = true - -[*] -indent_style = space -indent_size = 2 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true diff --git a/.env.example b/.env.example deleted file mode 100644 index 2be1f7d..0000000 --- a/.env.example +++ /dev/null @@ -1,4 +0,0 @@ -NEXT_PUBLIC_SUPABASE_URL=your_supabase_url -SUPABASE_SERVICE_ROLE_KEY=your_service_role_key -KITE_API_KEY=your_kite_api_key -KITE_API_SECRET=your_kite_api_secret \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 39d72f7..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": ["next/core-web-vitals", "eslint:recommended"], - "parser": "@typescript-eslint/parser", - "plugins": ["@typescript-eslint"], - "rules": { - "semi": ["error", "always"], - "quotes": ["error", "double"], - "no-unused-vars": "warn", - "no-console": "warn" - } -} diff --git a/.gitignore b/.gitignore index e72b4d6..5ef6a52 100644 --- a/.gitignore +++ b/.gitignore @@ -31,7 +31,7 @@ yarn-error.log* .pnpm-debug.log* # env files (can opt-in for committing if needed) -.env +.env* # vercel .vercel diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index 25bf17f..0000000 --- a/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -18 \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 74c8244..0000000 --- a/.prettierrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "semi": true, - "singleQuote": false, - "printWidth": 80, - "tabWidth": 2, - "trailingComma": "all" -} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..3b66410 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "git.ignoreLimitWarning": true +} \ No newline at end of file diff --git a/README.md b/README.md index 78edd8f..e215bc4 100644 --- a/README.md +++ b/README.md @@ -1,134 +1,36 @@ -# 🎯 BullsEye +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). -*"Making bad decisions faster with AI"* +## Getting Started -## What is BullsEye? 🤔 - -BullsEye is an open-source research chatbot that pretends to help you make better trading decisions. Because apparently, what the stock market really needed was another AI telling people when to buy high and sell low. - -Built with the delusion that technology can solve human greed, this tool connects to Zerodha's Kite API and uses Groq's AI models to analyze your portfolio. Think of it as your digital *munimji* who never sleeps, never judges, and definitely won't steal from the cash drawer. - -## Features That Actually Work 📈 - -- **Real-time Portfolio Analysis**: Watch your money disappear in high definition -- **AI-Powered Insights**: Get advice from machines that have never felt the pain of a margin call -- **Zerodha Kite Integration**: Because if you're going to lose money, do it through India's favorite broker -- **Modern UI**: Sleek interface to make your losses look aesthetic -- **Research Tools**: For when you want to feel scientific about your gambling addiction - -## Tech Stack 🛠️ - -- **Next.js**: Because React wasn't complicated enough -- **Zerodha Kite API**: Your gateway to financial enlightenment (or bankruptcy) -- **Groq API**: AI that's faster than your portfolio's decline -- **TypeScript**: For when you want your code to be as type-safe as your investments aren't - -## Prerequisites 📋 - -Before you begin this journey of self-discovery (and portfolio destruction), make sure you have: - -- Node.js (preferably newer than your trading strategy) -- A Zerodha account (and the stomach for what's coming) -- Groq API key (free, unlike your trading education) -- Basic understanding of JavaScript (optional, just like risk management apparently) - -## Installation 🚀 +First, run the development server: ```bash -# Clone this repo (your first mistake) -git clone https://github.com/BullsEyeOrg/BullsEye.git - -# Enter the danger zone -cd bullseye - -# Install dependencies (and dependency on false hope) -npm install - -# Set up environment variables -cp .env.example .env.local -``` - -## Environment Setup 🔧 - -Create a `.env.local` file with the following variables: - -```env -KITE_API_KEY=your_kite_api_key -KITE_API_SECRET=your_kite_secret -GROQ_API_KEY=your_groq_api_key -NEXT_PUBLIC_APP_URL=http://localhost:3000 -``` - -*Pro tip: Guard these keys like they're the last samosa at a corporate meeting - because unlike your trading strategy, these actually work* - -## Getting Started 🏁 - -```bash -# Start the development server npm run dev - -# Open http://localhost:3000 -# Prepare for enlightenment (or entertainment) +# or +yarn dev +# or +pnpm dev +# or +bun dev ``` -## How It Works 🧠 - -1. **Connect**: Link your Zerodha account (surrender your financial soul) -2. **Analyze**: AI processes your portfolio data (judges you silently) -3. **Chat**: Ask questions about your investments (receive existential crisis) -4. **Research**: Get insights based on market data (learn why you're wrong) -5. **Repeat**: Continue the cycle of hope and despair - -## API Integration 🔌 - -BullsEye leverages: -- **Kite Connect API**: For real-time market data and portfolio information -- **Groq API**: For lightning-fast AI inference (faster than your money disappearing) -- **Next.js API Routes**: Because we needed more moving parts - -## Contributing 🤝 - -Found a bug? Want to add a feature? Think you can make this tool actually profitable? - -1. Fork the repository -2. Create a feature branch -3. Make your changes -4. Submit a pull request -5. Wait for review (like waiting for your stocks to recover) - -## Disclaimer ⚠️ - -**IMPORTANT**: This tool is for research and educational purposes only. The AI's suggestions are about as reliable as a weather forecast. - -- Past performance doesn't indicate future results -- Markets can remain irrational longer than you can remain solvent -- This tool won't make you the next Rakesh Jhunjhunwala -- Your mileage may vary (and probably will, downward) - -*"Risk hai toh ishq hai"* - Every trader's last words - -## License 📄 - -MIT License - Because even our legal framework should be open source. +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. -Use this code freely, modify it wildly, and distribute it responsibly. Just don't blame us when your AI trading bot achieves consciousness and decides to short your entire portfolio. +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. -## Support 💬 +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. -Having issues? Join the club. +## Learn More -- Create an issue on GitHub -- Check existing discussions -- Remember: there are no stupid questions, only expensive ones +To learn more about Next.js, take a look at the following resources: -## Final Words 🎭 +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. -*"Yeh jo public hai, yeh sab jaanti hai"* - Naseeruddin Shah +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! -The market knows everything, the AI knows patterns, but nobody knows when to actually buy or sell. BullsEye just makes the confusion more organized. +## Deploy on Vercel -Built with ❤️ and unrealistic expectations in India. +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. ---- - -**Happy Trading! May your profits be high and your losses be tax-deductible** 📊🚀 \ No newline at end of file +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/app/api/auth/route.ts b/app/api/auth/route.ts deleted file mode 100644 index b8aa415..0000000 --- a/app/api/auth/route.ts +++ /dev/null @@ -1,176 +0,0 @@ -// pages/api/kite-login.ts or app/api/kite-login/route.ts -import { NextApiRequest, NextApiResponse } from 'next'; -import { createClient } from '@supabase/supabase-js'; -import { v4 as uuidv4 } from 'uuid'; -import crypto from 'crypto'; - -// Initialize Supabase client -const supabase = createClient( - process.env.NEXT_PUBLIC_SUPABASE_URL!, - process.env.SUPABASE_SERVICE_ROLE_KEY! -); - -interface KiteLoginRequest { - user_id: string; - password: string; - twofa?: string; -} - -interface KiteLoginResponse { - success: boolean; - user_uuid?: string; - access_token?: string; - message?: string; -} - -// Generate checksum for Kite API -function generateChecksum(data: string, secret: string): string { - return crypto.createHmac('sha256', secret).update(data).digest('hex'); -} - -export default async function handler( - req: NextApiRequest, - res: NextApiResponse -) { - if (req.method !== 'POST') { - return res.status(405).json({ success: false, message: 'Method not allowed' }); - } - - try { - const { user_id, password, twofa }: KiteLoginRequest = req.body; - - if (!user_id || !password) { - return res.status(400).json({ - success: false, - message: 'User ID and password are required' - }); - } - - // Check if user already exists in our database - const { data: existingUser, error: fetchError } = await supabase - .from('users') - .select('user_uuid, kite_user_id') - .eq('kite_user_id', user_id) - .single(); - - let userUuid: string; - - if (existingUser && !fetchError) { - // User exists, use existing UUID - userUuid = existingUser.user_uuid; - } else { - // New user, generate UUID - userUuid = uuidv4(); - } - - // Kite Connect login API call - const kiteApiKey = process.env.KITE_API_KEY!; - const kiteApiSecret = process.env.KITE_API_SECRET!; - - // Step 1: Login to get request_token (this is simplified - in reality you'd need to handle the OAuth flow) - const loginData = { - user_id: user_id, - password: password, - twofa: twofa || '' - }; - - // Note: This is a simplified version. In production, you'd need to: - // 1. Redirect user to Kite login page - // 2. Handle the callback with request_token - // 3. Exchange request_token for access_token - - const loginResponse = await fetch('https://kite.zerodha.com/api/login', { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'X-Kite-Version': '3' - }, - body: new URLSearchParams(loginData) - }); - - if (!loginResponse.ok) { - return res.status(401).json({ - success: false, - message: 'Invalid Kite credentials' - }); - } - - const loginResult = await loginResponse.json(); - - // Assuming we get a request_token, exchange it for access_token - const requestToken = loginResult.data?.request_token; - - if (!requestToken) { - return res.status(401).json({ - success: false, - message: 'Failed to get request token from Kite' - }); - } - - // Generate access token - const checksumData = `${kiteApiKey}${requestToken}${kiteApiSecret}`; - const checksum = generateChecksum(checksumData, kiteApiSecret); - - const sessionResponse = await fetch('https://api.kite.trade/session/token', { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded' - }, - body: new URLSearchParams({ - api_key: kiteApiKey, - request_token: requestToken, - checksum: checksum - }) - }); - - const sessionResult = await sessionResponse.json(); - - if (!sessionResult.data?.access_token) { - return res.status(401).json({ - success: false, - message: 'Failed to generate access token' - }); - } - - const accessToken = sessionResult.data.access_token; - - // Save or update user in Supabase - const userData = { - user_uuid: userUuid, - kite_user_id: user_id, - kite_access_token: accessToken, - last_login: new Date().toISOString(), - created_at: existingUser ? existingUser.created_at : new Date().toISOString() - }; - - const { error: upsertError } = await supabase - .from('users') - .upsert(userData, { - onConflict: 'kite_user_id', - ignoreDuplicates: false - }); - - if (upsertError) { - console.error('Database error:', upsertError); - return res.status(500).json({ - success: false, - message: 'Failed to save user data' - }); - } - - // Return success response - return res.status(200).json({ - success: true, - user_uuid: userUuid, - access_token: accessToken, - message: existingUser ? 'User logged in successfully' : 'New user created and logged in' - }); - - } catch (error) { - console.error('Login error:', error); - return res.status(500).json({ - success: false, - message: 'Internal server error' - }); - } -} diff --git a/app/api/components/portfolio/route.ts b/app/api/components/portfolio/route.ts new file mode 100644 index 0000000..3ce25ee --- /dev/null +++ b/app/api/components/portfolio/route.ts @@ -0,0 +1,294 @@ +import { NextRequest, NextResponse } from 'next/server'; + +// Types for portfolio data +interface PortfolioHolding { + tradingsymbol: string; + exchange: string; + instrument_token: string; + isin: string; + product: string; + price: number; + quantity: number; + used_quantity: number; + t1_quantity: number; + realised_quantity: number; + authorised_quantity: number; + authorised_date: string; + opening_quantity: number; + collateral_quantity: number; + collateral_type: string; + discrepancy: boolean; + average_price: number; + last_price: number; + close_price: number; + pnl: number; + day_change: number; + day_change_percentage: number; +} + +interface ProcessedPortfolioData { + holding_quantity: number; + avg_buy_price: number; + current_market_value: number; + unrealized_pnl: number; + realized_pnl: number; + pnl_percent: number; + asset_allocation_percent: number; + portfolio_turnover: number; + margin_utilized: number; + margin_breakdown: { + span: number; + exposure: number; + }; + order_history: any[]; + time_in_market: number; + liquidity_score: number; + holding_period_avg_days: number; + execution_quality_rating: number; + slippage_percent: number; +} + +// Dummy data for fallback +const getDummyPortfolioData = (segment?: string): ProcessedPortfolioData => ({ + holding_quantity: 100, + avg_buy_price: 1250.50, + current_market_value: 135000.00, + unrealized_pnl: 10000.00, + realized_pnl: 5000.00, + pnl_percent: 8.00, + asset_allocation_percent: 25.5, + portfolio_turnover: 1.2, + margin_utilized: 75000.00, + margin_breakdown: { + span: 45000.00, + exposure: 30000.00 + }, + order_history: [ + { + order_id: "240625000001", + tradingsymbol: "RELIANCE", + transaction_type: "BUY", + quantity: 50, + price: 1250.50, + order_timestamp: "2024-06-25T09:15:00Z", + status: "COMPLETE" + } + ], + time_in_market: 45, + liquidity_score: 85.5, + holding_period_avg_days: 120, + execution_quality_rating: 4.2, + slippage_percent: 0.15 +}); + +// Helper function to get session token from request +const getSessionToken = (request: NextRequest): string | null => { + const authHeader = request.headers.get('Authorization'); + if (!authHeader || !authHeader.startsWith('Bearer ')) { + return null; + } + return authHeader.substring(7); +}; + +// Helper function to validate session token with Kite Auth API +const validateSessionToken = async (sessionToken: string): Promise => { + try { + const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/kite-auth?action=profile`, { + headers: { + 'Authorization': `Bearer ${sessionToken}`, + 'Content-Type': 'application/json' + } + }); + + if (!response.ok) { + console.error('Session validation failed:', response.status); + return false; + } + + const userData = await response.json(); + return userData && userData.user_id; + } catch (error) { + console.error('Error validating session token:', error); + return false; + } +}; + +// Helper function to fetch portfolio data from Kite API +const fetchKitePortfolioData = async (sessionToken: string, segment?: string): Promise => { + try { + // Construct Kite API URL based on segment + let kiteApiUrl = `${process.env.KITE_API_BASE_URL}/portfolio/holdings`; + + const response = await fetch(kiteApiUrl, { + method: 'GET', + headers: { + 'Authorization': `token ${process.env.KITE_API_KEY}:${sessionToken}`, + 'X-Kite-Version': '3', + 'Content-Type': 'application/json' + } + }); + + if (!response.ok) { + throw new Error(`Kite API request failed: ${response.status} ${response.statusText}`); + } + + const data = await response.json(); + + // Filter by segment if specified + let holdings = data.data || []; + if (segment) { + holdings = holdings.filter((holding: PortfolioHolding) => { + switch (segment) { + case 'equity': + return holding.exchange === 'NSE' || holding.exchange === 'BSE'; + case 'futures': + return holding.product === 'NRML' && holding.tradingsymbol.includes('FUT'); + case 'options': + return holding.product === 'NRML' && (holding.tradingsymbol.includes('CE') || holding.tradingsymbol.includes('PE')); + default: + return true; + } + }); + } + + return holdings; + } catch (error) { + console.error('Error fetching Kite portfolio data:', error); + throw error; + } +}; + +// Helper function to process raw portfolio data into required metrics +const processPortfolioData = (holdings: PortfolioHolding[], details: boolean): ProcessedPortfolioData => { + if (!holdings.length) { + return getDummyPortfolioData(); + } + + const totalQuantity = holdings.reduce((sum, h) => sum + h.quantity, 0); + const totalValue = holdings.reduce((sum, h) => sum + (h.last_price * h.quantity), 0); + const totalCost = holdings.reduce((sum, h) => sum + (h.average_price * h.quantity), 0); + const totalPnl = holdings.reduce((sum, h) => sum + h.pnl, 0); + + // Calculate additional metrics + const pnlPercent = totalCost > 0 ? (totalPnl / totalCost) * 100 : 0; + const avgHoldingPeriod = Math.floor(Math.random() * 200) + 30; // Mock calculation + + const processedData: ProcessedPortfolioData = { + holding_quantity: totalQuantity, + avg_buy_price: totalCost / totalQuantity, + current_market_value: totalValue, + unrealized_pnl: totalPnl, + realized_pnl: Math.random() * 10000, // Mock data - would need separate API call + pnl_percent: pnlPercent, + asset_allocation_percent: 100, // Mock - would need total portfolio context + portfolio_turnover: Math.random() * 2, + margin_utilized: totalValue * 0.2, // Mock calculation + margin_breakdown: { + span: totalValue * 0.12, + exposure: totalValue * 0.08 + }, + order_history: details ? holdings.map(h => ({ + order_id: `mock_${h.instrument_token}`, + tradingsymbol: h.tradingsymbol, + transaction_type: "BUY", + quantity: h.quantity, + price: h.average_price, + order_timestamp: new Date().toISOString(), + status: "COMPLETE" + })) : [], + time_in_market: avgHoldingPeriod, + liquidity_score: Math.random() * 30 + 70, + holding_period_avg_days: avgHoldingPeriod, + execution_quality_rating: Math.random() * 2 + 3, + slippage_percent: Math.random() * 0.5 + }; + + return processedData; +}; + +export async function GET(request: NextRequest) { + try { + // Parse query parameters + const { searchParams } = new URL(request.url); + const segment = searchParams.get('segment') as 'equity' | 'futures' | 'options' | null; + const details = searchParams.get('details') === 'true'; + + // Validate segment parameter + if (segment && !['equity', 'futures', 'options'].includes(segment)) { + return NextResponse.json( + { error: 'Invalid segment. Must be one of: equity, futures, options' }, + { status: 400 } + ); + } + + // Get and validate session token + const sessionToken = getSessionToken(request); + if (!sessionToken) { + return NextResponse.json( + { error: 'Missing or invalid Authorization header' }, + { status: 401 } + ); + } + + // Validate session token + const isValidToken = await validateSessionToken(sessionToken); + if (!isValidToken) { + console.warn('Invalid session token, falling back to dummy data'); + return NextResponse.json({ + success: true, + data: getDummyPortfolioData(segment || undefined), + source: 'fallback', + message: 'Using dummy data due to authentication failure' + }); + } + + let portfolioData: ProcessedPortfolioData; + + try { + // Attempt to fetch real data from Kite API + const holdings = await fetchKitePortfolioData(sessionToken, segment || undefined); + portfolioData = processPortfolioData(holdings, details); + + return NextResponse.json({ + success: true, + data: portfolioData, + source: 'kite_api', + message: 'Portfolio data retrieved successfully' + }); + + } catch (kiteError) { + // Fallback to dummy data if Kite API fails + console.error('Kite API failed, using fallback data:', kiteError); + + portfolioData = getDummyPortfolioData(segment || undefined); + + return NextResponse.json({ + success: true, + data: portfolioData, + source: 'fallback', + message: 'Using dummy data due to API failure', + error: process.env.NODE_ENV === 'development' ? String(kiteError) : undefined + }); + } + + } catch (error) { + console.error('Portfolio API error:', error); + + // Final fallback + return NextResponse.json({ + success: false, + data: getDummyPortfolioData(), + source: 'fallback', + message: 'API error occurred, returning dummy data', + error: process.env.NODE_ENV === 'development' ? String(error) : 'Internal server error' + }, { status: 500 }); + } +} + +// Optional: Add other HTTP methods if needed +export async function POST(request: NextRequest) { + return NextResponse.json( + { error: 'Method not allowed' }, + { status: 405 } + ); +} \ No newline at end of file diff --git a/app/api/kite-auth/route.ts b/app/api/kite-auth/route.ts new file mode 100644 index 0000000..24e2a18 --- /dev/null +++ b/app/api/kite-auth/route.ts @@ -0,0 +1,310 @@ +// app/api/kite-auth/route.ts +import { NextRequest, NextResponse } from 'next/server'; +import crypto from 'crypto'; + +// Types for Kite Connect API +interface KiteLoginResponse { + access_token: string; + refresh_token?: string; + user_id: string; + user_name: string; + user_shortname: string; + email: string; + user_type: string; + broker: string; + exchanges: string[]; + products: string[]; + order_types: string[]; + avatar_url: string; +} + +interface KiteTokenRequest { + api_key: string; + request_token: string; + api_secret: string; +} + +interface SessionData { + access_token: string; + user_id: string; + user_name: string; + email: string; + expires_at: number; + created_at: number; +} + +// In-memory session store (use Redis/Database in production) +const sessionStore = new Map(); + +// Environment variables needed: +// KITE_API_KEY=your_kite_api_key +// KITE_API_SECRET=your_kite_api_secret +// SESSION_SECRET=your_session_secret (for signing session tokens) + +const KITE_API_KEY = process.env.KITE_API_KEY; +const KITE_API_SECRET = process.env.KITE_API_SECRET; +const SESSION_SECRET = process.env.SESSION_SECRET || 'your-session-secret'; + +// Generate session token +function generateSessionToken(userId: string): string { + const payload = `${userId}:${Date.now()}`; + const signature = crypto + .createHmac('sha256', SESSION_SECRET) + .update(payload) + .digest('hex'); + return `${Buffer.from(payload).toString('base64')}.${signature}`; +} + +// Verify session token +function verifySessionToken(token: string): { userId: string; timestamp: number } | null { + try { + const [payloadBase64, signature] = token.split('.'); + const payload = Buffer.from(payloadBase64, 'base64').toString(); + + const expectedSignature = crypto + .createHmac('sha256', SESSION_SECRET) + .update(payload) + .digest('hex'); + + if (signature !== expectedSignature) { + return null; + } + + const [userId, timestamp] = payload.split(':'); + return { userId, timestamp: parseInt(timestamp) }; + } catch { + return null; + } +} + +// Generate checksum for Kite API +function generateChecksum(apiKey: string, requestToken: string, apiSecret: string): string { + const data = apiKey + requestToken + apiSecret; + return crypto.createHash('sha256').update(data).digest('hex'); +} + +// Login endpoint - Step 1: Get login URL +export async function GET(request: NextRequest) { + try { + const { searchParams } = new URL(request.url); + const action = searchParams.get('action'); + + if (action === 'login-url') { + if (!KITE_API_KEY) { + return NextResponse.json( + { error: 'Kite API key not configured' }, + { status: 500 } + ); + } + + const loginUrl = `https://kite.trade/connect/login?api_key=${KITE_API_KEY}&v=3`; + + return NextResponse.json({ + success: true, + login_url: loginUrl, + message: 'Redirect user to this URL for authentication' + }); + } + + // Get user data using session token + if (action === 'profile') { + const authHeader = request.headers.get('authorization'); + const sessionToken = authHeader?.replace('Bearer ', ''); + + if (!sessionToken) { + return NextResponse.json( + { error: 'Session token required' }, + { status: 401 } + ); + } + + const tokenData = verifySessionToken(sessionToken); + if (!tokenData) { + return NextResponse.json( + { error: 'Invalid session token' }, + { status: 401 } + ); + } + + const sessionData = sessionStore.get(tokenData.userId); + if (!sessionData) { + return NextResponse.json( + { error: 'Session expired' }, + { status: 401 } + ); + } + + // Check if session is expired (24 hours) + if (Date.now() > sessionData.expires_at) { + sessionStore.delete(tokenData.userId); + return NextResponse.json( + { error: 'Session expired' }, + { status: 401 } + ); + } + + // Fetch fresh user data from Kite + try { + const profileResponse = await fetch('https://api.kite.trade/user/profile', { + headers: { + 'Authorization': `token ${KITE_API_KEY}:${sessionData.access_token}`, + 'X-Kite-Version': '3' + } + }); + + if (!profileResponse.ok) { + throw new Error('Failed to fetch profile'); + } + + const profileData = await profileResponse.json(); + + return NextResponse.json({ + success: true, + user: profileData.data, + session_info: { + user_id: sessionData.user_id, + expires_at: sessionData.expires_at + } + }); + } catch (error) { + return NextResponse.json( + { error: 'Failed to fetch user profile' }, + { status: 500 } + ); + } + } + + return NextResponse.json( + { error: 'Invalid action parameter' }, + { status: 400 } + ); + + } catch (error) { + console.error('GET Error:', error); + return NextResponse.json( + { error: 'Internal server error' }, + { status: 500 } + ); + } +} + +// Login endpoint - Step 2: Exchange request token for access token +export async function POST(request: NextRequest) { + try { + const body: KiteTokenRequest = await request.json(); + const { request_token } = body; + + if (!request_token) { + return NextResponse.json( + { error: 'Request token is required' }, + { status: 400 } + ); + } + + if (!KITE_API_KEY || !KITE_API_SECRET) { + return NextResponse.json( + { error: 'Kite API credentials not configured' }, + { status: 500 } + ); + } + + // Generate checksum + const checksum = generateChecksum(KITE_API_KEY, request_token, KITE_API_SECRET); + + // Exchange request token for access token + const tokenResponse = await fetch('https://api.kite.trade/session/token', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'X-Kite-Version': '3' + }, + body: new URLSearchParams({ + api_key: KITE_API_KEY, + request_token: request_token, + checksum: checksum + }) + }); + + if (!tokenResponse.ok) { + const errorData = await tokenResponse.json(); + return NextResponse.json( + { error: errorData.message || 'Authentication failed' }, + { status: 400 } + ); + } + + const tokenData: { data: KiteLoginResponse } = await tokenResponse.json(); + const kiteUser = tokenData.data; + + // Create session + const sessionToken = generateSessionToken(kiteUser.user_id); + const expiresAt = Date.now() + (24 * 60 * 60 * 1000); // 24 hours + + const sessionData: SessionData = { + access_token: kiteUser.access_token, + user_id: kiteUser.user_id, + user_name: kiteUser.user_name, + email: kiteUser.email, + expires_at: expiresAt, + created_at: Date.now() + }; + + // Store session (use Redis/Database in production) + sessionStore.set(kiteUser.user_id, sessionData); + + return NextResponse.json({ + success: true, + session_token: sessionToken, + user: { + user_id: kiteUser.user_id, + user_name: kiteUser.user_name, + email: kiteUser.email, + user_shortname: kiteUser.user_shortname, + user_type: kiteUser.user_type, + broker: kiteUser.broker, + avatar_url: kiteUser.avatar_url + }, + expires_at: expiresAt, + message: 'Login successful' + }); + + } catch (error) { + console.error('POST Error:', error); + return NextResponse.json( + { error: 'Internal server error' }, + { status: 500 } + ); + } +} + +// Logout endpoint +export async function DELETE(request: NextRequest) { + try { + const authHeader = request.headers.get('authorization'); + const sessionToken = authHeader?.replace('Bearer ', ''); + + if (!sessionToken) { + return NextResponse.json( + { error: 'Session token required' }, + { status: 401 } + ); + } + + const tokenData = verifySessionToken(sessionToken); + if (tokenData) { + sessionStore.delete(tokenData.userId); + } + + return NextResponse.json({ + success: true, + message: 'Logged out successfully' + }); + + } catch (error) { + console.error('DELETE Error:', error); + return NextResponse.json( + { error: 'Internal server error' }, + { status: 500 } + ); + } +} \ No newline at end of file diff --git a/app/auth/page.tsx b/app/auth/page.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/app/page.tsx b/app/page.tsx index dfd0ebe..3eb7240 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,339 +1,287 @@ -"use client" - +'use client'; import React, { useState, useEffect } from 'react'; -import { - ArrowRight, - TrendingUp, - PieChart, - BarChart3, - MessageSquare, - Github, - ExternalLink, - Target, - Shield, - Users, - Activity, - Moon, - Sun, - Code, - Zap, - Lock -} from 'lucide-react'; -import '../styles/welcome-page.css'; -export default function BullsEyeWelcome() { - const [isDark, setIsDark] = useState(false); +// Type definitions +interface UserData { + user_id: string; + user_name: string; + email: string; + user_shortname: string; + user_type: string; + broker: string; + avatar_url: string; +} + +export default function KiteLoginPage() { + const [sessionToken, setSessionToken] = useState(null); + const [userData, setUserData] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); + const [status, setStatus] = useState(''); + // Check for existing session on page load useEffect(() => { - const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; - setIsDark(prefersDark); - document.documentElement.setAttribute('data-theme', prefersDark ? 'dark' : 'light'); + const token = localStorage.getItem('kite_session'); + if (token) { + setSessionToken(token); + fetchUserProfile(token); + } + + // Check if we're coming back from Kite with request_token + const urlParams = new URLSearchParams(window.location.search); + const requestToken = urlParams.get('request_token'); + const status = urlParams.get('status'); + + if (requestToken && status === 'success') { + handleKiteCallback(requestToken); + } else if (status === 'error') { + setError('Authentication was cancelled or failed'); + } }, []); - const toggleTheme = () => { - const newTheme = !isDark; - setIsDark(newTheme); - document.documentElement.setAttribute('data-theme', newTheme ? 'dark' : 'light'); + const handleLogin = async () => { + setLoading(true); + setError(''); + setStatus('Fetching login URL...'); + + try { + const response = await fetch('/api/kite-auth?action=login-url'); + const data = await response.json(); + + if (data.success) { + setStatus('Redirecting to Kite...'); + window.location.href = data.login_url; + } else { + setError(data.error || 'Failed to get login URL'); + } + } catch (err) { + setError('Network error occurred'); + } finally { + setLoading(false); + } }; - const features = [ - { - icon: , - title: "Stock Analysis", - description: "Real-time market data analysis with AI-powered insights and predictive analytics", - accent: "green" - }, - { - icon: , - title: "Portfolio Management", - description: "Intelligent portfolio tracking with risk assessment and optimization suggestions", - accent: "purple" - }, - { - icon: , - title: "Market Intelligence", - description: "Advanced market trends analysis with sector insights and trading opportunities", - accent: "orange" - }, - { - icon: , - title: "Conversational Trading", - description: "Execute trades and get market insights through natural language interactions", - accent: "yellow" + const handleKiteCallback = async (requestToken: string) => { + setLoading(true); + setError(''); + setStatus('Completing authentication...'); + + try { + const response = await fetch('/api/kite-auth', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ request_token: requestToken }), + }); + + const data = await response.json(); + + if (data.success) { + localStorage.setItem('kite_session', data.session_token); + setSessionToken(data.session_token); + setUserData(data.user); + setStatus('Login successful!'); + + // Clean up URL + window.history.replaceState({}, document.title, window.location.pathname); + } else { + setError(data.error || 'Authentication failed'); + } + } catch (err) { + setError('Failed to complete authentication'); + } finally { + setLoading(false); } - ]; + }; + + const fetchUserProfile = async (token: string) => { + setLoading(true); + setError(''); + setStatus('Fetching user profile...'); - const stats = [ - { - icon: , - value: "100%", - label: "Open Source", - description: "Fully transparent and community-driven development", - accent: "green" - }, - { - icon: , - value: "Real-time", - label: "Market Data", - description: "Live market feeds with millisecond precision", - accent: "purple" - }, - { - icon: , - value: "MCP", - label: "Integration", - description: "Built on Zerodha's Model Context Protocol", - accent: "orange" + try { + const response = await fetch('/api/kite-auth?action=profile', { + headers: { + 'Authorization': `Bearer ${token}`, + }, + }); + + const data = await response.json(); + + if (data.success) { + setUserData(data.user); + setStatus('Profile loaded successfully'); + } else { + setError(data.error || 'Failed to fetch profile'); + if (data.error === 'Session expired') { + handleLogout(); + } + } + } catch (err) { + setError('Failed to fetch user profile'); + } finally { + setLoading(false); } - ]; + }; + + const handleLogout = async () => { + setLoading(true); + setStatus('Logging out...'); - const capabilities = [ - { - icon: , - title: "Lightning Fast", - description: "Sub-second response times for critical trading decisions" - }, - { - icon: , - title: "Bank-level Security", - description: "Enterprise-grade encryption and security protocols" - }, - { - icon: , - title: "Precision Trading", - description: "AI-driven accuracy for optimal trade execution" + try { + if (sessionToken) { + await fetch('/api/kite-auth', { + method: 'DELETE', + headers: { + 'Authorization': `Bearer ${sessionToken}`, + }, + }); + } + } catch (err) { + // Ignore logout errors + } finally { + localStorage.removeItem('kite_session'); + setSessionToken(null); + setUserData(null); + setLoading(false); + setStatus('Logged out successfully'); + setError(''); } - ]; + }; + + const refreshProfile = () => { + if (sessionToken) { + fetchUserProfile(sessionToken); + } + }; return ( -
- {/* Navigation Header */} -
-
-
-
-
BullsEye
- -
-
- - - - GitHub - - - - Get Started - -
-
+
+
+ {/* Header */} +
+

KITE CONNECT

+
+

Trading API Authentication

-
- {/* Hero Section */} -
-
-
-

BullsEye

-

- AI-powered financial intelligence built on Zerodha MCP. - Analyze markets, manage portfolios, and execute trades through intelligent conversation. -

- -
- - - Start Trading - - - -
+ {/* Status Messages */} + {error && ( +
+ ERROR: {error}
-
-
+ )} - {/* Capabilities Strip */} -
-
-
- {capabilities.map((capability, index) => ( -
-
- {capability.icon} -
-
-
- {capability.title} -
-
- {capability.description} -
-
-
- ))} + {status && !error && ( +
+ STATUS: {status}
-
-
+ )} - {/* Features Section */} -
-
-
-

Core Features

-

- Everything you need for intelligent trading decisions -

-
- -
- {features.map((feature, index) => ( -
-
- {feature.icon} -
-

- {feature.title} -

-

- {feature.description} + {/* Main Content */} +

+ {!sessionToken ? ( + /* Login Section */ +
+
+
🔐
+

Authentication Required

+

+ Connect your Kite account to access trading data

- ))} -
-
-
- {/* Chat Demo Section */} -
-
-
-

Natural Language Trading

-

- Experience how BullsEye transforms complex trading into simple conversations -

-
- -
-
- {/* User Message */} -
-
- -
-
-
You
-
- "What's the current trend for RELIANCE? Should I buy more?" -
-
+ + +
+

• You will be redirected to Kite for authentication

+

• Your session will be valid for 24 hours

+

• No passwords are stored locally

- - {/* AI Response */} -
-
- -
-
-
BullsEye AI
-
- RELIANCE is showing strong upward momentum - (+2.3% today). Technical analysis suggests continued growth. - Current price: ₹2,847. - Shall I execute a buy order for you? +
+ ) : ( + /* Dashboard Section */ +
+
+
+

Dashboard

+
+ Session Active • {new Date().toLocaleString()}
+
- - {/* User Confirmation */} -
-
- -
-
-
You
-
- "Yes, buy 10 shares" + + {userData ? ( +
+ {/* User Info Grid */} +
+
+
USER ID
+
{userData.user_id}
+
+
+
NAME
+
{userData.user_name}
+
+
+
EMAIL
+
{userData.email}
+
+
+
BROKER
+
{userData.broker}
+
-
-
-
-
-
-
- {/* Stats Section */} -
-
-
- {stats.map((stat, index) => ( -
-
- {stat.icon} -
-
- {stat.value} -
-
- {stat.label} + {/* Actions */} +
+ +
+ + {/* API Status */} +
+
API STATUS
+
+
+ Connected to Kite API +
+
-
- {stat.description} + ) : ( +
+
+

Loading user data...

-
- ))} -
-
-
- - {/* CTA Section */} -
-
-
-

- Ready to Start Trading with AI? -

-

- Join the future of conversational trading with intelligent market analysis and seamless execution -

- -
+ )}
-
- {/* Footer */} - +
); } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 08af345..3990563 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,6 @@ "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" }, @@ -45,7 +44,6 @@ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -58,7 +56,6 @@ "version": "1.4.3", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", - "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" @@ -71,7 +68,6 @@ "cpu": [ "arm64" ], - "license": "Apache-2.0", "optional": true, "os": [ "darwin" @@ -93,7 +89,6 @@ "cpu": [ "x64" ], - "license": "Apache-2.0", "optional": true, "os": [ "darwin" @@ -115,7 +110,6 @@ "cpu": [ "arm64" ], - "license": "LGPL-3.0-or-later", "optional": true, "os": [ "darwin" @@ -131,7 +125,6 @@ "cpu": [ "x64" ], - "license": "LGPL-3.0-or-later", "optional": true, "os": [ "darwin" @@ -147,7 +140,6 @@ "cpu": [ "arm" ], - "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -163,7 +155,6 @@ "cpu": [ "arm64" ], - "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -179,7 +170,6 @@ "cpu": [ "ppc64" ], - "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -195,7 +185,6 @@ "cpu": [ "s390x" ], - "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -211,7 +200,6 @@ "cpu": [ "x64" ], - "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -227,7 +215,6 @@ "cpu": [ "arm64" ], - "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -243,7 +230,6 @@ "cpu": [ "x64" ], - "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -259,7 +245,6 @@ "cpu": [ "arm" ], - "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -281,7 +266,6 @@ "cpu": [ "arm64" ], - "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -303,7 +287,6 @@ "cpu": [ "s390x" ], - "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -325,7 +308,6 @@ "cpu": [ "x64" ], - "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -347,7 +329,6 @@ "cpu": [ "arm64" ], - "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -369,7 +350,6 @@ "cpu": [ "x64" ], - "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -391,7 +371,6 @@ "cpu": [ "wasm32" ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { "@emnapi/runtime": "^1.4.3" @@ -410,7 +389,6 @@ "cpu": [ "arm64" ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ "win32" @@ -429,7 +407,6 @@ "cpu": [ "ia32" ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ "win32" @@ -448,7 +425,6 @@ "cpu": [ "x64" ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ "win32" @@ -465,7 +441,6 @@ "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.4" }, @@ -478,7 +453,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -493,7 +467,6 @@ "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" } @@ -503,7 +476,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -512,15 +484,13 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -529,8 +499,7 @@ "node_modules/@next/env": { "version": "15.3.3", "resolved": "https://registry.npmjs.org/@next/env/-/env-15.3.3.tgz", - "integrity": "sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw==", - "license": "MIT" + "integrity": "sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw==" }, "node_modules/@next/swc-darwin-arm64": { "version": "15.3.3", @@ -539,7 +508,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "darwin" @@ -555,7 +523,6 @@ "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "darwin" @@ -571,7 +538,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -587,7 +553,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -603,7 +568,6 @@ "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -619,7 +583,6 @@ "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -635,7 +598,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "win32" @@ -651,7 +613,6 @@ "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "win32" @@ -661,10 +622,9 @@ } }, "node_modules/@supabase/auth-js": { - "version": "2.69.1", - "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.69.1.tgz", - "integrity": "sha512-FILtt5WjCNzmReeRLq5wRs3iShwmnWgBvxHfqapC/VoljJl+W8hDAyFmf1NVw3zH+ZjZ05AKxiKxVeb0HNWRMQ==", - "license": "MIT", + "version": "2.70.0", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.70.0.tgz", + "integrity": "sha512-BaAK/tOAZFJtzF1sE3gJ2FwTjLf4ky3PSvcvLGEgEmO4BSBkwWKu8l67rLLIBZPDnCyV7Owk2uPyKHa0kj5QGg==", "dependencies": { "@supabase/node-fetch": "^2.6.14" } @@ -673,7 +633,6 @@ "version": "2.4.4", "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.4.4.tgz", "integrity": "sha512-WL2p6r4AXNGwop7iwvul2BvOtuJ1YQy8EbOd0dhG1oN1q8el/BIRSFCFnWAMM/vJJlHWLi4ad22sKbKr9mvjoA==", - "license": "MIT", "dependencies": { "@supabase/node-fetch": "^2.6.14" } @@ -682,7 +641,6 @@ "version": "2.6.15", "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz", "integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==", - "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -694,67 +652,60 @@ "version": "1.19.4", "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.19.4.tgz", "integrity": "sha512-O4soKqKtZIW3olqmbXXbKugUtByD2jPa8kL2m2c1oozAO11uCcGrRhkZL0kVxjBLrXHE0mdSkFsMj7jDSfyNpw==", - "license": "MIT", "dependencies": { "@supabase/node-fetch": "^2.6.14" } }, "node_modules/@supabase/realtime-js": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.11.2.tgz", - "integrity": "sha512-u/XeuL2Y0QEhXSoIPZZwR6wMXgB+RQbJzG9VErA3VghVt7uRfSVsjeqd7m5GhX3JR6dM/WRmLbVR8URpDWG4+w==", - "license": "MIT", + "version": "2.11.10", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.11.10.tgz", + "integrity": "sha512-SJKVa7EejnuyfImrbzx+HaD9i6T784khuw1zP+MBD7BmJYChegGxYigPzkKX8CK8nGuDntmeSD3fvriaH0EGZA==", "dependencies": { - "@supabase/node-fetch": "^2.6.14", - "@types/phoenix": "^1.5.4", - "@types/ws": "^8.5.10", - "ws": "^8.18.0" + "@supabase/node-fetch": "^2.6.13", + "@types/phoenix": "^1.6.6", + "@types/ws": "^8.18.1", + "ws": "^8.18.2" } }, "node_modules/@supabase/storage-js": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.7.1.tgz", "integrity": "sha512-asYHcyDR1fKqrMpytAS1zjyEfvxuOIp1CIXX7ji4lHHcJKqyk+sLl/Vxgm4sN6u8zvuUtae9e4kDxQP2qrwWBA==", - "license": "MIT", "dependencies": { "@supabase/node-fetch": "^2.6.14" } }, "node_modules/@supabase/supabase-js": { - "version": "2.49.8", - "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.49.8.tgz", - "integrity": "sha512-zzBQLgS/jZs7btWcIAc7V5yfB+juG7h0AXxKowMJuySsO5vK+F7Vp+HCa07Z+tu9lZtr3sT9fofkc86bdylmtw==", - "license": "MIT", + "version": "2.50.0", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.50.0.tgz", + "integrity": "sha512-M1Gd5tPaaghYZ9OjeO1iORRqbTWFEz/cF3pPubRnMPzA+A8SiUsXXWDP+DWsASZcjEcVEcVQIAF38i5wrijYOg==", "dependencies": { - "@supabase/auth-js": "2.69.1", + "@supabase/auth-js": "2.70.0", "@supabase/functions-js": "2.4.4", "@supabase/node-fetch": "2.6.15", "@supabase/postgrest-js": "1.19.4", - "@supabase/realtime-js": "2.11.2", + "@supabase/realtime-js": "2.11.10", "@supabase/storage-js": "2.7.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" + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==" }, "node_modules/@swc/helpers": { "version": "0.5.15", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", - "license": "Apache-2.0", "dependencies": { "tslib": "^2.8.0" } }, "node_modules/@tailwindcss/node": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.8.tgz", - "integrity": "sha512-OWwBsbC9BFAJelmnNcrKuf+bka2ZxCE2A4Ft53Tkg4uoiE67r/PMEYwCsourC26E+kmxfwE0hVzMdxqeW+xu7Q==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.10.tgz", + "integrity": "sha512-2ACf1znY5fpRBwRhMgj9ZXvb2XZW8qs+oTfotJ2C5xR0/WNL7UHZ7zXl6s+rUqedL1mNi+0O+WQr5awGowS3PQ==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.3.0", "enhanced-resolve": "^5.18.1", @@ -762,16 +713,15 @@ "lightningcss": "1.30.1", "magic-string": "^0.30.17", "source-map-js": "^1.2.1", - "tailwindcss": "4.1.8" + "tailwindcss": "4.1.10" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.8.tgz", - "integrity": "sha512-d7qvv9PsM5N3VNKhwVUhpK6r4h9wtLkJ6lz9ZY9aeZgrUWk1Z8VPyqyDT9MZlem7GTGseRQHkeB1j3tC7W1P+A==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.10.tgz", + "integrity": "sha512-v0C43s7Pjw+B9w21htrQwuFObSkio2aV/qPx/mhrRldbqxbWJK6KizM+q7BF1/1CmuLqZqX3CeYF7s7P9fbA8Q==", "dev": true, "hasInstallScript": true, - "license": "MIT", "dependencies": { "detect-libc": "^2.0.4", "tar": "^7.4.3" @@ -780,29 +730,28 @@ "node": ">= 10" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.8", - "@tailwindcss/oxide-darwin-arm64": "4.1.8", - "@tailwindcss/oxide-darwin-x64": "4.1.8", - "@tailwindcss/oxide-freebsd-x64": "4.1.8", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.8", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.8", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.8", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.8", - "@tailwindcss/oxide-linux-x64-musl": "4.1.8", - "@tailwindcss/oxide-wasm32-wasi": "4.1.8", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.8", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.8" + "@tailwindcss/oxide-android-arm64": "4.1.10", + "@tailwindcss/oxide-darwin-arm64": "4.1.10", + "@tailwindcss/oxide-darwin-x64": "4.1.10", + "@tailwindcss/oxide-freebsd-x64": "4.1.10", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.10", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.10", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.10", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.10", + "@tailwindcss/oxide-linux-x64-musl": "4.1.10", + "@tailwindcss/oxide-wasm32-wasi": "4.1.10", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.10", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.10" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.8.tgz", - "integrity": "sha512-Fbz7qni62uKYceWYvUjRqhGfZKwhZDQhlrJKGtnZfuNtHFqa8wmr+Wn74CTWERiW2hn3mN5gTpOoxWKk0jRxjg==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.10.tgz", + "integrity": "sha512-VGLazCoRQ7rtsCzThaI1UyDu/XRYVyH4/EWiaSX6tFglE+xZB5cvtC5Omt0OQ+FfiIVP98su16jDVHDEIuH4iQ==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "android" @@ -812,14 +761,13 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.8.tgz", - "integrity": "sha512-RdRvedGsT0vwVVDztvyXhKpsU2ark/BjgG0huo4+2BluxdXo8NDgzl77qh0T1nUxmM11eXwR8jA39ibvSTbi7A==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.10.tgz", + "integrity": "sha512-ZIFqvR1irX2yNjWJzKCqTCcHZbgkSkSkZKbRM3BPzhDL/18idA8uWCoopYA2CSDdSGFlDAxYdU2yBHwAwx8euQ==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -829,14 +777,13 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.8.tgz", - "integrity": "sha512-t6PgxjEMLp5Ovf7uMb2OFmb3kqzVTPPakWpBIFzppk4JE4ix0yEtbtSjPbU8+PZETpaYMtXvss2Sdkx8Vs4XRw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.10.tgz", + "integrity": "sha512-eCA4zbIhWUFDXoamNztmS0MjXHSEJYlvATzWnRiTqJkcUteSjO94PoRHJy1Xbwp9bptjeIxxBHh+zBWFhttbrQ==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -846,14 +793,13 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.8.tgz", - "integrity": "sha512-g8C8eGEyhHTqwPStSwZNSrOlyx0bhK/V/+zX0Y+n7DoRUzyS8eMbVshVOLJTDDC+Qn9IJnilYbIKzpB9n4aBsg==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.10.tgz", + "integrity": "sha512-8/392Xu12R0cc93DpiJvNpJ4wYVSiciUlkiOHOSOQNH3adq9Gi/dtySK7dVQjXIOzlpSHjeCL89RUUI8/GTI6g==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "freebsd" @@ -863,14 +809,13 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.8.tgz", - "integrity": "sha512-Jmzr3FA4S2tHhaC6yCjac3rGf7hG9R6Gf2z9i9JFcuyy0u79HfQsh/thifbYTF2ic82KJovKKkIB6Z9TdNhCXQ==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.10.tgz", + "integrity": "sha512-t9rhmLT6EqeuPT+MXhWhlRYIMSfh5LZ6kBrC4FS6/+M1yXwfCtp24UumgCWOAJVyjQwG+lYva6wWZxrfvB+NhQ==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -880,14 +825,13 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.8.tgz", - "integrity": "sha512-qq7jXtO1+UEtCmCeBBIRDrPFIVI4ilEQ97qgBGdwXAARrUqSn/L9fUrkb1XP/mvVtoVeR2bt/0L77xx53bPZ/Q==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.10.tgz", + "integrity": "sha512-3oWrlNlxLRxXejQ8zImzrVLuZ/9Z2SeKoLhtCu0hpo38hTO2iL86eFOu4sVR8cZc6n3z7eRXXqtHJECa6mFOvA==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -897,14 +841,13 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.8.tgz", - "integrity": "sha512-O6b8QesPbJCRshsNApsOIpzKt3ztG35gfX9tEf4arD7mwNinsoCKxkj8TgEE0YRjmjtO3r9FlJnT/ENd9EVefQ==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.10.tgz", + "integrity": "sha512-saScU0cmWvg/Ez4gUmQWr9pvY9Kssxt+Xenfx1LG7LmqjcrvBnw4r9VjkFcqmbBb7GCBwYNcZi9X3/oMda9sqQ==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -914,14 +857,13 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.8.tgz", - "integrity": "sha512-32iEXX/pXwikshNOGnERAFwFSfiltmijMIAbUhnNyjFr3tmWmMJWQKU2vNcFX0DACSXJ3ZWcSkzNbaKTdngH6g==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.10.tgz", + "integrity": "sha512-/G3ao/ybV9YEEgAXeEg28dyH6gs1QG8tvdN9c2MNZdUXYBaIY/Gx0N6RlJzfLy/7Nkdok4kaxKPHKJUlAaoTdA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -931,14 +873,13 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.8.tgz", - "integrity": "sha512-s+VSSD+TfZeMEsCaFaHTaY5YNj3Dri8rST09gMvYQKwPphacRG7wbuQ5ZJMIJXN/puxPcg/nU+ucvWguPpvBDg==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.10.tgz", + "integrity": "sha512-LNr7X8fTiKGRtQGOerSayc2pWJp/9ptRYAa4G+U+cjw9kJZvkopav1AQc5HHD+U364f71tZv6XamaHKgrIoVzA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -948,9 +889,9 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.8.tgz", - "integrity": "sha512-CXBPVFkpDjM67sS1psWohZ6g/2/cd+cq56vPxK4JeawelxwK4YECgl9Y9TjkE2qfF+9/s1tHHJqrC4SS6cVvSg==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.10.tgz", + "integrity": "sha512-d6ekQpopFQJAcIK2i7ZzWOYGZ+A6NzzvQ3ozBvWFdeyqfOZdYHU66g5yr+/HC4ipP1ZgWsqa80+ISNILk+ae/Q==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -963,7 +904,6 @@ "wasm32" ], "dev": true, - "license": "MIT", "optional": true, "dependencies": { "@emnapi/core": "^1.4.3", @@ -978,14 +918,13 @@ } }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.8.tgz", - "integrity": "sha512-7GmYk1n28teDHUjPlIx4Z6Z4hHEgvP5ZW2QS9ygnDAdI/myh3HTHjDqtSqgu1BpRoI4OiLx+fThAyA1JePoENA==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.10.tgz", + "integrity": "sha512-i1Iwg9gRbwNVOCYmnigWCCgow8nDWSFmeTUU5nbNx3rqbe4p0kRbEqLwLJbYZKmSSp23g4N6rCDmm7OuPBXhDA==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" @@ -995,14 +934,13 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.8.tgz", - "integrity": "sha512-fou+U20j+Jl0EHwK92spoWISON2OBnCazIc038Xj2TdweYV33ZRkS9nwqiUi2d/Wba5xg5UoHfvynnb/UB49cQ==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.10.tgz", + "integrity": "sha512-sGiJTjcBSfGq2DVRtaSljq5ZgZS2SDHSIfhOylkBvHVjwOsodBhnb3HdmiKkVuUGKD0I7G63abMOVaskj1KpOA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" @@ -1012,50 +950,45 @@ } }, "node_modules/@tailwindcss/postcss": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.8.tgz", - "integrity": "sha512-vB/vlf7rIky+w94aWMw34bWW1ka6g6C3xIOdICKX2GC0VcLtL6fhlLiafF0DVIwa9V6EHz8kbWMkS2s2QvvNlw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.10.tgz", + "integrity": "sha512-B+7r7ABZbkXJwpvt2VMnS6ujcDoR2OOcFaqrLIo1xbcdxje4Vf+VgJdBzNNbrAjBj/rLZ66/tlQ1knIGNLKOBQ==", "dev": true, - "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.1.8", - "@tailwindcss/oxide": "4.1.8", + "@tailwindcss/node": "4.1.10", + "@tailwindcss/oxide": "4.1.10", "postcss": "^8.4.41", - "tailwindcss": "4.1.8" + "tailwindcss": "4.1.10" } }, "node_modules/@types/node": { - "version": "20.17.57", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.57.tgz", - "integrity": "sha512-f3T4y6VU4fVQDKVqJV4Uppy8c1p/sVvS3peyqxyWnzkqXFJLRU7Y1Bl7rMS1Qe9z0v4M6McY0Fp9yBsgHJUsWQ==", - "license": "MIT", + "version": "20.19.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.1.tgz", + "integrity": "sha512-jJD50LtlD2dodAEO653i3YF04NWak6jN3ky+Ri3Em3mGR39/glWiboM/IePaRbgwSfqM1TpGXfAg8ohn/4dTgA==", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.21.0" } }, "node_modules/@types/phoenix": { "version": "1.6.6", "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.6.tgz", - "integrity": "sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==", - "license": "MIT" + "integrity": "sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==" }, "node_modules/@types/react": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.6.tgz", - "integrity": "sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==", + "version": "19.1.8", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", + "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", "dev": true, - "license": "MIT", "dependencies": { "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "19.1.5", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.5.tgz", - "integrity": "sha512-CMCjrWucUBZvohgZxkjd6S9h0nZxXjzus6yDfUb+xLxYM7VvjKNH1tQrE9GWLql1XoOP4/Ds3bwFqShHUYraGg==", + "version": "19.1.6", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz", + "integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==", "dev": true, - "license": "MIT", "peerDependencies": { "@types/react": "^19.0.0" } @@ -1064,14 +997,12 @@ "version": "10.0.0", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@types/ws": { "version": "8.18.1", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "license": "MIT", "dependencies": { "@types/node": "*" } @@ -1080,7 +1011,6 @@ "version": "5.7.4", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -1092,7 +1022,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", - "license": "BSD-3-Clause OR MIT", "engines": { "node": ">=0.4.2" } @@ -1101,7 +1030,6 @@ "version": "0.9.6", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", "integrity": "sha512-qEdtR2UH78yyHX/AUNfXmJTlM48XoFZKBdwi1nzkI1mJL21cmbu0cvjxjpkXJ5NENMq42H+hNs8VLJcqXLerBQ==", - "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1109,23 +1037,20 @@ "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==", - "license": "MIT" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base62": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/base62/-/base62-1.2.8.tgz", "integrity": "sha512-V6YHUbjLxN1ymqNLb1DPHoU1CpfdL7d2YTIp5W3U4hhoG4hhxNmsFDs66M9EXxBiSEke5Bt5dwdfMwwZF70iLA==", - "license": "MIT", "engines": { "node": "*" } }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1143,9 +1068,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001720", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001720.tgz", - "integrity": "sha512-Ec/2yV2nNPwb4DnTANEV99ZWwm3ZWfdlfkQbWSDDt+PsXEVYwlhPH8tdMaPunYTKKmz7AnHi2oNEi1GcmKCD8g==", + "version": "1.0.30001723", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001723.tgz", + "integrity": "sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==", "funding": [ { "type": "opencollective", @@ -1159,15 +1084,13 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" + ] }, "node_modules/chownr": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", "dev": true, - "license": "BlueOak-1.0.0", "engines": { "node": ">=18" } @@ -1175,14 +1098,12 @@ "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" + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "license": "MIT", "optional": true, "dependencies": { "color-convert": "^2.0.1", @@ -1196,7 +1117,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", "optional": true, "dependencies": { "color-name": "~1.1.4" @@ -1209,14 +1129,12 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT", "optional": true }, "node_modules/color-string": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "license": "MIT", "optional": true, "dependencies": { "color-name": "^1.0.0", @@ -1226,20 +1144,17 @@ "node_modules/colornames": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/colornames/-/colornames-0.0.2.tgz", - "integrity": "sha512-aeaoTql364CeoC6VHeRJd8uUiOVZDDtCyTP2dwXPD3WIt8UuPcXzmBB5gEhLDLaJS3MW152O7DfYm1a2HQv11g==", - "license": "MIT" + "integrity": "sha512-aeaoTql364CeoC6VHeRJd8uUiOVZDDtCyTP2dwXPD3WIt8UuPcXzmBB5gEhLDLaJS3MW152O7DfYm1a2HQv11g==" }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "node_modules/commoner": { "version": "0.10.8", "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz", "integrity": "sha512-3/qHkNMM6o/KGXHITA14y78PcfmXh4+AOCJpSoF73h4VY1JpdGv3CHMS5+JW6SwLhfJt4RhNmLAa7+RRX/62EQ==", - "license": "MIT", "dependencies": { "commander": "^2.5.0", "detective": "^4.3.1", @@ -1262,7 +1177,6 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "license": "MIT", "dependencies": { "minimist": "^1.2.6" }, @@ -1273,21 +1187,18 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "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" + "dev": true }, "node_modules/defined": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1297,7 +1208,6 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", "devOptional": true, - "license": "Apache-2.0", "engines": { "node": ">=8" } @@ -1306,7 +1216,6 @@ "version": "4.7.1", "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", - "license": "MIT", "dependencies": { "acorn": "^5.2.1", "defined": "^1.0.0" @@ -1316,7 +1225,6 @@ "version": "0.0.4", "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-0.0.4.tgz", "integrity": "sha512-lRRB9aAnL5kTwxstxyQLuOoM+wf6hiatl85791uhCDr/mXTxDTal+wFr59QG8nAvKr31ZO/IKfoMFiaZqTZdxg==", - "license": "MIT", "dependencies": { "color": "0.7.x", "colornames": "0.0.x", @@ -1342,8 +1250,7 @@ "node_modules/diagnostics/node_modules/color-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.0.1.tgz", - "integrity": "sha512-ipj55CYipJcmYpiDwpDRZ91iMJOnsTW9wICiE1efyPWadY2FapkgfTvB8IJLxf5muHHrpKVVxhEnv03UIshOJQ==", - "license": "Unlicense" + "integrity": "sha512-ipj55CYipJcmYpiDwpDRZ91iMJOnsTW9wICiE1efyPWadY2FapkgfTvB8IJLxf5muHHrpKVVxhEnv03UIshOJQ==" }, "node_modules/diagnostics/node_modules/color-string": { "version": "0.2.4", @@ -1358,7 +1265,6 @@ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", "dev": true, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -1370,14 +1276,12 @@ "node_modules/env-variable": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.6.tgz", - "integrity": "sha512-bHz59NlBbtS0NhftmR8+ExBEekE7br0e01jw+kk0NDro7TtZzBYZ5ScGPs3OmwnpyfHTHOtr1Y6uedCdrIldtg==", - "license": "MIT" + "integrity": "sha512-bHz59NlBbtS0NhftmR8+ExBEekE7br0e01jw+kk0NDro7TtZzBYZ5ScGPs3OmwnpyfHTHOtr1Y6uedCdrIldtg==" }, "node_modules/envify": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/envify/-/envify-3.4.1.tgz", "integrity": "sha512-XLiBFsLtNF0MOZl+vWU59yPb3C2JtrQY2CNJn22KH75zPlHWY5ChcAQuf4knJeWT/lLkrx3sqvhP/J349bt4Bw==", - "license": "MIT", "dependencies": { "jstransform": "^11.0.3", "through": "~2.3.4" @@ -1390,7 +1294,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", "integrity": "sha512-AWwVMNxwhN8+NIPQzAQZCm7RkLC4RbM3B1OobMuyp3i+w73X57KCKaVIxaRZb+DYCojq7rspo+fmuQfAboyhFg==", - "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -1414,14 +1317,12 @@ "node_modules/extendible": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/extendible/-/extendible-0.1.1.tgz", - "integrity": "sha512-AglckQA0TJV8/ZmhQcNmaaFcFFPXFIoZbfuoQOlGDK7Jh/roWotYzJ7ik1FBBCHBr8n7CgTR8lXXPAN8Rfb7rw==", - "license": "MIT" + "integrity": "sha512-AglckQA0TJV8/ZmhQcNmaaFcFFPXFIoZbfuoQOlGDK7Jh/roWotYzJ7ik1FBBCHBr8n7CgTR8lXXPAN8Rfb7rw==" }, "node_modules/fittings": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fittings/-/fittings-1.0.1.tgz", "integrity": "sha512-YdfjL66YGTd+mGa9cBH0nvIjKuqu74AxxAFB7H9xOizU02nosy6nT23RdlrhuQ0EAXx0le2lySnZdw9iP5r9Xw==", - "license": "MIT", "dependencies": { "diagnostics": "0.0.4", "extendible": "0.1.x" @@ -1432,7 +1333,6 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", "dependencies": { "inflight": "^1.0.4", "inherits": "2", @@ -1447,14 +1347,12 @@ "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" + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -1467,7 +1365,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.", - "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -1476,14 +1373,12 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "license": "MIT", "optional": true }, "node_modules/jiti": { @@ -1491,7 +1386,6 @@ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", "dev": true, - "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" } @@ -1500,7 +1394,6 @@ "version": "11.0.3", "resolved": "https://registry.npmjs.org/jstransform/-/jstransform-11.0.3.tgz", "integrity": "sha512-LGm87w0A8E92RrcXt94PnNHkFqHmgDy3mKHvNZOG7QepKCTCH/VB6S+IEN+bT4uLN3gVpOT0vvOOVd96osG71g==", - "license": "BSD-3-Clause", "dependencies": { "base62": "^1.1.0", "commoner": "^0.10.1", @@ -1519,7 +1412,6 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-0.0.0.tgz", "integrity": "sha512-5h7OEDPSHedoxB6alJXF4FtFB95QA2OTXGCFaLCutHdkh0VrcSSy/OwH9UHtYqsG2KTrdN7gVEc9KgCBNah/yA==", - "license": "MIT", "dependencies": { "colornames": "0.0.2" } @@ -1529,7 +1421,6 @@ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", "dev": true, - "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" }, @@ -1561,7 +1452,6 @@ "arm64" ], "dev": true, - "license": "MPL-2.0", "optional": true, "os": [ "darwin" @@ -1582,7 +1472,6 @@ "x64" ], "dev": true, - "license": "MPL-2.0", "optional": true, "os": [ "darwin" @@ -1603,7 +1492,6 @@ "x64" ], "dev": true, - "license": "MPL-2.0", "optional": true, "os": [ "freebsd" @@ -1624,7 +1512,6 @@ "arm" ], "dev": true, - "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -1645,7 +1532,6 @@ "arm64" ], "dev": true, - "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -1666,7 +1552,6 @@ "arm64" ], "dev": true, - "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -1687,7 +1572,6 @@ "x64" ], "dev": true, - "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -1708,7 +1592,6 @@ "x64" ], "dev": true, - "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -1729,7 +1612,6 @@ "arm64" ], "dev": true, - "license": "MPL-2.0", "optional": true, "os": [ "win32" @@ -1750,7 +1632,6 @@ "x64" ], "dev": true, - "license": "MPL-2.0", "optional": true, "os": [ "win32" @@ -1766,14 +1647,12 @@ "node_modules/lucide": { "version": "0.511.0", "resolved": "https://registry.npmjs.org/lucide/-/lucide-0.511.0.tgz", - "integrity": "sha512-3ppKPYcCJFXBloeM1H8OyIGjzINNQgsYvAYBTYOSKO45DF/5vbTQrCvwnvMDAGgDnUlI1uFxe0gJj52jdb1JAg==", - "license": "ISC" + "integrity": "sha512-3ppKPYcCJFXBloeM1H8OyIGjzINNQgsYvAYBTYOSKO45DF/5vbTQrCvwnvMDAGgDnUlI1uFxe0gJj52jdb1JAg==" }, "node_modules/lucide-react": { "version": "0.511.0", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.511.0.tgz", "integrity": "sha512-VK5a2ydJ7xm8GvBeKLS9mu1pVK6ucef9780JVUjw6bAjJL/QXnd4Y0p7SPeOUMC27YhzNCZvm5d/QX0Tp3rc0w==", - "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } @@ -1783,7 +1662,6 @@ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } @@ -1792,7 +1670,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1804,7 +1681,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1814,7 +1690,6 @@ "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" } @@ -1824,7 +1699,6 @@ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", "dev": true, - "license": "MIT", "dependencies": { "minipass": "^7.1.2" }, @@ -1837,7 +1711,6 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", "dev": true, - "license": "MIT", "bin": { "mkdirp": "dist/cjs/src/bin.js" }, @@ -1858,7 +1731,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -1870,7 +1742,6 @@ "version": "15.3.3", "resolved": "https://registry.npmjs.org/next/-/next-15.3.3.tgz", "integrity": "sha512-JqNj29hHNmCLtNvd090SyRbXJiivQ+58XjCcrC50Crb5g5u2zi7Y2YivbsEfzk6AtVI80akdOQbaMZwWB1Hthw==", - "license": "MIT", "dependencies": { "@next/env": "15.3.3", "@swc/counter": "0.1.3", @@ -1938,7 +1809,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -1952,7 +1822,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", "integrity": "sha512-CdsOUYIh5wIiozhJ3rLQgmUTgcyzFwZZrqhkKhODMoGtPKM+wt0h0CNIoauJWMsS9822EdzPsF/6mb4nLvPN5g==", - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1961,7 +1830,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", "dependencies": { "wrappy": "1" } @@ -1970,7 +1838,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1978,13 +1845,12 @@ "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" + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "node_modules/postcss": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz", - "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ { @@ -2000,7 +1866,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -2014,7 +1879,6 @@ "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2024,7 +1888,6 @@ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", - "license": "MIT", "engines": { "node": ">=0.6.0", "teleport": ">=0.2.0" @@ -2034,7 +1897,6 @@ "version": "19.1.0", "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2043,7 +1905,6 @@ "version": "19.1.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", - "license": "MIT", "dependencies": { "scheduler": "^0.26.0" }, @@ -2055,7 +1916,6 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/reacts/-/reacts-0.0.0.tgz", "integrity": "sha512-qwHcP6sJ7GFtRxuwvXCwCNU/Z7GlE47rWMIKca6iTRbVAkSQgTPGbGiXiYNp5UgId4d+wEqrlsG7Ez90K7p7VQ==", - "license": "MIT", "dependencies": { "fittings": "1.0.x", "react": "0.12.x" @@ -2065,7 +1925,6 @@ "version": "0.12.2", "resolved": "https://registry.npmjs.org/react/-/react-0.12.2.tgz", "integrity": "sha512-YVNx3+ljaus8P1AcDuntrJuQTQ2pCwWikbo5rDvMjtHYU6GihXcJWJOtZYufVE3sfr7wZPnbl/EePFvTxu/Wuw==", - "license": "BSD-3-Clause", "dependencies": { "envify": "^3.0.0" }, @@ -2077,7 +1936,6 @@ "version": "0.11.23", "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", "integrity": "sha512-+nixG+3NugceyR8O1bLU45qs84JgI3+8EauyRZafLgC9XbdAOIVgwV1Pe2da0YzGo62KzWoZwUpVEQf6qNAXWA==", - "license": "MIT", "dependencies": { "ast-types": "0.9.6", "esprima": "~3.1.0", @@ -2092,7 +1950,6 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -2100,20 +1957,17 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/scheduler": { "version": "0.26.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", - "license": "MIT" + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==" }, "node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "license": "ISC", "optional": true, "bin": { "semver": "bin/semver.js" @@ -2127,7 +1981,6 @@ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.2.tgz", "integrity": "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==", "hasInstallScript": true, - "license": "Apache-2.0", "optional": true, "dependencies": { "color": "^4.2.3", @@ -2168,7 +2021,6 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "license": "MIT", "optional": true, "dependencies": { "is-arrayish": "^0.3.1" @@ -2178,7 +2030,6 @@ "version": "0.4.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha512-Y8nIfcb1s/7DcobUz1yOO1GSp7gyL+D9zLHDehT7iRESqGSxjJ448Sg7rvfgsRJCnKLdSl11uGf0s9X80cH0/A==", - "license": "BSD-3-Clause", "dependencies": { "amdefine": ">=0.0.4" }, @@ -2190,7 +2041,6 @@ "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" } @@ -2207,7 +2057,6 @@ "version": "5.1.6", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", - "license": "MIT", "dependencies": { "client-only": "0.0.1" }, @@ -2227,18 +2076,16 @@ } }, "node_modules/tailwindcss": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.8.tgz", - "integrity": "sha512-kjeW8gjdxasbmFKpVGrGd5T4i40mV5J2Rasw48QARfYeQ8YS9x02ON9SFWax3Qf616rt4Cp3nVNIj6Hd1mP3og==", - "dev": true, - "license": "MIT" + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.10.tgz", + "integrity": "sha512-P3nr6WkvKV/ONsTzj6Gb57sWPMX29EPNPopo7+FcpkQaNsrNpZ1pv8QmrYI2RqEKD7mlGqLnGovlcYnBK0IqUA==", + "dev": true }, "node_modules/tapable": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -2248,7 +2095,6 @@ "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", "dev": true, - "license": "ISC", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", @@ -2264,33 +2110,28 @@ "node_modules/text-hex": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-0.0.0.tgz", - "integrity": "sha512-RpZDSt2VIQnsPVDiOySPfi/RTRBbPyJj2fikmH5O2H5Zc/MC6ZPVcc4GYGcnbTS/j2v1HZOmy6F4CimfiLPMRg==", - "license": "MIT" + "integrity": "sha512-RpZDSt2VIQnsPVDiOySPfi/RTRBbPyJj2fikmH5O2H5Zc/MC6ZPVcc4GYGcnbTS/j2v1HZOmy6F4CimfiLPMRg==" }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "license": "MIT" + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "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" + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "node_modules/typescript": { "version": "5.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2300,10 +2141,9 @@ } }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" }, "node_modules/uuid": { "version": "11.1.0", @@ -2313,7 +2153,6 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], - "license": "MIT", "bin": { "uuid": "dist/esm/bin/uuid" } @@ -2321,14 +2160,12 @@ "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -2337,14 +2174,12 @@ "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==", - "license": "ISC" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/ws": { "version": "8.18.2", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", - "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -2366,7 +2201,6 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", "dev": true, - "license": "BlueOak-1.0.0", "engines": { "node": ">=18" } diff --git a/package.json b/package.json index e56fa19..382d605 100644 --- a/package.json +++ b/package.json @@ -27,4 +27,4 @@ "tailwindcss": "^4", "typescript": "^5" } -} +} \ No newline at end of file diff --git a/src-tauri/.gitignore b/src-tauri/.gitignore new file mode 100644 index 0000000..502406b --- /dev/null +++ b/src-tauri/.gitignore @@ -0,0 +1,4 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ +/gen/schemas diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml new file mode 100644 index 0000000..4058973 --- /dev/null +++ b/src-tauri/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "app" +version = "0.1.0" +description = "A Tauri App" +authors = ["you"] +license = "" +repository = "" +edition = "2021" +rust-version = "1.77.2" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +name = "app_lib" +crate-type = ["staticlib", "cdylib", "rlib"] + +[build-dependencies] +tauri-build = { version = "2.2.0" } + +[dependencies] +serde_json = "1.0" +serde = { version = "1.0", features = ["derive"] } +log = "0.4" +tauri = { version = "2.5.0" } +tauri-plugin-log = "2.0.0-rc" diff --git a/src-tauri/build.rs b/src-tauri/build.rs new file mode 100644 index 0000000..795b9b7 --- /dev/null +++ b/src-tauri/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json new file mode 100644 index 0000000..c135d7f --- /dev/null +++ b/src-tauri/capabilities/default.json @@ -0,0 +1,11 @@ +{ + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "default", + "description": "enables the default permissions", + "windows": [ + "main" + ], + "permissions": [ + "core:default" + ] +} diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png new file mode 100644 index 0000000..77e7d23 Binary files /dev/null and b/src-tauri/icons/128x128.png differ diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png new file mode 100644 index 0000000..0f7976f Binary files /dev/null and b/src-tauri/icons/128x128@2x.png differ diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png new file mode 100644 index 0000000..98fda06 Binary files /dev/null and b/src-tauri/icons/32x32.png differ diff --git a/src-tauri/icons/Square107x107Logo.png b/src-tauri/icons/Square107x107Logo.png new file mode 100644 index 0000000..f35d84f Binary files /dev/null and b/src-tauri/icons/Square107x107Logo.png differ diff --git a/src-tauri/icons/Square142x142Logo.png b/src-tauri/icons/Square142x142Logo.png new file mode 100644 index 0000000..1823bb2 Binary files /dev/null and b/src-tauri/icons/Square142x142Logo.png differ diff --git a/src-tauri/icons/Square150x150Logo.png b/src-tauri/icons/Square150x150Logo.png new file mode 100644 index 0000000..dc2b22c Binary files /dev/null and b/src-tauri/icons/Square150x150Logo.png differ diff --git a/src-tauri/icons/Square284x284Logo.png b/src-tauri/icons/Square284x284Logo.png new file mode 100644 index 0000000..0ed3984 Binary files /dev/null and b/src-tauri/icons/Square284x284Logo.png differ diff --git a/src-tauri/icons/Square30x30Logo.png b/src-tauri/icons/Square30x30Logo.png new file mode 100644 index 0000000..60bf0ea Binary files /dev/null and b/src-tauri/icons/Square30x30Logo.png differ diff --git a/src-tauri/icons/Square310x310Logo.png b/src-tauri/icons/Square310x310Logo.png new file mode 100644 index 0000000..c8ca0ad Binary files /dev/null and b/src-tauri/icons/Square310x310Logo.png differ diff --git a/src-tauri/icons/Square44x44Logo.png b/src-tauri/icons/Square44x44Logo.png new file mode 100644 index 0000000..8756459 Binary files /dev/null and b/src-tauri/icons/Square44x44Logo.png differ diff --git a/src-tauri/icons/Square71x71Logo.png b/src-tauri/icons/Square71x71Logo.png new file mode 100644 index 0000000..2c8023c Binary files /dev/null and b/src-tauri/icons/Square71x71Logo.png differ diff --git a/src-tauri/icons/Square89x89Logo.png b/src-tauri/icons/Square89x89Logo.png new file mode 100644 index 0000000..2c5e603 Binary files /dev/null and b/src-tauri/icons/Square89x89Logo.png differ diff --git a/src-tauri/icons/StoreLogo.png b/src-tauri/icons/StoreLogo.png new file mode 100644 index 0000000..17d142c Binary files /dev/null and b/src-tauri/icons/StoreLogo.png differ diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns new file mode 100644 index 0000000..a2993ad Binary files /dev/null and b/src-tauri/icons/icon.icns differ diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico new file mode 100644 index 0000000..06c23c8 Binary files /dev/null and b/src-tauri/icons/icon.ico differ diff --git a/src-tauri/icons/icon.png b/src-tauri/icons/icon.png new file mode 100644 index 0000000..d1756ce Binary files /dev/null and b/src-tauri/icons/icon.png differ diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs new file mode 100644 index 0000000..9c3118c --- /dev/null +++ b/src-tauri/src/lib.rs @@ -0,0 +1,16 @@ +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + tauri::Builder::default() + .setup(|app| { + if cfg!(debug_assertions) { + app.handle().plugin( + tauri_plugin_log::Builder::default() + .level(log::LevelFilter::Info) + .build(), + )?; + } + Ok(()) + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs new file mode 100644 index 0000000..ad5fe83 --- /dev/null +++ b/src-tauri/src/main.rs @@ -0,0 +1,6 @@ +// Prevents additional console window on Windows in release, DO NOT REMOVE!! +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +fn main() { + app_lib::run(); +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json new file mode 100644 index 0000000..0a03756 --- /dev/null +++ b/src-tauri/tauri.conf.json @@ -0,0 +1,37 @@ +{ + "$schema": "../node_modules/@tauri-apps/cli/config.schema.json", + "productName": "bullseye", + "version": "0.1.0", + "identifier": "com.tauri.dev", + "build": { + "frontendDist": "../.next", + "devUrl": "http://localhost:3000", + "beforeDevCommand": "npm run dev", + "beforeBuildCommand": "npm run build" + }, + "app": { + "windows": [ + { + "title": "bullseye", + "width": 800, + "height": 600, + "resizable": true, + "fullscreen": false + } + ], + "security": { + "csp": null + } + }, + "bundle": { + "active": true, + "targets": "all", + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ] + } +}