diff --git a/backend/.env.example b/backend/.env.example index beaeb9b..bc1a2de 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -3,6 +3,7 @@ APP_ENV=local APP_KEY=base64:GaqTGHuKxQlEwjWIepV5jJPlc0EwlGhpgA17lDwAUN4= APP_DEBUG=true APP_URL=http://localhost:8000 +APP_TIMEZONE=Asia/Kolkata FRONTEND_URL=http://localhost:3000 diff --git a/backend/app/Filament/Resources/LunchDays/LunchDayResource.php b/backend/app/Filament/Resources/LunchDays/LunchDayResource.php index 63e713c..4765f53 100644 --- a/backend/app/Filament/Resources/LunchDays/LunchDayResource.php +++ b/backend/app/Filament/Resources/LunchDays/LunchDayResource.php @@ -6,14 +6,13 @@ use App\Filament\Resources\LunchDays\Pages\EditLunchDay; use App\Filament\Resources\LunchDays\Pages\ListLunchDays; use App\Filament\Resources\LunchDays\Schemas\LunchDayForm; -use App\Filament\Resources\LunchDays\Tables\LunchDaysTable; use App\Models\LunchDay; use BackedEnum; use Filament\Resources\Resource; use Filament\Schemas\Schema; use Filament\Support\Icons\Heroicon; -use Filament\Tables\Table; use Filament\Tables\Columns\TextColumn; +use Filament\Tables\Table; class LunchDayResource extends Resource { @@ -28,7 +27,6 @@ public static function form(Schema $schema): Schema return LunchDayForm::configure($schema); } - public static function table(Table $table): Table { return $table @@ -36,14 +34,14 @@ public static function table(Table $table): Table TextColumn::make('lunch_date') ->date() ->sortable(), - + TextColumn::make('menu.title') ->label('Meal'), - + TextColumn::make('orders_count') ->counts('orders') ->label('Total Votes'), - + TextColumn::make('opted_in_orders_count') ->counts('optedInOrders') ->label('Eating Count') diff --git a/backend/app/Filament/Resources/LunchDays/RelationManagers/OrdersRelationManager.php b/backend/app/Filament/Resources/LunchDays/RelationManagers/OrdersRelationManager.php index 32c4f5b..8a0d8ba 100644 --- a/backend/app/Filament/Resources/LunchDays/RelationManagers/OrdersRelationManager.php +++ b/backend/app/Filament/Resources/LunchDays/RelationManagers/OrdersRelationManager.php @@ -20,8 +20,7 @@ public function table(Table $table): Table TextColumn::make('status') ->badge() - ->color(fn ($state) => - $state === 'opted_in' ? 'success' : 'danger' + ->color(fn ($state) => $state === 'opted_in' ? 'success' : 'danger' ), TextColumn::make('created_at') @@ -30,4 +29,4 @@ public function table(Table $table): Table ]) ->defaultSort('created_at', 'desc'); } -} \ No newline at end of file +} diff --git a/backend/app/Filament/Resources/LunchDays/Schemas/LunchDayForm.php b/backend/app/Filament/Resources/LunchDays/Schemas/LunchDayForm.php index e177adb..2981c80 100644 --- a/backend/app/Filament/Resources/LunchDays/Schemas/LunchDayForm.php +++ b/backend/app/Filament/Resources/LunchDays/Schemas/LunchDayForm.php @@ -3,8 +3,8 @@ namespace App\Filament\Resources\LunchDays\Schemas; use Filament\Forms\Components\DatePicker; -use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Textarea; +use Filament\Forms\Components\TextInput; use Filament\Schemas\Schema; class LunchDayForm diff --git a/backend/app/Filament/Resources/Users/Schemas/UserForm.php b/backend/app/Filament/Resources/Users/Schemas/UserForm.php index 8c21127..7e1a233 100644 --- a/backend/app/Filament/Resources/Users/Schemas/UserForm.php +++ b/backend/app/Filament/Resources/Users/Schemas/UserForm.php @@ -3,10 +3,11 @@ namespace App\Filament\Resources\Users\Schemas; use Filament\Forms\Components\DateTimePicker; -use Filament\Forms\Components\TextInput; -use Filament\Forms\Components\Textarea; use Filament\Forms\Components\Select; +use Filament\Forms\Components\Textarea; +use Filament\Forms\Components\TextInput; use Filament\Schemas\Schema; +use Illuminate\Support\Facades\Hash; class UserForm { @@ -23,7 +24,7 @@ public static function configure(Schema $schema): Schema DateTimePicker::make('email_verified_at'), TextInput::make('password') ->password() - ->dehydrateStateUsing(fn ($state) => \Illuminate\Support\Facades\Hash::make($state)) + ->dehydrateStateUsing(fn ($state) => Hash::make($state)) ->dehydrated(fn ($state) => filled($state)) ->required(fn (string $context): bool => $context === 'create'), Select::make('role') diff --git a/backend/app/Filament/Resources/WeeklyMenus/Schemas/WeeklyMenuForm.php b/backend/app/Filament/Resources/WeeklyMenus/Schemas/WeeklyMenuForm.php index b08a045..84b66f9 100644 --- a/backend/app/Filament/Resources/WeeklyMenus/Schemas/WeeklyMenuForm.php +++ b/backend/app/Filament/Resources/WeeklyMenus/Schemas/WeeklyMenuForm.php @@ -2,9 +2,9 @@ namespace App\Filament\Resources\WeeklyMenus\Schemas; +use Filament\Forms\Components\FileUpload; use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; -use Filament\Forms\Components\FileUpload; use Filament\Schemas\Schema; class WeeklyMenuForm diff --git a/backend/app/Filament/Resources/WeeklyMenus/Tables/WeeklyMenusTable.php b/backend/app/Filament/Resources/WeeklyMenus/Tables/WeeklyMenusTable.php index 9e6b322..eb6d0ab 100644 --- a/backend/app/Filament/Resources/WeeklyMenus/Tables/WeeklyMenusTable.php +++ b/backend/app/Filament/Resources/WeeklyMenus/Tables/WeeklyMenusTable.php @@ -5,8 +5,8 @@ use Filament\Actions\BulkActionGroup; use Filament\Actions\DeleteBulkAction; use Filament\Actions\EditAction; -use Filament\Tables\Columns\TextColumn; use Filament\Tables\Columns\ImageColumn; +use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; class WeeklyMenusTable diff --git a/backend/app/Filament/Resources/WeeklyMenus/WeeklyMenuResource.php b/backend/app/Filament/Resources/WeeklyMenus/WeeklyMenuResource.php index 394aeba..2387140 100644 --- a/backend/app/Filament/Resources/WeeklyMenus/WeeklyMenuResource.php +++ b/backend/app/Filament/Resources/WeeklyMenus/WeeklyMenuResource.php @@ -26,7 +26,6 @@ class WeeklyMenuResource extends Resource protected static ?string $modelLabel = 'Weekly Menu'; - public static function form(Schema $schema): Schema { return WeeklyMenuForm::configure($schema); diff --git a/backend/app/Http/Controllers/Api/AuthController.php b/backend/app/Http/Controllers/Api/AuthController.php index 0ae4002..24dbe70 100644 --- a/backend/app/Http/Controllers/Api/AuthController.php +++ b/backend/app/Http/Controllers/Api/AuthController.php @@ -18,7 +18,7 @@ public function register(Request $request) $passwordRules = $this->passwordRules(); // Remove 'confirmed' if it's not provided in the request if (! $request->has('password_confirmation')) { - $passwordRules = array_filter($passwordRules, fn($rule) => $rule !== 'confirmed'); + $passwordRules = array_filter($passwordRules, fn ($rule) => $rule !== 'confirmed'); } $request->validate([ diff --git a/backend/app/Http/Controllers/Api/BroadcastController.php b/backend/app/Http/Controllers/Api/BroadcastController.php index 65b394e..b4718a5 100644 --- a/backend/app/Http/Controllers/Api/BroadcastController.php +++ b/backend/app/Http/Controllers/Api/BroadcastController.php @@ -4,9 +4,9 @@ use App\Http\Controllers\Controller; use App\Models\Broadcast; -use Illuminate\Http\Request; use Carbon\Carbon; use DB; +use Illuminate\Http\Request; class BroadcastController extends Controller { @@ -30,6 +30,7 @@ public function index(Request $request) // Attach is_read flag $broadcasts->transform(function ($b) use ($readIds) { $b->is_read = in_array($b->id, $readIds); + return $b; }); @@ -40,7 +41,7 @@ public function store(Request $request) { $request->validate([ 'message' => 'required|string|max:1000', - 'type' => 'nullable|string|max:50' + 'type' => 'nullable|string|max:50', ]); $broadcast = Broadcast::create([ @@ -58,6 +59,7 @@ public function markAsRead(Request $request, $id) ['user_id' => $request->user()->id, 'broadcast_id' => $id], ['created_at' => Carbon::now(), 'updated_at' => Carbon::now()] ); + return response()->json(['success' => true]); } } diff --git a/backend/app/Http/Controllers/Api/ExpenseController.php b/backend/app/Http/Controllers/Api/ExpenseController.php index 7bfee0f..3f72de8 100644 --- a/backend/app/Http/Controllers/Api/ExpenseController.php +++ b/backend/app/Http/Controllers/Api/ExpenseController.php @@ -3,8 +3,8 @@ namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; -use Illuminate\Http\Request; use App\Models\MonthlyExpense; +use Illuminate\Http\Request; class ExpenseController extends Controller { diff --git a/backend/app/Http/Controllers/Api/LunchController.php b/backend/app/Http/Controllers/Api/LunchController.php index 2907724..46ca79f 100644 --- a/backend/app/Http/Controllers/Api/LunchController.php +++ b/backend/app/Http/Controllers/Api/LunchController.php @@ -1,14 +1,15 @@ $request->lunch_date, - 'weekly_menu_id' => $request->weekly_menu_id + 'weekly_menu_id' => $request->weekly_menu_id, ]); } @@ -42,7 +43,7 @@ public function poll(Request $request) 'user_id' => $request->user()->id, ], [ - 'status' => $request->status + 'status' => $request->status, ] ); } @@ -66,53 +67,96 @@ public function monthlySummary(Request $request) // User activity history public function userActivity(Request $request) { + $userId = $request->user()->id; $limit = $request->query('limit'); - - $query = LunchOrder::with(['lunchDay', 'lunchDay.menu']) - ->where('user_id', $request->user()->id) - ->join('lunch_days', 'lunch_orders.lunch_day_id', '=', 'lunch_days.id') - ->orderBy('lunch_days.lunch_date', 'desc') - ->select('lunch_orders.*'); - + $today = Carbon::today()->toDateString(); + $userRegisterDate = $request->user()->getEffectiveLunchStartDate(); + + $daysQuery = LunchDay::with(['menu', 'orders' => function ($q) use ($userId) { + $q->where('user_id', $userId); + }]) + ->where('lunch_date', '>=', $userRegisterDate) + ->where('lunch_date', '<=', $today) + ->orderBy('lunch_date', 'desc'); + if ($limit) { - return $query->take($limit)->get(); + $days = $daysQuery->take($limit)->get(); + } else { + $days = $daysQuery->get(); } - - return $query->get(); + + $activities = $days->map(function ($day) use ($userId) { + $order = $day->orders->first(); + return [ + 'id' => $order ? $order->id : 'v-' . $day->id, + 'user_id' => $userId, + 'lunch_day_id' => $day->id, + 'status' => $order ? $order->status : 'opted_in', + 'created_at' => $order ? $order->created_at?->toIso8601String() : $day->created_at?->toIso8601String(), + 'updated_at' => $order ? $order->updated_at?->toIso8601String() : $day->updated_at?->toIso8601String(), + 'lunch_day' => [ + 'id' => $day->id, + 'lunch_date' => $day->lunch_date, + 'weekly_menu_id' => $day->weekly_menu_id, + 'notes' => $day->notes, + 'created_at' => $day->created_at?->toIso8601String(), + 'updated_at' => $day->updated_at?->toIso8601String(), + 'menu' => $day->menu ? [ + 'id' => $day->menu->id, + 'title' => $day->menu->title, + 'description' => $day->menu->description, + 'image_url' => $day->menu->image_url, + 'weekday' => $day->menu->weekday, + 'created_at' => $day->menu->created_at?->toIso8601String(), + 'updated_at' => $day->menu->updated_at?->toIso8601String(), + ] : null, + ], + ]; + }); + + return response()->json($activities); } // User statistics public function userStats(Request $request) { $userId = $request->user()->id; - $userCreatedAt = Carbon::parse($request->user()->created_at)->startOfDay(); - $userRegisterDate = $userCreatedAt->toDateString(); + $userRegisterDate = $request->user()->getEffectiveLunchStartDate(); + $today = Carbon::today()->toDateString(); $currentMonth = Carbon::now()->month; $currentYear = Carbon::now()->year; - // Count of explicitly opted_out orders ever + // Total lunch days ever on or after registration date up to today + $totalLunchDays = LunchDay::where('lunch_date', '>=', $userRegisterDate) + ->where('lunch_date', '<=', $today) + ->count(); + + // Count of explicitly opted_out orders ever up to today $totalSkipped = LunchOrder::where('user_id', $userId) ->where('status', 'opted_out') + ->join('lunch_days', 'lunch_orders.lunch_day_id', '=', 'lunch_days.id') + ->where('lunch_days.lunch_date', '>=', $userRegisterDate) + ->where('lunch_days.lunch_date', '<=', $today) ->count(); - // Total lunch days ever on or after registration date - $totalLunchDays = LunchDay::where('lunch_date', '>=', $userRegisterDate)->count(); - // Default 'Yes': joined = total days - skipped days $totalLunchEaten = max(0, $totalLunchDays - $totalSkipped); - // Count of explicitly opted_out orders this month + // Total lunch days this month on or after registration date up to today + $lunchDaysThisMonth = LunchDay::whereMonth('lunch_date', $currentMonth) + ->whereYear('lunch_date', $currentYear) + ->where('lunch_date', '>=', $userRegisterDate) + ->where('lunch_date', '<=', $today) + ->count(); + + // Count of explicitly opted_out orders this month up to today $skippedThisMonth = LunchOrder::where('user_id', $userId) ->where('status', 'opted_out') ->join('lunch_days', 'lunch_orders.lunch_day_id', '=', 'lunch_days.id') ->whereMonth('lunch_days.lunch_date', $currentMonth) ->whereYear('lunch_days.lunch_date', $currentYear) - ->count(); - - // Total lunch days this month on or after registration date - $lunchDaysThisMonth = LunchDay::whereMonth('lunch_date', $currentMonth) - ->whereYear('lunch_date', $currentYear) - ->where('lunch_date', '>=', $userRegisterDate) + ->where('lunch_days.lunch_date', '>=', $userRegisterDate) + ->where('lunch_days.lunch_date', '<=', $today) ->count(); // Default 'Yes' for this month @@ -130,7 +174,7 @@ public function todayPoll(Request $request) { $today = Carbon::today(); $weekday = strtolower($today->format('D')); - + // If it's a weekend, fallback to Monday or return no menu if ($weekday === 'sat' || $weekday === 'sun') { $weekday = 'mon'; @@ -138,7 +182,7 @@ public function todayPoll(Request $request) $menu = WeeklyMenu::where('weekday', $weekday)->first(); - if (!$menu) { + if (! $menu) { return response()->json(['error' => 'No menu found for today'], 404); } @@ -151,11 +195,170 @@ public function todayPoll(Request $request) ->where('user_id', $request->user()->id) ->first(); + $effectiveStartDate = $request->user()->getEffectiveLunchStartDate(); + $defaultStatus = $today->toDateString() < $effectiveStartDate ? 'opted_out' : 'opted_in'; + return response()->json([ 'lunch_day_id' => $lunchDay->id, 'menu' => $menu, - 'status' => $order ? $order->status : 'opted_in', // default to opted_in - 'is_deadline_met' => Carbon::now()->hour >= 10 + 'status' => $order ? $order->status : $defaultStatus, + 'is_deadline_met' => Carbon::now()->hour >= 10, + ]); + } + + // Get calendar poll data for the user + public function calendarPoll(Request $request) + { + $year = (int) $request->query('year', Carbon::now()->year); + $month = (int) $request->query('month', Carbon::now()->month); + + $startDate = Carbon::createFromDate($year, $month, 1)->startOfMonth(); + $endDate = $startDate->copy()->endOfMonth(); + $today = Carbon::today(); + + $effectiveStartDate = $request->user()->getEffectiveLunchStartDate(); + + // Fetch all lunch days in this month + $lunchDays = LunchDay::with('menu') + ->whereBetween('lunch_date', [$startDate->toDateString(), $endDate->toDateString()]) + ->get() + ->keyBy('lunch_date'); + + // Fetch user's orders for these lunch days + $lunchDayIds = $lunchDays->pluck('id'); + $orders = LunchOrder::whereIn('lunch_day_id', $lunchDayIds) + ->where('user_id', $request->user()->id) + ->get() + ->keyBy('lunch_day_id'); + + // Fetch all weekly menus + $menus = WeeklyMenu::all()->keyBy('weekday'); + + $days = []; + $currentDate = $startDate->copy(); + + while ($currentDate->lte($endDate)) { + $dateStr = $currentDate->toDateString(); + $weekday = strtolower($currentDate->format('D')); + $isWeekend = ($weekday === 'sat' || $weekday === 'sun'); + + $dayMenu = null; + $status = null; + $lunchDayId = null; + + if (! $isWeekend) { + $menu = $menus->get($weekday); + $dayMenu = $menu ? [ + 'id' => $menu->id, + 'title' => $menu->title, + ] : null; + + $lunchDay = $lunchDays->get($dateStr); + if ($lunchDay) { + $lunchDayId = $lunchDay->id; + $order = $orders->get($lunchDay->id); + $status = $order ? $order->status : null; + } + + if (! $status) { + $status = $dateStr < $effectiveStartDate ? 'opted_out' : 'opted_in'; + } + } + + $isPast = $currentDate->lt($today); + $isToday = $currentDate->eq($today); + $isLocked = $isPast || ($isToday && Carbon::now()->hour >= 10); + + $days[] = [ + 'date' => $dateStr, + 'day_of_week' => $weekday, + 'is_weekend' => $isWeekend, + 'menu' => $dayMenu, + 'status' => $status, + 'lunch_day_id' => $lunchDayId, + 'is_past' => $isPast, + 'is_today' => $isToday, + 'is_locked' => $isLocked, + ]; + + $currentDate = $currentDate->addDay(); + } + + return response()->json([ + 'year' => $year, + 'month' => $month, + 'days' => $days, + ]); + } + + // Submit batch votes for user + public function batchPoll(Request $request) + { + $request->validate([ + 'dates' => 'required|array', + 'dates.*' => 'required|date_format:Y-m-d', + 'status' => 'required|in:opted_in,opted_out', + ]); + + $dates = $request->dates; + $status = $request->status; + $user = $request->user(); + $today = Carbon::today(); + + // Load menus for day-of-week lookups + $menus = WeeklyMenu::all()->keyBy('weekday'); + + $updatedOrders = []; + + foreach ($dates as $dateStr) { + $date = Carbon::parse($dateStr); + + // Check validation: Cannot vote on past dates + if ($date->lt($today)) { + continue; // Skip past dates + } + + // If today, check if it's past 10 AM + if ($date->eq($today) && Carbon::now()->hour >= 10) { + continue; // Skip today if deadline met + } + + $weekday = strtolower($date->format('D')); + if ($weekday === 'sat' || $weekday === 'sun') { + continue; // Skip weekends + } + + $menu = $menus->get($weekday); + if (! $menu) { + continue; // Skip if no menu defined for this weekday + } + + // Get or create LunchDay + $lunchDay = LunchDay::firstOrCreate( + ['lunch_date' => $dateStr], + ['weekly_menu_id' => $menu->id] + ); + + // Update or create order + $order = LunchOrder::updateOrCreate( + [ + 'lunch_day_id' => $lunchDay->id, + 'user_id' => $user->id, + ], + [ + 'status' => $status, + ] + ); + + $updatedOrders[] = [ + 'date' => $dateStr, + 'status' => $order->status, + ]; + } + + return response()->json([ + 'message' => 'Votes updated successfully', + 'updated' => $updatedOrders, ]); } @@ -169,7 +372,7 @@ public function chefDashboardData(Request $request) $today = Carbon::today(); $weekday = strtolower($today->format('D')); - + if ($weekday === 'sat' || $weekday === 'sun') { $weekday = 'mon'; // fallback to Monday for UI demonstration on weekends } @@ -202,49 +405,64 @@ public function chefDashboardData(Request $request) $order = $orders->get($emp->id); $status = 'joining'; // default to joining $votedAt = '--:--'; - + if ($order) { if ($order->status === 'opted_in') { $status = 'joining'; $joined++; - } else if ($order->status === 'opted_out') { + } elseif ($order->status === 'opted_out') { $status = 'skipped'; $skipped++; } $votedAt = $order->updated_at->format('g:i A'); } else { - $joined++; + $effectiveStartDate = $emp->getEffectiveLunchStartDate(); + if ($today->toDateString() < $effectiveStartDate) { + $status = 'skipped'; + $skipped++; + } else { + $status = 'joining'; + $joined++; + } } - + $employeeDetails[] = [ 'id' => $emp->id, 'name' => $emp->name, 'department' => $emp->department ?? 'General', 'status' => $status, - 'votedAt' => $votedAt + 'votedAt' => $votedAt, ]; } } else { foreach ($employees as $emp) { + $effectiveStartDate = $emp->getEffectiveLunchStartDate(); + if ($today->toDateString() < $effectiveStartDate) { + $status = 'skipped'; + $skipped++; + } else { + $status = 'joining'; + $joined++; + } + $employeeDetails[] = [ 'id' => $emp->id, 'name' => $emp->name, 'department' => $emp->department ?? 'General', - 'status' => 'joining', // default to joining - 'votedAt' => '--:--' + 'status' => $status, + 'votedAt' => '--:--', ]; - $joined++; } } // Weekly joining (last 5 days) $chartData = []; $totalEmployeesCount = User::whereIn('role', ['employee', 'chef', 'accountant'])->where('is_active', true)->count(); - + for ($i = 4; $i >= 0; $i--) { $date = Carbon::today()->subDays($i); $dayName = $date->format('D'); // Mon, Tue - + $dayRecord = LunchDay::where('lunch_date', $date->format('Y-m-d'))->first(); $count = 0; if ($dayRecord) { @@ -254,10 +472,10 @@ public function chefDashboardData(Request $request) // If the day has no record, everyone is counted as opted_in by default $count = $totalEmployeesCount; } - + $chartData[] = [ 'day' => $dayName, - 'count' => $count + 'count' => $count, ]; } @@ -267,9 +485,9 @@ public function chefDashboardData(Request $request) 'totalEmployees' => $totalEmployees, 'joined' => $joined, 'skipped' => $skipped, - 'employees' => $employeeDetails + 'employees' => $employeeDetails, ], - 'chartData' => $chartData + 'chartData' => $chartData, ]); } @@ -293,110 +511,123 @@ public function participationReport(Request $request) if ($type === 'daily') { $parsedDate = Carbon::parse($dateStr); $dayRecord = LunchDay::with('menu')->where('lunch_date', $parsedDate->toDateString())->first(); - + $usersData = []; foreach ($activeUsers as $user) { - $userRegisterDate = Carbon::parse($user->created_at)->toDateString(); - + $userRegisterDate = $user->getEffectiveLunchStartDate(); + if ($parsedDate->toDateString() < $userRegisterDate) { $status = 'not_registered'; $votedAt = '--:--'; } else { $status = 'joining'; // default $votedAt = '--:--'; - + if ($dayRecord) { $order = LunchOrder::where('lunch_day_id', $dayRecord->id) ->where('user_id', $user->id) ->first(); - + if ($order) { if ($order->status === 'opted_in') { $status = 'joining'; - } else if ($order->status === 'opted_out') { + } elseif ($order->status === 'opted_out') { $status = 'skipped'; } $votedAt = $order->updated_at->format('g:i A'); } } } - + $usersData[] = [ 'id' => $user->id, 'name' => $user->name, 'role' => $user->role, 'department' => $user->department ?? 'General', 'status' => $status, - 'voted_at' => $votedAt + 'voted_at' => $votedAt, ]; } - + return response()->json([ 'date' => $parsedDate->toDateString(), 'has_menu' => $dayRecord ? true : false, 'menu_title' => $dayRecord && $dayRecord->menu ? $dayRecord->menu->title : null, - 'users' => $usersData + 'users' => $usersData, ]); - + } elseif ($type === 'weekly') { $parsedDate = Carbon::parse($dateStr); $monday = $parsedDate->copy()->startOfWeek(Carbon::MONDAY); - + $today = Carbon::today()->toDateString(); + // Get 5 weekdays $weekdays = []; for ($i = 0; $i < 5; $i++) { $weekdays[] = $monday->copy()->addDays($i)->toDateString(); } - + // Get lunch days for these weekdays $dayRecords = LunchDay::with('menu') ->whereIn('lunch_date', $weekdays) ->get() ->keyBy('lunch_date'); - + $lunchDayIds = $dayRecords->pluck('id'); $orders = LunchOrder::whereIn('lunch_day_id', $lunchDayIds) ->get() ->groupBy('lunch_day_id'); - + $usersData = []; foreach ($activeUsers as $user) { - $userRegisterDate = Carbon::parse($user->created_at)->toDateString(); - + $userRegisterDate = $user->getEffectiveLunchStartDate(); + $userDays = []; $userJoinedCount = 0; $userSkippedCount = 0; - + foreach ($weekdays as $day) { if ($day < $userRegisterDate) { $userDays[$day] = 'not_registered'; } else { $status = 'joining'; // default $dayRecord = $dayRecords->get($day); - + if ($dayRecord) { $dayOrders = $orders->get($dayRecord->id); $order = $dayOrders ? $dayOrders->firstWhere('user_id', $user->id) : null; - + if ($order) { if ($order->status === 'opted_in') { $status = 'joining'; - $userJoinedCount++; - } else if ($order->status === 'opted_out') { + if ($day <= $today) { + $userJoinedCount++; + } + } elseif ($order->status === 'opted_out') { $status = 'skipped'; - $userSkippedCount++; + if ($day <= $today) { + $userSkippedCount++; + } } } else { - $userJoinedCount++; // default to joining + if ($day <= $today) { + $userJoinedCount++; // default to joining + } } } else { - $userJoinedCount++; // default to joining if no record yet + if ($day <= $today) { + $userJoinedCount++; // default to joining if no record yet + } + } + + if ($day > $today) { + $status = null; } - + $userDays[$day] = $status; } } - + $usersData[] = [ 'id' => $user->id, 'name' => $user->name, @@ -404,10 +635,10 @@ public function participationReport(Request $request) 'department' => $user->department ?? 'General', 'days' => $userDays, 'joined_count' => $userJoinedCount, - 'skipped_count' => $userSkippedCount + 'skipped_count' => $userSkippedCount, ]; } - + $daysMeta = []; foreach ($weekdays as $day) { $dayRecord = $dayRecords->get($day); @@ -417,41 +648,46 @@ public function participationReport(Request $request) 'menu_title' => $dayRecord && $dayRecord->menu ? $dayRecord->menu->title : null, ]; } - + return response()->json([ 'week_start' => $monday->toDateString(), 'week_end' => $monday->copy()->addDays(4)->toDateString(), 'days' => $daysMeta, - 'users' => $usersData + 'users' => $usersData, ]); - + } elseif ($type === 'monthly') { - // Get all lunch days in month + $today = Carbon::today()->toDateString(); + // Get all lunch days in month up to today $lunchDays = LunchDay::whereMonth('lunch_date', $month) ->whereYear('lunch_date', $year) + ->where('lunch_date', '<=', $today) ->get() ->keyBy('lunch_date'); - + $lunchDayIds = $lunchDays->pluck('id'); - + $optedOutOrders = LunchOrder::whereIn('lunch_day_id', $lunchDayIds) ->where('status', 'opted_out') ->get() ->groupBy('user_id'); - + $usersData = []; foreach ($activeUsers as $user) { - $userRegisterDate = Carbon::parse($user->created_at)->toDateString(); - - // Count lunch days in month on or after user registration - $userEligibleDays = $lunchDays->filter(function ($day) use ($userRegisterDate) { - return $day->lunch_date >= $userRegisterDate; + $userRegisterDate = $user->getEffectiveLunchStartDate(); + + // Count lunch days in month on or after user registration and on or before today + $userEligibleDays = $lunchDays->filter(function ($day) use ($userRegisterDate, $today) { + return $day->lunch_date >= $userRegisterDate && $day->lunch_date <= $today; }); - + $totalEligibleCount = $userEligibleDays->count(); - $userOptedOutCount = $optedOutOrders->get($user->id)?->count() ?? 0; + $userEligibleDayIds = $userEligibleDays->pluck('id'); + $userOptedOutCount = $optedOutOrders->get($user->id) + ?->filter(fn ($order) => $userEligibleDayIds->contains($order->lunch_day_id)) + ?->count() ?? 0; $joinedCount = max(0, $totalEligibleCount - $userOptedOutCount); - + $usersData[] = [ 'id' => $user->id, 'name' => $user->name, @@ -459,18 +695,18 @@ public function participationReport(Request $request) 'department' => $user->department ?? 'General', 'total_eligible_days' => $totalEligibleCount, 'joined_count' => $joinedCount, - 'skipped_count' => $userOptedOutCount + 'skipped_count' => $userOptedOutCount, ]; } - + return response()->json([ 'month' => $month, 'year' => $year, 'total_lunch_days' => $lunchDays->count(), - 'users' => $usersData + 'users' => $usersData, ]); } - + return response()->json(['error' => 'Invalid report type'], 400); } -} \ No newline at end of file +} diff --git a/backend/app/Http/Controllers/Api/MonthlyBillController.php b/backend/app/Http/Controllers/Api/MonthlyBillController.php index 71c272f..f654488 100644 --- a/backend/app/Http/Controllers/Api/MonthlyBillController.php +++ b/backend/app/Http/Controllers/Api/MonthlyBillController.php @@ -156,4 +156,15 @@ public function updatePayment( 'data' => new UserMonthlyBillResource($updated), ]); } + + public function destroy(MonthlyBill $monthlyBill): JsonResponse + { + $this->authorize('delete', $monthlyBill); + + $this->billingService->deleteMonthlyBill($monthlyBill); + + return response()->json([ + 'message' => 'Monthly bill deleted successfully.', + ]); + } } diff --git a/backend/app/Models/LunchDay.php b/backend/app/Models/LunchDay.php index 6692398..a0dafbe 100644 --- a/backend/app/Models/LunchDay.php +++ b/backend/app/Models/LunchDay.php @@ -27,4 +27,4 @@ public function optedInOrders() return $this->hasMany(LunchOrder::class) ->where('status', 'opted_in'); } -} \ No newline at end of file +} diff --git a/backend/app/Models/LunchOrder.php b/backend/app/Models/LunchOrder.php index 750d8d2..c6c7d5d 100644 --- a/backend/app/Models/LunchOrder.php +++ b/backend/app/Models/LunchOrder.php @@ -7,13 +7,14 @@ class LunchOrder extends Model { protected $guarded = []; + public function user() -{ - return $this->belongsTo(User::class); -} + { + return $this->belongsTo(User::class); + } -public function lunchDay() -{ - return $this->belongsTo(LunchDay::class); -} + public function lunchDay() + { + return $this->belongsTo(LunchDay::class); + } } diff --git a/backend/app/Models/User.php b/backend/app/Models/User.php index 48a2ec0..7c4cbed 100644 --- a/backend/app/Models/User.php +++ b/backend/app/Models/User.php @@ -2,6 +2,7 @@ namespace App\Models; +use Carbon\Carbon; use Database\Factories\UserFactory; use Illuminate\Database\Eloquent\Attributes\Fillable; use Illuminate\Database\Eloquent\Attributes\Hidden; @@ -104,4 +105,14 @@ public function isSuperAdmin(): bool { return $this->role === 'super_admin'; } + + public function getEffectiveLunchStartDate(): string + { + $createdAt = Carbon::parse($this->created_at); + if ($createdAt->hour >= 10) { + return $createdAt->addDay()->toDateString(); + } + + return $createdAt->toDateString(); + } } diff --git a/backend/app/Policies/MonthlyBillPolicy.php b/backend/app/Policies/MonthlyBillPolicy.php index 51f9a50..11e4a34 100644 --- a/backend/app/Policies/MonthlyBillPolicy.php +++ b/backend/app/Policies/MonthlyBillPolicy.php @@ -27,6 +27,12 @@ public function updatePayment(User $user): bool return $this->isAccountantOrAdmin($user); } + public function delete(User $user, MonthlyBill $monthlyBill): bool + { + return $this->isAccountantOrAdmin($user); + } + + private function isAccountantOrAdmin(User $user): bool { return in_array($user->role, ['accountant', 'admin', 'super_admin'], true); diff --git a/backend/app/Services/MonthlyBillingService.php b/backend/app/Services/MonthlyBillingService.php index 2dc4d15..4c5fdd9 100644 --- a/backend/app/Services/MonthlyBillingService.php +++ b/backend/app/Services/MonthlyBillingService.php @@ -9,28 +9,28 @@ use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Storage; -use Carbon\Carbon; class MonthlyBillingService { public function countJoinedPlatesByUser(int $month, int $year): Collection { - // Get all lunch days in the specified month with their dates + $today = now()->toDateString(); + + // Get all lunch days in the specified month with their dates on or before today $lunchDays = DB::table('lunch_days') ->whereMonth('lunch_date', $month) ->whereYear('lunch_date', $year) + ->where('lunch_date', '<=', $today) ->get(['id', 'lunch_date']); $lunchDayIds = $lunchDays->pluck('id'); - // Get the count of opted_out orders for each active user - $optedOutCounts = DB::table('lunch_orders') + // Get all opted_out orders for each active user in the specified month + $optedOutOrders = DB::table('lunch_orders') ->whereIn('lunch_day_id', $lunchDayIds) ->where('status', 'opted_out') - ->select('user_id', DB::raw('COUNT(*) as opted_out_count')) - ->groupBy('user_id') ->get() - ->keyBy('user_id'); + ->groupBy('user_id'); $activeUsers = User::where('is_active', true) ->whereIn('role', ['employee', 'chef', 'accountant']) @@ -38,19 +38,24 @@ public function countJoinedPlatesByUser(int $month, int $year): Collection $results = collect(); foreach ($activeUsers as $user) { - $userRegisterDate = Carbon::parse($user->created_at)->toDateString(); - + $userRegisterDate = $user->getEffectiveLunchStartDate(); + // Filter lunch days in the month that are on or after the user's registration date - $userLunchDaysCount = $lunchDays->filter(function ($day) use ($userRegisterDate) { + $userLunchDays = $lunchDays->filter(function ($day) use ($userRegisterDate) { return $day->lunch_date >= $userRegisterDate; - })->count(); + }); + $userLunchDaysCount = $userLunchDays->count(); + + $userEligibleDayIds = $userLunchDays->pluck('id'); + $optedOutCount = $optedOutOrders->get($user->id) + ?->filter(fn ($order) => $userEligibleDayIds->contains($order->lunch_day_id)) + ?->count() ?? 0; - $optedOutCount = $optedOutCounts->get($user->id)?->opted_out_count ?? 0; $joinedCount = max(0, $userLunchDaysCount - $optedOutCount); - - $results->push((object)[ + + $results->push((object) [ 'user_id' => $user->id, - 'joined_count' => $joinedCount + 'joined_count' => $joinedCount, ]); } @@ -158,6 +163,17 @@ public function createMonthlyBill( }); } + public function deleteMonthlyBill(MonthlyBill $monthlyBill): void + { + DB::transaction(function () use ($monthlyBill) { + if ($monthlyBill->bill_image) { + $this->deleteBillImage($monthlyBill->bill_image); + } + $monthlyBill->delete(); + }); + } + + public function paymentStatistics(MonthlyBill $monthlyBill): array { $stats = UserMonthlyBill::where('monthly_bill_id', $monthlyBill->id) diff --git a/backend/bootstrap/providers.php b/backend/bootstrap/providers.php index 2baf31c..d23c829 100644 --- a/backend/bootstrap/providers.php +++ b/backend/bootstrap/providers.php @@ -1,7 +1,11 @@ 'UTC', + 'timezone' => env('APP_TIMEZONE', 'Asia/Kolkata'), /* |-------------------------------------------------------------------------- diff --git a/backend/config/cors.php b/backend/config/cors.php index ebe1f29..a54e988 100644 --- a/backend/config/cors.php +++ b/backend/config/cors.php @@ -2,20 +2,20 @@ return [ -'paths' => ['api/*', 'sanctum/csrf-cookie'], + 'paths' => ['api/*', 'sanctum/csrf-cookie'], -'allowed_methods' => ['*'], + 'allowed_methods' => ['*'], -'allowed_origins' => ['http://localhost:3000'], + 'allowed_origins' => ['http://localhost:3000'], -'allowed_origins_patterns' => [], + 'allowed_origins_patterns' => [], -'allowed_headers' => ['*'], + 'allowed_headers' => ['*'], -'exposed_headers' => [], + 'exposed_headers' => [], -'max_age' => 0, + 'max_age' => 0, -'supports_credentials' => true, + 'supports_credentials' => true, -]; \ No newline at end of file +]; diff --git a/backend/config/database.php b/backend/config/database.php index 96c9078..22043fc 100644 --- a/backend/config/database.php +++ b/backend/config/database.php @@ -93,10 +93,10 @@ 'port' => env('DB_PORT', '5432'), 'database' => env('DB_DATABASE', 'laravel'), 'username' => (file_exists('/.dockerenv') || filter_var(env('RUNNING_IN_DOCKER', false), FILTER_VALIDATE_BOOL)) - ? (env('DB_USERNAME') ?: 'mealbuddy') + ? (env('DOCKER_DB_USERNAME') ?: 'mealbuddy') : env('DB_USERNAME', 'root'), 'password' => (file_exists('/.dockerenv') || filter_var(env('RUNNING_IN_DOCKER', false), FILTER_VALIDATE_BOOL)) - ? (env('DB_PASSWORD') ?: 'secret') + ? (env('DOCKER_DB_PASSWORD') ?: 'strongpassword') : env('DB_PASSWORD', ''), 'charset' => env('DB_CHARSET', 'utf8'), 'prefix' => '', diff --git a/backend/database/migrations/2026_05_19_105312_create_broadcast_reads_table.php b/backend/database/migrations/2026_05_19_105312_create_broadcast_reads_table.php index 2278e2b..1256352 100644 --- a/backend/database/migrations/2026_05_19_105312_create_broadcast_reads_table.php +++ b/backend/database/migrations/2026_05_19_105312_create_broadcast_reads_table.php @@ -16,7 +16,7 @@ public function up(): void $table->foreignId('user_id')->constrained()->cascadeOnDelete(); $table->foreignId('broadcast_id')->constrained()->cascadeOnDelete(); $table->timestamps(); - + $table->unique(['user_id', 'broadcast_id']); }); } diff --git a/backend/database/seeders/DatabaseSeeder.php b/backend/database/seeders/DatabaseSeeder.php index e8efed5..6e993ee 100644 --- a/backend/database/seeders/DatabaseSeeder.php +++ b/backend/database/seeders/DatabaseSeeder.php @@ -4,7 +4,6 @@ use App\Models\User; use Illuminate\Database\Seeder; -use Illuminate\Support\Facades\Hash; class DatabaseSeeder extends Seeder { diff --git a/backend/public/vendor/livewire/livewire.csp.esm.js b/backend/public/vendor/livewire/livewire.csp.esm.js new file mode 100644 index 0000000..e96f907 --- /dev/null +++ b/backend/public/vendor/livewire/livewire.csp.esm.js @@ -0,0 +1,16282 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); + +// node_modules/@alpinejs/csp/dist/module.cjs.js +var require_module_cjs = __commonJS({ + "node_modules/@alpinejs/csp/dist/module.cjs.js"(exports, module) { + var __create2 = Object.create; + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __getProtoOf2 = Object.getPrototypeOf; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __commonJS2 = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + }; + var __export = (target, all2) => { + for (var name in all2) + __defProp2(target, name, { get: all2[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2( + isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var require_shared_cjs = __commonJS2({ + "node_modules/@vue/shared/dist/shared.cjs.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + function makeMap(str, expectsLowerCase) { + const map = /* @__PURE__ */ Object.create(null); + const list = str.split(","); + for (let i = 0; i < list.length; i++) { + map[list[i]] = true; + } + return expectsLowerCase ? (val) => !!map[val.toLowerCase()] : (val) => !!map[val]; + } + var PatchFlagNames = { + [1]: `TEXT`, + [2]: `CLASS`, + [4]: `STYLE`, + [8]: `PROPS`, + [16]: `FULL_PROPS`, + [32]: `HYDRATE_EVENTS`, + [64]: `STABLE_FRAGMENT`, + [128]: `KEYED_FRAGMENT`, + [256]: `UNKEYED_FRAGMENT`, + [512]: `NEED_PATCH`, + [1024]: `DYNAMIC_SLOTS`, + [2048]: `DEV_ROOT_FRAGMENT`, + [-1]: `HOISTED`, + [-2]: `BAIL` + }; + var slotFlagsText = { + [1]: "STABLE", + [2]: "DYNAMIC", + [3]: "FORWARDED" + }; + var GLOBALS_WHITE_LISTED = "Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt"; + var isGloballyWhitelisted = /* @__PURE__ */ makeMap(GLOBALS_WHITE_LISTED); + var range = 2; + function generateCodeFrame(source, start22 = 0, end = source.length) { + let lines = source.split(/(\r?\n)/); + const newlineSequences = lines.filter((_, idx) => idx % 2 === 1); + lines = lines.filter((_, idx) => idx % 2 === 0); + let count = 0; + const res = []; + for (let i = 0; i < lines.length; i++) { + count += lines[i].length + (newlineSequences[i] && newlineSequences[i].length || 0); + if (count >= start22) { + for (let j = i - range; j <= i + range || end > count; j++) { + if (j < 0 || j >= lines.length) + continue; + const line = j + 1; + res.push(`${line}${" ".repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`); + const lineLength = lines[j].length; + const newLineSeqLength = newlineSequences[j] && newlineSequences[j].length || 0; + if (j === i) { + const pad = start22 - (count - (lineLength + newLineSeqLength)); + const length = Math.max(1, end > count ? lineLength - pad : end - start22); + res.push(` | ` + " ".repeat(pad) + "^".repeat(length)); + } else if (j > i) { + if (end > count) { + const length = Math.max(Math.min(end - count, lineLength), 1); + res.push(` | ` + "^".repeat(length)); + } + count += lineLength + newLineSeqLength; + } + } + break; + } + } + return res.join("\n"); + } + var specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`; + var isSpecialBooleanAttr = /* @__PURE__ */ makeMap(specialBooleanAttrs); + var isBooleanAttr2 = /* @__PURE__ */ makeMap(specialBooleanAttrs + `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected`); + var unsafeAttrCharRE = /[>/="'\u0009\u000a\u000c\u0020]/; + var attrValidationCache = {}; + function isSSRSafeAttrName(name) { + if (attrValidationCache.hasOwnProperty(name)) { + return attrValidationCache[name]; + } + const isUnsafe = unsafeAttrCharRE.test(name); + if (isUnsafe) { + console.error(`unsafe attribute name: ${name}`); + } + return attrValidationCache[name] = !isUnsafe; + } + var propsToAttrMap = { + acceptCharset: "accept-charset", + className: "class", + htmlFor: "for", + httpEquiv: "http-equiv" + }; + var isNoUnitNumericStyleProp = /* @__PURE__ */ makeMap(`animation-iteration-count,border-image-outset,border-image-slice,border-image-width,box-flex,box-flex-group,box-ordinal-group,column-count,columns,flex,flex-grow,flex-positive,flex-shrink,flex-negative,flex-order,grid-row,grid-row-end,grid-row-span,grid-row-start,grid-column,grid-column-end,grid-column-span,grid-column-start,font-weight,line-clamp,line-height,opacity,order,orphans,tab-size,widows,z-index,zoom,fill-opacity,flood-opacity,stop-opacity,stroke-dasharray,stroke-dashoffset,stroke-miterlimit,stroke-opacity,stroke-width`); + var isKnownAttr = /* @__PURE__ */ makeMap(`accept,accept-charset,accesskey,action,align,allow,alt,async,autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,border,buffered,capture,challenge,charset,checked,cite,class,code,codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,formaction,formenctype,formmethod,formnovalidate,formtarget,headers,height,hidden,high,href,hreflang,http-equiv,icon,id,importance,integrity,ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,target,title,translate,type,usemap,value,width,wrap`); + function normalizeStyle(value) { + if (isArray2(value)) { + const res = {}; + for (let i = 0; i < value.length; i++) { + const item = value[i]; + const normalized = normalizeStyle(isString(item) ? parseStringStyle(item) : item); + if (normalized) { + for (const key in normalized) { + res[key] = normalized[key]; + } + } + } + return res; + } else if (isObject22(value)) { + return value; + } + } + var listDelimiterRE = /;(?![^(]*\))/g; + var propertyDelimiterRE = /:(.+)/; + function parseStringStyle(cssText) { + const ret = {}; + cssText.split(listDelimiterRE).forEach((item) => { + if (item) { + const tmp = item.split(propertyDelimiterRE); + tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim()); + } + }); + return ret; + } + function stringifyStyle(styles) { + let ret = ""; + if (!styles) { + return ret; + } + for (const key in styles) { + const value = styles[key]; + const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key); + if (isString(value) || typeof value === "number" && isNoUnitNumericStyleProp(normalizedKey)) { + ret += `${normalizedKey}:${value};`; + } + } + return ret; + } + function normalizeClass(value) { + let res = ""; + if (isString(value)) { + res = value; + } else if (isArray2(value)) { + for (let i = 0; i < value.length; i++) { + const normalized = normalizeClass(value[i]); + if (normalized) { + res += normalized + " "; + } + } + } else if (isObject22(value)) { + for (const name in value) { + if (value[name]) { + res += name + " "; + } + } + } + return res.trim(); + } + var HTML_TAGS = "html,body,base,head,link,meta,style,title,address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,summary,template,blockquote,iframe,tfoot"; + var SVG_TAGS = "svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,text,textPath,title,tspan,unknown,use,view"; + var VOID_TAGS = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr"; + var isHTMLTag = /* @__PURE__ */ makeMap(HTML_TAGS); + var isSVGTag = /* @__PURE__ */ makeMap(SVG_TAGS); + var isVoidTag = /* @__PURE__ */ makeMap(VOID_TAGS); + var escapeRE = /["'&<>]/; + function escapeHtml(string) { + const str = "" + string; + const match = escapeRE.exec(str); + if (!match) { + return str; + } + let html = ""; + let escaped; + let index; + let lastIndex = 0; + for (index = match.index; index < str.length; index++) { + switch (str.charCodeAt(index)) { + case 34: + escaped = """; + break; + case 38: + escaped = "&"; + break; + case 39: + escaped = "'"; + break; + case 60: + escaped = "<"; + break; + case 62: + escaped = ">"; + break; + default: + continue; + } + if (lastIndex !== index) { + html += str.substring(lastIndex, index); + } + lastIndex = index + 1; + html += escaped; + } + return lastIndex !== index ? html + str.substring(lastIndex, index) : html; + } + var commentStripRE = /^-?>||--!>| looseEqual(item, val)); + } + var toDisplayString = (val) => { + return val == null ? "" : isObject22(val) ? JSON.stringify(val, replacer, 2) : String(val); + }; + var replacer = (_key, val) => { + if (isMap(val)) { + return { + [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val2]) => { + entries[`${key} =>`] = val2; + return entries; + }, {}) + }; + } else if (isSet(val)) { + return { + [`Set(${val.size})`]: [...val.values()] + }; + } else if (isObject22(val) && !isArray2(val) && !isPlainObject(val)) { + return String(val); + } + return val; + }; + var babelParserDefaultPlugins = [ + "bigInt", + "optionalChaining", + "nullishCoalescingOperator" + ]; + var EMPTY_OBJ = Object.freeze({}); + var EMPTY_ARR = Object.freeze([]); + var NOOP = () => { + }; + var NO = () => false; + var onRE = /^on[^a-z]/; + var isOn = (key) => onRE.test(key); + var isModelListener = (key) => key.startsWith("onUpdate:"); + var extend = Object.assign; + var remove = (arr, el) => { + const i = arr.indexOf(el); + if (i > -1) { + arr.splice(i, 1); + } + }; + var hasOwnProperty = Object.prototype.hasOwnProperty; + var hasOwn = (val, key) => hasOwnProperty.call(val, key); + var isArray2 = Array.isArray; + var isMap = (val) => toTypeString(val) === "[object Map]"; + var isSet = (val) => toTypeString(val) === "[object Set]"; + var isDate = (val) => val instanceof Date; + var isFunction2 = (val) => typeof val === "function"; + var isString = (val) => typeof val === "string"; + var isSymbol = (val) => typeof val === "symbol"; + var isObject22 = (val) => val !== null && typeof val === "object"; + var isPromise = (val) => { + return isObject22(val) && isFunction2(val.then) && isFunction2(val.catch); + }; + var objectToString = Object.prototype.toString; + var toTypeString = (value) => objectToString.call(value); + var toRawType = (value) => { + return toTypeString(value).slice(8, -1); + }; + var isPlainObject = (val) => toTypeString(val) === "[object Object]"; + var isIntegerKey = (key) => isString(key) && key !== "NaN" && key[0] !== "-" && "" + parseInt(key, 10) === key; + var isReservedProp = /* @__PURE__ */ makeMap( + ",key,ref,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted" + ); + var cacheStringFunction = (fn) => { + const cache = /* @__PURE__ */ Object.create(null); + return (str) => { + const hit = cache[str]; + return hit || (cache[str] = fn(str)); + }; + }; + var camelizeRE = /-(\w)/g; + var camelize = cacheStringFunction((str) => { + return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : ""); + }); + var hyphenateRE = /\B([A-Z])/g; + var hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, "-$1").toLowerCase()); + var capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1)); + var toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``); + var hasChanged = (value, oldValue) => value !== oldValue && (value === value || oldValue === oldValue); + var invokeArrayFns = (fns, arg) => { + for (let i = 0; i < fns.length; i++) { + fns[i](arg); + } + }; + var def = (obj, key, value) => { + Object.defineProperty(obj, key, { + configurable: true, + enumerable: false, + value + }); + }; + var toNumber = (val) => { + const n = parseFloat(val); + return isNaN(n) ? val : n; + }; + var _globalThis; + var getGlobalThis = () => { + return _globalThis || (_globalThis = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {}); + }; + exports2.EMPTY_ARR = EMPTY_ARR; + exports2.EMPTY_OBJ = EMPTY_OBJ; + exports2.NO = NO; + exports2.NOOP = NOOP; + exports2.PatchFlagNames = PatchFlagNames; + exports2.babelParserDefaultPlugins = babelParserDefaultPlugins; + exports2.camelize = camelize; + exports2.capitalize = capitalize; + exports2.def = def; + exports2.escapeHtml = escapeHtml; + exports2.escapeHtmlComment = escapeHtmlComment; + exports2.extend = extend; + exports2.generateCodeFrame = generateCodeFrame; + exports2.getGlobalThis = getGlobalThis; + exports2.hasChanged = hasChanged; + exports2.hasOwn = hasOwn; + exports2.hyphenate = hyphenate; + exports2.invokeArrayFns = invokeArrayFns; + exports2.isArray = isArray2; + exports2.isBooleanAttr = isBooleanAttr2; + exports2.isDate = isDate; + exports2.isFunction = isFunction2; + exports2.isGloballyWhitelisted = isGloballyWhitelisted; + exports2.isHTMLTag = isHTMLTag; + exports2.isIntegerKey = isIntegerKey; + exports2.isKnownAttr = isKnownAttr; + exports2.isMap = isMap; + exports2.isModelListener = isModelListener; + exports2.isNoUnitNumericStyleProp = isNoUnitNumericStyleProp; + exports2.isObject = isObject22; + exports2.isOn = isOn; + exports2.isPlainObject = isPlainObject; + exports2.isPromise = isPromise; + exports2.isReservedProp = isReservedProp; + exports2.isSSRSafeAttrName = isSSRSafeAttrName; + exports2.isSVGTag = isSVGTag; + exports2.isSet = isSet; + exports2.isSpecialBooleanAttr = isSpecialBooleanAttr; + exports2.isString = isString; + exports2.isSymbol = isSymbol; + exports2.isVoidTag = isVoidTag; + exports2.looseEqual = looseEqual; + exports2.looseIndexOf = looseIndexOf; + exports2.makeMap = makeMap; + exports2.normalizeClass = normalizeClass; + exports2.normalizeStyle = normalizeStyle; + exports2.objectToString = objectToString; + exports2.parseStringStyle = parseStringStyle; + exports2.propsToAttrMap = propsToAttrMap; + exports2.remove = remove; + exports2.slotFlagsText = slotFlagsText; + exports2.stringifyStyle = stringifyStyle; + exports2.toDisplayString = toDisplayString; + exports2.toHandlerKey = toHandlerKey; + exports2.toNumber = toNumber; + exports2.toRawType = toRawType; + exports2.toTypeString = toTypeString; + } + }); + var require_shared = __commonJS2({ + "node_modules/@vue/shared/index.js"(exports2, module2) { + "use strict"; + if (false) { + module2.exports = null; + } else { + module2.exports = require_shared_cjs(); + } + } + }); + var require_reactivity_cjs = __commonJS2({ + "node_modules/@vue/reactivity/dist/reactivity.cjs.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + var shared = require_shared(); + var targetMap = /* @__PURE__ */ new WeakMap(); + var effectStack = []; + var activeEffect; + var ITERATE_KEY = Symbol("iterate"); + var MAP_KEY_ITERATE_KEY = Symbol("Map key iterate"); + function isEffect(fn) { + return fn && fn._isEffect === true; + } + function effect3(fn, options = shared.EMPTY_OBJ) { + if (isEffect(fn)) { + fn = fn.raw; + } + const effect4 = createReactiveEffect(fn, options); + if (!options.lazy) { + effect4(); + } + return effect4; + } + function stop2(effect4) { + if (effect4.active) { + cleanup(effect4); + if (effect4.options.onStop) { + effect4.options.onStop(); + } + effect4.active = false; + } + } + var uid = 0; + function createReactiveEffect(fn, options) { + const effect4 = function reactiveEffect() { + if (!effect4.active) { + return fn(); + } + if (!effectStack.includes(effect4)) { + cleanup(effect4); + try { + enableTracking(); + effectStack.push(effect4); + activeEffect = effect4; + return fn(); + } finally { + effectStack.pop(); + resetTracking(); + activeEffect = effectStack[effectStack.length - 1]; + } + } + }; + effect4.id = uid++; + effect4.allowRecurse = !!options.allowRecurse; + effect4._isEffect = true; + effect4.active = true; + effect4.raw = fn; + effect4.deps = []; + effect4.options = options; + return effect4; + } + function cleanup(effect4) { + const { deps } = effect4; + if (deps.length) { + for (let i = 0; i < deps.length; i++) { + deps[i].delete(effect4); + } + deps.length = 0; + } + } + var shouldTrack = true; + var trackStack = []; + function pauseTracking() { + trackStack.push(shouldTrack); + shouldTrack = false; + } + function enableTracking() { + trackStack.push(shouldTrack); + shouldTrack = true; + } + function resetTracking() { + const last = trackStack.pop(); + shouldTrack = last === void 0 ? true : last; + } + function track2(target, type, key) { + if (!shouldTrack || activeEffect === void 0) { + return; + } + let depsMap = targetMap.get(target); + if (!depsMap) { + targetMap.set(target, depsMap = /* @__PURE__ */ new Map()); + } + let dep = depsMap.get(key); + if (!dep) { + depsMap.set(key, dep = /* @__PURE__ */ new Set()); + } + if (!dep.has(activeEffect)) { + dep.add(activeEffect); + activeEffect.deps.push(dep); + if (activeEffect.options.onTrack) { + activeEffect.options.onTrack({ + effect: activeEffect, + target, + type, + key + }); + } + } + } + function trigger2(target, type, key, newValue, oldValue, oldTarget) { + const depsMap = targetMap.get(target); + if (!depsMap) { + return; + } + const effects = /* @__PURE__ */ new Set(); + const add2 = (effectsToAdd) => { + if (effectsToAdd) { + effectsToAdd.forEach((effect4) => { + if (effect4 !== activeEffect || effect4.allowRecurse) { + effects.add(effect4); + } + }); + } + }; + if (type === "clear") { + depsMap.forEach(add2); + } else if (key === "length" && shared.isArray(target)) { + depsMap.forEach((dep, key2) => { + if (key2 === "length" || key2 >= newValue) { + add2(dep); + } + }); + } else { + if (key !== void 0) { + add2(depsMap.get(key)); + } + switch (type) { + case "add": + if (!shared.isArray(target)) { + add2(depsMap.get(ITERATE_KEY)); + if (shared.isMap(target)) { + add2(depsMap.get(MAP_KEY_ITERATE_KEY)); + } + } else if (shared.isIntegerKey(key)) { + add2(depsMap.get("length")); + } + break; + case "delete": + if (!shared.isArray(target)) { + add2(depsMap.get(ITERATE_KEY)); + if (shared.isMap(target)) { + add2(depsMap.get(MAP_KEY_ITERATE_KEY)); + } + } + break; + case "set": + if (shared.isMap(target)) { + add2(depsMap.get(ITERATE_KEY)); + } + break; + } + } + const run = (effect4) => { + if (effect4.options.onTrigger) { + effect4.options.onTrigger({ + effect: effect4, + target, + key, + type, + newValue, + oldValue, + oldTarget + }); + } + if (effect4.options.scheduler) { + effect4.options.scheduler(effect4); + } else { + effect4(); + } + }; + effects.forEach(run); + } + var isNonTrackableKeys = /* @__PURE__ */ shared.makeMap(`__proto__,__v_isRef,__isVue`); + var builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol).map((key) => Symbol[key]).filter(shared.isSymbol)); + var get2 = /* @__PURE__ */ createGetter(); + var shallowGet = /* @__PURE__ */ createGetter(false, true); + var readonlyGet = /* @__PURE__ */ createGetter(true); + var shallowReadonlyGet = /* @__PURE__ */ createGetter(true, true); + var arrayInstrumentations = /* @__PURE__ */ createArrayInstrumentations(); + function createArrayInstrumentations() { + const instrumentations = {}; + ["includes", "indexOf", "lastIndexOf"].forEach((key) => { + instrumentations[key] = function(...args) { + const arr = toRaw2(this); + for (let i = 0, l = this.length; i < l; i++) { + track2(arr, "get", i + ""); + } + const res = arr[key](...args); + if (res === -1 || res === false) { + return arr[key](...args.map(toRaw2)); + } else { + return res; + } + }; + }); + ["push", "pop", "shift", "unshift", "splice"].forEach((key) => { + instrumentations[key] = function(...args) { + pauseTracking(); + const res = toRaw2(this)[key].apply(this, args); + resetTracking(); + return res; + }; + }); + return instrumentations; + } + function createGetter(isReadonly2 = false, shallow = false) { + return function get3(target, key, receiver) { + if (key === "__v_isReactive") { + return !isReadonly2; + } else if (key === "__v_isReadonly") { + return isReadonly2; + } else if (key === "__v_raw" && receiver === (isReadonly2 ? shallow ? shallowReadonlyMap : readonlyMap : shallow ? shallowReactiveMap : reactiveMap).get(target)) { + return target; + } + const targetIsArray = shared.isArray(target); + if (!isReadonly2 && targetIsArray && shared.hasOwn(arrayInstrumentations, key)) { + return Reflect.get(arrayInstrumentations, key, receiver); + } + const res = Reflect.get(target, key, receiver); + if (shared.isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) { + return res; + } + if (!isReadonly2) { + track2(target, "get", key); + } + if (shallow) { + return res; + } + if (isRef(res)) { + const shouldUnwrap = !targetIsArray || !shared.isIntegerKey(key); + return shouldUnwrap ? res.value : res; + } + if (shared.isObject(res)) { + return isReadonly2 ? readonly(res) : reactive3(res); + } + return res; + }; + } + var set2 = /* @__PURE__ */ createSetter(); + var shallowSet = /* @__PURE__ */ createSetter(true); + function createSetter(shallow = false) { + return function set3(target, key, value, receiver) { + let oldValue = target[key]; + if (!shallow) { + value = toRaw2(value); + oldValue = toRaw2(oldValue); + if (!shared.isArray(target) && isRef(oldValue) && !isRef(value)) { + oldValue.value = value; + return true; + } + } + const hadKey = shared.isArray(target) && shared.isIntegerKey(key) ? Number(key) < target.length : shared.hasOwn(target, key); + const result = Reflect.set(target, key, value, receiver); + if (target === toRaw2(receiver)) { + if (!hadKey) { + trigger2(target, "add", key, value); + } else if (shared.hasChanged(value, oldValue)) { + trigger2(target, "set", key, value, oldValue); + } + } + return result; + }; + } + function deleteProperty(target, key) { + const hadKey = shared.hasOwn(target, key); + const oldValue = target[key]; + const result = Reflect.deleteProperty(target, key); + if (result && hadKey) { + trigger2(target, "delete", key, void 0, oldValue); + } + return result; + } + function has(target, key) { + const result = Reflect.has(target, key); + if (!shared.isSymbol(key) || !builtInSymbols.has(key)) { + track2(target, "has", key); + } + return result; + } + function ownKeys(target) { + track2(target, "iterate", shared.isArray(target) ? "length" : ITERATE_KEY); + return Reflect.ownKeys(target); + } + var mutableHandlers = { + get: get2, + set: set2, + deleteProperty, + has, + ownKeys + }; + var readonlyHandlers = { + get: readonlyGet, + set(target, key) { + { + console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target); + } + return true; + }, + deleteProperty(target, key) { + { + console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target); + } + return true; + } + }; + var shallowReactiveHandlers = /* @__PURE__ */ shared.extend({}, mutableHandlers, { + get: shallowGet, + set: shallowSet + }); + var shallowReadonlyHandlers = /* @__PURE__ */ shared.extend({}, readonlyHandlers, { + get: shallowReadonlyGet + }); + var toReactive = (value) => shared.isObject(value) ? reactive3(value) : value; + var toReadonly = (value) => shared.isObject(value) ? readonly(value) : value; + var toShallow = (value) => value; + var getProto = (v) => Reflect.getPrototypeOf(v); + function get$1(target, key, isReadonly2 = false, isShallow = false) { + target = target["__v_raw"]; + const rawTarget = toRaw2(target); + const rawKey = toRaw2(key); + if (key !== rawKey) { + !isReadonly2 && track2(rawTarget, "get", key); + } + !isReadonly2 && track2(rawTarget, "get", rawKey); + const { has: has2 } = getProto(rawTarget); + const wrap = isShallow ? toShallow : isReadonly2 ? toReadonly : toReactive; + if (has2.call(rawTarget, key)) { + return wrap(target.get(key)); + } else if (has2.call(rawTarget, rawKey)) { + return wrap(target.get(rawKey)); + } else if (target !== rawTarget) { + target.get(key); + } + } + function has$1(key, isReadonly2 = false) { + const target = this["__v_raw"]; + const rawTarget = toRaw2(target); + const rawKey = toRaw2(key); + if (key !== rawKey) { + !isReadonly2 && track2(rawTarget, "has", key); + } + !isReadonly2 && track2(rawTarget, "has", rawKey); + return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey); + } + function size(target, isReadonly2 = false) { + target = target["__v_raw"]; + !isReadonly2 && track2(toRaw2(target), "iterate", ITERATE_KEY); + return Reflect.get(target, "size", target); + } + function add(value) { + value = toRaw2(value); + const target = toRaw2(this); + const proto = getProto(target); + const hadKey = proto.has.call(target, value); + if (!hadKey) { + target.add(value); + trigger2(target, "add", value, value); + } + return this; + } + function set$1(key, value) { + value = toRaw2(value); + const target = toRaw2(this); + const { has: has2, get: get3 } = getProto(target); + let hadKey = has2.call(target, key); + if (!hadKey) { + key = toRaw2(key); + hadKey = has2.call(target, key); + } else { + checkIdentityKeys(target, has2, key); + } + const oldValue = get3.call(target, key); + target.set(key, value); + if (!hadKey) { + trigger2(target, "add", key, value); + } else if (shared.hasChanged(value, oldValue)) { + trigger2(target, "set", key, value, oldValue); + } + return this; + } + function deleteEntry(key) { + const target = toRaw2(this); + const { has: has2, get: get3 } = getProto(target); + let hadKey = has2.call(target, key); + if (!hadKey) { + key = toRaw2(key); + hadKey = has2.call(target, key); + } else { + checkIdentityKeys(target, has2, key); + } + const oldValue = get3 ? get3.call(target, key) : void 0; + const result = target.delete(key); + if (hadKey) { + trigger2(target, "delete", key, void 0, oldValue); + } + return result; + } + function clear() { + const target = toRaw2(this); + const hadItems = target.size !== 0; + const oldTarget = shared.isMap(target) ? new Map(target) : new Set(target); + const result = target.clear(); + if (hadItems) { + trigger2(target, "clear", void 0, void 0, oldTarget); + } + return result; + } + function createForEach(isReadonly2, isShallow) { + return function forEach(callback, thisArg) { + const observed = this; + const target = observed["__v_raw"]; + const rawTarget = toRaw2(target); + const wrap = isShallow ? toShallow : isReadonly2 ? toReadonly : toReactive; + !isReadonly2 && track2(rawTarget, "iterate", ITERATE_KEY); + return target.forEach((value, key) => { + return callback.call(thisArg, wrap(value), wrap(key), observed); + }); + }; + } + function createIterableMethod(method, isReadonly2, isShallow) { + return function(...args) { + const target = this["__v_raw"]; + const rawTarget = toRaw2(target); + const targetIsMap = shared.isMap(rawTarget); + const isPair = method === "entries" || method === Symbol.iterator && targetIsMap; + const isKeyOnly = method === "keys" && targetIsMap; + const innerIterator = target[method](...args); + const wrap = isShallow ? toShallow : isReadonly2 ? toReadonly : toReactive; + !isReadonly2 && track2(rawTarget, "iterate", isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY); + return { + next() { + const { value, done } = innerIterator.next(); + return done ? { value, done } : { + value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value), + done + }; + }, + [Symbol.iterator]() { + return this; + } + }; + }; + } + function createReadonlyMethod(type) { + return function(...args) { + { + const key = args[0] ? `on key "${args[0]}" ` : ``; + console.warn(`${shared.capitalize(type)} operation ${key}failed: target is readonly.`, toRaw2(this)); + } + return type === "delete" ? false : this; + }; + } + function createInstrumentations() { + const mutableInstrumentations2 = { + get(key) { + return get$1(this, key); + }, + get size() { + return size(this); + }, + has: has$1, + add, + set: set$1, + delete: deleteEntry, + clear, + forEach: createForEach(false, false) + }; + const shallowInstrumentations2 = { + get(key) { + return get$1(this, key, false, true); + }, + get size() { + return size(this); + }, + has: has$1, + add, + set: set$1, + delete: deleteEntry, + clear, + forEach: createForEach(false, true) + }; + const readonlyInstrumentations2 = { + get(key) { + return get$1(this, key, true); + }, + get size() { + return size(this, true); + }, + has(key) { + return has$1.call(this, key, true); + }, + add: createReadonlyMethod( + "add" + ), + set: createReadonlyMethod( + "set" + ), + delete: createReadonlyMethod( + "delete" + ), + clear: createReadonlyMethod( + "clear" + ), + forEach: createForEach(true, false) + }; + const shallowReadonlyInstrumentations2 = { + get(key) { + return get$1(this, key, true, true); + }, + get size() { + return size(this, true); + }, + has(key) { + return has$1.call(this, key, true); + }, + add: createReadonlyMethod( + "add" + ), + set: createReadonlyMethod( + "set" + ), + delete: createReadonlyMethod( + "delete" + ), + clear: createReadonlyMethod( + "clear" + ), + forEach: createForEach(true, true) + }; + const iteratorMethods = ["keys", "values", "entries", Symbol.iterator]; + iteratorMethods.forEach((method) => { + mutableInstrumentations2[method] = createIterableMethod(method, false, false); + readonlyInstrumentations2[method] = createIterableMethod(method, true, false); + shallowInstrumentations2[method] = createIterableMethod(method, false, true); + shallowReadonlyInstrumentations2[method] = createIterableMethod(method, true, true); + }); + return [ + mutableInstrumentations2, + readonlyInstrumentations2, + shallowInstrumentations2, + shallowReadonlyInstrumentations2 + ]; + } + var [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* @__PURE__ */ createInstrumentations(); + function createInstrumentationGetter(isReadonly2, shallow) { + const instrumentations = shallow ? isReadonly2 ? shallowReadonlyInstrumentations : shallowInstrumentations : isReadonly2 ? readonlyInstrumentations : mutableInstrumentations; + return (target, key, receiver) => { + if (key === "__v_isReactive") { + return !isReadonly2; + } else if (key === "__v_isReadonly") { + return isReadonly2; + } else if (key === "__v_raw") { + return target; + } + return Reflect.get(shared.hasOwn(instrumentations, key) && key in target ? instrumentations : target, key, receiver); + }; + } + var mutableCollectionHandlers = { + get: /* @__PURE__ */ createInstrumentationGetter(false, false) + }; + var shallowCollectionHandlers = { + get: /* @__PURE__ */ createInstrumentationGetter(false, true) + }; + var readonlyCollectionHandlers = { + get: /* @__PURE__ */ createInstrumentationGetter(true, false) + }; + var shallowReadonlyCollectionHandlers = { + get: /* @__PURE__ */ createInstrumentationGetter(true, true) + }; + function checkIdentityKeys(target, has2, key) { + const rawKey = toRaw2(key); + if (rawKey !== key && has2.call(target, rawKey)) { + const type = shared.toRawType(target); + console.warn(`Reactive ${type} contains both the raw and reactive versions of the same object${type === `Map` ? ` as keys` : ``}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.`); + } + } + var reactiveMap = /* @__PURE__ */ new WeakMap(); + var shallowReactiveMap = /* @__PURE__ */ new WeakMap(); + var readonlyMap = /* @__PURE__ */ new WeakMap(); + var shallowReadonlyMap = /* @__PURE__ */ new WeakMap(); + function targetTypeMap(rawType) { + switch (rawType) { + case "Object": + case "Array": + return 1; + case "Map": + case "Set": + case "WeakMap": + case "WeakSet": + return 2; + default: + return 0; + } + } + function getTargetType(value) { + return value["__v_skip"] || !Object.isExtensible(value) ? 0 : targetTypeMap(shared.toRawType(value)); + } + function reactive3(target) { + if (target && target["__v_isReadonly"]) { + return target; + } + return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap); + } + function shallowReactive(target) { + return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap); + } + function readonly(target) { + return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap); + } + function shallowReadonly(target) { + return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap); + } + function createReactiveObject(target, isReadonly2, baseHandlers, collectionHandlers, proxyMap) { + if (!shared.isObject(target)) { + { + console.warn(`value cannot be made reactive: ${String(target)}`); + } + return target; + } + if (target["__v_raw"] && !(isReadonly2 && target["__v_isReactive"])) { + return target; + } + const existingProxy = proxyMap.get(target); + if (existingProxy) { + return existingProxy; + } + const targetType = getTargetType(target); + if (targetType === 0) { + return target; + } + const proxy = new Proxy(target, targetType === 2 ? collectionHandlers : baseHandlers); + proxyMap.set(target, proxy); + return proxy; + } + function isReactive2(value) { + if (isReadonly(value)) { + return isReactive2(value["__v_raw"]); + } + return !!(value && value["__v_isReactive"]); + } + function isReadonly(value) { + return !!(value && value["__v_isReadonly"]); + } + function isProxy(value) { + return isReactive2(value) || isReadonly(value); + } + function toRaw2(observed) { + return observed && toRaw2(observed["__v_raw"]) || observed; + } + function markRaw(value) { + shared.def(value, "__v_skip", true); + return value; + } + var convert = (val) => shared.isObject(val) ? reactive3(val) : val; + function isRef(r) { + return Boolean(r && r.__v_isRef === true); + } + function ref(value) { + return createRef(value); + } + function shallowRef(value) { + return createRef(value, true); + } + var RefImpl = class { + constructor(value, _shallow = false) { + this._shallow = _shallow; + this.__v_isRef = true; + this._rawValue = _shallow ? value : toRaw2(value); + this._value = _shallow ? value : convert(value); + } + get value() { + track2(toRaw2(this), "get", "value"); + return this._value; + } + set value(newVal) { + newVal = this._shallow ? newVal : toRaw2(newVal); + if (shared.hasChanged(newVal, this._rawValue)) { + this._rawValue = newVal; + this._value = this._shallow ? newVal : convert(newVal); + trigger2(toRaw2(this), "set", "value", newVal); + } + } + }; + function createRef(rawValue, shallow = false) { + if (isRef(rawValue)) { + return rawValue; + } + return new RefImpl(rawValue, shallow); + } + function triggerRef(ref2) { + trigger2(toRaw2(ref2), "set", "value", ref2.value); + } + function unref(ref2) { + return isRef(ref2) ? ref2.value : ref2; + } + var shallowUnwrapHandlers = { + get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)), + set: (target, key, value, receiver) => { + const oldValue = target[key]; + if (isRef(oldValue) && !isRef(value)) { + oldValue.value = value; + return true; + } else { + return Reflect.set(target, key, value, receiver); + } + } + }; + function proxyRefs(objectWithRefs) { + return isReactive2(objectWithRefs) ? objectWithRefs : new Proxy(objectWithRefs, shallowUnwrapHandlers); + } + var CustomRefImpl = class { + constructor(factory) { + this.__v_isRef = true; + const { get: get3, set: set3 } = factory(() => track2(this, "get", "value"), () => trigger2(this, "set", "value")); + this._get = get3; + this._set = set3; + } + get value() { + return this._get(); + } + set value(newVal) { + this._set(newVal); + } + }; + function customRef(factory) { + return new CustomRefImpl(factory); + } + function toRefs(object) { + if (!isProxy(object)) { + console.warn(`toRefs() expects a reactive object but received a plain one.`); + } + const ret = shared.isArray(object) ? new Array(object.length) : {}; + for (const key in object) { + ret[key] = toRef(object, key); + } + return ret; + } + var ObjectRefImpl = class { + constructor(_object, _key) { + this._object = _object; + this._key = _key; + this.__v_isRef = true; + } + get value() { + return this._object[this._key]; + } + set value(newVal) { + this._object[this._key] = newVal; + } + }; + function toRef(object, key) { + return isRef(object[key]) ? object[key] : new ObjectRefImpl(object, key); + } + var ComputedRefImpl = class { + constructor(getter, _setter, isReadonly2) { + this._setter = _setter; + this._dirty = true; + this.__v_isRef = true; + this.effect = effect3(getter, { + lazy: true, + scheduler: () => { + if (!this._dirty) { + this._dirty = true; + trigger2(toRaw2(this), "set", "value"); + } + } + }); + this["__v_isReadonly"] = isReadonly2; + } + get value() { + const self2 = toRaw2(this); + if (self2._dirty) { + self2._value = this.effect(); + self2._dirty = false; + } + track2(self2, "get", "value"); + return self2._value; + } + set value(newValue) { + this._setter(newValue); + } + }; + function computed(getterOrOptions) { + let getter; + let setter; + if (shared.isFunction(getterOrOptions)) { + getter = getterOrOptions; + setter = () => { + console.warn("Write operation failed: computed value is readonly"); + }; + } else { + getter = getterOrOptions.get; + setter = getterOrOptions.set; + } + return new ComputedRefImpl(getter, setter, shared.isFunction(getterOrOptions) || !getterOrOptions.set); + } + exports2.ITERATE_KEY = ITERATE_KEY; + exports2.computed = computed; + exports2.customRef = customRef; + exports2.effect = effect3; + exports2.enableTracking = enableTracking; + exports2.isProxy = isProxy; + exports2.isReactive = isReactive2; + exports2.isReadonly = isReadonly; + exports2.isRef = isRef; + exports2.markRaw = markRaw; + exports2.pauseTracking = pauseTracking; + exports2.proxyRefs = proxyRefs; + exports2.reactive = reactive3; + exports2.readonly = readonly; + exports2.ref = ref; + exports2.resetTracking = resetTracking; + exports2.shallowReactive = shallowReactive; + exports2.shallowReadonly = shallowReadonly; + exports2.shallowRef = shallowRef; + exports2.stop = stop2; + exports2.toRaw = toRaw2; + exports2.toRef = toRef; + exports2.toRefs = toRefs; + exports2.track = track2; + exports2.trigger = trigger2; + exports2.triggerRef = triggerRef; + exports2.unref = unref; + } + }); + var require_reactivity = __commonJS2({ + "node_modules/@vue/reactivity/index.js"(exports2, module2) { + "use strict"; + if (false) { + module2.exports = null; + } else { + module2.exports = require_reactivity_cjs(); + } + } + }); + var module_exports = {}; + __export(module_exports, { + Alpine: () => src_default2, + default: () => module_default2 + }); + module.exports = __toCommonJS(module_exports); + var flushPending = false; + var flushing = false; + var queue = []; + var lastFlushedIndex = -1; + var transactionActive = false; + function scheduler(callback) { + queueJob(callback); + } + function startTransaction() { + transactionActive = true; + } + function commitTransaction() { + transactionActive = false; + queueFlush(); + } + function queueJob(job) { + if (!queue.includes(job)) + queue.push(job); + queueFlush(); + } + function dequeueJob(job) { + let index = queue.indexOf(job); + if (index !== -1 && index > lastFlushedIndex) + queue.splice(index, 1); + } + function queueFlush() { + if (!flushing && !flushPending) { + if (transactionActive) + return; + flushPending = true; + queueMicrotask(flushJobs); + } + } + function flushJobs() { + flushPending = false; + flushing = true; + for (let i = 0; i < queue.length; i++) { + queue[i](); + lastFlushedIndex = i; + } + queue.length = 0; + lastFlushedIndex = -1; + flushing = false; + } + var reactive; + var effect; + var release; + var raw; + var shouldSchedule = true; + function disableEffectScheduling(callback) { + shouldSchedule = false; + callback(); + shouldSchedule = true; + } + function setReactivityEngine(engine) { + reactive = engine.reactive; + release = engine.release; + effect = (callback) => engine.effect(callback, { scheduler: (task) => { + if (shouldSchedule) { + scheduler(task); + } else { + task(); + } + } }); + raw = engine.raw; + } + function overrideEffect(override) { + effect = override; + } + function elementBoundEffect(el) { + let cleanup = () => { + }; + let wrappedEffect = (callback) => { + let effectReference = effect(callback); + if (!el._x_effects) { + el._x_effects = /* @__PURE__ */ new Set(); + el._x_runEffects = () => { + el._x_effects.forEach((i) => i()); + }; + } + el._x_effects.add(effectReference); + cleanup = () => { + if (effectReference === void 0) + return; + el._x_effects.delete(effectReference); + release(effectReference); + }; + return effectReference; + }; + return [wrappedEffect, () => { + cleanup(); + }]; + } + function watch(getter, callback) { + let firstTime = true; + let oldValue; + let oldValueJSON; + let effectReference = effect(() => { + let value = getter(); + let newJSON = JSON.stringify(value); + if (!firstTime) { + if (typeof value === "object" || value !== oldValue) { + let previousValue = typeof oldValue === "object" ? JSON.parse(oldValueJSON) : oldValue; + queueMicrotask(() => { + callback(value, previousValue); + }); + } + } + oldValue = value; + oldValueJSON = newJSON; + firstTime = false; + }); + return () => release(effectReference); + } + async function transaction(callback) { + startTransaction(); + try { + await callback(); + await Promise.resolve(); + } finally { + commitTransaction(); + } + } + var onAttributeAddeds = []; + var onElRemoveds = []; + var onElAddeds = []; + function onElAdded(callback) { + onElAddeds.push(callback); + } + function onElRemoved(el, callback) { + if (typeof callback === "function") { + if (!el._x_cleanups) + el._x_cleanups = []; + el._x_cleanups.push(callback); + } else { + callback = el; + onElRemoveds.push(callback); + } + } + function onAttributesAdded(callback) { + onAttributeAddeds.push(callback); + } + function onAttributeRemoved(el, name, callback) { + if (!el._x_attributeCleanups) + el._x_attributeCleanups = {}; + if (!el._x_attributeCleanups[name]) + el._x_attributeCleanups[name] = []; + el._x_attributeCleanups[name].push(callback); + } + function cleanupAttributes(el, names) { + if (!el._x_attributeCleanups) + return; + Object.entries(el._x_attributeCleanups).forEach(([name, value]) => { + if (names === void 0 || names.includes(name)) { + value.forEach((i) => i()); + delete el._x_attributeCleanups[name]; + } + }); + } + function cleanupElement(el) { + var _a, _b; + (_a = el._x_effects) == null ? void 0 : _a.forEach(dequeueJob); + while ((_b = el._x_cleanups) == null ? void 0 : _b.length) + el._x_cleanups.pop()(); + } + var observer = new MutationObserver(onMutate); + var currentlyObserving = false; + function startObservingMutations() { + observer.observe(document, { subtree: true, childList: true, attributes: true, attributeOldValue: true }); + currentlyObserving = true; + } + function stopObservingMutations() { + flushObserver(); + observer.disconnect(); + currentlyObserving = false; + } + var queuedMutations = []; + function flushObserver() { + let records = observer.takeRecords(); + queuedMutations.push(() => records.length > 0 && onMutate(records)); + let queueLengthWhenTriggered = queuedMutations.length; + queueMicrotask(() => { + if (queuedMutations.length === queueLengthWhenTriggered) { + while (queuedMutations.length > 0) + queuedMutations.shift()(); + } + }); + } + function mutateDom(callback) { + if (!currentlyObserving) + return callback(); + stopObservingMutations(); + let result = callback(); + startObservingMutations(); + return result; + } + var isCollecting = false; + var deferredMutations = []; + function deferMutations() { + isCollecting = true; + } + function flushAndStopDeferringMutations() { + isCollecting = false; + onMutate(deferredMutations); + deferredMutations = []; + } + function onMutate(mutations) { + if (isCollecting) { + deferredMutations = deferredMutations.concat(mutations); + return; + } + let addedNodes = []; + let removedNodes = /* @__PURE__ */ new Set(); + let addedAttributes = /* @__PURE__ */ new Map(); + let removedAttributes = /* @__PURE__ */ new Map(); + for (let i = 0; i < mutations.length; i++) { + if (mutations[i].target._x_ignoreMutationObserver) + continue; + if (mutations[i].type === "childList") { + mutations[i].removedNodes.forEach((node) => { + if (node.nodeType !== 1) + return; + if (!node._x_marker) + return; + removedNodes.add(node); + }); + mutations[i].addedNodes.forEach((node) => { + if (node.nodeType !== 1) + return; + if (removedNodes.has(node)) { + removedNodes.delete(node); + return; + } + if (node._x_marker) + return; + addedNodes.push(node); + }); + } + if (mutations[i].type === "attributes") { + let el = mutations[i].target; + let name = mutations[i].attributeName; + let oldValue = mutations[i].oldValue; + let add = () => { + if (!addedAttributes.has(el)) + addedAttributes.set(el, []); + addedAttributes.get(el).push({ name, value: el.getAttribute(name) }); + }; + let remove = () => { + if (!removedAttributes.has(el)) + removedAttributes.set(el, []); + removedAttributes.get(el).push(name); + }; + if (el.hasAttribute(name) && oldValue === null) { + add(); + } else if (el.hasAttribute(name)) { + remove(); + add(); + } else { + remove(); + } + } + } + removedAttributes.forEach((attrs, el) => { + cleanupAttributes(el, attrs); + }); + addedAttributes.forEach((attrs, el) => { + onAttributeAddeds.forEach((i) => i(el, attrs)); + }); + for (let node of removedNodes) { + if (addedNodes.some((i) => i.contains(node))) + continue; + onElRemoveds.forEach((i) => i(node)); + } + for (let node of addedNodes) { + if (!node.isConnected) + continue; + onElAddeds.forEach((i) => i(node)); + } + addedNodes = null; + removedNodes = null; + addedAttributes = null; + removedAttributes = null; + } + function scope(node) { + return mergeProxies(closestDataStack(node)); + } + function addScopeToNode(node, data2, referenceNode) { + node._x_dataStack = [data2, ...closestDataStack(referenceNode || node)]; + return () => { + node._x_dataStack = node._x_dataStack.filter((i) => i !== data2); + }; + } + function closestDataStack(node) { + if (node._x_dataStack) + return node._x_dataStack; + if (typeof ShadowRoot === "function" && node instanceof ShadowRoot) { + return closestDataStack(node.host); + } + if (!node.parentNode) { + return []; + } + return closestDataStack(node.parentNode); + } + function mergeProxies(objects) { + return new Proxy({ objects }, mergeProxyTrap); + } + function keyInPrototypeChain(obj, key) { + if (obj === null || obj === Object.prototype) + return null; + if (Object.prototype.hasOwnProperty.call(obj, key)) + return obj; + return keyInPrototypeChain(Object.getPrototypeOf(obj), key); + } + var mergeProxyTrap = { + ownKeys({ objects }) { + return Array.from( + new Set(objects.flatMap((i) => Object.keys(i))) + ); + }, + has({ objects }, name) { + if (name == Symbol.unscopables) + return false; + return objects.some( + (obj) => Object.prototype.hasOwnProperty.call(obj, name) || Reflect.has(obj, name) + ); + }, + get({ objects }, name, thisProxy) { + if (name == "toJSON") + return collapseProxies; + return Reflect.get( + objects.find( + (obj) => Reflect.has(obj, name) + ) || {}, + name, + thisProxy + ); + }, + set({ objects }, name, value, thisProxy) { + let target; + for (const obj of objects) { + target = keyInPrototypeChain(obj, name); + if (target) + break; + } + if (!target) + target = objects[objects.length - 1]; + const descriptor = Object.getOwnPropertyDescriptor(target, name); + if ((descriptor == null ? void 0 : descriptor.set) && (descriptor == null ? void 0 : descriptor.get)) + return descriptor.set.call(thisProxy, value) || true; + return Reflect.set(target, name, value); + } + }; + function collapseProxies() { + let keys = Reflect.ownKeys(this); + return keys.reduce((acc, key) => { + acc[key] = Reflect.get(this, key); + return acc; + }, {}); + } + function initInterceptors(data2) { + let isObject22 = (val) => typeof val === "object" && !Array.isArray(val) && val !== null; + let recurse = (obj, basePath = "") => { + Object.entries(Object.getOwnPropertyDescriptors(obj)).forEach(([key, { value, enumerable }]) => { + if (enumerable === false || value === void 0) + return; + if (typeof value === "object" && value !== null && value.__v_skip) + return; + let path = basePath === "" ? key : `${basePath}.${key}`; + if (typeof value === "object" && value !== null && value._x_interceptor) { + obj[key] = value.initialize(data2, path, key); + } else { + if (isObject22(value) && value !== obj && !(value instanceof Element)) { + recurse(value, path); + } + } + }); + }; + return recurse(data2); + } + function interceptor(callback, mutateObj = () => { + }) { + let obj = { + initialValue: void 0, + _x_interceptor: true, + initialize(data2, path, key) { + return callback(this.initialValue, () => get(data2, path), (value) => set(data2, path, value), path, key); + } + }; + mutateObj(obj); + return (initialValue) => { + if (typeof initialValue === "object" && initialValue !== null && initialValue._x_interceptor) { + let initialize = obj.initialize.bind(obj); + obj.initialize = (data2, path, key) => { + let innerValue = initialValue.initialize(data2, path, key); + obj.initialValue = innerValue; + return initialize(data2, path, key); + }; + } else { + obj.initialValue = initialValue; + } + return obj; + }; + } + function get(obj, path) { + return path.split(".").reduce((carry, segment) => carry[segment], obj); + } + function set(obj, path, value) { + if (typeof path === "string") + path = path.split("."); + if (path.length === 1) + obj[path[0]] = value; + else if (path.length === 0) + throw error; + else { + if (obj[path[0]]) + return set(obj[path[0]], path.slice(1), value); + else { + obj[path[0]] = {}; + return set(obj[path[0]], path.slice(1), value); + } + } + } + var magics = {}; + function magic(name, callback) { + magics[name] = callback; + } + function injectMagics(obj, el) { + let memoizedUtilities = getUtilities(el); + Object.entries(magics).forEach(([name, callback]) => { + Object.defineProperty(obj, `$${name}`, { + get() { + return callback(el, memoizedUtilities); + }, + enumerable: false + }); + }); + return obj; + } + function getUtilities(el) { + let [utilities, cleanup] = getElementBoundUtilities(el); + let utils = { interceptor, ...utilities }; + onElRemoved(el, cleanup); + return utils; + } + function tryCatch(el, expression, callback, ...args) { + try { + return callback(...args); + } catch (e) { + handleError(e, el, expression); + } + } + function handleError(...args) { + return errorHandler(...args); + } + var errorHandler = normalErrorHandler; + function setErrorHandler(handler4) { + errorHandler = handler4; + } + function normalErrorHandler(error2, el, expression = void 0) { + error2 = Object.assign( + error2 != null ? error2 : { message: "No error message given." }, + { el, expression } + ); + console.warn(`Alpine Expression Error: ${error2.message} + +${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); + setTimeout(() => { + throw error2; + }, 0); + } + var shouldAutoEvaluateFunctions = true; + function dontAutoEvaluateFunctions(callback) { + let cache = shouldAutoEvaluateFunctions; + shouldAutoEvaluateFunctions = false; + let result = callback(); + shouldAutoEvaluateFunctions = cache; + return result; + } + function evaluate(el, expression, extras = {}) { + let result; + evaluateLater(el, expression)((value) => result = value, extras); + return result; + } + function evaluateLater(...args) { + return theEvaluatorFunction(...args); + } + var theEvaluatorFunction = () => { + }; + function setEvaluator(newEvaluator) { + theEvaluatorFunction = newEvaluator; + } + var theRawEvaluatorFunction; + function setRawEvaluator(newEvaluator) { + theRawEvaluatorFunction = newEvaluator; + } + function generateEvaluatorFromFunction(dataStack, func) { + return (receiver = () => { + }, { scope: scope2 = {}, params = [], context } = {}) => { + if (!shouldAutoEvaluateFunctions) { + runIfTypeOfFunction(receiver, func, mergeProxies([scope2, ...dataStack]), params); + return; + } + let result = func.apply(mergeProxies([scope2, ...dataStack]), params); + runIfTypeOfFunction(receiver, result); + }; + } + function runIfTypeOfFunction(receiver, value, scope2, params, el) { + if (shouldAutoEvaluateFunctions && typeof value === "function") { + let result = value.apply(scope2, params); + if (result instanceof Promise) { + result.then((i) => runIfTypeOfFunction(receiver, i, scope2, params)).catch((error2) => handleError(error2, el, value)); + } else { + receiver(result); + } + } else if (typeof value === "object" && value instanceof Promise) { + value.then((i) => receiver(i)); + } else { + receiver(value); + } + } + function evaluateRaw(...args) { + return theRawEvaluatorFunction(...args); + } + var prefixAsString = "x-"; + function prefix(subject = "") { + return prefixAsString + subject; + } + function setPrefix(newPrefix) { + prefixAsString = newPrefix; + } + var directiveHandlers = {}; + function directive2(name, callback) { + directiveHandlers[name] = callback; + return { + before(directive22) { + if (!directiveHandlers[directive22]) { + console.warn(String.raw`Cannot find directive \`${directive22}\`. \`${name}\` will use the default order of execution`); + return; + } + const pos = directiveOrder.indexOf(directive22); + directiveOrder.splice(pos >= 0 ? pos : directiveOrder.indexOf("DEFAULT"), 0, name); + } + }; + } + function directiveExists(name) { + return Object.keys(directiveHandlers).includes(name); + } + function directives(el, attributes, originalAttributeOverride) { + attributes = Array.from(attributes); + if (el._x_virtualDirectives) { + let vAttributes = Object.entries(el._x_virtualDirectives).map(([name, value]) => ({ name, value })); + let staticAttributes = attributesOnly(vAttributes); + vAttributes = vAttributes.map((attribute) => { + if (staticAttributes.find((attr) => attr.name === attribute.name)) { + return { + name: `x-bind:${attribute.name}`, + value: `"${attribute.value}"` + }; + } + return attribute; + }); + attributes = attributes.concat(vAttributes); + } + let transformedAttributeMap = {}; + let directives2 = attributes.map(toTransformedAttributes((newName, oldName) => transformedAttributeMap[newName] = oldName)).filter(outNonAlpineAttributes).map(toParsedDirectives(transformedAttributeMap, originalAttributeOverride)).sort(byPriority); + return directives2.map((directive22) => { + return getDirectiveHandler(el, directive22); + }); + } + function attributesOnly(attributes) { + return Array.from(attributes).map(toTransformedAttributes()).filter((attr) => !outNonAlpineAttributes(attr)); + } + var isDeferringHandlers = false; + var directiveHandlerStacks = /* @__PURE__ */ new Map(); + var currentHandlerStackKey = Symbol(); + function deferHandlingDirectives(callback) { + isDeferringHandlers = true; + let key = Symbol(); + currentHandlerStackKey = key; + directiveHandlerStacks.set(key, []); + let flushHandlers = () => { + while (directiveHandlerStacks.get(key).length) + directiveHandlerStacks.get(key).shift()(); + directiveHandlerStacks.delete(key); + }; + let stopDeferring = () => { + isDeferringHandlers = false; + flushHandlers(); + }; + callback(flushHandlers); + stopDeferring(); + } + function getElementBoundUtilities(el) { + let cleanups2 = []; + let cleanup = (callback) => cleanups2.push(callback); + let [effect3, cleanupEffect] = elementBoundEffect(el); + cleanups2.push(cleanupEffect); + let utilities = { + Alpine: alpine_default, + effect: effect3, + cleanup, + evaluateLater: evaluateLater.bind(evaluateLater, el), + evaluate: evaluate.bind(evaluate, el) + }; + let doCleanup = () => cleanups2.forEach((i) => i()); + return [utilities, doCleanup]; + } + function getDirectiveHandler(el, directive22) { + let noop = () => { + }; + let handler4 = directiveHandlers[directive22.type] || noop; + let [utilities, cleanup] = getElementBoundUtilities(el); + onAttributeRemoved(el, directive22.original, cleanup); + let fullHandler = () => { + if (el._x_ignore || el._x_ignoreSelf) + return; + handler4.inline && handler4.inline(el, directive22, utilities); + handler4 = handler4.bind(handler4, el, directive22, utilities); + isDeferringHandlers ? directiveHandlerStacks.get(currentHandlerStackKey).push(handler4) : handler4(); + }; + fullHandler.runCleanups = cleanup; + return fullHandler; + } + var startingWith = (subject, replacement) => ({ name, value }) => { + if (name.startsWith(subject)) + name = name.replace(subject, replacement); + return { name, value }; + }; + var into = (i) => i; + function toTransformedAttributes(callback = () => { + }) { + return ({ name, value }) => { + let { name: newName, value: newValue } = attributeTransformers.reduce((carry, transform) => { + return transform(carry); + }, { name, value }); + if (newName !== name) + callback(newName, name); + return { name: newName, value: newValue }; + }; + } + var attributeTransformers = []; + function mapAttributes(callback) { + attributeTransformers.push(callback); + } + function outNonAlpineAttributes({ name }) { + return alpineAttributeRegex().test(name); + } + var alpineAttributeRegex = () => new RegExp(`^${prefixAsString}([^:^.]+)\\b`); + function toParsedDirectives(transformedAttributeMap, originalAttributeOverride) { + return ({ name, value }) => { + if (name === value) + value = ""; + let typeMatch = name.match(alpineAttributeRegex()); + let valueMatch = name.match(/:([a-zA-Z0-9\-_:]+)/); + let modifiers = name.match(/\.[^.\]]+(?=[^\]]*$)/g) || []; + let original = originalAttributeOverride || transformedAttributeMap[name] || name; + return { + type: typeMatch ? typeMatch[1] : null, + value: valueMatch ? valueMatch[1] : null, + modifiers: modifiers.map((i) => i.replace(".", "")), + expression: value, + original + }; + }; + } + var DEFAULT = "DEFAULT"; + var directiveOrder = [ + "ignore", + "ref", + "id", + "data", + "anchor", + "bind", + "init", + "for", + "model", + "modelable", + "transition", + "show", + "if", + DEFAULT, + "teleport" + ]; + function byPriority(a, b) { + let typeA = directiveOrder.indexOf(a.type) === -1 ? DEFAULT : a.type; + let typeB = directiveOrder.indexOf(b.type) === -1 ? DEFAULT : b.type; + return directiveOrder.indexOf(typeA) - directiveOrder.indexOf(typeB); + } + function dispatch3(el, name, detail = {}, options = {}) { + return el.dispatchEvent( + new CustomEvent(name, { + detail, + bubbles: true, + composed: true, + cancelable: true, + ...options + }) + ); + } + function walk(el, callback) { + if (typeof ShadowRoot === "function" && el instanceof ShadowRoot) { + Array.from(el.children).forEach((el2) => walk(el2, callback)); + return; + } + let skip = false; + callback(el, () => skip = true); + if (skip) + return; + let node = el.firstElementChild; + while (node) { + walk(node, callback, false); + node = node.nextElementSibling; + } + } + function warn(message, ...args) { + console.warn(`Alpine Warning: ${message}`, ...args); + } + var started = false; + function start2() { + if (started) + warn("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."); + started = true; + if (!document.body) + warn("Unable to initialize. Trying to load Alpine before `
` is available. Did you forget to add `defer` in Alpine's `