commit d4fd478e1ff2d98884066105adcbd9ae94caef15 Author: debesocial Date: Thu May 21 15:57:29 2026 +0700 feat: inisialisasi project kit v2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d869bea --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +/node_modules +/vendor +/.env +/.env.backup +/.env.production +/storage/*.key +/storage/framework/cache/data/* +/storage/framework/sessions/* +/storage/framework/testing/* +/storage/framework/views/* +/storage/logs/* +.phpunit.result.cache +npm-debug.log +yarn-error.log +.idea/ +.vscode/ +Homestead.json +Homestead.yaml +auth.json +.phpunit.cache diff --git a/README.md b/README.md new file mode 100644 index 0000000..c8bc42c --- /dev/null +++ b/README.md @@ -0,0 +1,145 @@ +# biiproject kit + +A production-ready Laravel + Inertia.js starter kit with full RBAC, API auth, activity logging, and system settings — built to ship fast. + +## Stack + +| Layer | Technology | +|---|---| +| Backend | Laravel 13, PHP 8.3, PostgreSQL | +| Frontend | React 18, TypeScript, TailwindCSS v4, Vite 8 | +| Bridge | Inertia.js v2 | +| Auth | Breeze (web session) + Sanctum (API token) + Passport (OAuth2/SSO) | +| RBAC | spatie/laravel-permission | +| Logging | spatie/laravel-activitylog | +| Export/Import | maatwebsite/excel | +| API Docs | knuckleswtf/scribe | + +## Quick Start + +This project is fully containerized and features an automated startup script. + +With **Docker** running on your machine, simply execute the following command at the root of the project: + +```bash +./run.sh +``` + +This script will completely automate the setup by: +1. Creating a `.env` file from `.env.example` (if it does not exist yet). +2. Starting the PostgreSQL and Redis containers in the background. +3. Installing Composer dependencies. +4. Generating the application encryption key. +5. Running all database migrations and seeding the default accounts. +6. Installing Node.js (NPM) frontend dependencies. +7. Starting the development server (`php artisan serve` + `Vite` + queue listeners + logs) concurrently. + +--- + +### Manual Setup (Without Automation Script) + +If you prefer to perform the setup manually: + +1. **Spin up database & cache services:** + ```bash + docker compose up -d + ``` +2. **Install backend dependencies:** + ```bash + composer install + ``` +3. **Setup environment configuration:** + ```bash + cp .env.example .env + php artisan key:generate + ``` +4. **Run migrations and seed default users:** + ```bash + php artisan migrate --seed + ``` +5. **Install frontend dependencies & start dev server:** + ```bash + npm install + composer dev + ``` + + +## Default Credentials + +| Role | Email | Password | +|---|---|---| +| super-admin | superadmin@biiskit.com | password | +| admin | admin@biiskit.com | password | +| user | user@biiskit.com | password | + +## Roles & Permissions + +| Permission | super-admin | admin | user | +|---|:---:|:---:|:---:| +| user.view | ✓ | ✓ | ✓ | +| user.create | ✓ | ✓ | — | +| user.edit | ✓ | ✓ | — | +| user.delete | ✓ | ✓ | — | +| role.view | ✓ | ✓ | — | +| role.manage | ✓ | ✓ | — | +| settings.manage | ✓ | — | — | + +`super-admin` bypasses all checks via `Gate::before`. + +## Features + +- **User Management** — CRUD, soft delete, restore, bulk export/import (Excel/CSV), avatar upload +- **Role & Permission Management** — Assign roles, fine-grained permission matrix UI +- **Activity Logs** — Auto-logged actions via spatie/activitylog, filterable, clearable +- **Notifications** — Admin broadcast notifications with read/unread tracking +- **Two-Factor Auth** — TOTP 2FA (Google Authenticator compatible), enable/disable per user via Account Settings, recovery codes, full login challenge flow +- **Account Settings** — Profile, avatar, phone, bio, password change, 2FA management, account deletion — with tab state persisted in URL hash +- **System Settings** — App name, branding, mail/SMTP, OAuth (Google/GitHub), password rules, mobile app version gate — stored in DB, cached; super-admin only +- **Remote Config** — Mobile app version gate (`GET /api/v1/app/config?platform=android`) +- **Branded Error Pages** — Inertia-rendered 403, 404, 419, 500, 503 +- **API** — Versioned REST API (`/api/v1/*`) with Sanctum token auth + rate limiting +- **OAuth2/SSO** — Laravel Passport endpoints for third-party app integration +- **In-app Documentation** — Full feature docs at `/documentation` (accessible via sidebar) + +## Environment Variables + +Key variables beyond the Laravel defaults: + +```env +# Mail (overridable via System Settings UI) +MAIL_MAILER=smtp +MAIL_HOST= +MAIL_PORT=587 +MAIL_USERNAME= +MAIL_PASSWORD= + +# OAuth (Passport) +PASSPORT_PERSONAL_ACCESS_CLIENT_ID= +PASSPORT_PERSONAL_ACCESS_CLIENT_SECRET= +``` + +## API Endpoints (v1) + +| Method | Endpoint | Auth | Description | +|---|---|---|---| +| POST | `/api/v1/login` | — | Get Bearer token (rate-limited: 10/min) | +| POST | `/api/v1/logout` | Bearer | Revoke token | +| GET | `/api/v1/me` | Bearer | Authenticated user with roles & permissions | +| GET | `/api/v1/users` | Bearer | List users (paginated, sortable, filterable) | +| POST | `/api/v1/users` | Bearer | Create user | +| GET | `/api/v1/users/{id}` | Bearer | Get user | +| PATCH | `/api/v1/users/{id}` | Bearer | Update user | +| DELETE | `/api/v1/users/{id}` | Bearer | Soft-delete user | +| POST | `/api/v1/users/{id}/restore` | Bearer | Restore user | +| DELETE | `/api/v1/users/{id}/force` | Bearer | Permanent delete | +| GET | `/api/v1/app-config` | — | Mobile remote config | + +Full interactive docs: `GET /documentation` + +## Running Tests + +```bash +php artisan test +# or with coverage: +php artisan test --coverage +``` diff --git a/app/Actions/Auth/LoginAction.php b/app/Actions/Auth/LoginAction.php new file mode 100644 index 0000000..6b79325 --- /dev/null +++ b/app/Actions/Auth/LoginAction.php @@ -0,0 +1,37 @@ +first(); + + if (!$user || !Hash::check($credentials['password'], $user->password)) { + throw ValidationException::withMessages([ + 'email' => [__('auth.failed')], + ]); + } + + $token = $user->createToken('auth_token')->plainTextToken; + + return [ + 'user' => $user, + 'token' => $token, + 'roles' => $user->getRoleNames(), + 'permissions' => $user->getAllPermissions()->pluck('name'), + ]; + } +} diff --git a/app/Actions/Users/CreateUserAction.php b/app/Actions/Users/CreateUserAction.php new file mode 100644 index 0000000..77d7e2c --- /dev/null +++ b/app/Actions/Users/CreateUserAction.php @@ -0,0 +1,33 @@ + $data['firstName'], + 'last_name' => $data['lastName'], + 'email' => $data['email'], + 'password' => Hash::make($data['password']), + 'status' => $data['status'] ?? 'active', + 'meta' => $data['meta'] ?? [], + ]); + + if (isset($data['roles'])) { + $user->assignRole($data['roles']); + } + + return $user; + } +} diff --git a/app/Exports/UsersExport.php b/app/Exports/UsersExport.php new file mode 100644 index 0000000..e1b6777 --- /dev/null +++ b/app/Exports/UsersExport.php @@ -0,0 +1,40 @@ +id, + $user->first_name, + $user->last_name, + $user->email, + $user->status, + $user->created_at->toDateTimeString(), + ]; + } +} diff --git a/app/Http/Controllers/ActivityLogController.php b/app/Http/Controllers/ActivityLogController.php new file mode 100644 index 0000000..97cd0f9 --- /dev/null +++ b/app/Http/Controllers/ActivityLogController.php @@ -0,0 +1,69 @@ +authorize('user.view'); + + $search = $request->input('search'); + $logName = $request->input('log_name'); + $event = $request->input('event'); + $perPage = (int) $request->input('per_page', 15); + + $query = Activity::with('causer')->latest(); + + if ($search) { + $query->where(function ($q) use ($search) { + $q->where('description', 'like', "%{$search}%") + ->orWhere('log_name', 'like', "%{$search}%"); + }); + } + + if ($logName) { + $query->where('log_name', $logName); + } + + if ($event) { + $query->where('event', $event); + } + + $activities = $query->paginate($perPage)->withQueryString(); + + $logNames = Activity::distinct()->pluck('log_name'); + $events = Activity::distinct()->whereNotNull('event')->pluck('event'); + + return Inertia::render('ActivityLogs/Index', [ + 'activities' => [ + 'data' => $activities->items(), + 'meta' => [ + 'current_page' => $activities->currentPage(), + 'last_page' => $activities->lastPage(), + 'total' => $activities->total(), + 'per_page' => $activities->perPage(), + ], + 'links' => $activities->linkCollection()->toArray(), + ], + 'filters' => $request->only(['search', 'log_name', 'event', 'per_page']), + 'availableLogNames' => $logNames, + 'availableEvents' => $events, + ]); + } + + public function bulkDelete(Request $request) + { + $this->authorize('user.delete'); + + $ids = (array) $request->input('ids', []); + + Activity::whereIn('id', $ids)->delete(); + + return back()->with('success', \count($ids) . ' logs deleted successfully.'); + } +} diff --git a/app/Http/Controllers/Api/V1/AppConfigController.php b/app/Http/Controllers/Api/V1/AppConfigController.php new file mode 100644 index 0000000..ac503be --- /dev/null +++ b/app/Http/Controllers/Api/V1/AppConfigController.php @@ -0,0 +1,69 @@ +input('platform', 'android'); + if (!\in_array($platform, ['android', 'ios'], true)) { + $platform = 'android'; + } + + $settings = Cache::get('system_settings', function () { + try { + return Setting::pluck('value', 'key')->toArray(); + } catch (\Throwable) { + return []; + } + }); + + if ($platform === 'android') { + $maintenance = filter_var($settings['android_maintenance_mode'] ?? false, FILTER_VALIDATE_BOOLEAN); + + if ($maintenance) { + return response()->json([ + 'maintenance' => true, + 'message' => 'The app is temporarily under maintenance. Please try again later.', + ], 503); + } + + return response()->json([ + 'maintenance' => false, + 'latest_version' => $settings['android_latest_version'] ?? '1.0.0', + 'min_version' => $settings['android_min_version'] ?? '1.0.0', + 'store_url' => $settings['android_playstore_url'] ?? null, + 'platform' => 'android', + ]); + } + + // ios — placeholder using same pattern, expandable when ios settings are added + return response()->json([ + 'maintenance' => false, + 'latest_version' => $settings['ios_latest_version'] ?? '1.0.0', + 'min_version' => $settings['ios_min_version'] ?? '1.0.0', + 'store_url' => $settings['ios_appstore_url'] ?? null, + 'platform' => 'ios', + ]); + } +} diff --git a/app/Http/Controllers/Api/V1/AuthController.php b/app/Http/Controllers/Api/V1/AuthController.php new file mode 100644 index 0000000..4a811da --- /dev/null +++ b/app/Http/Controllers/Api/V1/AuthController.php @@ -0,0 +1,63 @@ +validate([ + 'email' => 'required|email', + 'password' => 'required', + ]); + + $result = $action->execute($credentials); + + return response()->json([ + 'data' => new UserResource($result['user']), + 'token' => $result['token'], + 'roles' => $result['roles'], + 'permissions' => $result['permissions'], + ]); + } + + /** + * Get Current User + * + * Return the currently authenticated user's details. + */ + public function me(Request $request): UserResource + { + return new UserResource($request->user()); + } + + /** + * Logout + * + * Revoke the current user's token. + */ + public function logout(Request $request): JsonResponse + { + $request->user()->currentAccessToken()->delete(); + + return response()->json(['message' => 'Logged out successfully']); + } +} diff --git a/app/Http/Controllers/Api/V1/UserController.php b/app/Http/Controllers/Api/V1/UserController.php new file mode 100644 index 0000000..7a3c0e9 --- /dev/null +++ b/app/Http/Controllers/Api/V1/UserController.php @@ -0,0 +1,115 @@ +authorize('user.view'); + + $users = User::query() + ->when($request->search, function ($query, $search) { + $query->where('first_name', 'like', "%{$search}%") + ->orWhere('last_name', 'like', "%{$search}%") + ->orWhere('email', 'like', "%{$search}%"); + }) + ->paginate($request->perPage ?? 15); + + return UserResource::collection($users); + } + + /** + * Create User + * + * Create a new user with roles. + */ + public function store(Request $request, CreateUserAction $action): UserResource + { + $this->authorize('user.create'); + + $validated = $request->validate([ + 'firstName' => 'required|string|max:100', + 'lastName' => 'required|string|max:100', + 'email' => 'required|email|unique:users,email', + 'password' => 'required|min:8', + 'status' => 'string|in:active,inactive,suspended', + 'roles' => 'array', + ]); + + $user = $action->execute($validated); + + return new UserResource($user); + } + + /** + * Get User + * + * Get details of a specific user. + */ + public function show(User $user): UserResource + { + $this->authorize('user.view'); + + return new UserResource($user); + } + + /** + * Update User + * + * Update a user's details. + */ + public function update(Request $request, User $user): UserResource + { + $this->authorize('user.edit'); + + $validated = $request->validate([ + 'firstName' => 'string|max:100', + 'lastName' => 'string|max:100', + 'email' => 'email|unique:users,email,' . $user->id, + 'status' => 'string|in:active,inactive,suspended', + ]); + + // Mapping camelCase to snake_case for DB + if (isset($validated['firstName'])) $user->first_name = $validated['firstName']; + if (isset($validated['lastName'])) $user->last_name = $validated['lastName']; + if (isset($validated['email'])) $user->email = $validated['email']; + if (isset($validated['status'])) $user->status = $validated['status']; + + $user->save(); + + return new UserResource($user); + } + + /** + * Delete User + * + * Soft delete a user. + */ + public function destroy(User $user): JsonResponse + { + $this->authorize('user.delete'); + + $user->delete(); + + return response()->json(['message' => 'User deleted successfully']); + } +} diff --git a/app/Http/Controllers/Auth/AuthenticatedSessionController.php b/app/Http/Controllers/Auth/AuthenticatedSessionController.php new file mode 100644 index 0000000..12c2882 --- /dev/null +++ b/app/Http/Controllers/Auth/AuthenticatedSessionController.php @@ -0,0 +1,63 @@ + Route::has('password.request'), + 'status' => session('status'), + ]); + } + + /** + * Handle an incoming authentication request. + */ + public function store(LoginRequest $request): RedirectResponse + { + $request->authenticate(); + + $request->session()->regenerate(); + + $user = Auth::user(); + + // If user has 2FA enabled, redirect to challenge screen + if ($user->two_factor_confirmed_at && $user->two_factor_secret) { + $request->session()->put('two_factor_user_id', $user->id); + Auth::guard('web')->logout(); + $request->session()->forget('password_hash_web'); + + return redirect()->route('two-factor.challenge'); + } + + return redirect()->intended(route('dashboard', absolute: false)); + } + + /** + * Destroy an authenticated session. + */ + public function destroy(Request $request): RedirectResponse + { + Auth::guard('web')->logout(); + + $request->session()->invalidate(); + + $request->session()->regenerateToken(); + + return redirect('/'); + } +} diff --git a/app/Http/Controllers/Auth/ConfirmablePasswordController.php b/app/Http/Controllers/Auth/ConfirmablePasswordController.php new file mode 100644 index 0000000..d2b1f14 --- /dev/null +++ b/app/Http/Controllers/Auth/ConfirmablePasswordController.php @@ -0,0 +1,41 @@ +validate([ + 'email' => $request->user()->email, + 'password' => $request->password, + ])) { + throw ValidationException::withMessages([ + 'password' => __('auth.password'), + ]); + } + + $request->session()->put('auth.password_confirmed_at', time()); + + return redirect()->intended(route('dashboard', absolute: false)); + } +} diff --git a/app/Http/Controllers/Auth/EmailVerificationNotificationController.php b/app/Http/Controllers/Auth/EmailVerificationNotificationController.php new file mode 100644 index 0000000..f64fa9b --- /dev/null +++ b/app/Http/Controllers/Auth/EmailVerificationNotificationController.php @@ -0,0 +1,24 @@ +user()->hasVerifiedEmail()) { + return redirect()->intended(route('dashboard', absolute: false)); + } + + $request->user()->sendEmailVerificationNotification(); + + return back()->with('status', 'verification-link-sent'); + } +} diff --git a/app/Http/Controllers/Auth/EmailVerificationPromptController.php b/app/Http/Controllers/Auth/EmailVerificationPromptController.php new file mode 100644 index 0000000..b42e0d5 --- /dev/null +++ b/app/Http/Controllers/Auth/EmailVerificationPromptController.php @@ -0,0 +1,22 @@ +user()->hasVerifiedEmail() + ? redirect()->intended(route('dashboard', absolute: false)) + : Inertia::render('Auth/VerifyEmail', ['status' => session('status')]); + } +} diff --git a/app/Http/Controllers/Auth/NewPasswordController.php b/app/Http/Controllers/Auth/NewPasswordController.php new file mode 100644 index 0000000..740cc51 --- /dev/null +++ b/app/Http/Controllers/Auth/NewPasswordController.php @@ -0,0 +1,69 @@ + $request->email, + 'token' => $request->route('token'), + ]); + } + + /** + * Handle an incoming new password request. + * + * @throws ValidationException + */ + public function store(Request $request): RedirectResponse + { + $request->validate([ + 'token' => 'required', + 'email' => 'required|email', + 'password' => ['required', 'confirmed', Rules\Password::defaults()], + ]); + + // Here we will attempt to reset the user's password. If it is successful we + // will update the password on an actual user model and persist it to the + // database. Otherwise we will parse the error and return the response. + $status = Password::reset( + $request->only('email', 'password', 'password_confirmation', 'token'), + function ($user) use ($request) { + $user->forceFill([ + 'password' => Hash::make($request->password), + 'remember_token' => Str::random(60), + ])->save(); + + event(new PasswordReset($user)); + } + ); + + // If the password was successfully reset, we will redirect the user back to + // the application's home authenticated view. If there is an error we can + // redirect them back to where they came from with their error message. + if ($status == Password::PASSWORD_RESET) { + return redirect()->route('login')->with('status', __($status)); + } + + throw ValidationException::withMessages([ + 'email' => [trans($status)], + ]); + } +} diff --git a/app/Http/Controllers/Auth/PasswordController.php b/app/Http/Controllers/Auth/PasswordController.php new file mode 100644 index 0000000..57a82b5 --- /dev/null +++ b/app/Http/Controllers/Auth/PasswordController.php @@ -0,0 +1,29 @@ +validate([ + 'current_password' => ['required', 'current_password'], + 'password' => ['required', Password::defaults(), 'confirmed'], + ]); + + $request->user()->update([ + 'password' => Hash::make($validated['password']), + ]); + + return back(); + } +} diff --git a/app/Http/Controllers/Auth/PasswordResetLinkController.php b/app/Http/Controllers/Auth/PasswordResetLinkController.php new file mode 100644 index 0000000..c8b2b6f --- /dev/null +++ b/app/Http/Controllers/Auth/PasswordResetLinkController.php @@ -0,0 +1,51 @@ + session('status'), + ]); + } + + /** + * Handle an incoming password reset link request. + * + * @throws ValidationException + */ + public function store(Request $request): RedirectResponse + { + $request->validate([ + 'email' => 'required|email', + ]); + + // We will send the password reset link to this user. Once we have attempted + // to send the link, we will examine the response then see the message we + // need to show to the user. Finally, we'll send out a proper response. + $status = Password::sendResetLink( + $request->only('email') + ); + + if ($status == Password::RESET_LINK_SENT) { + return back()->with('status', __($status)); + } + + throw ValidationException::withMessages([ + 'email' => [trans($status)], + ]); + } +} diff --git a/app/Http/Controllers/Auth/RegisteredUserController.php b/app/Http/Controllers/Auth/RegisteredUserController.php new file mode 100644 index 0000000..b5a3a52 --- /dev/null +++ b/app/Http/Controllers/Auth/RegisteredUserController.php @@ -0,0 +1,61 @@ +validate([ + 'first_name' => 'required|string|max:255', + 'last_name' => 'required|string|max:255', + 'email' => 'required|string|lowercase|email|max:255|unique:'.User::class, + 'password' => ['required', 'confirmed', Rules\Password::defaults()], + ]); + + $user = User::create([ + 'first_name' => $request->first_name, + 'last_name' => $request->last_name, + 'email' => $request->email, + 'password' => Hash::make($request->password), + 'status' => 'active', + ]); + + event(new Registered($user)); + + Auth::login($user); + + return redirect(route('dashboard', absolute: false)); + } +} diff --git a/app/Http/Controllers/Auth/VerifyEmailController.php b/app/Http/Controllers/Auth/VerifyEmailController.php new file mode 100644 index 0000000..784765e --- /dev/null +++ b/app/Http/Controllers/Auth/VerifyEmailController.php @@ -0,0 +1,27 @@ +user()->hasVerifiedEmail()) { + return redirect()->intended(route('dashboard', absolute: false).'?verified=1'); + } + + if ($request->user()->markEmailAsVerified()) { + event(new Verified($request->user())); + } + + return redirect()->intended(route('dashboard', absolute: false).'?verified=1'); + } +} diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php new file mode 100644 index 0000000..e7f7c94 --- /dev/null +++ b/app/Http/Controllers/Controller.php @@ -0,0 +1,10 @@ +count(); + $totalRoles = Role::count(); + $recentUsers = User::with('roles')->latest()->take(5)->get(); + + $driver = DB::connection()->getDriverName(); + + // Chart Data: User Growth (Last 6 Months) + if ($driver === 'sqlite') { + $monthFormat = "strftime('%Y-%m', created_at)"; + } elseif ($driver === 'pgsql') { + $monthFormat = "to_char(created_at, 'YYYY-MM')"; + } else { + $monthFormat = "DATE_FORMAT(created_at, '%Y-%m')"; + } + + $userGrowth = User::select( + DB::raw('count(id) as total'), + DB::raw("$monthFormat as month") + ) + ->groupBy('month') + ->orderBy('month', 'asc') + ->take(6) + ->get() + ->map(function ($item) { + return [ + 'label' => Carbon::parse($item->month . '-01')->format('M Y'), + 'value' => $item->total, + ]; + }); + + // Chart Data: Activity Logs (Last 7 Days) + if ($driver === 'sqlite') { + $dateFormat = "strftime('%Y-%m-%d', created_at)"; + } elseif ($driver === 'pgsql') { + $dateFormat = "to_char(created_at, 'YYYY-MM-DD')"; + } else { + $dateFormat = "DATE(created_at)"; + } + + $activityStats = []; + if (Schema::hasTable('activity_log')) { + $activityStats = DB::table('activity_log') + ->select( + DB::raw('count(id) as total'), + DB::raw("$dateFormat as date") + ) + ->where('created_at', '>=', Carbon::now()->subDays(7)) + ->groupBy('date') + ->orderBy('date', 'asc') + ->get() + ->map(function ($item) { + return [ + 'label' => Carbon::parse($item->date)->format('D, M d'), + 'value' => $item->total, + ]; + }); + } + + return Inertia::render('Dashboard', [ + 'stats' => [ + 'totalUsers' => $totalUsers, + 'activeUsers' => $activeUsers, + 'totalRoles' => $totalRoles, + 'recentUsers' => $recentUsers, + 'charts' => [ + 'userGrowth' => $userGrowth, + 'activityStats' => $activityStats, + ] + ] + ]); + } +} diff --git a/app/Http/Controllers/DocsController.php b/app/Http/Controllers/DocsController.php new file mode 100644 index 0000000..140d700 --- /dev/null +++ b/app/Http/Controllers/DocsController.php @@ -0,0 +1,16 @@ +input('query'); + + if (empty($query)) { + return response()->json([]); + } + + $results = []; + + // Search Users + $users = User::where('first_name', 'like', "%{$query}%") + ->orWhere('last_name', 'like', "%{$query}%") + ->orWhere('email', 'like', "%{$query}%") + ->limit(5) + ->get() + ->map(fn($u) => [ + 'type' => 'User', + 'title' => "{$u->first_name} {$u->last_name}", + 'subtitle' => $u->email, + 'url' => route('users.show', $u->id), + 'icon' => 'user' + ]); + $results = array_merge($results, $users->toArray()); + + // Search Roles + $roles = Role::where('name', 'like', "%{$query}%") + ->limit(3) + ->get() + ->map(fn($r) => [ + 'type' => 'Role', + 'title' => $r->name, + 'subtitle' => "{$r->permissions()->count()} permissions", + 'url' => route('roles.index'), + 'icon' => 'shield' + ]); + $results = array_merge($results, $roles->toArray()); + + // Search Activity Logs + $logs = Activity::where('description', 'like', "%{$query}%") + ->orWhere('log_name', 'like', "%{$query}%") + ->latest() + ->limit(5) + ->get() + ->map(fn($l) => [ + 'type' => 'Log', + 'title' => $l->description, + 'subtitle' => $l->created_at->diffForHumans(), + 'url' => route('activity-logs.index'), + 'icon' => 'clock' + ]); + $results = array_merge($results, $logs->toArray()); + + // Search Navigation Pages + $pages = [ + ['title' => 'Dashboard', 'url' => route('dashboard'), 'icon' => 'clock', 'keywords' => ['home', 'index', 'dashboard']], + ['title' => 'User Management', 'url' => route('users.index'), 'icon' => 'user', 'keywords' => ['users', 'people', 'staff', 'accounts']], + ['title' => 'Role Management', 'url' => route('roles.index'), 'icon' => 'shield', 'keywords' => ['roles', 'permissions', 'access', 'security']], + ['title' => 'Activity Logs', 'url' => route('activity-logs.index'), 'icon' => 'clock', 'keywords' => ['logs', 'audit', 'history', 'events']], + ['title' => 'System Settings', 'url' => route('system.settings.index'), 'icon' => 'shield', 'keywords' => ['settings', 'config', 'setup', 'system']], + ['title' => 'Profile Settings', 'url' => route('profile.edit'), 'icon' => 'user', 'keywords' => ['profile', 'me', 'account', 'password']], + ]; + + $matchedPages = array_filter($pages, function($page) use ($query) { + $q = strtolower($query); + if (str_contains(strtolower($page['title']), $q)) return true; + foreach ($page['keywords'] as $keyword) { + if (str_contains($keyword, $q)) return true; + } + return false; + }); + + foreach ($matchedPages as $page) { + $results[] = [ + 'type' => 'Page', + 'title' => $page['title'], + 'subtitle' => 'System Navigation', + 'url' => $page['url'], + 'icon' => $page['icon'] + ]; + } + + return response()->json($results); + } +} diff --git a/app/Http/Controllers/NotificationController.php b/app/Http/Controllers/NotificationController.php new file mode 100644 index 0000000..f5a0676 --- /dev/null +++ b/app/Http/Controllers/NotificationController.php @@ -0,0 +1,74 @@ +latest() + ->paginate(10); + + $users = User::select('id', 'first_name', 'last_name', 'email') + ->where('status', 'active') + ->get(); + + return Inertia::render('Notifications/Index', [ + 'logs' => [ + 'data' => $logs->items(), + 'meta' => [ + 'current_page' => $logs->currentPage(), + 'last_page' => $logs->lastPage(), + 'total' => $logs->total(), + 'per_page' => $logs->perPage(), + ], + 'links' => $logs->linkCollection()->toArray(), + ], + 'users' => $users, + ]); + } + + public function store(Request $request) + { + $validated = $request->validate([ + 'title' => 'required|string|max:255', + 'body' => 'required|string', + 'image_url' => 'nullable|url', + 'deep_link' => 'nullable|string', + 'target_type' => 'required|in:all,individual', + 'target_user_id' => 'required_if:target_type,individual|nullable|exists:users,id', + ]); + + try { + // Mocking FCM Sending logic + // In production, use Kreait/Firebase-PHP or Laravel-Notification-Channels/WebPush + $status = 'sent'; + $errorMessage = null; + + // Log the notification + NotificationLog::create([ + 'title' => $validated['title'], + 'body' => $validated['body'], + 'image_url' => $validated['image_url'], + 'deep_link' => $validated['deep_link'], + 'target_type' => $validated['target_type'], + 'target_user_id' => $validated['target_user_id'], + 'sender_id' => auth()->id(), + 'status' => $status, + 'error_message' => $errorMessage, + ]); + + return back()->with('success', 'Notification dispatched successfully.'); + } catch (\Exception $e) { + Log::error('FCM Error: ' . $e->getMessage()); + return back()->with('error', 'Failed to send notification: ' . $e->getMessage()); + } + } +} diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php new file mode 100644 index 0000000..b51c4ee --- /dev/null +++ b/app/Http/Controllers/ProfileController.php @@ -0,0 +1,74 @@ +user(); + $user->fill($request->validated()); + + if ($user->isDirty('email')) { + $user->email_verified_at = null; + } + + // Handle Avatar Upload + if ($request->hasFile('avatar_file')) { + // Delete old avatar if exists + if ($user->avatar_url) { + $oldPath = str_replace('/storage/', '', $user->avatar_url); + Storage::disk('public')->delete($oldPath); + } + + $path = $request->file('avatar_file')->store('avatars', 'public'); + $user->avatar_url = Storage::url($path); + } + + $user->save(); + + return Redirect::route('settings.index')->with('status', 'profile-updated'); + } + + /** + * Delete the user's account. + */ + public function destroy(Request $request): RedirectResponse + { + $request->validate([ + 'password' => ['required', 'current_password'], + ]); + + $user = $request->user(); + + Auth::logout(); + + $user->delete(); + + $request->session()->invalidate(); + $request->session()->regenerateToken(); + + return Redirect::to('/'); + } +} diff --git a/app/Http/Controllers/RoleController.php b/app/Http/Controllers/RoleController.php new file mode 100644 index 0000000..30ef74e --- /dev/null +++ b/app/Http/Controllers/RoleController.php @@ -0,0 +1,92 @@ + 0, 'admin' => 1, 'user' => 2]; + + $roles = Role::where('guard_name', 'web') + ->with('permissions') + ->get() + ->map(function ($role) { + return [ + 'id' => $role->id, + 'name' => $role->name, + 'guard_name' => $role->guard_name, + 'permissions' => $role->permissions->pluck('name')->toArray(), + 'users_count' => $role->users()->count(), + 'created_at' => $role->created_at, + ]; + }) + ->sortBy(fn ($role) => $order[$role['name']] ?? 99) + ->values(); + + $permissions = Permission::where('guard_name', 'web') + ->get() + ->map(fn($p) => [ + 'id' => $p->id, + 'name' => $p->name, + 'group' => explode('.', $p->name)[0] ?? 'other', + ]); + + return Inertia::render('Roles/Index', [ + 'roles' => $roles, + 'permissions' => $permissions, + ]); + } + + /** + * Update the permissions matrix for a role. + */ + public function updatePermissions(Request $request, Role $role) + { + $validated = $request->validate([ + 'permissions' => 'required|array', + 'permissions.*' => 'string|exists:permissions,name', + ]); + + // Sync only web guard permissions + $role->syncPermissions($validated['permissions']); + + return back()->with('success', "Permissions updated for role '{$role->name}'."); + } + + /** + * Store a new role. + */ + public function store(Request $request) + { + $validated = $request->validate([ + 'name' => 'required|string|max:50|unique:roles,name', + ]); + + Role::create([ + 'name' => $validated['name'], + 'guard_name' => 'web', + ]); + + return back()->with('success', 'Role created successfully.'); + } + + /** + * Delete a role. + */ + public function destroy(Role $role) + { + if ($role->name === 'super-admin') { + return back()->withErrors(['error' => 'Cannot delete the super-admin role.']); + } + + $role->delete(); + + return back()->with('success', 'Role deleted successfully.'); + } +} diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php new file mode 100644 index 0000000..0c6bd98 --- /dev/null +++ b/app/Http/Controllers/SettingsController.php @@ -0,0 +1,50 @@ +user(); + $twoFactorEnabled = !is_null($user->two_factor_confirmed_at); + + $qrCode = null; + $secret = null; + + if (!$twoFactorEnabled) { + if (!$user->two_factor_secret) { + $g2fa = new \PragmaRX\Google2FA\Google2FA(); + $user->update(['two_factor_secret' => $g2fa->generateSecretKey()]); + } + $secret = $user->fresh()->two_factor_secret; + $g2fa = new \PragmaRX\Google2FA\Google2FA(); + $otpUrl = $g2fa->getQRCodeUrl(config('app.name'), $user->email, $secret); + $renderer = new \BaconQrCode\Renderer\ImageRenderer( + new \BaconQrCode\Renderer\RendererStyle\RendererStyle(200), + new \BaconQrCode\Renderer\Image\SvgImageBackEnd() + ); + $qrCode = 'data:image/svg+xml;base64,' . base64_encode((new \BaconQrCode\Writer($renderer))->writeString($otpUrl)); + } + + return Inertia::render('Settings/Index', [ + 'mustVerifyEmail' => $user instanceof \Illuminate\Contracts\Auth\MustVerifyEmail, + 'status' => session('status'), + 'twoFactor' => [ + 'enabled' => $twoFactorEnabled, + 'qr_code' => $qrCode, + 'secret' => $secret, + 'recovery_codes' => $user->two_factor_recovery_codes + ? json_decode($user->two_factor_recovery_codes, true) + : [], + ], + ]); + } +} diff --git a/app/Http/Controllers/SystemSettingController.php b/app/Http/Controllers/SystemSettingController.php new file mode 100644 index 0000000..b12456c --- /dev/null +++ b/app/Http/Controllers/SystemSettingController.php @@ -0,0 +1,179 @@ +user()->hasRole('super-admin'), 403, 'Unauthorized. Super-Admin only.'); + + $settings = Setting::all()->pluck('value', 'key'); + + $defaultSettings = [ + 'app_name' => 'biiproject kit v2', + 'app_logo' => null, + 'app_logo_text' => 'BK', + 'app_description' => 'Enterprise Admin Platform', + 'allow_registration' => '1', + 'require_email_verification' => '0', + 'password_minimum_length' => '8', + 'password_require_symbols' => '0', + 'password_require_numbers' => '0', + 'password_require_mixed_case' => '0', + + // OAuth + 'oauth_google_enabled' => '0', + 'oauth_google_client_id' => '', + 'oauth_google_client_secret' => '', + 'oauth_github_enabled' => '0', + 'oauth_github_client_id' => '', + 'oauth_github_client_secret' => '', + + // SMTP + 'mail_host' => 'smtp.mailtrap.io', + 'mail_port' => '2525', + 'mail_username' => '', + 'mail_password' => '', + 'mail_encryption' => 'tls', + 'mail_from_address' => 'hello@biiproject.com', + 'mail_from_name' => 'biiproject kit Admin', + + 'primary_color' => '#6366f1', + + // Mobile App Control + 'android_latest_version' => '1.0.0', + 'android_min_version' => '1.0.0', + 'android_maintenance_mode' => '0', + 'android_playstore_url' => '', + ]; + + $mergedSettings = array_merge($defaultSettings, $settings->toArray()); + + return Inertia::render('SystemSettings/Index', [ + 'settings' => $mergedSettings, + ]); + } + + /** + * Update the system settings. + */ + public function update(Request $request) + { + abort_if(!auth()->user()->hasRole('super-admin'), 403, 'Unauthorized. Super-Admin only.'); + + $validated = $request->validate([ + 'settings' => 'required|array', + 'settings.app_name' => 'required|string|max:255', + 'settings.app_logo_text' => 'required|string|max:3', + 'settings.app_description' => 'nullable|string', + 'settings.allow_registration' => 'boolean', + 'settings.require_email_verification' => 'boolean', + 'settings.password_minimum_length' => 'integer|min:8', + 'settings.password_require_symbols' => 'boolean', + 'settings.password_require_numbers' => 'boolean', + 'settings.password_require_mixed_case' => 'boolean', + + 'settings.oauth_google_enabled' => 'boolean', + 'settings.oauth_google_client_id' => 'nullable|string', + 'settings.oauth_google_client_secret' => 'nullable|string', + 'settings.oauth_github_enabled' => 'boolean', + 'settings.oauth_github_client_id' => 'nullable|string', + 'settings.oauth_github_client_secret' => 'nullable|string', + + 'settings.mail_host' => 'nullable|string', + 'settings.mail_port' => 'nullable|string', + 'settings.mail_username' => 'nullable|string', + 'settings.mail_password' => 'nullable|string', + 'settings.mail_encryption' => 'nullable|string', + 'settings.mail_from_address' => 'nullable|email', + 'settings.mail_from_name' => 'nullable|string', + + 'settings.primary_color' => 'required|string', + + // Mobile App Control + 'settings.android_latest_version' => 'nullable|string', + 'settings.android_min_version' => 'nullable|string', + 'settings.android_maintenance_mode' => 'boolean', + 'settings.android_playstore_url' => 'nullable|url', + 'logo_file' => 'nullable|image|max:2048', + ]); + + $settings = $validated['settings']; + + if ($request->hasFile('logo_file')) { + $path = $request->file('logo_file')->store('branding', 'public'); + $logoUrl = Storage::url($path); + Setting::updateOrCreate(['key' => 'app_logo'], ['value' => $logoUrl, 'type' => 'string']); + } + + foreach ($settings as $key => $value) { + Setting::updateOrCreate( + ['key' => $key], + ['value' => (string) $value, 'type' => is_bool($value) ? 'boolean' : (is_int($value) ? 'integer' : 'string')] + ); + } + + Cache::forget('system_settings'); + + return back()->with('success', 'System configurations updated successfully.'); + } + + /** + * Send a test email using SMTP details from the request. + */ + public function testEmail(Request $request) + { + abort_if(!auth()->user()->hasRole('super-admin'), 403, 'Unauthorized. Super-Admin only.'); + + $request->validate([ + 'recipient' => 'required|email', + 'mail_host' => 'nullable|string', + 'mail_port' => 'nullable|string', + 'mail_username' => 'nullable|string', + 'mail_password' => 'nullable|string', + 'mail_encryption' => 'nullable|string', + 'mail_from_address' => 'nullable|email', + 'mail_from_name' => 'nullable|string', + ]); + + try { + // Apply SMTP settings at runtime + config([ + 'mail.default' => 'smtp', + 'mail.mailers.smtp.transport' => 'smtp', + 'mail.mailers.smtp.host' => $request->input('mail_host'), + 'mail.mailers.smtp.port' => $request->input('mail_port'), + 'mail.mailers.smtp.username' => $request->input('mail_username'), + 'mail.mailers.smtp.password' => $request->input('mail_password'), + 'mail.mailers.smtp.encryption' => $request->input('mail_encryption') ?: 'tls', + 'mail.from.address' => $request->input('mail_from_address'), + 'mail.from.name' => $request->input('mail_from_name'), + ]); + + \Illuminate\Support\Facades\Mail::raw("Halo!\n\nIni adalah email uji coba (test email) dari sistem biiskit.\n\nJika Anda menerima email ini, berarti konfigurasi SMTP Anda berfungsi dengan baik!\n\nDetail Konfigurasi:\n- Host: " . ($request->input('mail_host') ?: '-') . "\n- Port: " . ($request->input('mail_port') ?: '-') . "\n- Sender: " . ($request->input('mail_from_address') ?: '-') . "\n\nSalam,\nAdmin biiskit", function ($message) use ($request) { + $message->to($request->input('recipient')) + ->subject("Uji Coba Konfigurasi SMTP - biiskit"); + }); + + return response()->json([ + 'success' => true, + 'message' => 'Email uji coba telah berhasil dikirim ke ' . $request->input('recipient') + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Gagal mengirim email uji coba. Error: ' . $e->getMessage() + ]); + } + } +} diff --git a/app/Http/Controllers/TwoFactorController.php b/app/Http/Controllers/TwoFactorController.php new file mode 100644 index 0000000..5aad8f7 --- /dev/null +++ b/app/Http/Controllers/TwoFactorController.php @@ -0,0 +1,177 @@ +google2fa = new Google2FA(); + } + + /** + * Show 2FA setup page (generate QR code data). + */ + public function show() + { + $user = auth()->user(); + + // If not yet set up, generate a new secret + if (!$user->two_factor_secret) { + $secret = $this->google2fa->generateSecretKey(); + $user->update(['two_factor_secret' => $secret]); + } + + $secret = $user->two_factor_secret; + + $otpUrl = $this->google2fa->getQRCodeUrl( + config('app.name'), + $user->email, + $secret + ); + + // Generate QR code as SVG using BaconQrCode + $renderer = new \BaconQrCode\Renderer\ImageRenderer( + new \BaconQrCode\Renderer\RendererStyle\RendererStyle(200), + new \BaconQrCode\Renderer\Image\SvgImageBackEnd() + ); + $qrCode = (new \BaconQrCode\Writer($renderer))->writeString($otpUrl); + $qrCodeBase64 = 'data:image/svg+xml;base64,' . base64_encode($qrCode); + + return Inertia::render('TwoFactor/Setup', [ + 'enabled' => !is_null($user->two_factor_confirmed_at), + 'qr_code' => $qrCodeBase64, + 'secret' => $secret, + 'recovery_codes' => $user->two_factor_recovery_codes + ? json_decode($user->two_factor_recovery_codes, true) + : [], + ]); + } + + /** + * Confirm & enable 2FA. + */ + public function enable(Request $request) + { + $request->validate([ + 'code' => 'required|string', + ]); + + $user = auth()->user(); + $secret = $user->two_factor_secret; + + $valid = $this->google2fa->verifyKey($secret, $request->code); + + if (!$valid) { + return back()->withErrors(['code' => 'Invalid authentication code. Please try again.']); + } + + // Generate recovery codes + $recoveryCodes = Collection::times(8, fn() => Str::random(10) . '-' . Str::random(10)); + + $user->update([ + 'two_factor_confirmed_at' => now(), + 'two_factor_recovery_codes' => json_encode($recoveryCodes->toArray()), + ]); + + return back()->with('success', 'Two-Factor Authentication has been enabled successfully.'); + } + + /** + * Disable 2FA. + */ + public function disable(Request $request) + { + $request->validate([ + 'password' => 'required|current_password', + ]); + + auth()->user()->update([ + 'two_factor_secret' => null, + 'two_factor_recovery_codes' => null, + 'two_factor_confirmed_at' => null, + ]); + + return back()->with('success', 'Two-Factor Authentication has been disabled.'); + } + + /** + * Regenerate recovery codes. + */ + public function regenerateCodes() + { + $recoveryCodes = Collection::times(8, fn() => Str::random(10) . '-' . Str::random(10)); + + auth()->user()->update([ + 'two_factor_recovery_codes' => json_encode($recoveryCodes->toArray()), + ]); + + return back()->with('success', 'Recovery codes have been regenerated.'); + } + + /** + * Show the 2FA challenge screen (after login). + */ + public function challenge(Request $request) + { + if (!$request->session()->has('two_factor_user_id')) { + return redirect()->route('login'); + } + + return Inertia::render('TwoFactor/Challenge'); + } + + /** + * Verify the 2FA challenge code after login. + */ + public function verify(Request $request) + { + $request->validate([ + 'code' => 'required|string', + ]); + + $userId = $request->session()->get('two_factor_user_id'); + + if (!$userId) { + return redirect()->route('login'); + } + + $user = \App\Models\User::find($userId); + + if (!$user || !$user->two_factor_secret) { + $request->session()->forget('two_factor_user_id'); + return redirect()->route('login'); + } + + $code = $request->code; + $valid = $this->google2fa->verifyKey($user->two_factor_secret, $code); + + if (!$valid) { + $recoveryCodes = json_decode($user->two_factor_recovery_codes ?? '[]', true); + if (in_array($code, $recoveryCodes)) { + $remaining = array_filter($recoveryCodes, fn($c) => $c !== $code); + $user->update(['two_factor_recovery_codes' => json_encode(array_values($remaining))]); + $valid = true; + } + } + + if (!$valid) { + return back()->withErrors(['code' => 'Invalid code. Please try again.']); + } + + $request->session()->forget('two_factor_user_id'); + + \Illuminate\Support\Facades\Auth::login($user); + $request->session()->regenerate(); + + return redirect()->intended(route('dashboard')); + } +} diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php new file mode 100644 index 0000000..5e42ba0 --- /dev/null +++ b/app/Http/Controllers/UserController.php @@ -0,0 +1,240 @@ +authorize('viewAny', User::class); + + $trashed = $request->input('trashed'); + $search = $request->input('search'); + $status = $request->input('status'); + $role = $request->input('role'); + $sortField = $request->input('sort_field', 'created_at'); + $sortDir = $request->input('sort_direction', 'desc'); + $perPage = (int) $request->input('per_page', 15); + + $query = User::with('roles'); + + if ($trashed === 'only') { + $query->onlyTrashed(); + } elseif ($trashed === 'with') { + $query->withTrashed(); + } + + if ($search) { + $query->where(function ($q) use ($search) { + $q->where('first_name', 'like', "%{$search}%") + ->orWhere('last_name', 'like', "%{$search}%") + ->orWhere('email', 'like', "%{$search}%"); + }); + } + + if ($status) { + $query->where('status', $status); + } + + if ($role) { + $query->role($role); + } + + $allowedSortFields = ['first_name', 'last_name', 'email', 'status', 'created_at']; + if (!\in_array($sortField, $allowedSortFields, true)) { + $sortField = 'created_at'; + } + $sortDir = $sortDir === 'asc' ? 'asc' : 'desc'; + + $users = $query->orderBy($sortField, $sortDir) + ->paginate($perPage) + ->withQueryString(); + + $roles = Role::where('guard_name', 'web')->pluck('name'); + + return Inertia::render('Users/Index', [ + 'users' => [ + 'data' => $users->items(), + 'meta' => [ + 'current_page' => $users->currentPage(), + 'last_page' => $users->lastPage(), + 'total' => $users->total(), + 'per_page' => $users->perPage(), + ], + 'links' => $users->linkCollection()->toArray(), + ], + 'filters' => $request->only(['search', 'status', 'role', 'sort_field', 'sort_direction', 'per_page', 'trashed']), + 'availableRoles' => $roles, + ]); + } + + public function show(User $user) + { + $this->authorize('view', $user); + $user->load(['roles', 'permissions']); + + return Inertia::render('Users/Show', [ + 'viewUser' => $user, + ]); + } + + public function store(Request $request) + { + $this->authorize('create', User::class); + + $validated = $request->validate([ + 'first_name' => 'required|string|max:255', + 'last_name' => 'required|string|max:255', + 'email' => 'required|email|unique:users', + 'password' => ['required', Password::defaults()], + 'status' => 'in:active,inactive', + 'roles' => 'nullable|array', + 'roles.*' => 'string|exists:roles,name', + ]); + + $user = User::create([ + 'first_name' => $validated['first_name'], + 'last_name' => $validated['last_name'], + 'email' => $validated['email'], + 'password' => Hash::make($validated['password']), + 'status' => $validated['status'] ?? 'active', + ]); + + if (!empty($validated['roles'])) { + $user->syncRoles($validated['roles']); + } + + return back()->with('success', 'User created successfully.'); + } + + public function update(Request $request, User $user) + { + $this->authorize('update', $user); + + $validated = $request->validate([ + 'first_name' => 'sometimes|string|max:255', + 'last_name' => 'sometimes|string|max:255', + 'email' => 'sometimes|email|unique:users,email,' . $user->id, + 'status' => 'sometimes|in:active,inactive', + 'roles' => 'nullable|array', + 'roles.*' => 'string|exists:roles,name', + ]); + + $roles = $validated['roles'] ?? null; + unset($validated['roles']); + + $user->update($validated); + + if ($roles !== null) { + $user->syncRoles($roles); + } + + return back()->with('success', 'User updated successfully.'); + } + + public function destroy(User $user) + { + $this->authorize('delete', $user); + + if ($user->id === auth()->id()) { + return back()->withErrors(['error' => 'You cannot delete your own account.']); + } + + $user->delete(); + + return back()->with('success', 'Entity moved to archive.'); + } + + public function restore(int $id) + { + $user = User::withTrashed()->findOrFail($id); + $this->authorize('restore', $user); + + $user->restore(); + + return back()->with('success', 'Entity restored from archive.'); + } + + public function forceDelete(int $id) + { + $user = User::withTrashed()->findOrFail($id); + $this->authorize('forceDelete', $user); + + if ($user->id === auth()->id()) { + return back()->withErrors(['error' => 'You cannot delete your own account.']); + } + + $user->forceDelete(); + + return back()->with('success', 'Entity permanently purged.'); + } + + public function bulkArchive(Request $request) + { + $this->authorize('user.delete'); + + $ids = array_filter( + (array) $request->input('ids', []), + fn ($id) => (int) $id !== auth()->id() + ); + + User::whereIn('id', $ids)->delete(); + + return back()->with('success', \count($ids) . ' users archived.'); + } + + public function bulkRestore(Request $request) + { + $this->authorize('user.delete'); + + $ids = (array) $request->input('ids', []); + + User::withTrashed()->whereIn('id', $ids)->restore(); + + return back()->with('success', \count($ids) . ' users restored.'); + } + + public function bulkForceDelete(Request $request) + { + $this->authorize('user.delete'); + + $ids = array_filter( + (array) $request->input('ids', []), + fn ($id) => (int) $id !== auth()->id() + ); + + User::withTrashed()->whereIn('id', $ids)->forceDelete(); + + return back()->with('success', \count($ids) . ' users permanently deleted.'); + } + + public function export() + { + $this->authorize('viewAny', User::class); + + return Excel::download(new UsersExport, 'users-' . now()->format('Y-m-d') . '.xlsx'); + } + + public function import(Request $request) + { + $this->authorize('create', User::class); + + $request->validate([ + 'file' => 'required|mimes:xlsx,csv,xls|max:5120', + ]); + + Excel::import(new UsersImport, $request->file('file')); + + return back()->with('success', 'Users imported successfully.'); + } +} diff --git a/app/Http/Middleware/HandleInertiaRequests.php b/app/Http/Middleware/HandleInertiaRequests.php new file mode 100644 index 0000000..4df4785 --- /dev/null +++ b/app/Http/Middleware/HandleInertiaRequests.php @@ -0,0 +1,65 @@ + + */ + public function share(Request $request): array + { + $settings = \Illuminate\Support\Facades\Cache::rememberForever('system_settings', function() { + return \App\Models\Setting::pluck('value', 'key')->toArray(); + }); + + // Inject default defaults if not in DB + $defaultSettings = [ + 'app_name' => 'biiskit', + 'app_logo' => null, + 'app_logo_text' => 'B', + 'allow_registration' => '1', + ]; + $settings = array_merge($defaultSettings, $settings); + + return [ + ...parent::share($request), + 'auth' => [ + 'user' => $request->user(), + 'permissions' => $request->user()?->getAllPermissions()->pluck('name') ?? [], + 'roles' => $request->user()?->getRoleNames() ?? [], + ], + 'system_settings' => $settings, + 'unread_notifications' => $request->user() + ? \App\Models\NotificationLog::where('status', 'sent') + ->where('created_at', '>=', now()->subDays(7)) + ->count() + : 0, + 'flash' => [ + 'success' => $request->session()->get('success'), + 'error' => $request->session()->get('error'), + 'plain_text_token' => $request->session()->get('plain_text_token'), + ], + ]; + } +} diff --git a/app/Http/Requests/Auth/LoginRequest.php b/app/Http/Requests/Auth/LoginRequest.php new file mode 100644 index 0000000..711e0a1 --- /dev/null +++ b/app/Http/Requests/Auth/LoginRequest.php @@ -0,0 +1,86 @@ +|string> + */ + public function rules(): array + { + return [ + 'email' => ['required', 'string', 'email'], + 'password' => ['required', 'string'], + ]; + } + + /** + * Attempt to authenticate the request's credentials. + * + * @throws ValidationException + */ + public function authenticate(): void + { + $this->ensureIsNotRateLimited(); + + if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) { + RateLimiter::hit($this->throttleKey()); + + throw ValidationException::withMessages([ + 'email' => trans('auth.failed'), + ]); + } + + RateLimiter::clear($this->throttleKey()); + } + + /** + * Ensure the login request is not rate limited. + * + * @throws ValidationException + */ + public function ensureIsNotRateLimited(): void + { + if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) { + return; + } + + event(new Lockout($this)); + + $seconds = RateLimiter::availableIn($this->throttleKey()); + + throw ValidationException::withMessages([ + 'email' => trans('auth.throttle', [ + 'seconds' => $seconds, + 'minutes' => ceil($seconds / 60), + ]), + ]); + } + + /** + * Get the rate limiting throttle key for the request. + */ + public function throttleKey(): string + { + return Str::transliterate(Str::lower($this->string('email')).'|'.$this->ip()); + } +} diff --git a/app/Http/Requests/ProfileUpdateRequest.php b/app/Http/Requests/ProfileUpdateRequest.php new file mode 100644 index 0000000..014ce9a --- /dev/null +++ b/app/Http/Requests/ProfileUpdateRequest.php @@ -0,0 +1,34 @@ +|string> + */ + public function rules(): array + { + return [ + 'first_name' => ['required', 'string', 'max:255'], + 'last_name' => ['required', 'string', 'max:255'], + 'phone' => ['nullable', 'string', 'max:20'], + 'bio' => ['nullable', 'string', 'max:1000'], + 'email' => [ + 'required', + 'string', + 'lowercase', + 'email', + 'max:255', + Rule::unique(User::class)->ignore($this->user()->id), + ], + ]; + } +} diff --git a/app/Http/Resources/UserResource.php b/app/Http/Resources/UserResource.php new file mode 100644 index 0000000..5bfd552 --- /dev/null +++ b/app/Http/Resources/UserResource.php @@ -0,0 +1,28 @@ + $this->id, + 'firstName' => $this->first_name, + 'lastName' => $this->last_name, + 'fullName' => $this->getFullName(), + 'email' => $this->email, + 'phone' => $this->phone, + 'bio' => $this->bio, + 'status' => $this->status, + 'avatarUrl' => $this->avatar_url, + 'roles' => $this->getRoleNames(), + 'permissions' => $this->getAllPermissions()->pluck('name'), + 'createdAt' => $this->created_at, + 'updatedAt' => $this->updated_at, + ]; + } +} diff --git a/app/Imports/UsersImport.php b/app/Imports/UsersImport.php new file mode 100644 index 0000000..e2247d6 --- /dev/null +++ b/app/Imports/UsersImport.php @@ -0,0 +1,32 @@ + $row['first_name'], + 'last_name' => $row['last_name'], + 'email' => $row['email'], + 'status' => $row['status'] ?? 'active', + 'password' => Hash::make($row['password'] ?? 'password123'), + ]); + } + + public function rules(): array + { + return [ + 'first_name' => 'required|string|max:255', + 'last_name' => 'required|string|max:255', + 'email' => 'required|email|unique:users,email', + ]; + } +} diff --git a/app/Models/NotificationLog.php b/app/Models/NotificationLog.php new file mode 100644 index 0000000..9f9ff79 --- /dev/null +++ b/app/Models/NotificationLog.php @@ -0,0 +1,30 @@ +belongsTo(User::class, 'target_user_id'); + } + + public function sender() + { + return $this->belongsTo(User::class, 'sender_id'); + } +} diff --git a/app/Models/RemoteConfig.php b/app/Models/RemoteConfig.php new file mode 100644 index 0000000..03250c4 --- /dev/null +++ b/app/Models/RemoteConfig.php @@ -0,0 +1,23 @@ + 'boolean', + ]; + } +} diff --git a/app/Models/Setting.php b/app/Models/Setting.php new file mode 100644 index 0000000..edc3bb4 --- /dev/null +++ b/app/Models/Setting.php @@ -0,0 +1,50 @@ +first(); + if (!$setting) { + return $default; + } + + return match($setting->type) { + 'boolean' => filter_var($setting->value, FILTER_VALIDATE_BOOLEAN), + 'integer' => (int) $setting->value, + 'json' => json_decode($setting->value, true), + default => $setting->value, + }; + } + + /** + * Set a setting value. + */ + public static function set(string $key, $value, string $type = 'string') + { + if (is_array($value)) { + $value = json_encode($value); + $type = 'json'; + } elseif (is_bool($value)) { + $value = $value ? '1' : '0'; + $type = 'boolean'; + } + + return self::updateOrCreate( + ['key' => $key], + ['value' => $value, 'type' => $type] + ); + } +} diff --git a/app/Models/User.php b/app/Models/User.php new file mode 100644 index 0000000..f940d33 --- /dev/null +++ b/app/Models/User.php @@ -0,0 +1,80 @@ + */ + use HasFactory, Notifiable, HasRoles, SoftDeletes, LogsActivity, HasApiTokens; + + public function getActivitylogOptions(): LogOptions + { + return LogOptions::defaults() + ->logFillable() + ->logOnlyDirty() + ->dontSubmitEmptyLogs(); + } + + /** + * PHP 8.4 Property Hooks (Polyfill for PHP 8.3 environment) + */ + public function getFullName(): string + { + return "{$this->first_name} {$this->last_name}"; + } + + public function isActive(): bool + { + return $this->status === 'active' && !$this->deleted_at; + } + + /** + * PHP 8.4 Asymmetric Visibility (Polyfill) + */ + protected ?string $avatarUrl = null; + + public function getAvatarUrl(): ?string + { + return $this->avatarUrl; + } + + /** + * Get the attributes that should be cast. + * + * @return array + */ + protected function casts(): array + { + return [ + 'email_verified_at' => 'datetime', + 'password' => 'hashed', + 'meta' => 'array', + 'status' => 'string', + ]; + } + + /** + * Sync avatarUrl with avatar_url attribute. + */ + public function setAvatar(string $path): void + { + $this->avatar_url = $path; + $this->avatarUrl = \Illuminate\Support\Facades\Storage::url($path); + } +} diff --git a/app/Policies/UserPolicy.php b/app/Policies/UserPolicy.php new file mode 100644 index 0000000..11bbf48 --- /dev/null +++ b/app/Policies/UserPolicy.php @@ -0,0 +1,43 @@ +hasPermissionTo('user.view'); + } + + public function view(User $authUser, User $user): bool + { + return $authUser->hasPermissionTo('user.view'); + } + + public function create(User $authUser): bool + { + return $authUser->hasPermissionTo('user.create'); + } + + public function update(User $authUser, User $user): bool + { + return $authUser->hasPermissionTo('user.edit'); + } + + public function delete(User $authUser, User $user): bool + { + return $authUser->hasPermissionTo('user.delete') && $authUser->id !== $user->id; + } + + public function restore(User $authUser, User $user): bool + { + return $authUser->hasPermissionTo('user.delete'); + } + + public function forceDelete(User $authUser, User $user): bool + { + return $authUser->hasPermissionTo('user.delete') && $authUser->id !== $user->id; + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php new file mode 100644 index 0000000..55097b7 --- /dev/null +++ b/app/Providers/AppServiceProvider.php @@ -0,0 +1,64 @@ +app->bind(\Illuminate\Contracts\Auth\StatefulGuard::class, function () { + return \Illuminate\Support\Facades\Auth::guard('web'); + }); + + $this->app->bind(AuthorizationViewResponse::class, function () { + return new SimpleViewResponse('passport::authorize'); + }); + } + + public function boot(): void + { + Vite::prefetch(concurrency: 3); + + Gate::policy(User::class, UserPolicy::class); + + // super-admin bypasses all gates + Gate::before(function (User $user, string $ability) { + if ($user->hasRole('super-admin')) { + return true; + } + }); + + // Dynamic password rules driven by system settings + Password::defaults(function () { + $settings = Cache::get('system_settings', []); + + $rule = Password::min((int) ($settings['password_minimum_length'] ?? 8)); + + if (filter_var($settings['password_require_symbols'] ?? false, FILTER_VALIDATE_BOOLEAN)) { + $rule->symbols(); + } + if (filter_var($settings['password_require_numbers'] ?? false, FILTER_VALIDATE_BOOLEAN)) { + $rule->numbers(); + } + if (filter_var($settings['password_require_mixed_case'] ?? false, FILTER_VALIDATE_BOOLEAN)) { + $rule->mixedCase(); + } + + return $rule; + }); + } +} diff --git a/app/Providers/ConfigServiceProvider.php b/app/Providers/ConfigServiceProvider.php new file mode 100644 index 0000000..fb54c11 --- /dev/null +++ b/app/Providers/ConfigServiceProvider.php @@ -0,0 +1,65 @@ +app->runningInConsole()) { + return; + } + + try { + $settings = Cache::rememberForever('system_settings', function () { + return Setting::all()->pluck('value', 'key')->toArray(); + }); + } catch (\Throwable $e) { + // DB not ready yet (e.g. first migration) + return; + } + + if (empty($settings)) { + return; + } + + if (!empty($settings['app_name'])) { + Config::set('app.name', $settings['app_name']); + } + + if (!empty($settings['mail_host'])) { + Config::set([ + 'mail.mailers.smtp.host' => $settings['mail_host'], + 'mail.mailers.smtp.port' => $settings['mail_port'] ?? '587', + 'mail.mailers.smtp.username' => $settings['mail_username'] ?? '', + 'mail.mailers.smtp.password' => $settings['mail_password'] ?? '', + 'mail.mailers.smtp.encryption' => $settings['mail_encryption'] ?? 'tls', + 'mail.from.address' => $settings['mail_from_address'] ?? 'hello@example.com', + 'mail.from.name' => $settings['mail_from_name'] ?? ($settings['app_name'] ?? config('app.name')), + ]); + } + + if (!empty($settings['oauth_google_client_id'])) { + Config::set([ + 'services.google.client_id' => $settings['oauth_google_client_id'], + 'services.google.client_secret' => $settings['oauth_google_client_secret'] ?? '', + 'services.google.redirect' => url('/auth/google/callback'), + ]); + } + + if (!empty($settings['oauth_github_client_id'])) { + Config::set([ + 'services.github.client_id' => $settings['oauth_github_client_id'], + 'services.github.client_secret' => $settings['oauth_github_client_secret'] ?? '', + 'services.github.redirect' => url('/auth/github/callback'), + ]); + } + } +} diff --git a/artisan b/artisan new file mode 100644 index 0000000..c35e31d --- /dev/null +++ b/artisan @@ -0,0 +1,18 @@ +#!/usr/bin/env php +handleCommand(new ArgvInput); + +exit($status); diff --git a/bootstrap/app.php b/bootstrap/app.php new file mode 100644 index 0000000..c7858d6 --- /dev/null +++ b/bootstrap/app.php @@ -0,0 +1,37 @@ +withRouting( + web: __DIR__.'/../routes/web.php', + api: __DIR__.'/../routes/api.php', + commands: __DIR__.'/../routes/console.php', + health: '/up', + ) + ->withMiddleware(function (Middleware $middleware): void { + $middleware->web(append: [ + \App\Http\Middleware\HandleInertiaRequests::class, + \Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class, + ]); + + $middleware->alias([ + 'role' => \Spatie\Permission\Middleware\RoleMiddleware::class, + 'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class, + 'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class, + ]); + }) + ->withExceptions(function (Exceptions $e): void { + $e->respond(function (\Symfony\Component\HttpFoundation\Response $response) { + if (in_array($response->getStatusCode(), [403, 404, 419, 500, 503]) + && !request()->expectsJson() + ) { + return inertia('Errors/Error', ['status' => $response->getStatusCode()]) + ->toResponse(request()) + ->setStatusCode($response->getStatusCode()); + } + return $response; + }); + })->create(); diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore new file mode 100755 index 0000000..d6b7ef3 --- /dev/null +++ b/bootstrap/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/bootstrap/providers.php b/bootstrap/providers.php new file mode 100644 index 0000000..40725e7 --- /dev/null +++ b/bootstrap/providers.php @@ -0,0 +1,8 @@ +=5.0.0" + }, + "require-dev": { + "doctrine/dbal": "^4.0.0", + "nesbot/carbon": "^2.71.0 || ^3.0.0", + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KyleKatarn", + "email": "kylekatarnls@gmail.com" + } + ], + "description": "Types to use Carbon in Doctrine", + "keywords": [ + "carbon", + "date", + "datetime", + "doctrine", + "time" + ], + "support": { + "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", + "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" + } + ], + "time": "2024-02-09T16:56:22+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.4", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + } + ], + "time": "2025-08-20T19:15:30+00:00" + }, + { + "name": "dasprid/enum", + "version": "1.0.7", + "source": { + "type": "git", + "url": "https://github.com/DASPRiD/Enum.git", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "shasum": "" + }, + "require": { + "php": ">=7.1 <9.0" + }, + "require-dev": { + "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "PHP 7.1 enum implementation", + "keywords": [ + "enum", + "map" + ], + "support": { + "issues": "https://github.com/DASPRiD/Enum/issues", + "source": "https://github.com/DASPRiD/Enum/tree/1.0.7" + }, + "time": "2025-09-16T12:23:56+00:00" + }, + { + "name": "defuse/php-encryption", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/defuse/php-encryption.git", + "reference": "f53396c2d34225064647a05ca76c1da9d99e5828" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/defuse/php-encryption/zipball/f53396c2d34225064647a05ca76c1da9d99e5828", + "reference": "f53396c2d34225064647a05ca76c1da9d99e5828", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "paragonie/random_compat": ">= 2", + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "^5|^6|^7|^8|^9|^10", + "yoast/phpunit-polyfills": "^2.0.0" + }, + "bin": [ + "bin/generate-defuse-key" + ], + "type": "library", + "autoload": { + "psr-4": { + "Defuse\\Crypto\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Hornby", + "email": "taylor@defuse.ca", + "homepage": "https://defuse.ca/" + }, + { + "name": "Scott Arciszewski", + "email": "info@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "Secure PHP Encryption Library", + "keywords": [ + "aes", + "authenticated encryption", + "cipher", + "crypto", + "cryptography", + "encrypt", + "encryption", + "openssl", + "security", + "symmetric key cryptography" + ], + "support": { + "issues": "https://github.com/defuse/php-encryption/issues", + "source": "https://github.com/defuse/php-encryption/tree/v2.4.0" + }, + "time": "2023-06-19T06:10:36+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.3", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f", + "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3" + }, + "time": "2024-07-08T12:26:09+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/6d6c96277ea252fc1304627204c3d5e6e15faa3b", + "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^12.0 || ^13.0", + "phpstan/phpstan": "^1.12 || ^2.0", + "phpstan/phpstan-phpunit": "^1.4 || ^2.0", + "phpstan/phpstan-strict-rules": "^1.6 || ^2.0", + "phpunit/phpunit": "^8.5 || ^12.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.1.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" + } + ], + "time": "2025-08-10T19:31:58+00:00" + }, + { + "name": "doctrine/lexer", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2024-02-05T11:56:58+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/d61a8a9604ec1f8c3d150d09db6ce98b32675013", + "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013", + "shasum": "" + }, + "require": { + "php": "^8.2|^8.3|^8.4|^8.5" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.32|^2.1.31", + "phpunit/phpunit": "^8.5.48|^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2025-10-31T18:51:33+00:00" + }, + { + "name": "egulias/email-validator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2.0 || ^3.0", + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2025-03-06T22:45:56+00:00" + }, + { + "name": "ezyang/htmlpurifier", + "version": "v4.19.0", + "source": { + "type": "git", + "url": "https://github.com/ezyang/htmlpurifier.git", + "reference": "b287d2a16aceffbf6e0295559b39662612b77fcf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/b287d2a16aceffbf6e0295559b39662612b77fcf", + "reference": "b287d2a16aceffbf6e0295559b39662612b77fcf", + "shasum": "" + }, + "require": { + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" + }, + "require-dev": { + "cerdic/css-tidy": "^1.7 || ^2.0", + "simpletest/simpletest": "dev-master" + }, + "suggest": { + "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", + "ext-bcmath": "Used for unit conversion and imagecrash protection", + "ext-iconv": "Converts text to and from non-UTF-8 encodings", + "ext-tidy": "Used for pretty-printing HTML" + }, + "type": "library", + "autoload": { + "files": [ + "library/HTMLPurifier.composer.php" + ], + "psr-0": { + "HTMLPurifier": "library/" + }, + "exclude-from-classmap": [ + "/library/HTMLPurifier/Language/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-or-later" + ], + "authors": [ + { + "name": "Edward Z. Yang", + "email": "admin@htmlpurifier.org", + "homepage": "http://ezyang.com" + } + ], + "description": "Standards compliant HTML filter written in PHP", + "homepage": "http://htmlpurifier.org/", + "keywords": [ + "html" + ], + "support": { + "issues": "https://github.com/ezyang/htmlpurifier/issues", + "source": "https://github.com/ezyang/htmlpurifier/tree/v4.19.0" + }, + "time": "2025-10-17T16:34:55+00:00" + }, + { + "name": "fakerphp/faker", + "version": "v1.24.1", + "source": { + "type": "git", + "url": "https://github.com/FakerPHP/Faker.git", + "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", + "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "conflict": { + "fzaninotto/faker": "*" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "doctrine/persistence": "^1.3 || ^2.0", + "ext-intl": "*", + "phpunit/phpunit": "^9.5.26", + "symfony/phpunit-bridge": "^5.4.16" + }, + "suggest": { + "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", + "ext-curl": "Required by Faker\\Provider\\Image to download images.", + "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", + "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", + "ext-mbstring": "Required for multibyte Unicode string functionality." + }, + "type": "library", + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "support": { + "issues": "https://github.com/FakerPHP/Faker/issues", + "source": "https://github.com/FakerPHP/Faker/tree/v1.24.1" + }, + "time": "2024-11-21T13:46:39+00:00" + }, + { + "name": "filp/whoops", + "version": "2.18.4", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/d2102955e48b9fd9ab24280a7ad12ed552752c4d", + "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^4.0 || ^5.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.18.4" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2025-08-08T12:00:00+00:00" + }, + { + "name": "firebase/php-jwt", + "version": "v7.0.5", + "source": { + "type": "git", + "url": "https://github.com/googleapis/php-jwt.git", + "reference": "47ad26bab5e7c70ae8a6f08ed25ff83631121380" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/php-jwt/zipball/47ad26bab5e7c70ae8a6f08ed25ff83631121380", + "reference": "47ad26bab5e7c70ae8a6f08ed25ff83631121380", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.4", + "phpfastcache/phpfastcache": "^9.2", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psr/cache": "^2.0||^3.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" + }, + "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "support": { + "issues": "https://github.com/googleapis/php-jwt/issues", + "source": "https://github.com/googleapis/php-jwt/tree/v7.0.5" + }, + "time": "2026-04-01T20:38:03+00:00" + }, + { + "name": "fruitcake/php-cors", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/fruitcake/php-cors.git", + "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379", + "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379", + "shasum": "" + }, + "require": { + "php": "^8.1", + "symfony/http-foundation": "^5.4|^6.4|^7.3|^8" + }, + "require-dev": { + "phpstan/phpstan": "^2", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" + } + ], + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "homepage": "https://github.com/fruitcake/php-cors", + "keywords": [ + "cors", + "laravel", + "symfony" + ], + "support": { + "issues": "https://github.com/fruitcake/php-cors/issues", + "source": "https://github.com/fruitcake/php-cors/tree/v1.4.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2025-12-03T09:33:47+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.1.4", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/e01f4a821471308ba86aa202fed6698b6b695e3b", + "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.5" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.41 || ^9.6.22 || ^10.5.45 || ^11.5.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.4" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2025-12-27T19:43:20+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.10.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^2.3", + "guzzlehttp/psr7": "^2.8", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "guzzle/client-integration-tests": "3.0.2", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.10.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2025-08-23T22:36:01+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "481557b130ef3790cf82b713667b43030dc9c957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957", + "reference": "481557b130ef3790cf82b713667b43030dc9c957", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.44 || ^9.6.25" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.3.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2025-08-22T14:34:08+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.9.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/7d0ed42f28e42d61352a7a79de682e5e67fec884", + "reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "0.9.0", + "jshttp/mime-db": "1.54.0.1", + "phpunit/phpunit": "^8.5.44 || ^9.6.25" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.9.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2026-03-10T16:41:02+00:00" + }, + { + "name": "guzzlehttp/uri-template", + "version": "v1.0.5", + "source": { + "type": "git", + "url": "https://github.com/guzzle/uri-template.git", + "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/4f4bbd4e7172148801e76e3decc1e559bdee34e1", + "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.44 || ^9.6.25", + "uri-template/tests": "1.0.0" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + } + ], + "description": "A polyfill class for uri_template of PHP", + "keywords": [ + "guzzlehttp", + "uri-template" + ], + "support": { + "issues": "https://github.com/guzzle/uri-template/issues", + "source": "https://github.com/guzzle/uri-template/tree/v1.0.5" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/uri-template", + "type": "tidelift" + } + ], + "time": "2025-08-22T14:27:06+00:00" + }, + { + "name": "inertiajs/inertia-laravel", + "version": "v2.0.24", + "source": { + "type": "git", + "url": "https://github.com/inertiajs/inertia-laravel.git", + "reference": "ea345adad12f110edbbc4bef03b69c2374a535d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/inertiajs/inertia-laravel/zipball/ea345adad12f110edbbc4bef03b69c2374a535d4", + "reference": "ea345adad12f110edbbc4bef03b69c2374a535d4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel/framework": "^10.0|^11.0|^12.0|^13.0", + "php": "^8.1.0", + "symfony/console": "^6.2|^7.0|^8.0" + }, + "conflict": { + "laravel/boost": "<2.2.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.2", + "larastan/larastan": "^3.0", + "laravel/pint": "^1.16", + "mockery/mockery": "^1.3.3", + "orchestra/testbench": "^8.0|^9.2|^10.0|^11.0", + "phpunit/phpunit": "^10.4|^11.5|^12.0", + "roave/security-advisories": "dev-master" + }, + "suggest": { + "ext-pcntl": "Recommended when running the Inertia SSR server via the `inertia:start-ssr` artisan command." + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Inertia\\ServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "./helpers.php" + ], + "psr-4": { + "Inertia\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jonathan Reinink", + "email": "jonathan@reinink.ca", + "homepage": "https://reinink.ca" + } + ], + "description": "The Laravel adapter for Inertia.js.", + "keywords": [ + "inertia", + "laravel" + ], + "support": { + "issues": "https://github.com/inertiajs/inertia-laravel/issues", + "source": "https://github.com/inertiajs/inertia-laravel/tree/v2.0.24" + }, + "time": "2026-04-10T14:36:44+00:00" + }, + { + "name": "knuckleswtf/scribe", + "version": "5.10.0", + "source": { + "type": "git", + "url": "https://github.com/knuckleswtf/scribe.git", + "reference": "d4da86e57e49dac4694b200354cfa962bfae3168" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/knuckleswtf/scribe/zipball/d4da86e57e49dac4694b200354cfa962bfae3168", + "reference": "d4da86e57e49dac4694b200354cfa962bfae3168", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "ext-pdo": "*", + "fakerphp/faker": "^1.23.1", + "laravel/framework": "^9.21 || ^10.0 || ^11.0 || ^12.0 || ^13.0", + "league/flysystem": "^3.0", + "mpociot/reflection-docblock": "^1.0.1", + "nikic/php-parser": "^5.0", + "nunomaduro/collision": "^6.0 || ^7.0 || ^8.0", + "parsedown/parsedown": "^1.7", + "php": ">=8.1", + "ramsey/uuid": "^4.2.2", + "shalvah/upgrader": "^0.6.0", + "symfony/var-exporter": "^6.0 || ^7.0 || ^8.0", + "symfony/yaml": "^6.0 || ^7.0 || ^8.0" + }, + "replace": { + "mpociot/laravel-apidoc-generator": "*" + }, + "require-dev": { + "dms/phpunit-arraysubset-asserts": "^0.5.0", + "laravel/legacy-factories": "^1.3.0", + "laravel/pint": "^1.20", + "league/fractal": "^0.20", + "nikic/fast-route": "^1.3", + "orchestra/testbench": "^7.0 || ^8.0 || ^9.10 || ^10.0 || ^11.0", + "pestphp/pest": "^1.21 || ^2.0 || ^3.0 || ^4.0", + "phpstan/phpstan": "^2.1.5", + "phpunit/phpunit": "^9.0 || ^10.0 || ^11.0 || ^12.0", + "spatie/ray": "^1.41", + "symfony/css-selector": "^6.0 || ^7.0 || ^8.0", + "symfony/dom-crawler": "^6.0 || ^7.0 || ^8.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Knuckles\\Scribe\\ScribeServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/Config/helpers.php" + ], + "psr-4": { + "Knuckles\\Camel\\": "camel/", + "Knuckles\\Scribe\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Shalvah" + } + ], + "description": "Generate API documentation for humans from your Laravel codebase.✍", + "homepage": "https://github.com/knuckleswtf/scribe", + "keywords": [ + "api", + "documentation", + "laravel" + ], + "support": { + "issues": "https://github.com/knuckleswtf/scribe/issues", + "source": "https://github.com/knuckleswtf/scribe/tree/5.10.0" + }, + "funding": [ + { + "url": "https://patreon.com/shalvah", + "type": "patreon" + } + ], + "time": "2026-05-09T21:49:49+00:00" + }, + { + "name": "laravel/framework", + "version": "v13.8.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/framework.git", + "reference": "e7db333a025a1e93ebca7744953069d7719f4bcf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/framework/zipball/e7db333a025a1e93ebca7744953069d7719f4bcf", + "reference": "e7db333a025a1e93ebca7744953069d7719f4bcf", + "shasum": "" + }, + "require": { + "brick/math": "^0.14.2 || ^0.15 || ^0.16 || ^0.17", + "composer-runtime-api": "^2.2", + "doctrine/inflector": "^2.0.5", + "dragonmantank/cron-expression": "^3.4", + "egulias/email-validator": "^4.0", + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-session": "*", + "ext-tokenizer": "*", + "fruitcake/php-cors": "^1.3", + "guzzlehttp/guzzle": "^7.8.2", + "guzzlehttp/promises": "^2.0.3", + "guzzlehttp/uri-template": "^1.0", + "laravel/prompts": "^0.3.0", + "laravel/serializable-closure": "^2.0.10", + "league/commonmark": "^2.8.1", + "league/flysystem": "^3.25.1", + "league/flysystem-local": "^3.25.1", + "league/uri": "^7.5.1", + "monolog/monolog": "^3.0", + "nesbot/carbon": "^3.8.4", + "nunomaduro/termwind": "^2.0", + "php": "^8.3", + "psr/container": "^1.1.1 || ^2.0.1", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0", + "ramsey/uuid": "^4.7", + "symfony/console": "^7.4.0 || ^8.0.0", + "symfony/error-handler": "^7.4.0 || ^8.0.0", + "symfony/finder": "^7.4.0 || ^8.0.0", + "symfony/http-foundation": "^7.4.0 || ^8.0.0", + "symfony/http-kernel": "^7.4.0 || ^8.0.0", + "symfony/mailer": "^7.4.0 || ^8.0.0", + "symfony/mime": "^7.4.0 || ^8.0.0", + "symfony/polyfill-php84": "^1.36", + "symfony/polyfill-php85": "^1.36", + "symfony/polyfill-php86": "^1.36", + "symfony/process": "^7.4.5 || ^8.0.5", + "symfony/routing": "^7.4.0 || ^8.0.0", + "symfony/uid": "^7.4.0 || ^8.0.0", + "symfony/var-dumper": "^7.4.0 || ^8.0.0", + "tijsverkoyen/css-to-inline-styles": "^2.2.5", + "vlucas/phpdotenv": "^5.6.1", + "voku/portable-ascii": "^2.0.2" + }, + "conflict": { + "tightenco/collect": "<5.5.33" + }, + "provide": { + "psr/container-implementation": "1.1 || 2.0", + "psr/log-implementation": "1.0 || 2.0 || 3.0", + "psr/simple-cache-implementation": "1.0 || 2.0 || 3.0" + }, + "replace": { + "illuminate/auth": "self.version", + "illuminate/broadcasting": "self.version", + "illuminate/bus": "self.version", + "illuminate/cache": "self.version", + "illuminate/collections": "self.version", + "illuminate/concurrency": "self.version", + "illuminate/conditionable": "self.version", + "illuminate/config": "self.version", + "illuminate/console": "self.version", + "illuminate/container": "self.version", + "illuminate/contracts": "self.version", + "illuminate/cookie": "self.version", + "illuminate/database": "self.version", + "illuminate/encryption": "self.version", + "illuminate/events": "self.version", + "illuminate/filesystem": "self.version", + "illuminate/hashing": "self.version", + "illuminate/http": "self.version", + "illuminate/json-schema": "self.version", + "illuminate/log": "self.version", + "illuminate/macroable": "self.version", + "illuminate/mail": "self.version", + "illuminate/notifications": "self.version", + "illuminate/pagination": "self.version", + "illuminate/pipeline": "self.version", + "illuminate/process": "self.version", + "illuminate/queue": "self.version", + "illuminate/redis": "self.version", + "illuminate/reflection": "self.version", + "illuminate/routing": "self.version", + "illuminate/session": "self.version", + "illuminate/support": "self.version", + "illuminate/testing": "self.version", + "illuminate/translation": "self.version", + "illuminate/validation": "self.version", + "illuminate/view": "self.version", + "spatie/once": "*" + }, + "require-dev": { + "ably/ably-php": "^1.0", + "aws/aws-sdk-php": "^3.322.9", + "ext-gmp": "*", + "fakerphp/faker": "^1.24", + "guzzlehttp/psr7": "^2.4", + "laravel/pint": "^1.18", + "league/flysystem-aws-s3-v3": "^3.25.1", + "league/flysystem-ftp": "^3.25.1", + "league/flysystem-path-prefixing": "^3.25.1", + "league/flysystem-read-only": "^3.25.1", + "league/flysystem-sftp-v3": "^3.25.1", + "mockery/mockery": "^1.6.10", + "opis/json-schema": "^2.4.1", + "orchestra/testbench-core": "^11.0.0", + "pda/pheanstalk": "^7.0.0 || ^8.0.0", + "php-http/discovery": "^1.15", + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^11.5.50 || ^12.5.8 || ^13.0.3", + "predis/predis": "^2.3 || ^3.0", + "rector/rector": "^2.3", + "resend/resend-php": "^1.0", + "symfony/cache": "^7.4.0 || ^8.0.0", + "symfony/http-client": "^7.4.0 || ^8.0.0", + "symfony/psr-http-message-bridge": "^7.4.0 || ^8.0.0", + "symfony/translation": "^7.4.0 || ^8.0.0" + }, + "suggest": { + "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", + "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.322.9).", + "brianium/paratest": "Required to run tests in parallel (^7.0 || ^8.0).", + "ext-apcu": "Required to use the APC cache driver.", + "ext-fileinfo": "Required to use the Filesystem class.", + "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", + "ext-memcached": "Required to use the memcache cache driver.", + "ext-pcntl": "Required to use all features of the queue worker and console signal trapping.", + "ext-pdo": "Required to use all database features.", + "ext-posix": "Required to use all features of the queue worker.", + "ext-redis": "Required to use the Redis cache and queue drivers (^4.0 || ^5.0 || ^6.0).", + "fakerphp/faker": "Required to generate fake data using the fake() helper (^1.23).", + "filp/whoops": "Required for friendly error pages in development (^2.14.3).", + "laravel/tinker": "Required to use the tinker console command (^2.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.25.1).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.25.1).", + "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.25.1).", + "league/flysystem-read-only": "Required to use read-only disks (^3.25.1)", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.25.1).", + "mockery/mockery": "Required to use mocking (^1.6).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^7.0 || ^8.0).", + "php-http/discovery": "Required to use PSR-7 bridging features (^1.15).", + "phpunit/phpunit": "Required to use assertions and run tests (^11.5.50 || ^12.5.8 || ^13.0.3).", + "predis/predis": "Required to use the predis connector (^2.3 || ^3.0).", + "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0 || ^7.0).", + "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0 || ^1.0).", + "spatie/fork": "Required to use the 'fork' concurrency driver (^1.2).", + "symfony/cache": "Required to PSR-6 cache bridge (^7.4 || ^8.0).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^7.4 || ^8.0).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.4 || ^8.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.4 || ^8.0).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.4 || ^8.0).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.4 || ^8.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "13.0.x-dev" + } + }, + "autoload": { + "files": [ + "src/Illuminate/Collections/functions.php", + "src/Illuminate/Collections/helpers.php", + "src/Illuminate/Events/functions.php", + "src/Illuminate/Filesystem/functions.php", + "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Log/functions.php", + "src/Illuminate/Reflection/helpers.php", + "src/Illuminate/Support/functions.php", + "src/Illuminate/Support/helpers.php" + ], + "psr-4": { + "Illuminate\\": "src/Illuminate/", + "Illuminate\\Support\\": [ + "src/Illuminate/Macroable/", + "src/Illuminate/Collections/", + "src/Illuminate/Conditionable/", + "src/Illuminate/Reflection/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Laravel Framework.", + "homepage": "https://laravel.com", + "keywords": [ + "framework", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2026-05-05T21:01:14+00:00" + }, + { + "name": "laravel/passport", + "version": "v13.7.5", + "source": { + "type": "git", + "url": "https://github.com/laravel/passport.git", + "reference": "90053dc4ba681c076855779250109bb624f961f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/passport/zipball/90053dc4ba681c076855779250109bb624f961f6", + "reference": "90053dc4ba681c076855779250109bb624f961f6", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-openssl": "*", + "firebase/php-jwt": "^6.4|^7.0", + "illuminate/auth": "^11.35|^12.0|^13.0", + "illuminate/console": "^11.35|^12.0|^13.0", + "illuminate/container": "^11.35|^12.0|^13.0", + "illuminate/contracts": "^11.35|^12.0|^13.0", + "illuminate/cookie": "^11.35|^12.0|^13.0", + "illuminate/database": "^11.35|^12.0|^13.0", + "illuminate/encryption": "^11.35|^12.0|^13.0", + "illuminate/http": "^11.35|^12.0|^13.0", + "illuminate/support": "^11.35|^12.0|^13.0", + "league/oauth2-server": "^9.2", + "php": "^8.2", + "php-http/discovery": "^1.20", + "phpseclib/phpseclib": "^3.0", + "psr/http-factory-implementation": "*", + "symfony/console": "^7.1|^8.0", + "symfony/psr-http-message-bridge": "^7.1|^8.0" + }, + "require-dev": { + "orchestra/testbench": "^9.15|^10.8|^11.0", + "phpstan/phpstan": "^2.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Passport\\PassportServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Passport\\": "src/", + "Laravel\\Passport\\Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Passport provides OAuth2 server support to Laravel.", + "keywords": [ + "laravel", + "oauth", + "passport" + ], + "support": { + "issues": "https://github.com/laravel/passport/issues", + "source": "https://github.com/laravel/passport" + }, + "time": "2026-04-16T14:00:29+00:00" + }, + { + "name": "laravel/prompts", + "version": "v0.3.17", + "source": { + "type": "git", + "url": "https://github.com/laravel/prompts.git", + "reference": "6a82ac19a28b916ae0885828795dbd4c59d9a818" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/prompts/zipball/6a82ac19a28b916ae0885828795dbd4c59d9a818", + "reference": "6a82ac19a28b916ae0885828795dbd4c59d9a818", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "ext-mbstring": "*", + "php": "^8.1", + "symfony/console": "^6.2|^7.0|^8.0" + }, + "conflict": { + "illuminate/console": ">=10.17.0 <10.25.0", + "laravel/framework": ">=10.17.0 <10.25.0" + }, + "require-dev": { + "illuminate/collections": "^10.0|^11.0|^12.0|^13.0", + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.3|^3.4|^4.0", + "phpstan/phpstan": "^1.12.28", + "phpstan/phpstan-mockery": "^1.1.3" + }, + "suggest": { + "ext-pcntl": "Required for the spinner to be animated." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.3.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Laravel\\Prompts\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Add beautiful and user-friendly forms to your command-line applications.", + "support": { + "issues": "https://github.com/laravel/prompts/issues", + "source": "https://github.com/laravel/prompts/tree/v0.3.17" + }, + "time": "2026-04-20T16:07:33+00:00" + }, + { + "name": "laravel/sanctum", + "version": "v4.3.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/sanctum.git", + "reference": "2a9bccc18e9907808e0018dd15fa643937886b1e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sanctum/zipball/2a9bccc18e9907808e0018dd15fa643937886b1e", + "reference": "2a9bccc18e9907808e0018dd15fa643937886b1e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^11.0|^12.0|^13.0", + "illuminate/contracts": "^11.0|^12.0|^13.0", + "illuminate/database": "^11.0|^12.0|^13.0", + "illuminate/support": "^11.0|^12.0|^13.0", + "php": "^8.2", + "symfony/console": "^7.0|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.6", + "orchestra/testbench": "^9.15|^10.8|^11.0", + "phpstan/phpstan": "^1.10" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Sanctum\\SanctumServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sanctum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.", + "keywords": [ + "auth", + "laravel", + "sanctum" + ], + "support": { + "issues": "https://github.com/laravel/sanctum/issues", + "source": "https://github.com/laravel/sanctum" + }, + "time": "2026-04-30T11:46:25+00:00" + }, + { + "name": "laravel/serializable-closure", + "version": "v2.0.13", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/b566ee0dd251f3c4078bed003a7ce015f5ea6dce", + "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "illuminate/support": "^10.0|^11.0|^12.0|^13.0", + "nesbot/carbon": "^2.67|^3.0", + "pestphp/pest": "^2.36|^3.0|^4.0", + "phpstan/phpstan": "^2.0", + "symfony/var-dumper": "^6.2.0|^7.0.0|^8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2026-04-16T14:03:50+00:00" + }, + { + "name": "laravel/tinker", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/tinker.git", + "reference": "4faba77764bd33411735936acdf30446d058c78b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/tinker/zipball/4faba77764bd33411735936acdf30446d058c78b", + "reference": "4faba77764bd33411735936acdf30446d058c78b", + "shasum": "" + }, + "require": { + "illuminate/console": "^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", + "illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", + "illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", + "php": "^8.1", + "psy/psysh": "^0.12.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0|^8.0" + }, + "require-dev": { + "mockery/mockery": "~1.3.3|^1.4.2", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5|^11.5" + }, + "suggest": { + "illuminate/database": "The Illuminate Database package (^8.0|^9.0|^10.0|^11.0|^12.0|^13.0)." + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Tinker\\TinkerServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\Tinker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Powerful REPL for the Laravel framework.", + "keywords": [ + "REPL", + "Tinker", + "laravel", + "psysh" + ], + "support": { + "issues": "https://github.com/laravel/tinker/issues", + "source": "https://github.com/laravel/tinker/tree/v3.0.2" + }, + "time": "2026-03-17T14:54:13+00:00" + }, + { + "name": "lcobucci/clock", + "version": "3.6.0", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/clock.git", + "reference": "4cdd88f761e9be9095ccbedf3e08d61ae216c643" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/clock/zipball/4cdd88f761e9be9095ccbedf3e08d61ae216c643", + "reference": "4cdd88f761e9be9095ccbedf3e08d61ae216c643", + "shasum": "" + }, + "require": { + "php": "~8.4.0 || ~8.5.0", + "psr/clock": "^1.0" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "require-dev": { + "infection/infection": "^0.32", + "lcobucci/coding-standard": "^12.0", + "phpstan/extension-installer": "^1.3.1", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^13.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lcobucci\\Clock\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Luís Cobucci", + "email": "lcobucci@gmail.com" + } + ], + "description": "Yet another clock abstraction", + "support": { + "issues": "https://github.com/lcobucci/clock/issues", + "source": "https://github.com/lcobucci/clock/tree/3.6.0" + }, + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2026-04-13T21:30:16+00:00" + }, + { + "name": "lcobucci/jwt", + "version": "5.6.0", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/jwt.git", + "reference": "bb3e9f21e4196e8afc41def81ef649c164bca25e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/bb3e9f21e4196e8afc41def81ef649c164bca25e", + "reference": "bb3e9f21e4196e8afc41def81ef649c164bca25e", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-sodium": "*", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", + "psr/clock": "^1.0" + }, + "require-dev": { + "infection/infection": "^0.29", + "lcobucci/clock": "^3.2", + "lcobucci/coding-standard": "^11.0", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.10.7", + "phpstan/phpstan-deprecation-rules": "^1.1.3", + "phpstan/phpstan-phpunit": "^1.3.10", + "phpstan/phpstan-strict-rules": "^1.5.0", + "phpunit/phpunit": "^11.1" + }, + "suggest": { + "lcobucci/clock": ">= 3.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lcobucci\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Luís Cobucci", + "email": "lcobucci@gmail.com", + "role": "Developer" + } + ], + "description": "A simple library to work with JSON Web Token and JSON Web Signature", + "keywords": [ + "JWS", + "jwt" + ], + "support": { + "issues": "https://github.com/lcobucci/jwt/issues", + "source": "https://github.com/lcobucci/jwt/tree/5.6.0" + }, + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2025-10-17T11:30:53+00:00" + }, + { + "name": "league/commonmark", + "version": "2.8.2", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "59fb075d2101740c337c7216e3f32b36c204218b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/59fb075d2101740c337c7216e3f32b36c204218b", + "reference": "59fb075d2101740c337c7216e3f32b36c204218b", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.31.1", + "commonmark/commonmark.js": "0.31.1", + "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4 || ^2.0", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3 | ^6.0 | ^7.0 || ^8.0", + "symfony/process": "^5.4 | ^6.0 | ^7.0 || ^8.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0 || ^8.0", + "unleashedtech/php-coding-standard": "^3.1.1", + "vimeo/psalm": "^4.24.0 || ^5.0.0 || ^6.0.0" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.9-dev" + } + }, + "autoload": { + "psr-4": { + "League\\CommonMark\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], + "support": { + "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2026-03-19T13:16:38+00:00" + }, + { + "name": "league/config", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2022-12-11T20:36:23+00:00" + }, + { + "name": "league/event", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/event.git", + "reference": "ec38ff7ea10cad7d99a79ac937fbcffb9334c210" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/event/zipball/ec38ff7ea10cad7d99a79ac937fbcffb9334c210", + "reference": "ec38ff7ea10cad7d99a79ac937fbcffb9334c210", + "shasum": "" + }, + "require": { + "php": ">=7.2.0", + "psr/event-dispatcher": "^1.0" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16", + "phpstan/phpstan": "^0.12.45", + "phpunit/phpunit": "^8.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Event\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Event package", + "keywords": [ + "emitter", + "event", + "listener" + ], + "support": { + "issues": "https://github.com/thephpleague/event/issues", + "source": "https://github.com/thephpleague/event/tree/3.0.3" + }, + "time": "2024-09-04T16:06:53+00:00" + }, + { + "name": "league/flysystem", + "version": "3.33.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "570b8871e0ce693764434b29154c54b434905350" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/570b8871e0ce693764434b29154c54b434905350", + "reference": "570b8871e0ce693764434b29154c54b434905350", + "shasum": "" + }, + "require": { + "league/flysystem-local": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "async-aws/core": "<1.19.0", + "async-aws/s3": "<1.14.0", + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", + "symfony/http-client": "<5.2" + }, + "require-dev": { + "async-aws/s3": "^1.5 || ^2.0", + "async-aws/simple-s3": "^1.1 || ^2.0", + "aws/aws-sdk-php": "^3.295.10", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-mongodb": "^1.3|^2", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "guzzlehttp/psr7": "^2.6", + "microsoft/azure-storage-blob": "^1.1", + "mongodb/mongodb": "^1.2|^2", + "phpseclib/phpseclib": "^3.0.36", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5.11|^10.0", + "sabre/dav": "^4.6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "File storage abstraction for PHP", + "keywords": [ + "WebDAV", + "aws", + "cloud", + "file", + "files", + "filesystem", + "filesystems", + "ftp", + "s3", + "sftp", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/3.33.0" + }, + "time": "2026-03-25T07:59:30+00:00" + }, + { + "name": "league/flysystem-local", + "version": "3.31.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-local.git", + "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/2f669db18a4c20c755c2bb7d3a7b0b2340488079", + "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "league/flysystem": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\Local\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Local filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "file", + "files", + "filesystem", + "local" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-local/tree/3.31.0" + }, + "time": "2026-01-23T15:30:45+00:00" + }, + { + "name": "league/mime-type-detection", + "version": "1.16.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.16.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2024-09-21T08:32:55+00:00" + }, + { + "name": "league/oauth2-server", + "version": "9.3.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth2-server.git", + "reference": "d8e2f39f645a82b207bbac441694d6e6079357cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/d8e2f39f645a82b207bbac441694d6e6079357cb", + "reference": "d8e2f39f645a82b207bbac441694d6e6079357cb", + "shasum": "" + }, + "require": { + "defuse/php-encryption": "^2.4", + "ext-json": "*", + "ext-openssl": "*", + "lcobucci/clock": "^2.3 || ^3.0", + "lcobucci/jwt": "^5.0", + "league/event": "^3.0", + "league/uri": "^7.0", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", + "psr/http-message": "^2.0", + "psr/http-server-middleware": "^1.0" + }, + "replace": { + "league/oauth2server": "*", + "lncd/oauth2": "*" + }, + "require-dev": { + "laminas/laminas-diactoros": "^3.5", + "php-parallel-lint/php-parallel-lint": "^1.3.2", + "phpstan/extension-installer": "^1.3.1", + "phpstan/phpstan": "^1.12|^2.0", + "phpstan/phpstan-deprecation-rules": "^1.1.4|^2.0", + "phpstan/phpstan-phpunit": "^1.3.15|^2.0", + "phpstan/phpstan-strict-rules": "^1.5.2|^2.0", + "phpunit/phpunit": "^10.5|^11.5|^12.0", + "roave/security-advisories": "dev-master", + "slevomat/coding-standard": "^8.14.1", + "squizlabs/php_codesniffer": "^3.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\OAuth2\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alex Bilbie", + "email": "hello@alexbilbie.com", + "homepage": "http://www.alexbilbie.com", + "role": "Developer" + }, + { + "name": "Andy Millington", + "email": "andrew@noexceptions.io", + "homepage": "https://www.noexceptions.io", + "role": "Developer" + } + ], + "description": "A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.", + "homepage": "https://oauth2.thephpleague.com/", + "keywords": [ + "Authentication", + "api", + "auth", + "authorisation", + "authorization", + "oauth", + "oauth 2", + "oauth 2.0", + "oauth2", + "protect", + "resource", + "secure", + "server" + ], + "support": { + "issues": "https://github.com/thephpleague/oauth2-server/issues", + "source": "https://github.com/thephpleague/oauth2-server/tree/9.3.0" + }, + "funding": [ + { + "url": "https://github.com/sephster", + "type": "github" + } + ], + "time": "2025-11-25T22:51:15+00:00" + }, + { + "name": "league/uri", + "version": "7.8.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri.git", + "reference": "08cf38e3924d4f56238125547b5720496fac8fd4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/08cf38e3924d4f56238125547b5720496fac8fd4", + "reference": "08cf38e3924d4f56238125547b5720496fac8fd4", + "shasum": "" + }, + "require": { + "league/uri-interfaces": "^7.8.1", + "php": "^8.1", + "psr/http-factory": "^1" + }, + "conflict": { + "league/uri-schemes": "^1.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-dom": "to convert the URI into an HTML anchor tag", + "ext-fileinfo": "to create Data URI from file contennts", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "ext-uri": "to use the PHP native URI class", + "jeremykendall/php-domain-parser": "to further parse the URI host and resolve its Public Suffix and Top Level Domain", + "league/uri-components": "to provide additional tools to manipulate URI objects components", + "league/uri-polyfill": "to backport the PHP URI extension for older versions of PHP", + "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "URI manipulation library", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "URN", + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc2141", + "rfc3986", + "rfc3987", + "rfc6570", + "rfc8141", + "uri", + "uri-template", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2026-03-15T20:22:25+00:00" + }, + { + "name": "league/uri-interfaces", + "version": "7.8.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/85d5c77c5d6d3af6c54db4a78246364908f3c928", + "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^8.1", + "psr/http-message": "^1.1 || ^2.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common tools for parsing and resolving RFC3987/RFC3986 URI", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2026-03-08T20:05:35+00:00" + }, + { + "name": "maatwebsite/excel", + "version": "3.1.69", + "source": { + "type": "git", + "url": "https://github.com/SpartnerNL/Laravel-Excel.git", + "reference": "ae5d65b7c9a2fac43bff4d44f796ac95d7a8e760" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/ae5d65b7c9a2fac43bff4d44f796ac95d7a8e760", + "reference": "ae5d65b7c9a2fac43bff4d44f796ac95d7a8e760", + "shasum": "" + }, + "require": { + "composer/semver": "^3.3", + "ext-json": "*", + "illuminate/support": "5.8.*||^6.0||^7.0||^8.0||^9.0||^10.0||^11.0||^12.0||^13.0", + "php": "^7.0||^8.0", + "phpoffice/phpspreadsheet": "^1.30.4", + "psr/simple-cache": "^1.0||^2.0||^3.0" + }, + "require-dev": { + "laravel/scout": "^7.0||^8.0||^9.0||^10.0||^11.0", + "orchestra/testbench": "^6.0||^7.0||^8.0||^9.0||^10.0||^11.0", + "predis/predis": "^1.1" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "Excel": "Maatwebsite\\Excel\\Facades\\Excel" + }, + "providers": [ + "Maatwebsite\\Excel\\ExcelServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Maatwebsite\\Excel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Patrick Brouwers", + "email": "patrick@spartner.nl" + } + ], + "description": "Supercharged Excel exports and imports in Laravel", + "keywords": [ + "PHPExcel", + "batch", + "csv", + "excel", + "export", + "import", + "laravel", + "php", + "phpspreadsheet" + ], + "support": { + "issues": "https://github.com/SpartnerNL/Laravel-Excel/issues", + "source": "https://github.com/SpartnerNL/Laravel-Excel/tree/3.1.69" + }, + "funding": [ + { + "url": "https://laravel-excel.com/commercial-support", + "type": "custom" + }, + { + "url": "https://github.com/patrickbrouwers", + "type": "github" + } + ], + "time": "2026-04-30T20:03:58+00:00" + }, + { + "name": "maennchen/zipstream-php", + "version": "3.2.2", + "source": { + "type": "git", + "url": "https://github.com/maennchen/ZipStream-PHP.git", + "reference": "77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e", + "reference": "77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-zlib": "*", + "php-64bit": "^8.3" + }, + "require-dev": { + "brianium/paratest": "^7.7", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.86", + "guzzlehttp/guzzle": "^7.5", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.5", + "phpunit/phpunit": "^12.0", + "vimeo/psalm": "^6.0" + }, + "suggest": { + "guzzlehttp/psr7": "^2.4", + "psr/http-message": "^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZipStream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paul Duncan", + "email": "pabs@pablotron.org" + }, + { + "name": "Jonatan Männchen", + "email": "jonatan@maennchen.ch" + }, + { + "name": "Jesse Donat", + "email": "donatj@gmail.com" + }, + { + "name": "András Kolesár", + "email": "kolesar@kolesar.hu" + } + ], + "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.", + "keywords": [ + "stream", + "zip" + ], + "support": { + "issues": "https://github.com/maennchen/ZipStream-PHP/issues", + "source": "https://github.com/maennchen/ZipStream-PHP/tree/3.2.2" + }, + "funding": [ + { + "url": "https://github.com/maennchen", + "type": "github" + } + ], + "time": "2026-04-11T18:38:28+00:00" + }, + { + "name": "markbaker/complex", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPComplex.git", + "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9", + "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "phpcompatibility/php-compatibility": "^9.3", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "squizlabs/php_codesniffer": "^3.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with complex numbers", + "homepage": "https://github.com/MarkBaker/PHPComplex", + "keywords": [ + "complex", + "mathematics" + ], + "support": { + "issues": "https://github.com/MarkBaker/PHPComplex/issues", + "source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2" + }, + "time": "2022-12-06T16:21:08+00:00" + }, + { + "name": "markbaker/matrix", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPMatrix.git", + "reference": "728434227fe21be27ff6d86621a1b13107a2562c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c", + "reference": "728434227fe21be27ff6d86621a1b13107a2562c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "phpcompatibility/php-compatibility": "^9.3", + "phpdocumentor/phpdocumentor": "2.*", + "phploc/phploc": "^4.0", + "phpmd/phpmd": "2.*", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "sebastian/phpcpd": "^4.0", + "squizlabs/php_codesniffer": "^3.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Matrix\\": "classes/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@demon-angel.eu" + } + ], + "description": "PHP Class for working with matrices", + "homepage": "https://github.com/MarkBaker/PHPMatrix", + "keywords": [ + "mathematics", + "matrix", + "vector" + ], + "support": { + "issues": "https://github.com/MarkBaker/PHPMatrix/issues", + "source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1" + }, + "time": "2022-12-02T22:17:43+00:00" + }, + { + "name": "monolog/monolog", + "version": "3.10.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0", + "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8 || ^2.0", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "php-console/php-console": "^3.1.8", + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^10.5.17 || ^11.0.7", + "predis/predis": "^1.1 || ^2", + "rollbar/rollbar": "^4.0", + "ruflin/elastica": "^7 || ^8", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/3.10.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2026-01-02T08:56:05+00:00" + }, + { + "name": "mpociot/reflection-docblock", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/mpociot/reflection-docblock.git", + "reference": "c8b2e2b1f5cebbb06e2b5ccbf2958f2198867587" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mpociot/reflection-docblock/zipball/c8b2e2b1f5cebbb06e2b5ccbf2958f2198867587", + "reference": "c8b2e2b1f5cebbb06e2b5ccbf2958f2198867587", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mpociot": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "support": { + "issues": "https://github.com/mpociot/reflection-docblock/issues", + "source": "https://github.com/mpociot/reflection-docblock/tree/master" + }, + "time": "2016-06-20T20:53:12+00:00" + }, + { + "name": "nesbot/carbon", + "version": "3.11.4", + "source": { + "type": "git", + "url": "https://github.com/CarbonPHP/carbon.git", + "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/e890471a3494740f7d9326d72ce6a8c559ffee60", + "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60", + "shasum": "" + }, + "require": { + "carbonphp/carbon-doctrine-types": "<100.0", + "ext-json": "*", + "php": "^8.1", + "psr/clock": "^1.0", + "symfony/clock": "^6.3.12 || ^7.0 || ^8.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0 || ^8.0" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "require-dev": { + "doctrine/dbal": "^3.6.3 || ^4.0", + "doctrine/orm": "^2.15.2 || ^3.0", + "friendsofphp/php-cs-fixer": "^v3.87.1", + "kylekatarnls/multi-tester": "^2.5.3", + "phpmd/phpmd": "^2.15.0", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^2.1.22", + "phpunit/phpunit": "^10.5.53", + "squizlabs/php_codesniffer": "^3.13.4 || ^4.0.0" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev", + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbonphp.github.io/carbon/", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbonphp.github.io/carbon/guide/getting-started/introduction.html", + "issues": "https://github.com/CarbonPHP/carbon/issues", + "source": "https://github.com/CarbonPHP/carbon" + }, + "funding": [ + { + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" + } + ], + "time": "2026-04-07T09:57:54+00:00" + }, + { + "name": "nette/schema", + "version": "v1.3.5", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/f0ab1a3cda782dbc5da270d28545236aa80c4002", + "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.39@stable", + "tracy/tracy": "^2.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.3.5" + }, + "time": "2026-02-23T03:47:12+00:00" + }, + { + "name": "nette/utils", + "version": "v4.1.4", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "7da6c396d7ebe142bc857c20479d5e70a5e1aac7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/7da6c396d7ebe142bc857c20479d5e70a5e1aac7", + "reference": "7da6c396d7ebe142bc857c20479d5e70a5e1aac7", + "shasum": "" + }, + "require": { + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.5", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.1.4" + }, + "time": "2026-05-11T20:49:54+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.7.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + }, + "time": "2025-12-06T11:56:16+00:00" + }, + { + "name": "nunomaduro/collision", + "version": "v8.9.4", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/collision.git", + "reference": "716af8f95a470e9094cfca09ed897b023be191a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/716af8f95a470e9094cfca09ed897b023be191a5", + "reference": "716af8f95a470e9094cfca09ed897b023be191a5", + "shasum": "" + }, + "require": { + "filp/whoops": "^2.18.4", + "nunomaduro/termwind": "^2.4.0", + "php": "^8.2.0", + "symfony/console": "^7.4.8 || ^8.0.8" + }, + "conflict": { + "laravel/framework": "<11.48.0 || >=14.0.0", + "phpunit/phpunit": "<11.5.50 || >=14.0.0" + }, + "require-dev": { + "brianium/paratest": "^7.8.5", + "larastan/larastan": "^3.9.6", + "laravel/framework": "^11.48.0 || ^12.56.0 || ^13.5.0", + "laravel/pint": "^1.29.1", + "orchestra/testbench-core": "^9.12.0 || ^10.12.1 || ^11.2.1", + "pestphp/pest": "^3.8.5 || ^4.4.3 || ^5.0.0", + "sebastian/environment": "^7.2.1 || ^8.0.4 || ^9.3.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" + ] + }, + "branch-alias": { + "dev-8.x": "8.x-dev" + } + }, + "autoload": { + "files": [ + "./src/Adapters/Phpunit/Autoload.php" + ], + "psr-4": { + "NunoMaduro\\Collision\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Cli error handling for console/command-line PHP applications.", + "keywords": [ + "artisan", + "cli", + "command-line", + "console", + "dev", + "error", + "handling", + "laravel", + "laravel-zero", + "php", + "symfony" + ], + "support": { + "issues": "https://github.com/nunomaduro/collision/issues", + "source": "https://github.com/nunomaduro/collision" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2026-04-21T14:04:20+00:00" + }, + { + "name": "nunomaduro/termwind", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "712a31b768f5daea284c2169a7d227031001b9a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/712a31b768f5daea284c2169a7d227031001b9a8", + "reference": "712a31b768f5daea284c2169a7d227031001b9a8", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.2", + "symfony/console": "^7.4.4 || ^8.0.4" + }, + "require-dev": { + "illuminate/console": "^11.47.0", + "laravel/pint": "^1.27.1", + "mockery/mockery": "^1.6.12", + "pestphp/pest": "^2.36.0 || ^3.8.4 || ^4.3.2", + "phpstan/phpstan": "^1.12.32", + "phpstan/phpstan-strict-rules": "^1.6.2", + "symfony/var-dumper": "^7.3.5 || ^8.0.4", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Termwind\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "It's like Tailwind CSS, but for the console.", + "keywords": [ + "cli", + "console", + "css", + "package", + "php", + "style" + ], + "support": { + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v2.4.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", + "type": "github" + } + ], + "time": "2026-02-16T23:10:27+00:00" + }, + { + "name": "paragonie/constant_time_encoding", + "version": "v3.1.3", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", + "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", + "shasum": "" + }, + "require": { + "php": "^8" + }, + "require-dev": { + "infection/infection": "^0", + "nikic/php-fuzzer": "^0", + "phpunit/phpunit": "^9|^10|^11", + "vimeo/psalm": "^4|^5|^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2025-09-24T15:06:41+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, + { + "name": "parsedown/parsedown", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/parsedown/parsedown.git", + "reference": "96baaad00f71ba04d76e45b4620f54d3beabd6f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/parsedown/parsedown/zipball/96baaad00f71ba04d76e45b4620f54d3beabd6f7", + "reference": "96baaad00f71ba04d76e45b4620f54d3beabd6f7", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5|^8.5|^9.6" + }, + "type": "library", + "autoload": { + "psr-0": { + "Parsedown": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Emanuil Rusev", + "email": "hello@erusev.com", + "homepage": "http://erusev.com" + } + ], + "description": "Parser for Markdown.", + "homepage": "http://parsedown.org", + "keywords": [ + "markdown", + "parser" + ], + "support": { + "issues": "https://github.com/parsedown/parsedown/issues", + "source": "https://github.com/parsedown/parsedown/tree/1.8.0" + }, + "time": "2026-02-16T11:41:01+00:00" + }, + { + "name": "php-http/discovery", + "version": "1.20.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/82fe4c73ef3363caed49ff8dd1539ba06044910d", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" + }, + "require-dev": { + "composer/composer": "^1.0.2|^2.0", + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "sebastian/comparator": "^3.0.5 || ^4.0.8", + "symfony/phpunit-bridge": "^6.4.4 || ^7.0.1" + }, + "type": "composer-plugin", + "extra": { + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + }, + "exclude-from-classmap": [ + "src/Composer/Plugin.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr17", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.20.0" + }, + "time": "2024-10-02T11:20:13+00:00" + }, + { + "name": "phpoffice/phpspreadsheet", + "version": "1.30.4", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", + "reference": "02970383cc12e7bf0bc0707ea6e2e8ed23a7aec9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/02970383cc12e7bf0bc0707ea6e2e8ed23a7aec9", + "reference": "02970383cc12e7bf0bc0707ea6e2e8ed23a7aec9", + "shasum": "" + }, + "require": { + "composer/pcre": "^1||^2||^3", + "ext-ctype": "*", + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-gd": "*", + "ext-iconv": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-xml": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "ext-zip": "*", + "ext-zlib": "*", + "ezyang/htmlpurifier": "^4.15", + "maennchen/zipstream-php": "^2.1 || ^3.0", + "markbaker/complex": "^3.0", + "markbaker/matrix": "^3.0", + "php": ">=7.4.0 <8.5.0", + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-main", + "doctrine/instantiator": "^1.5", + "dompdf/dompdf": "^1.0 || ^2.0 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.2", + "mitoteam/jpgraph": "^10.3", + "mpdf/mpdf": "^8.1.1", + "phpcompatibility/php-compatibility": "^9.3", + "phpstan/phpstan": "^1.1", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^8.5 || ^9.0", + "squizlabs/php_codesniffer": "^3.7", + "tecnickcom/tcpdf": "^6.5" + }, + "suggest": { + "dompdf/dompdf": "Option for rendering PDF with PDF Writer", + "ext-intl": "PHP Internationalization Functions", + "mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", + "mpdf/mpdf": "Option for rendering PDF with PDF Writer", + "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Maarten Balliauw", + "homepage": "https://blog.maartenballiauw.be" + }, + { + "name": "Mark Baker", + "homepage": "https://markbakeruk.net" + }, + { + "name": "Franck Lefevre", + "homepage": "https://rootslabs.net" + }, + { + "name": "Erik Tilt" + }, + { + "name": "Adrien Crivelli" + }, + { + "name": "Owen Leibman" + } + ], + "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", + "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", + "keywords": [ + "OpenXML", + "excel", + "gnumeric", + "ods", + "php", + "spreadsheet", + "xls", + "xlsx" + ], + "support": { + "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.30.4" + }, + "time": "2026-04-19T06:00:39+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.9.5", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "75365b91986c2405cf5e1e012c5595cd487a98be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/75365b91986c2405cf5e1e012c5595cd487a98be", + "reference": "75365b91986c2405cf5e1e012c5595cd487a98be", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.44 || ^9.6.25 || ^10.5.53 || ^11.5.34" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.5" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2025-12-27T19:41:33+00:00" + }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.52", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "2adaefc83df2ec548558307690f376dd7d4f4fce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/2adaefc83df2ec548558307690f376dd7d4f4fce", + "reference": "2adaefc83df2ec548558307690f376dd7d4f4fce", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2|^3", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.52" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2026-04-27T07:02:15+00:00" + }, + { + "name": "pragmarx/google2fa", + "version": "v9.0.0", + "source": { + "type": "git", + "url": "https://github.com/antonioribeiro/google2fa.git", + "reference": "e6bc62dd6ae83acc475f57912e27466019a1f2cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/e6bc62dd6ae83acc475f57912e27466019a1f2cf", + "reference": "e6bc62dd6ae83acc475f57912e27466019a1f2cf", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1.0|^2.0|^3.0", + "php": "^7.1|^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.9", + "phpunit/phpunit": "^7.5.15|^8.5|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "PragmaRX\\Google2FA\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antonio Carlos Ribeiro", + "email": "acr@antoniocarlosribeiro.com", + "role": "Creator & Designer" + } + ], + "description": "A One Time Password Authentication package, compatible with Google Authenticator.", + "keywords": [ + "2fa", + "Authentication", + "Two Factor Authentication", + "google2fa" + ], + "support": { + "issues": "https://github.com/antonioribeiro/google2fa/issues", + "source": "https://github.com/antonioribeiro/google2fa/tree/v9.0.0" + }, + "time": "2025-09-19T22:51:08+00:00" + }, + { + "name": "pragmarx/google2fa-laravel", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/antonioribeiro/google2fa-laravel.git", + "reference": "d885bb5bca8be03b226d040aa80250402760a67c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antonioribeiro/google2fa-laravel/zipball/d885bb5bca8be03b226d040aa80250402760a67c", + "reference": "d885bb5bca8be03b226d040aa80250402760a67c", + "shasum": "" + }, + "require": { + "laravel/framework": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", + "php": ">=7.0", + "pragmarx/google2fa-qrcode": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "bacon/bacon-qr-code": "^2.0", + "orchestra/testbench": "3.4.*|3.5.*|3.6.*|3.7.*|4.*|5.*|6.*|7.*|8.*|9.*|10.*|11.*", + "phpunit/phpunit": "~5|~6|~7|~8|~9|~10|~11|~12" + }, + "suggest": { + "bacon/bacon-qr-code": "Required to generate inline QR Codes.", + "pragmarx/recovery": "Generate recovery codes." + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "Google2FA": "PragmaRX\\Google2FALaravel\\Facade" + }, + "providers": [ + "PragmaRX\\Google2FALaravel\\ServiceProvider" + ] + }, + "component": "package", + "frameworks": [ + "Laravel" + ], + "branch-alias": { + "dev-master": "0.2-dev" + } + }, + "autoload": { + "psr-4": { + "PragmaRX\\Google2FALaravel\\": "src/", + "PragmaRX\\Google2FALaravel\\Tests\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antonio Carlos Ribeiro", + "email": "acr@antoniocarlosribeiro.com", + "role": "Creator & Designer" + } + ], + "description": "A One Time Password Authentication package, compatible with Google Authenticator.", + "keywords": [ + "Authentication", + "Two Factor Authentication", + "google2fa", + "laravel" + ], + "support": { + "issues": "https://github.com/antonioribeiro/google2fa-laravel/issues", + "source": "https://github.com/antonioribeiro/google2fa-laravel/tree/v3.0.1" + }, + "time": "2026-03-17T20:54:53+00:00" + }, + { + "name": "pragmarx/google2fa-qrcode", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/antonioribeiro/google2fa-qrcode.git", + "reference": "ce4d8a729b6c93741c607cfb2217acfffb5bf76b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antonioribeiro/google2fa-qrcode/zipball/ce4d8a729b6c93741c607cfb2217acfffb5bf76b", + "reference": "ce4d8a729b6c93741c607cfb2217acfffb5bf76b", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "pragmarx/google2fa": ">=4.0" + }, + "require-dev": { + "bacon/bacon-qr-code": "^2.0", + "chillerlan/php-qrcode": "^1.0|^2.0|^3.0|^4.0", + "khanamiryan/qrcode-detector-decoder": "^1.0", + "phpunit/phpunit": "~4|~5|~6|~7|~8|~9" + }, + "suggest": { + "bacon/bacon-qr-code": "For QR Code generation, requires imagick", + "chillerlan/php-qrcode": "For QR Code generation" + }, + "type": "library", + "extra": { + "component": "package", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "PragmaRX\\Google2FAQRCode\\": "src/", + "PragmaRX\\Google2FAQRCode\\Tests\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antonio Carlos Ribeiro", + "email": "acr@antoniocarlosribeiro.com", + "role": "Creator & Designer" + } + ], + "description": "QR Code package for Google2FA", + "keywords": [ + "2fa", + "Authentication", + "Two Factor Authentication", + "google2fa", + "qr code", + "qrcode" + ], + "support": { + "issues": "https://github.com/antonioribeiro/google2fa-qrcode/issues", + "source": "https://github.com/antonioribeiro/google2fa-qrcode/tree/v3.0.0" + }, + "time": "2021-08-15T12:53:48+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/http-server-handler", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-handler.git", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side request handler", + "keywords": [ + "handler", + "http", + "http-interop", + "psr", + "psr-15", + "psr-7", + "request", + "response", + "server" + ], + "support": { + "source": "https://github.com/php-fig/http-server-handler/tree/1.0.2" + }, + "time": "2023-04-10T20:06:20+00:00" + }, + { + "name": "psr/http-server-middleware", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-middleware.git", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/http-server-handler": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side middleware", + "keywords": [ + "http", + "http-interop", + "middleware", + "psr", + "psr-15", + "psr-7", + "request", + "response" + ], + "support": { + "issues": "https://github.com/php-fig/http-server-middleware/issues", + "source": "https://github.com/php-fig/http-server-middleware/tree/1.0.2" + }, + "time": "2023-04-11T06:14:47+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "psy/psysh", + "version": "v0.12.22", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "3be75d5b9244936dd4ac62ade2bfb004d13acf0f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/3be75d5b9244936dd4ac62ade2bfb004d13acf0f", + "reference": "3be75d5b9244936dd4ac62ade2bfb004d13acf0f", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^5.0 || ^4.0", + "php": "^8.0 || ^7.4", + "symfony/console": "^8.0 || ^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^8.0 || ^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2", + "composer/class-map-generator": "^1.6" + }, + "suggest": { + "composer/class-map-generator": "Improved tab completion performance with better class discovery.", + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": false, + "forward-command": false + }, + "branch-alias": { + "dev-main": "0.12.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "https://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "support": { + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.12.22" + }, + "time": "2026-03-22T23:03:24+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "ramsey/collection", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.45", + "fakerphp/faker": "^1.24", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^2.1", + "mockery/mockery": "^1.6", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpspec/prophecy-phpunit": "^2.3", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5", + "ramsey/coding-standard": "^2.3", + "ramsey/conventional-commits": "^1.6", + "roave/security-advisories": "dev-latest" + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/2.1.1" + }, + "time": "2025-03-22T05:38:12+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.9.2", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "8429c78ca35a09f27565311b98101e2826affde0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/8429c78ca35a09f27565311b98101e2826affde0", + "reference": "8429c78ca35a09f27565311b98101e2826affde0", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.25", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "ergebnis/composer-normalize": "^2.47", + "mockery/mockery": "^1.6", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.6", + "php-mock/php-mock-mockery": "^1.5", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "phpbench/phpbench": "^1.2.14", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6", + "slevomat/coding-standard": "^8.18", + "squizlabs/php_codesniffer": "^3.13" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.9.2" + }, + "time": "2025-12-14T04:43:48+00:00" + }, + { + "name": "shalvah/upgrader", + "version": "0.6.0", + "source": { + "type": "git", + "url": "https://github.com/shalvah/upgrader.git", + "reference": "d95ed17fe9f5e1ee7d47ad835595f1af080a867f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/shalvah/upgrader/zipball/d95ed17fe9f5e1ee7d47ad835595f1af080a867f", + "reference": "d95ed17fe9f5e1ee7d47ad835595f1af080a867f", + "shasum": "" + }, + "require": { + "illuminate/support": ">=8.0", + "nikic/php-parser": "^5.0", + "php": ">=8.0" + }, + "require-dev": { + "dms/phpunit-arraysubset-asserts": "^0.2.0", + "pestphp/pest": "^1.21", + "phpstan/phpstan": "^1.0", + "spatie/ray": "^1.33" + }, + "type": "library", + "autoload": { + "psr-4": { + "Shalvah\\Upgrader\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Shalvah", + "email": "hello@shalvah.me" + } + ], + "description": "Create automatic upgrades for your package.", + "homepage": "http://github.com/shalvah/upgrader", + "keywords": [ + "upgrade" + ], + "support": { + "issues": "https://github.com/shalvah/upgrader/issues", + "source": "https://github.com/shalvah/upgrader/tree/0.6.0" + }, + "funding": [ + { + "url": "https://patreon.com/shalvah", + "type": "patreon" + } + ], + "time": "2024-02-20T11:51:46+00:00" + }, + { + "name": "spatie/laravel-activitylog", + "version": "4.12.3", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-activitylog.git", + "reference": "2a2024fcac05628b0d1bfdbb1b94dda8b0661dc0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-activitylog/zipball/2a2024fcac05628b0d1bfdbb1b94dda8b0661dc0", + "reference": "2a2024fcac05628b0d1bfdbb1b94dda8b0661dc0", + "shasum": "" + }, + "require": { + "illuminate/config": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0 || ^13.0", + "illuminate/database": "^8.69 || ^9.27 || ^10.0 || ^11.0 || ^12.0 || ^13.0", + "illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0 || ^13.0", + "php": "^8.1", + "spatie/laravel-package-tools": "^1.6.3" + }, + "require-dev": { + "ext-json": "*", + "orchestra/testbench": "^6.23 || ^7.0 || ^8.0 || ^9.6 || ^10.0 || ^11.0", + "pestphp/pest": "^1.20 || ^2.0 || ^3.0 || ^4.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Activitylog\\ActivitylogServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Activitylog\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Sebastian De Deyne", + "email": "sebastian@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Tom Witkowski", + "email": "dev.gummibeer@gmail.com", + "homepage": "https://gummibeer.de", + "role": "Developer" + } + ], + "description": "A very simple activity logger to monitor the users of your website or application", + "homepage": "https://github.com/spatie/activitylog", + "keywords": [ + "activity", + "laravel", + "log", + "spatie", + "user" + ], + "support": { + "issues": "https://github.com/spatie/laravel-activitylog/issues", + "source": "https://github.com/spatie/laravel-activitylog/tree/4.12.3" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2026-03-24T12:33:53+00:00" + }, + { + "name": "spatie/laravel-package-tools", + "version": "1.93.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-package-tools.git", + "reference": "0d097bce95b2bf6802fb1d83e1e753b0f5a948e7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/0d097bce95b2bf6802fb1d83e1e753b0f5a948e7", + "reference": "0d097bce95b2bf6802fb1d83e1e753b0f5a948e7", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^10.0|^11.0|^12.0|^13.0", + "php": "^8.1" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "orchestra/testbench": "^8.0|^9.2|^10.0|^11.0", + "pestphp/pest": "^2.1|^3.1|^4.0", + "phpunit/php-code-coverage": "^10.0|^11.0|^12.0", + "phpunit/phpunit": "^10.5|^11.5|^12.5", + "spatie/pest-plugin-test-time": "^2.2|^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\LaravelPackageTools\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Tools for creating Laravel packages", + "homepage": "https://github.com/spatie/laravel-package-tools", + "keywords": [ + "laravel-package-tools", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-package-tools/issues", + "source": "https://github.com/spatie/laravel-package-tools/tree/1.93.0" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2026-02-21T12:49:54+00:00" + }, + { + "name": "spatie/laravel-permission", + "version": "7.4.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-permission.git", + "reference": "ef42ecb781e5534d368a3853fa161e420ad51397" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/ef42ecb781e5534d368a3853fa161e420ad51397", + "reference": "ef42ecb781e5534d368a3853fa161e420ad51397", + "shasum": "" + }, + "require": { + "illuminate/auth": "^12.0|^13.0", + "illuminate/container": "^12.0|^13.0", + "illuminate/contracts": "^12.0|^13.0", + "illuminate/database": "^12.0|^13.0", + "php": "^8.3", + "spatie/laravel-package-tools": "^1.0" + }, + "require-dev": { + "larastan/larastan": "^3.9", + "laravel/passport": "^13.0", + "laravel/pint": "^1.0", + "orchestra/testbench": "^10.0|^11.0", + "pestphp/pest": "^3.0|^4.0", + "pestphp/pest-plugin-laravel": "^3.0|^4.1", + "phpstan/phpstan": "^2.1" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Permission\\PermissionServiceProvider" + ] + }, + "branch-alias": { + "dev-main": "7.x-dev", + "dev-master": "7.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Permission\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Permission handling for Laravel 12 and up", + "homepage": "https://github.com/spatie/laravel-permission", + "keywords": [ + "acl", + "laravel", + "permission", + "permissions", + "rbac", + "roles", + "security", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-permission/issues", + "source": "https://github.com/spatie/laravel-permission/tree/7.4.1" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2026-04-29T07:59:45+00:00" + }, + { + "name": "symfony/clock", + "version": "v7.4.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/clock.git", + "reference": "674fa3b98e21531dd040e613479f5f6fa8f32111" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/clock/zipball/674fa3b98e21531dd040e613479f5f6fa8f32111", + "reference": "674fa3b98e21531dd040e613479f5f6fa8f32111", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/clock": "^1.0", + "symfony/polyfill-php83": "^1.28" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/now.php" + ], + "psr-4": { + "Symfony\\Component\\Clock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Decouples applications from the system clock", + "homepage": "https://symfony.com", + "keywords": [ + "clock", + "psr20", + "time" + ], + "support": { + "source": "https://github.com/symfony/clock/tree/v7.4.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-24T13:12:05+00:00" + }, + { + "name": "symfony/console", + "version": "v7.4.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "d7d2b64a45a89d607865927b176fa51c33ddbb58" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/d7d2b64a45a89d607865927b176fa51c33ddbb58", + "reference": "d7d2b64a45a89d607865927b176fa51c33ddbb58", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.2|^8.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/event-dispatcher": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/lock": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-22T15:21:55+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v7.4.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "b75663ed96cf4756e28e3105476f220f92886cc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/b75663ed96cf4756e28e3105476f220f92886cc4", + "reference": "b75663ed96cf4756e28e3105476f220f92886cc4", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Converts CSS selectors to XPath expressions", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v7.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-18T13:18:21+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/50f59d1f3ca46d41ac911f97a78626b6756af35b", + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-13T15:52:40+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v7.4.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "8dd79d8af777ee6cba2fd4d98da6ffb839f3c0fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/8dd79d8af777ee6cba2fd4d98da6ffb839f3c0fa", + "reference": "8dd79d8af777ee6cba2fd4d98da6ffb839f3c0fa", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/polyfill-php85": "^1.32", + "symfony/var-dumper": "^6.4|^7.0|^8.0" + }, + "conflict": { + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/serializer": "^6.4|^7.0|^8.0", + "symfony/webpack-encore-bundle": "^1.0|^2.0" + }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v7.4.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-24T13:12:05+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.4.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "e4a2e29753c7801f7a8340e066cfa788f3bc8101" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e4a2e29753c7801f7a8340e066cfa788f3bc8101", + "reference": "e4a2e29753c7801f7a8340e066cfa788f3bc8101", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/error-handler": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/framework-bundle": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-18T13:18:21+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "ccba7060602b7fed0b03c85bf025257f76d9ef32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/ccba7060602b7fed0b03c85bf025257f76d9ef32", + "reference": "ccba7060602b7fed0b03c85bf025257f76d9ef32", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.7.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-01-05T13:30:16+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.4.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "e0be088d22278583a82da281886e8c3592fbf149" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/e0be088d22278583a82da281886e8c3592fbf149", + "reference": "e0be088d22278583a82da281886e8c3592fbf149", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v7.4.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-24T13:12:05+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v7.4.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "9381209597ec66c25be154cbf2289076e64d1eab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9381209597ec66c25be154cbf2289076e64d1eab", + "reference": "9381209597ec66c25be154cbf2289076e64d1eab", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "^1.1" + }, + "conflict": { + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4.12|>=7.0,<7.1.5" + }, + "require-dev": { + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.4.12|^7.1.5|^8.0", + "symfony/clock": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/mime": "^6.4|^7.0|^8.0", + "symfony/rate-limiter": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v7.4.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-24T13:12:05+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v7.4.10", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "23486f59234c6fd6e8f1bec97124f3829d686627" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/23486f59234c6fd6e8f1bec97124f3829d686627", + "reference": "23486f59234c6fd6e8f1bec97124f3829d686627", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0|^8.0", + "symfony/event-dispatcher": "^7.3|^8.0", + "symfony/http-foundation": "^7.4|^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<6.4", + "symfony/cache": "<6.4", + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/flex": "<2.10", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/translation": "<6.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<6.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.4", + "twig/twig": "<3.12" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^6.4|^7.0|^8.0", + "symfony/clock": "^6.4|^7.0|^8.0", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/css-selector": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4.1|^7.0.1|^8.0", + "symfony/dom-crawler": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/finder": "^6.4|^7.0|^8.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/property-access": "^7.1|^8.0", + "symfony/routing": "^6.4|^7.0|^8.0", + "symfony/serializer": "^7.1|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0", + "symfony/translation": "^6.4|^7.0|^8.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^6.4|^7.0|^8.0", + "symfony/validator": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0", + "symfony/var-exporter": "^6.4|^7.0|^8.0", + "twig/twig": "^3.12" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a structured process for converting a Request into a Response", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v7.4.10" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-06T12:07:34+00:00" + }, + { + "name": "symfony/mailer", + "version": "v7.4.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "f6ea532250b476bfc1b56699b388a1bdbf168f62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/f6ea532250b476bfc1b56699b388a1bdbf168f62", + "reference": "f6ea532250b476bfc1b56699b388a1bdbf168f62", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.2", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^6.4|^7.0|^8.0", + "symfony/mime": "^7.2|^8.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/twig-bridge": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/http-client": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/twig-bridge": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v7.4.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-24T13:12:05+00:00" + }, + { + "name": "symfony/mime", + "version": "v7.4.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "2d550c4758ba4c47519a6667c36553d535705b0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/2d550c4758ba4c47519a6667c36553d535705b0c", + "reference": "2d550c4758ba4c47519a6667c36553d535705b0c", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<5.2|>=7", + "phpdocumentor/type-resolver": "<1.5.1", + "symfony/mailer": "<6.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^5.2|^6.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/property-access": "^6.4|^7.0|^8.0", + "symfony/property-info": "^6.4|^7.0|^8.0", + "symfony/serializer": "^6.4.3|^7.0.3|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v7.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-29T13:21:53+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-10T16:19:22+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/4864388bfbd3001ce88e234fab652acd91fdc57e", + "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-26T13:13:48+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-10T14:38:51+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-10T17:25:58+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-10T16:19:22+00:00" + }, + { + "name": "symfony/polyfill-php83", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/3600c2cb22399e25bb226e4a135ce91eeb2a6149", + "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-10T17:25:58+00:00" + }, + { + "name": "symfony/polyfill-php84", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06", + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php84\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php84/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-10T18:47:49+00:00" + }, + { + "name": "symfony/polyfill-php85", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php85.git", + "reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/fcfa4973a9917cef23f2e38774da74a2b7d115ee", + "reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php85\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.5+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php85/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-26T13:10:57+00:00" + }, + { + "name": "symfony/polyfill-php86", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php86.git", + "reference": "33d8fc5a705481e21fe3a81212b26f9b1f61749c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php86/zipball/33d8fc5a705481e21fe3a81212b26f9b1f61749c", + "reference": "33d8fc5a705481e21fe3a81212b26f9b1f61749c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php86\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.6+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php86/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-26T13:13:48+00:00" + }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/26dfec253c4cf3e51b541b52ddf7e42cb0908e94", + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-uuid": "*" + }, + "suggest": { + "ext-uuid": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Uuid\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for uuid functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-10T16:19:22+00:00" + }, + { + "name": "symfony/process", + "version": "v7.4.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "60f19cd3badc8de688421e21e4305eba50f8089a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/60f19cd3badc8de688421e21e4305eba50f8089a", + "reference": "60f19cd3badc8de688421e21e4305eba50f8089a", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v7.4.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-24T13:12:05+00:00" + }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v8.0.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "94facc221260c1d5f20e31ee43cd6c6a824b4a19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/94facc221260c1d5f20e31ee43cd6c6a824b4a19", + "reference": "94facc221260c1d5f20e31ee43cd6c6a824b4a19", + "shasum": "" + }, + "require": { + "php": ">=8.4", + "psr/http-message": "^1.0|^2.0", + "symfony/http-foundation": "^7.4|^8.0" + }, + "conflict": { + "php-http/discovery": "<1.15" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "php-http/discovery": "^1.15", + "psr/log": "^1.1.4|^2|^3", + "symfony/browser-kit": "^7.4|^8.0", + "symfony/config": "^7.4|^8.0", + "symfony/event-dispatcher": "^7.4|^8.0", + "symfony/framework-bundle": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/runtime": "^7.4|^8.0" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "https://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "support": { + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v8.0.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-30T15:14:47+00:00" + }, + { + "name": "symfony/routing", + "version": "v7.4.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "287771d8bc86eacb30678dd10eda6c64a859951f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/287771d8bc86eacb30678dd10eda6c64a859951f", + "reference": "287771d8bc86eacb30678dd10eda6c64a859951f", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/yaml": "<6.4" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/yaml": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Maps an HTTP request to a set of configuration variables", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "support": { + "source": "https://github.com/symfony/routing/tree/v7.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-22T15:21:55+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d25d82433a80eba6aa0e6c24b61d7370d99e444a", + "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.7.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-28T09:44:51+00:00" + }, + { + "name": "symfony/string", + "version": "v7.4.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "114ac57257d75df748eda23dd003878080b8e688" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/114ac57257d75df748eda23dd003878080b8e688", + "reference": "114ac57257d75df748eda23dd003878080b8e688", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.33", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.1|^8.0", + "symfony/http-client": "^6.4|^7.0|^8.0", + "symfony/intl": "^6.4|^7.0|^8.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.4.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-24T13:12:05+00:00" + }, + { + "name": "symfony/translation", + "version": "v7.4.10", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "ada7578c30dd5feaa8259cff3e885069ea81ddde" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/ada7578c30dd5feaa8259cff3e885069ea81ddde", + "reference": "ada7578c30dd5feaa8259cff3e885069ea81ddde", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.5.3|^3.3" + }, + "conflict": { + "nikic/php-parser": "<5.0", + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<6.4", + "symfony/yaml": "<6.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "nikic/php-parser": "^5.0", + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/finder": "^6.4|^7.0|^8.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/intl": "^6.4|^7.0|^8.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^6.4|^7.0|^8.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v7.4.10" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-06T11:19:24+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "0ab302977a952b42fd51475c4ebac81f8da0a95d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/0ab302977a952b42fd51475c4ebac81f8da0a95d", + "reference": "0ab302977a952b42fd51475c4ebac81f8da0a95d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v3.7.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-01-05T13:30:16+00:00" + }, + { + "name": "symfony/uid", + "version": "v7.4.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/uid.git", + "reference": "2676b524340abcfe4d6151ec698463cebafee439" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/uid/zipball/2676b524340abcfe4d6151ec698463cebafee439", + "reference": "2676b524340abcfe4d6151ec698463cebafee439", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-uuid": "^1.15" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Uid\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to generate and represent UIDs", + "homepage": "https://symfony.com", + "keywords": [ + "UID", + "ulid", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/uid/tree/v7.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-30T15:19:22+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v7.4.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "9510c3966f749a1d1ff0059e1eabef6cc621e7fd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/9510c3966f749a1d1ff0059e1eabef6cc621e7fd", + "reference": "9510c3966f749a1d1ff0059e1eabef6cc621e7fd", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/uid": "^6.4|^7.0|^8.0", + "twig/twig": "^3.12" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v7.4.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-30T13:44:50+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v7.4.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "22e03a49c95ef054a43601cd159b222bfab1c701" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/22e03a49c95ef054a43601cd159b222bfab1c701", + "reference": "22e03a49c95ef054a43601cd159b222bfab1c701", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "require-dev": { + "symfony/property-access": "^6.4|^7.0|^8.0", + "symfony/serializer": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v7.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-18T13:18:21+00:00" + }, + { + "name": "symfony/yaml", + "version": "v7.4.10", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "c660d6538545a3e8e65a5621ee3d7a6d352892c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/c660d6538545a3e8e65a5621ee3d7a6d352892c7", + "reference": "c660d6538545a3e8e65a5621ee3d7a6d352892c7", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0|^8.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v7.4.10" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-05T08:01:55+00:00" + }, + { + "name": "tightenco/ziggy", + "version": "v2.6.2", + "source": { + "type": "git", + "url": "https://github.com/tighten/ziggy.git", + "reference": "8a0b645921623f77dceaf543d61ecd51a391d96e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tighten/ziggy/zipball/8a0b645921623f77dceaf543d61ecd51a391d96e", + "reference": "8a0b645921623f77dceaf543d61ecd51a391d96e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel/framework": ">=9.0", + "php": ">=8.1" + }, + "require-dev": { + "laravel/folio": "^1.1", + "orchestra/testbench": "^8.0 || ^9.0 || ^10.0", + "pestphp/pest": "^2.0 || ^3.0 || ^4.0", + "pestphp/pest-plugin-laravel": "^2.0 || ^3.0 || ^4.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Tighten\\Ziggy\\ZiggyServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Tighten\\Ziggy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Coulbourne", + "email": "daniel@tighten.co" + }, + { + "name": "Jake Bathman", + "email": "jake@tighten.co" + }, + { + "name": "Jacob Baker-Kretzmar", + "email": "jacob@tighten.co" + } + ], + "description": "Use your Laravel named routes in JavaScript.", + "homepage": "https://github.com/tighten/ziggy", + "keywords": [ + "Ziggy", + "javascript", + "laravel", + "routes" + ], + "support": { + "issues": "https://github.com/tighten/ziggy/issues", + "source": "https://github.com/tighten/ziggy/tree/v2.6.2" + }, + "time": "2026-03-05T14:41:19+00:00" + }, + { + "name": "tijsverkoyen/css-to-inline-styles", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", + "reference": "f0292ccf0ec75843d65027214426b6b163b48b41" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/f0292ccf0ec75843d65027214426b6b163b48b41", + "reference": "f0292ccf0ec75843d65027214426b6b163b48b41", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": "^7.4 || ^8.0", + "symfony/css-selector": "^5.4 || ^6.0 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^8.5.21 || ^9.5.10" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "TijsVerkoyen\\CssToInlineStyles\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "css_to_inline_styles@verkoyen.eu", + "role": "Developer" + } + ], + "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", + "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "support": { + "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.4.0" + }, + "time": "2025-12-02T11:56:42+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.6.3", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "955e7815d677a3eaa7075231212f2110983adecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/955e7815d677a3eaa7075231212f2110983adecc", + "reference": "955e7815d677a3eaa7075231212f2110983adecc", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.1.4", + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.5", + "symfony/polyfill-ctype": "^1.26", + "symfony/polyfill-mbstring": "^1.26", + "symfony/polyfill-php80": "^1.26" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-filter": "*", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "5.6-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2025-12-27T19:49:13+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "8e1051fe39379367aecf014f41744ce7539a856f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/8e1051fe39379367aecf014f41744ce7539a856f", + "reference": "8e1051fe39379367aecf014f41744ce7539a856f", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "phpunit/phpunit": "~8.5 || ~9.6 || ~10.5 || ~11.5" + }, + "suggest": { + "ext-intl": "Use Intl for transliterator_transliterate() support" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Moelleken", + "homepage": "https://www.moelleken.org/" + } + ], + "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", + "homepage": "https://github.com/voku/portable-ascii", + "keywords": [ + "ascii", + "clean", + "php" + ], + "support": { + "issues": "https://github.com/voku/portable-ascii/issues", + "source": "https://github.com/voku/portable-ascii/tree/2.1.1" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-ascii", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2026-04-26T05:33:54+00:00" + } + ], + "packages-dev": [ + { + "name": "brianium/paratest", + "version": "v7.20.0", + "source": { + "type": "git", + "url": "https://github.com/paratestphp/paratest.git", + "reference": "81c80677c9ec0ed4ef16b246167f11dec81a6e3d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/81c80677c9ec0ed4ef16b246167f11dec81a6e3d", + "reference": "81c80677c9ec0ed4ef16b246167f11dec81a6e3d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-simplexml": "*", + "fidry/cpu-core-counter": "^1.3.0", + "jean85/pretty-package-versions": "^2.1.1", + "php": "~8.3.0 || ~8.4.0 || ~8.5.0", + "phpunit/php-code-coverage": "^12.5.3 || ^13.0.1", + "phpunit/php-file-iterator": "^6.0.1 || ^7", + "phpunit/php-timer": "^8 || ^9", + "phpunit/phpunit": "^12.5.14 || ^13.0.5", + "sebastian/environment": "^8.0.3 || ^9", + "symfony/console": "^7.4.7 || ^8.0.7", + "symfony/process": "^7.4.5 || ^8.0.5" + }, + "require-dev": { + "doctrine/coding-standard": "^14.0.0", + "ext-pcntl": "*", + "ext-pcov": "*", + "ext-posix": "*", + "phpstan/phpstan": "^2.1.44", + "phpstan/phpstan-deprecation-rules": "^2.0.4", + "phpstan/phpstan-phpunit": "^2.0.16", + "phpstan/phpstan-strict-rules": "^2.0.10", + "symfony/filesystem": "^7.4.6 || ^8.0.6" + }, + "bin": [ + "bin/paratest", + "bin/paratest_for_phpstorm" + ], + "type": "library", + "autoload": { + "psr-4": { + "ParaTest\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Scaturro", + "email": "scaturrob@gmail.com", + "role": "Developer" + }, + { + "name": "Filippo Tessarotto", + "email": "zoeslam@gmail.com", + "role": "Developer" + } + ], + "description": "Parallel testing for PHP", + "homepage": "https://github.com/paratestphp/paratest", + "keywords": [ + "concurrent", + "parallel", + "phpunit", + "testing" + ], + "support": { + "issues": "https://github.com/paratestphp/paratest/issues", + "source": "https://github.com/paratestphp/paratest/tree/v7.20.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/Slamdunk", + "type": "github" + }, + { + "url": "https://paypal.me/filippotessarotto", + "type": "paypal" + } + ], + "time": "2026-03-29T15:46:14+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.6", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<=7.5 || >=14" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^12 || ^14", + "phpstan/phpstan": "1.4.10 || 2.1.30", + "phpstan/phpstan-phpunit": "^1.0 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0", + "psr/log": "^1 || ^2 || ^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.6" + }, + "time": "2026-02-07T07:09:04+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2025-08-14T07:29:31+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", + "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0 || ^3.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.1.1" + }, + "time": "2025-04-30T06:54:44+00:00" + }, + { + "name": "jean85/pretty-package-versions", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/4d7aa5dab42e2a76d99559706022885de0e18e1a", + "reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.1.0", + "php": "^7.4|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "jean85/composer-provided-replaced-stub-package": "^1.0", + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^7.5|^8.5|^9.6", + "rector/rector": "^2.0", + "vimeo/psalm": "^4.3 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A library to get pretty versions strings of installed dependencies", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "support": { + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.1" + }, + "time": "2025-03-19T14:43:43+00:00" + }, + { + "name": "laravel/agent-detector", + "version": "v2.0.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/agent-detector.git", + "reference": "90694b9256099591cf9e55d08c18ba7a00bf099f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/agent-detector/zipball/90694b9256099591cf9e55d08c18ba7a00bf099f", + "reference": "90694b9256099591cf9e55d08c18ba7a00bf099f", + "shasum": "" + }, + "require": { + "php": "^8.2.0" + }, + "require-dev": { + "laravel/pint": "^1.24.0", + "pestphp/pest": "^3.8.5|^4.1.0", + "pestphp/pest-plugin-type-coverage": "^3.0|^4.0.2", + "phpstan/phpstan": "^2.1.26", + "rector/rector": "^2.1.7", + "symfony/var-dumper": "^7.3.3" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Laravel\\AgentDetector\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Detect if code is running in an AI agent or automated development environment", + "homepage": "https://github.com/laravel/agent-detector", + "keywords": [ + "Agent", + "ai", + "automation", + "claude", + "cursor", + "detection", + "devin", + "php" + ], + "support": { + "issues": "https://github.com/laravel/agent-detector/issues", + "source": "https://github.com/laravel/agent-detector" + }, + "time": "2026-04-29T18:32:34+00:00" + }, + { + "name": "laravel/breeze", + "version": "v2.4.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/breeze.git", + "reference": "28cefeaf6af20177ddf5cc7b93e87e4ad79d533f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/breeze/zipball/28cefeaf6af20177ddf5cc7b93e87e4ad79d533f", + "reference": "28cefeaf6af20177ddf5cc7b93e87e4ad79d533f", + "shasum": "" + }, + "require": { + "illuminate/console": "^11.0|^12.0|^13.0", + "illuminate/filesystem": "^11.0|^12.0|^13.0", + "illuminate/support": "^11.0|^12.0|^13.0", + "illuminate/validation": "^11.0|^12.0|^13.0", + "php": "^8.2.0", + "symfony/console": "^7.0|^8.0" + }, + "require-dev": { + "laravel/framework": "^11.0|^12.0|^13.0", + "orchestra/testbench-core": "^9.0|^10.0|^11.0", + "phpstan/phpstan": "^2.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Breeze\\BreezeServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Breeze\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Minimal Laravel authentication scaffolding with Blade and Tailwind.", + "keywords": [ + "auth", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/breeze/issues", + "source": "https://github.com/laravel/breeze" + }, + "time": "2026-03-10T19:59:01+00:00" + }, + { + "name": "laravel/pail", + "version": "v1.2.6", + "source": { + "type": "git", + "url": "https://github.com/laravel/pail.git", + "reference": "aa71a01c309e7f66bc2ec4fb1a59291b82eb4abf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pail/zipball/aa71a01c309e7f66bc2ec4fb1a59291b82eb4abf", + "reference": "aa71a01c309e7f66bc2ec4fb1a59291b82eb4abf", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "illuminate/console": "^10.24|^11.0|^12.0|^13.0", + "illuminate/contracts": "^10.24|^11.0|^12.0|^13.0", + "illuminate/log": "^10.24|^11.0|^12.0|^13.0", + "illuminate/process": "^10.24|^11.0|^12.0|^13.0", + "illuminate/support": "^10.24|^11.0|^12.0|^13.0", + "nunomaduro/termwind": "^1.15|^2.0", + "php": "^8.2", + "symfony/console": "^6.0|^7.0|^8.0" + }, + "require-dev": { + "laravel/framework": "^10.24|^11.0|^12.0|^13.0", + "laravel/pint": "^1.13", + "orchestra/testbench-core": "^8.13|^9.17|^10.8|^11.0", + "pestphp/pest": "^2.20|^3.0|^4.0", + "pestphp/pest-plugin-type-coverage": "^2.3|^3.0|^4.0", + "phpstan/phpstan": "^1.12.27", + "symfony/var-dumper": "^6.3|^7.0|^8.0", + "symfony/yaml": "^6.3|^7.0|^8.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Pail\\PailServiceProvider" + ] + }, + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\Pail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Easily delve into your Laravel application's log files directly from the command line.", + "homepage": "https://github.com/laravel/pail", + "keywords": [ + "dev", + "laravel", + "logs", + "php", + "tail" + ], + "support": { + "issues": "https://github.com/laravel/pail/issues", + "source": "https://github.com/laravel/pail" + }, + "time": "2026-02-09T13:44:54+00:00" + }, + { + "name": "laravel/pao", + "version": "v1.0.6", + "source": { + "type": "git", + "url": "https://github.com/laravel/pao.git", + "reference": "02f62a64c2b60af44a418ee490fee193590d8269" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pao/zipball/02f62a64c2b60af44a418ee490fee193590d8269", + "reference": "02f62a64c2b60af44a418ee490fee193590d8269", + "shasum": "" + }, + "require": { + "laravel/agent-detector": "^2.0.0", + "php": "^8.3" + }, + "conflict": { + "laravel/framework": "<12.0.0", + "nunomaduro/collision": "<8.9.3", + "pestphp/pest": "<4.6.3 || >=6.0.0", + "phpunit/phpunit": "<12.5.23 || >=13.0.0 <13.1.7 || >=14.0.0" + }, + "require-dev": { + "brianium/paratest": "^7.20.0", + "laravel/pint": "^1.29.1", + "orchestra/testbench": "^10.11.0 || ^11.1.0", + "pestphp/pest": "^4.6.3 || ^5.0.0", + "pestphp/pest-plugin-type-coverage": "^4.0.4 || ^5.0.0", + "phpstan/phpstan": "^2.1.51", + "rector/rector": "^2.4.2", + "symfony/process": "^7.4.8 || ^8.1.0", + "symfony/var-dumper": "^7.4.8 || ^8.0.8" + }, + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Laravel\\Pao\\Drivers\\Pest\\Plugin" + ] + }, + "laravel": { + "providers": [ + "Laravel\\Pao\\Laravel\\ServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/Autoload.php" + ], + "psr-4": { + "Laravel\\Pao\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Agent-optimized output for PHP testing tools", + "keywords": [ + "Agent", + "PHPStan", + "ai", + "dev", + "paratest", + "pest", + "php", + "phpunit", + "testing" + ], + "support": { + "issues": "https://github.com/laravel/pao/issues", + "source": "https://github.com/laravel/pao" + }, + "time": "2026-04-27T22:37:26+00:00" + }, + { + "name": "laravel/pint", + "version": "v1.29.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/pint.git", + "reference": "0770e9b7fafd50d4586881d456d6eb41c9247a80" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pint/zipball/0770e9b7fafd50d4586881d456d6eb41c9247a80", + "reference": "0770e9b7fafd50d4586881d456d6eb41c9247a80", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": "^8.2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.95.1", + "illuminate/view": "^12.56.0", + "larastan/larastan": "^3.9.6", + "laravel-zero/framework": "^12.1.0", + "mockery/mockery": "^1.6.12", + "nunomaduro/termwind": "^2.4.0", + "pestphp/pest": "^3.8.6", + "shipfastlabs/agent-detector": "^1.1.3" + }, + "bin": [ + "builds/pint" + ], + "type": "project", + "autoload": { + "psr-4": { + "App\\": "app/", + "Database\\Seeders\\": "database/seeders/", + "Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "An opinionated code formatter for PHP.", + "homepage": "https://laravel.com", + "keywords": [ + "dev", + "format", + "formatter", + "lint", + "linter", + "php" + ], + "support": { + "issues": "https://github.com/laravel/pint/issues", + "source": "https://github.com/laravel/pint" + }, + "time": "2026-04-20T15:26:14+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.6.12", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699", + "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": ">=7.3" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.6.17", + "symplify/easy-coding-standard": "^12.1.14" + }, + "type": "library", + "autoload": { + "files": [ + "library/helpers.php", + "library/Mockery.php" + ], + "psr-4": { + "Mockery\\": "library/Mockery" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "https://github.com/padraic", + "role": "Author" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "https://davedevelopment.co.uk", + "role": "Developer" + }, + { + "name": "Nathanael Esayeas", + "email": "nathanael.esayeas@protonmail.com", + "homepage": "https://github.com/ghostwriter", + "role": "Lead Developer" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "docs": "https://docs.mockery.io/", + "issues": "https://github.com/mockery/mockery/issues", + "rss": "https://github.com/mockery/mockery/releases.atom", + "security": "https://github.com/mockery/mockery/security/advisories", + "source": "https://github.com/mockery/mockery" + }, + "time": "2024-05-16T03:13:13+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.13.4", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-08-01T08:46:24+00:00" + }, + { + "name": "pestphp/pest", + "version": "v4.7.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest.git", + "reference": "2fc75cfcf03c041c804778fa894282234adc3c66" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest/zipball/2fc75cfcf03c041c804778fa894282234adc3c66", + "reference": "2fc75cfcf03c041c804778fa894282234adc3c66", + "shasum": "" + }, + "require": { + "brianium/paratest": "^7.20.0", + "composer/xdebug-handler": "^3.0.5", + "nunomaduro/collision": "^8.9.4", + "nunomaduro/termwind": "^2.4.0", + "pestphp/pest-plugin": "^4.0.0", + "pestphp/pest-plugin-arch": "^4.0.2", + "pestphp/pest-plugin-mutate": "^4.0.1", + "pestphp/pest-plugin-profanity": "^4.2.1", + "php": "^8.3.0", + "phpunit/phpunit": "^12.5.24", + "symfony/process": "^7.4.8|^8.0.8" + }, + "conflict": { + "filp/whoops": "<2.18.3", + "phpunit/phpunit": ">12.5.24", + "sebastian/exporter": "<7.0.0", + "webmozart/assert": "<1.11.0" + }, + "require-dev": { + "mrpunyapal/peststan": "^0.2.9", + "pestphp/pest-dev-tools": "^4.1.0", + "pestphp/pest-plugin-browser": "^4.3.1", + "pestphp/pest-plugin-type-coverage": "^4.0.4", + "psy/psysh": "^0.12.22" + }, + "bin": [ + "bin/pest" + ], + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Pest\\Mutate\\Plugins\\Mutate", + "Pest\\Plugins\\Configuration", + "Pest\\Plugins\\Bail", + "Pest\\Plugins\\Cache", + "Pest\\Plugins\\Coverage", + "Pest\\Plugins\\Init", + "Pest\\Plugins\\Environment", + "Pest\\Plugins\\Help", + "Pest\\Plugins\\Memory", + "Pest\\Plugins\\Only", + "Pest\\Plugins\\Printer", + "Pest\\Plugins\\ProcessIsolation", + "Pest\\Plugins\\Profile", + "Pest\\Plugins\\Retry", + "Pest\\Plugins\\Snapshot", + "Pest\\Plugins\\Verbose", + "Pest\\Plugins\\Version", + "Pest\\Plugins\\Shard", + "Pest\\Plugins\\Tia", + "Pest\\Plugins\\Parallel" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "files": [ + "src/Functions.php", + "src/Pest.php" + ], + "psr-4": { + "Pest\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "The elegant PHP Testing Framework.", + "keywords": [ + "framework", + "pest", + "php", + "test", + "testing", + "unit" + ], + "support": { + "issues": "https://github.com/pestphp/pest/issues", + "source": "https://github.com/pestphp/pest/tree/v4.7.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2026-05-03T16:09:32+00:00" + }, + { + "name": "pestphp/pest-plugin", + "version": "v4.0.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin.git", + "reference": "9d4b93d7f73d3f9c3189bb22c220fef271cdf568" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/9d4b93d7f73d3f9c3189bb22c220fef271cdf568", + "reference": "9d4b93d7f73d3f9c3189bb22c220fef271cdf568", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0.0", + "composer-runtime-api": "^2.2.2", + "php": "^8.3" + }, + "conflict": { + "pestphp/pest": "<4.0.0" + }, + "require-dev": { + "composer/composer": "^2.8.10", + "pestphp/pest": "^4.0.0", + "pestphp/pest-dev-tools": "^4.0.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Pest\\Plugin\\Manager" + }, + "autoload": { + "psr-4": { + "Pest\\Plugin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest plugin manager", + "keywords": [ + "framework", + "manager", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin/tree/v4.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2025-08-20T12:35:58+00:00" + }, + { + "name": "pestphp/pest-plugin-arch", + "version": "v4.0.2", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-arch.git", + "reference": "3fb0d02a91b9da504b139dc7ab2a31efb7c3215c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/3fb0d02a91b9da504b139dc7ab2a31efb7c3215c", + "reference": "3fb0d02a91b9da504b139dc7ab2a31efb7c3215c", + "shasum": "" + }, + "require": { + "pestphp/pest-plugin": "^4.0.0", + "php": "^8.3", + "ta-tikoma/phpunit-architecture-test": "^0.8.7" + }, + "require-dev": { + "pestphp/pest": "^4.4.6", + "pestphp/pest-dev-tools": "^4.1.0" + }, + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Pest\\Arch\\Plugin" + ] + } + }, + "autoload": { + "files": [ + "src/Autoload.php" + ], + "psr-4": { + "Pest\\Arch\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Arch plugin for Pest PHP.", + "keywords": [ + "arch", + "architecture", + "framework", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-arch/tree/v4.0.2" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2026-04-10T17:20:19+00:00" + }, + { + "name": "pestphp/pest-plugin-laravel", + "version": "v4.1.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-laravel.git", + "reference": "3057a36669ff11416cc0dc2b521b3aec58c488d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-laravel/zipball/3057a36669ff11416cc0dc2b521b3aec58c488d0", + "reference": "3057a36669ff11416cc0dc2b521b3aec58c488d0", + "shasum": "" + }, + "require": { + "laravel/framework": "^11.45.2|^12.52.0|^13.0", + "pestphp/pest": "^4.4.1", + "php": "^8.3.0" + }, + "require-dev": { + "laravel/dusk": "^8.3.6", + "orchestra/testbench": "^9.13.0|^10.9.0|^11.0", + "pestphp/pest-dev-tools": "^4.1.0" + }, + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Pest\\Laravel\\Plugin" + ] + }, + "laravel": { + "providers": [ + "Pest\\Laravel\\PestServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/Autoload.php" + ], + "psr-4": { + "Pest\\Laravel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest Laravel Plugin", + "keywords": [ + "framework", + "laravel", + "pest", + "php", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-laravel/tree/v4.1.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2026-02-21T00:29:45+00:00" + }, + { + "name": "pestphp/pest-plugin-mutate", + "version": "v4.0.1", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-mutate.git", + "reference": "d9b32b60b2385e1688a68cc227594738ec26d96c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-mutate/zipball/d9b32b60b2385e1688a68cc227594738ec26d96c", + "reference": "d9b32b60b2385e1688a68cc227594738ec26d96c", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.6.1", + "pestphp/pest-plugin": "^4.0.0", + "php": "^8.3", + "psr/simple-cache": "^3.0.0" + }, + "require-dev": { + "pestphp/pest": "^4.0.0", + "pestphp/pest-dev-tools": "^4.0.0", + "pestphp/pest-plugin-type-coverage": "^4.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Pest\\Mutate\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + }, + { + "name": "Sandro Gehri", + "email": "sandrogehri@gmail.com" + } + ], + "description": "Mutates your code to find untested cases", + "keywords": [ + "framework", + "mutate", + "mutation", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-mutate/tree/v4.0.1" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/gehrisandro", + "type": "github" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2025-08-21T20:19:25+00:00" + }, + { + "name": "pestphp/pest-plugin-profanity", + "version": "v4.2.1", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-profanity.git", + "reference": "343cfa6f3564b7e35df0ebb77b7fa97039f72b27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-profanity/zipball/343cfa6f3564b7e35df0ebb77b7fa97039f72b27", + "reference": "343cfa6f3564b7e35df0ebb77b7fa97039f72b27", + "shasum": "" + }, + "require": { + "pestphp/pest-plugin": "^4.0.0", + "php": "^8.3" + }, + "require-dev": { + "faissaloux/pest-plugin-inside": "^1.9", + "pestphp/pest": "^4.0.0", + "pestphp/pest-dev-tools": "^4.0.0" + }, + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Pest\\Profanity\\Plugin" + ] + } + }, + "autoload": { + "psr-4": { + "Pest\\Profanity\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest Profanity Plugin", + "keywords": [ + "framework", + "pest", + "php", + "plugin", + "profanity", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-profanity/tree/v4.2.1" + }, + "time": "2025-12-08T00:13:17+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "6.0.3", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/7bae67520aa9f5ecc506d646810bd40d9da54582", + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.1", + "ext-filter": "*", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^2.0", + "phpstan/phpdoc-parser": "^2.0", + "webmozart/assert": "^1.9.1 || ^2" + }, + "require-dev": { + "mockery/mockery": "~1.3.5 || ~1.6.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^5.26", + "shipmonk/dead-code-detector": "^0.5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.3" + }, + "time": "2026-03-18T20:49:53+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.0.0" + }, + "time": "2026-01-06T21:53:42+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "2.3.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.2" + }, + "time": "2026-01-25T14:56:51+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "12.5.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "876099a072646c7745f673d7aeab5382c4439691" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/876099a072646c7745f673d7aeab5382c4439691", + "reference": "876099a072646c7745f673d7aeab5382c4439691", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.7.0", + "php": ">=8.3", + "phpunit/php-text-template": "^5.0", + "sebastian/complexity": "^5.0", + "sebastian/environment": "^8.0.3", + "sebastian/lines-of-code": "^4.0", + "sebastian/version": "^6.0", + "theseer/tokenizer": "^2.0.1" + }, + "require-dev": { + "phpunit/phpunit": "^12.5.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "12.5.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", + "type": "tidelift" + } + ], + "time": "2026-04-15T08:23:17+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5", + "reference": "3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-file-iterator", + "type": "tidelift" + } + ], + "time": "2026-02-02T14:04:18+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/12b54e689b07a25a9b41e57736dfab6ec9ae5406", + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^12.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:58:58+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/e1367a453f0eda562eedb4f659e13aa900d66c53", + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:59:16+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "8.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "8.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/8.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:59:38+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "12.5.24", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "d75dd30597caa80e72fad2ef7904601a30ef1046" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d75dd30597caa80e72fad2ef7904601a30ef1046", + "reference": "d75dd30597caa80e72fad2ef7904601a30ef1046", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.3", + "phpunit/php-code-coverage": "^12.5.6", + "phpunit/php-file-iterator": "^6.0.1", + "phpunit/php-invoker": "^6.0.0", + "phpunit/php-text-template": "^5.0.0", + "phpunit/php-timer": "^8.0.0", + "sebastian/cli-parser": "^4.2.0", + "sebastian/comparator": "^7.1.6", + "sebastian/diff": "^7.0.0", + "sebastian/environment": "^8.1.0", + "sebastian/exporter": "^7.0.2", + "sebastian/global-state": "^8.0.2", + "sebastian/object-enumerator": "^7.0.0", + "sebastian/recursion-context": "^7.0.1", + "sebastian/type": "^6.0.3", + "sebastian/version": "^6.0.0", + "staabm/side-effects-detector": "^1.0.5" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "12.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.24" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsoring.html", + "type": "other" + } + ], + "time": "2026-05-01T04:21:04+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "4.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "90f41072d220e5c40df6e8635f5dafba2d9d4d04" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/90f41072d220e5c40df6e8635f5dafba2d9d4d04", + "reference": "90f41072d220e5c40df6e8635f5dafba2d9d4d04", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/4.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/cli-parser", + "type": "tidelift" + } + ], + "time": "2025-09-14T09:36:45+00:00" + }, + { + "name": "sebastian/comparator", + "version": "7.1.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "c769009dee98f494e0edc3fd4f4087501688f11e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c769009dee98f494e0edc3fd4f4087501688f11e", + "reference": "c769009dee98f494e0edc3fd4f4087501688f11e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.3", + "sebastian/diff": "^7.0", + "sebastian/exporter": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^12.2" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/7.1.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" + } + ], + "time": "2026-04-14T08:23:15+00:00" + }, + { + "name": "sebastian/complexity", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/bad4316aba5303d0221f43f8cee37eb58d384bbb", + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:55:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "7.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0", + "symfony/process": "^7.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/7.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:55:46+00:00" + }, + { + "name": "sebastian/environment", + "version": "8.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "b121608b28a13f721e76ffbbd386d08eff58f3f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/b121608b28a13f721e76ffbbd386d08eff58f3f6", + "reference": "b121608b28a13f721e76ffbbd386d08eff58f3f6", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "8.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/8.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" + } + ], + "time": "2026-04-15T12:13:01+00:00" + }, + { + "name": "sebastian/exporter", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "016951ae10980765e4e7aee491eb288c64e505b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/016951ae10980765e4e7aee491eb288c64e505b7", + "reference": "016951ae10980765e4e7aee491eb288c64e505b7", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.3", + "sebastian/recursion-context": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" + } + ], + "time": "2025-09-24T06:16:11+00:00" + }, + { + "name": "sebastian/global-state", + "version": "8.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "ef1377171613d09edd25b7816f05be8313f9115d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/ef1377171613d09edd25b7816f05be8313f9115d", + "reference": "ef1377171613d09edd25b7816f05be8313f9115d", + "shasum": "" + }, + "require": { + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "8.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/8.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/global-state", + "type": "tidelift" + } + ], + "time": "2025-08-29T11:29:25+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/97ffee3bcfb5805568d6af7f0f893678fc076d2f", + "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:57:28+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "7.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894", + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894", + "shasum": "" + }, + "require": { + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/7.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:57:48+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "4bfa827c969c98be1e527abd576533293c634f6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a", + "reference": "4bfa827c969c98be1e527abd576533293c634f6a", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:58:17+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/0b01998a7d5b1f122911a66bebcb8d46f0c82d8c", + "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/7.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" + } + ], + "time": "2025-08-13T04:44:59+00:00" + }, + { + "name": "sebastian/type", + "version": "6.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "e549163b9760b8f71f191651d22acf32d56d6d4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/e549163b9760b8f71f191651d22acf32d56d6d4d", + "reference": "e549163b9760b8f71f191651d22acf32d56d6d4d", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/6.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/type", + "type": "tidelift" + } + ], + "time": "2025-08-09T06:57:12+00:00" + }, + { + "name": "sebastian/version", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c", + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T05:00:38+00:00" + }, + { + "name": "staabm/side-effects-detector", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" + ], + "support": { + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + }, + "funding": [ + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2024-10-20T05:08:20+00:00" + }, + { + "name": "ta-tikoma/phpunit-architecture-test", + "version": "0.8.7", + "source": { + "type": "git", + "url": "https://github.com/ta-tikoma/phpunit-architecture-test.git", + "reference": "1248f3f506ca9641d4f68cebcd538fa489754db8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/1248f3f506ca9641d4f68cebcd538fa489754db8", + "reference": "1248f3f506ca9641d4f68cebcd538fa489754db8", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18.0 || ^5.0.0", + "php": "^8.1.0", + "phpdocumentor/reflection-docblock": "^5.3.0 || ^6.0.0", + "phpunit/phpunit": "^10.5.5 || ^11.0.0 || ^12.0.0 || ^13.0.0", + "symfony/finder": "^6.4.0 || ^7.0.0 || ^8.0.0" + }, + "require-dev": { + "laravel/pint": "^1.13.7", + "phpstan/phpstan": "^1.10.52" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPUnit\\Architecture\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ni Shi", + "email": "futik0ma011@gmail.com" + }, + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Methods for testing application architecture", + "keywords": [ + "architecture", + "phpunit", + "stucture", + "test", + "testing" + ], + "support": { + "issues": "https://github.com/ta-tikoma/phpunit-architecture-test/issues", + "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.8.7" + }, + "time": "2026-02-17T17:25:14+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "7989e43bf381af0eac72e4f0ca5bcbfa81658be4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/7989e43bf381af0eac72e4f0ca5bcbfa81658be4", + "reference": "7989e43bf381af0eac72e4f0ca5bcbfa81658be4", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^8.1" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2025-12-08T11:19:18+00:00" + }, + { + "name": "webmozart/assert", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "eb0d790f735ba6cff25c683a85a1da0eadeff9e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/eb0d790f735ba6cff25c683a85a1da0eadeff9e4", + "reference": "eb0d790f735ba6cff25c683a85a1da0eadeff9e4", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-date": "*", + "ext-filter": "*", + "php": "^8.2" + }, + "suggest": { + "ext-intl": "", + "ext-simplexml": "", + "ext-spl": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-feature/2-0": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + }, + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/2.3.0" + }, + "time": "2026-04-11T10:33:05+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": "^8.3" + }, + "platform-dev": [], + "plugin-api-version": "2.2.0" +} diff --git a/config/app.php b/config/app.php new file mode 100644 index 0000000..423eed5 --- /dev/null +++ b/config/app.php @@ -0,0 +1,126 @@ + env('APP_NAME', 'Laravel'), + + /* + |-------------------------------------------------------------------------- + | Application Environment + |-------------------------------------------------------------------------- + | + | This value determines the "environment" your application is currently + | running in. This may determine how you prefer to configure various + | services the application utilizes. Set this in your ".env" file. + | + */ + + 'env' => env('APP_ENV', 'production'), + + /* + |-------------------------------------------------------------------------- + | Application Debug Mode + |-------------------------------------------------------------------------- + | + | When your application is in debug mode, detailed error messages with + | stack traces will be shown on every error that occurs within your + | application. If disabled, a simple generic error page is shown. + | + */ + + 'debug' => (bool) env('APP_DEBUG', false), + + /* + |-------------------------------------------------------------------------- + | Application URL + |-------------------------------------------------------------------------- + | + | This URL is used by the console to properly generate URLs when using + | the Artisan command line tool. You should set this to the root of + | the application so that it's available within Artisan commands. + | + */ + + 'url' => env('APP_URL', 'http://localhost'), + + /* + |-------------------------------------------------------------------------- + | Application Timezone + |-------------------------------------------------------------------------- + | + | Here you may specify the default timezone for your application, which + | will be used by the PHP date and date-time functions. The timezone + | is set to "UTC" by default as it is suitable for most use cases. + | + */ + + 'timezone' => 'UTC', + + /* + |-------------------------------------------------------------------------- + | Application Locale Configuration + |-------------------------------------------------------------------------- + | + | The application locale determines the default locale that will be used + | by Laravel's translation / localization methods. This option can be + | set to any locale for which you plan to have translation strings. + | + */ + + 'locale' => env('APP_LOCALE', 'en'), + + 'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'), + + 'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'), + + /* + |-------------------------------------------------------------------------- + | Encryption Key + |-------------------------------------------------------------------------- + | + | This key is utilized by Laravel's encryption services and should be set + | to a random, 32 character string to ensure that all encrypted values + | are secure. You should do this prior to deploying the application. + | + */ + + 'cipher' => 'AES-256-CBC', + + 'key' => env('APP_KEY'), + + 'previous_keys' => [ + ...array_filter( + explode(',', (string) env('APP_PREVIOUS_KEYS', '')) + ), + ], + + /* + |-------------------------------------------------------------------------- + | Maintenance Mode Driver + |-------------------------------------------------------------------------- + | + | These configuration options determine the driver used to determine and + | manage Laravel's "maintenance mode" status. The "cache" driver will + | allow maintenance mode to be controlled across multiple machines. + | + | Supported drivers: "file", "cache" + | + */ + + 'maintenance' => [ + 'driver' => env('APP_MAINTENANCE_DRIVER', 'file'), + 'store' => env('APP_MAINTENANCE_STORE', 'database'), + ], + +]; diff --git a/config/auth.php b/config/auth.php new file mode 100644 index 0000000..24d8311 --- /dev/null +++ b/config/auth.php @@ -0,0 +1,122 @@ + [ + 'guard' => env('AUTH_GUARD', 'web'), + 'passwords' => env('AUTH_PASSWORD_BROKER', 'users'), + ], + + /* + |-------------------------------------------------------------------------- + | Authentication Guards + |-------------------------------------------------------------------------- + | + | Next, you may define every authentication guard for your application. + | Of course, a great default configuration has been defined for you + | which utilizes session storage plus the Eloquent user provider. + | + | All authentication guards have a user provider, which defines how the + | users are actually retrieved out of your database or other storage + | system used by the application. Typically, Eloquent is utilized. + | + | Supported: "session" + | + */ + + 'guards' => [ + 'web' => [ + 'driver' => 'session', + 'provider' => 'users', + ], + + 'api' => [ + 'driver' => 'passport', + 'provider' => 'users', + ], + ], + + /* + |-------------------------------------------------------------------------- + | User Providers + |-------------------------------------------------------------------------- + | + | All authentication guards have a user provider, which defines how the + | users are actually retrieved out of your database or other storage + | system used by the application. Typically, Eloquent is utilized. + | + | If you have multiple user tables or models you may configure multiple + | providers to represent the model / table. These providers may then + | be assigned to any extra authentication guards you have defined. + | + | Supported: "database", "eloquent" + | + */ + + 'providers' => [ + 'users' => [ + 'driver' => 'eloquent', + 'model' => env('AUTH_MODEL', User::class), + ], + + // 'users' => [ + // 'driver' => 'database', + // 'table' => 'users', + // ], + ], + + /* + |-------------------------------------------------------------------------- + | Resetting Passwords + |-------------------------------------------------------------------------- + | + | These configuration options specify the behavior of Laravel's password + | reset functionality, including the table utilized for token storage + | and the user provider that is invoked to actually retrieve users. + | + | The expiry time is the number of minutes that each reset token will be + | considered valid. This security feature keeps tokens short-lived so + | they have less time to be guessed. You may change this as needed. + | + | The throttle setting is the number of seconds a user must wait before + | generating more password reset tokens. This prevents the user from + | quickly generating a very large amount of password reset tokens. + | + */ + + 'passwords' => [ + 'users' => [ + 'provider' => 'users', + 'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'), + 'expire' => 60, + 'throttle' => 60, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Password Confirmation Timeout + |-------------------------------------------------------------------------- + | + | Here you may define the number of seconds before a password confirmation + | window expires and users are asked to re-enter their password via the + | confirmation screen. By default, the timeout lasts for three hours. + | + */ + + 'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800), + +]; diff --git a/config/cache.php b/config/cache.php new file mode 100644 index 0000000..c68acdf --- /dev/null +++ b/config/cache.php @@ -0,0 +1,130 @@ + env('CACHE_STORE', 'database'), + + /* + |-------------------------------------------------------------------------- + | Cache Stores + |-------------------------------------------------------------------------- + | + | Here you may define all of the cache "stores" for your application as + | well as their drivers. You may even define multiple stores for the + | same cache driver to group types of items stored in your caches. + | + | Supported drivers: "array", "database", "file", "memcached", + | "redis", "dynamodb", "octane", + | "failover", "null" + | + */ + + 'stores' => [ + + 'array' => [ + 'driver' => 'array', + 'serialize' => false, + ], + + 'database' => [ + 'driver' => 'database', + 'connection' => env('DB_CACHE_CONNECTION'), + 'table' => env('DB_CACHE_TABLE', 'cache'), + 'lock_connection' => env('DB_CACHE_LOCK_CONNECTION'), + 'lock_table' => env('DB_CACHE_LOCK_TABLE'), + ], + + 'file' => [ + 'driver' => 'file', + 'path' => storage_path('framework/cache/data'), + 'lock_path' => storage_path('framework/cache/data'), + ], + + 'memcached' => [ + 'driver' => 'memcached', + 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), + 'sasl' => [ + env('MEMCACHED_USERNAME'), + env('MEMCACHED_PASSWORD'), + ], + 'options' => [ + // Memcached::OPT_CONNECT_TIMEOUT => 2000, + ], + 'servers' => [ + [ + 'host' => env('MEMCACHED_HOST', '127.0.0.1'), + 'port' => env('MEMCACHED_PORT', 11211), + 'weight' => 100, + ], + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => env('REDIS_CACHE_CONNECTION', 'cache'), + 'lock_connection' => env('REDIS_CACHE_LOCK_CONNECTION', 'default'), + ], + + 'dynamodb' => [ + 'driver' => 'dynamodb', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), + 'endpoint' => env('DYNAMODB_ENDPOINT'), + ], + + 'octane' => [ + 'driver' => 'octane', + ], + + 'failover' => [ + 'driver' => 'failover', + 'stores' => [ + 'database', + 'array', + ], + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Cache Key Prefix + |-------------------------------------------------------------------------- + | + | When utilizing the APC, database, memcached, Redis, and DynamoDB cache + | stores, there might be other applications using the same cache. For + | that reason, you may prefix every cache key to avoid collisions. + | + */ + + 'prefix' => env('CACHE_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-cache-'), + + /* + |-------------------------------------------------------------------------- + | Serializable Classes + |-------------------------------------------------------------------------- + | + | This value determines the classes that can be unserialized from cache + | storage. By default, no PHP classes will be unserialized from your + | cache to prevent gadget chain attacks if your APP_KEY is leaked. + | + */ + + 'serializable_classes' => false, + +]; diff --git a/config/database.php b/config/database.php new file mode 100644 index 0000000..64709ce --- /dev/null +++ b/config/database.php @@ -0,0 +1,184 @@ + env('DB_CONNECTION', 'sqlite'), + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | Below are all of the database connections defined for your application. + | An example configuration is provided for each database system which + | is supported by Laravel. You're free to add / remove connections. + | + */ + + 'connections' => [ + + 'sqlite' => [ + 'driver' => 'sqlite', + 'url' => env('DB_URL'), + 'database' => env('DB_DATABASE', database_path('database.sqlite')), + 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), + 'busy_timeout' => null, + 'journal_mode' => null, + 'synchronous' => null, + 'transaction_mode' => 'DEFERRED', + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + (PHP_VERSION_ID >= 80500 ? Mysql::ATTR_SSL_CA : PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + + 'mariadb' => [ + 'driver' => 'mariadb', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + (PHP_VERSION_ID >= 80500 ? Mysql::ATTR_SSL_CA : PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + 'search_path' => 'public', + 'sslmode' => env('DB_SSLMODE', 'prefer'), + ], + + 'sqlsrv' => [ + 'driver' => 'sqlsrv', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '1433'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + // 'encrypt' => env('DB_ENCRYPT', 'yes'), + // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'), + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Migration Repository Table + |-------------------------------------------------------------------------- + | + | This table keeps track of all the migrations that have already run for + | your application. Using this information, we can determine which of + | the migrations on disk haven't actually been run on the database. + | + */ + + 'migrations' => [ + 'table' => 'migrations', + 'update_date_on_publish' => true, + ], + + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store that also + | provides a richer body of commands than a typical key-value system + | such as Memcached. You may define your connection settings here. + | + */ + + 'redis' => [ + + 'client' => env('REDIS_CLIENT', 'phpredis'), + + 'options' => [ + 'cluster' => env('REDIS_CLUSTER', 'redis'), + 'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-'), + 'persistent' => env('REDIS_PERSISTENT', false), + ], + + 'default' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_DB', '0'), + 'max_retries' => env('REDIS_MAX_RETRIES', 3), + 'backoff_algorithm' => env('REDIS_BACKOFF_ALGORITHM', 'decorrelated_jitter'), + 'backoff_base' => env('REDIS_BACKOFF_BASE', 100), + 'backoff_cap' => env('REDIS_BACKOFF_CAP', 1000), + ], + + 'cache' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_CACHE_DB', '1'), + 'max_retries' => env('REDIS_MAX_RETRIES', 3), + 'backoff_algorithm' => env('REDIS_BACKOFF_ALGORITHM', 'decorrelated_jitter'), + 'backoff_base' => env('REDIS_BACKOFF_BASE', 100), + 'backoff_cap' => env('REDIS_BACKOFF_CAP', 1000), + ], + + ], + +]; diff --git a/config/filesystems.php b/config/filesystems.php new file mode 100644 index 0000000..37d8fca --- /dev/null +++ b/config/filesystems.php @@ -0,0 +1,80 @@ + env('FILESYSTEM_DISK', 'local'), + + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Below you may configure as many filesystem disks as necessary, and you + | may even configure multiple disks for the same driver. Examples for + | most supported storage drivers are configured here for reference. + | + | Supported drivers: "local", "ftp", "sftp", "s3" + | + */ + + 'disks' => [ + + 'local' => [ + 'driver' => 'local', + 'root' => storage_path('app/private'), + 'serve' => true, + 'throw' => false, + 'report' => false, + ], + + 'public' => [ + 'driver' => 'local', + 'root' => storage_path('app/public'), + 'url' => rtrim(env('APP_URL', 'http://localhost'), '/').'/storage', + 'visibility' => 'public', + 'throw' => false, + 'report' => false, + ], + + 's3' => [ + 'driver' => 's3', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION'), + 'bucket' => env('AWS_BUCKET'), + 'url' => env('AWS_URL'), + 'endpoint' => env('AWS_ENDPOINT'), + 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), + 'throw' => false, + 'report' => false, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Symbolic Links + |-------------------------------------------------------------------------- + | + | Here you may configure the symbolic links that will be created when the + | `storage:link` Artisan command is executed. The array keys should be + | the locations of the links and the values should be their targets. + | + */ + + 'links' => [ + public_path('storage') => storage_path('app/public'), + ], + +]; diff --git a/config/logging.php b/config/logging.php new file mode 100644 index 0000000..b09cb25 --- /dev/null +++ b/config/logging.php @@ -0,0 +1,132 @@ + env('LOG_CHANNEL', 'stack'), + + /* + |-------------------------------------------------------------------------- + | Deprecations Log Channel + |-------------------------------------------------------------------------- + | + | This option controls the log channel that should be used to log warnings + | regarding deprecated PHP and library features. This allows you to get + | your application ready for upcoming major versions of dependencies. + | + */ + + 'deprecations' => [ + 'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), + 'trace' => env('LOG_DEPRECATIONS_TRACE', false), + ], + + /* + |-------------------------------------------------------------------------- + | Log Channels + |-------------------------------------------------------------------------- + | + | Here you may configure the log channels for your application. Laravel + | utilizes the Monolog PHP logging library, which includes a variety + | of powerful log handlers and formatters that you're free to use. + | + | Available drivers: "single", "daily", "slack", "syslog", + | "errorlog", "monolog", "custom", "stack" + | + */ + + 'channels' => [ + + 'stack' => [ + 'driver' => 'stack', + 'channels' => explode(',', (string) env('LOG_STACK', 'single')), + 'ignore_exceptions' => false, + ], + + 'single' => [ + 'driver' => 'single', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, + ], + + 'daily' => [ + 'driver' => 'daily', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + 'days' => env('LOG_DAILY_DAYS', 14), + 'replace_placeholders' => true, + ], + + 'slack' => [ + 'driver' => 'slack', + 'url' => env('LOG_SLACK_WEBHOOK_URL'), + 'username' => env('LOG_SLACK_USERNAME', env('APP_NAME', 'Laravel')), + 'emoji' => env('LOG_SLACK_EMOJI', ':boom:'), + 'level' => env('LOG_LEVEL', 'critical'), + 'replace_placeholders' => true, + ], + + 'papertrail' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class), + 'handler_with' => [ + 'host' => env('PAPERTRAIL_URL'), + 'port' => env('PAPERTRAIL_PORT'), + 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), + ], + 'processors' => [PsrLogMessageProcessor::class], + ], + + 'stderr' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => StreamHandler::class, + 'handler_with' => [ + 'stream' => 'php://stderr', + ], + 'formatter' => env('LOG_STDERR_FORMATTER'), + 'processors' => [PsrLogMessageProcessor::class], + ], + + 'syslog' => [ + 'driver' => 'syslog', + 'level' => env('LOG_LEVEL', 'debug'), + 'facility' => env('LOG_SYSLOG_FACILITY', LOG_USER), + 'replace_placeholders' => true, + ], + + 'errorlog' => [ + 'driver' => 'errorlog', + 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, + ], + + 'null' => [ + 'driver' => 'monolog', + 'handler' => NullHandler::class, + ], + + 'emergency' => [ + 'path' => storage_path('logs/laravel.log'), + ], + + ], + +]; diff --git a/config/mail.php b/config/mail.php new file mode 100644 index 0000000..e32e88d --- /dev/null +++ b/config/mail.php @@ -0,0 +1,118 @@ + env('MAIL_MAILER', 'log'), + + /* + |-------------------------------------------------------------------------- + | Mailer Configurations + |-------------------------------------------------------------------------- + | + | Here you may configure all of the mailers used by your application plus + | their respective settings. Several examples have been configured for + | you and you are free to add your own as your application requires. + | + | Laravel supports a variety of mail "transport" drivers that can be used + | when delivering an email. You may specify which one you're using for + | your mailers below. You may also add additional mailers if needed. + | + | Supported: "smtp", "sendmail", "mailgun", "ses", "ses-v2", + | "postmark", "resend", "log", "array", + | "failover", "roundrobin" + | + */ + + 'mailers' => [ + + 'smtp' => [ + 'transport' => 'smtp', + 'scheme' => env('MAIL_SCHEME'), + 'url' => env('MAIL_URL'), + 'host' => env('MAIL_HOST', '127.0.0.1'), + 'port' => env('MAIL_PORT', 2525), + 'username' => env('MAIL_USERNAME'), + 'password' => env('MAIL_PASSWORD'), + 'timeout' => null, + 'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url((string) env('APP_URL', 'http://localhost'), PHP_URL_HOST)), + ], + + 'ses' => [ + 'transport' => 'ses', + ], + + 'postmark' => [ + 'transport' => 'postmark', + // 'message_stream_id' => env('POSTMARK_MESSAGE_STREAM_ID'), + // 'client' => [ + // 'timeout' => 5, + // ], + ], + + 'resend' => [ + 'transport' => 'resend', + ], + + 'sendmail' => [ + 'transport' => 'sendmail', + 'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'), + ], + + 'log' => [ + 'transport' => 'log', + 'channel' => env('MAIL_LOG_CHANNEL'), + ], + + 'array' => [ + 'transport' => 'array', + ], + + 'failover' => [ + 'transport' => 'failover', + 'mailers' => [ + 'smtp', + 'log', + ], + 'retry_after' => 60, + ], + + 'roundrobin' => [ + 'transport' => 'roundrobin', + 'mailers' => [ + 'ses', + 'postmark', + ], + 'retry_after' => 60, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Global "From" Address + |-------------------------------------------------------------------------- + | + | You may wish for all emails sent by your application to be sent from + | the same address. Here you may specify a name and address that is + | used globally for all emails that are sent by your application. + | + */ + + 'from' => [ + 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), + 'name' => env('MAIL_FROM_NAME', env('APP_NAME', 'Laravel')), + ], + +]; diff --git a/config/passport.php b/config/passport.php new file mode 100644 index 0000000..aed4358 --- /dev/null +++ b/config/passport.php @@ -0,0 +1,48 @@ + 'web', + + 'middleware' => [], + + /* + |-------------------------------------------------------------------------- + | Encryption Keys + |-------------------------------------------------------------------------- + | + | Passport uses encryption keys while generating secure access tokens for + | your application. By default, the keys are stored as local files but + | can be set via environment variables when that is more convenient. + | + */ + + 'private_key' => env('PASSPORT_PRIVATE_KEY'), + + 'public_key' => env('PASSPORT_PUBLIC_KEY'), + + /* + |-------------------------------------------------------------------------- + | Passport Database Connection + |-------------------------------------------------------------------------- + | + | By default, Passport's models will utilize your application's default + | database connection. If you wish to use a different connection you + | may specify the configured name of the database connection here. + | + */ + + 'connection' => env('PASSPORT_CONNECTION'), + +]; diff --git a/config/permission.php b/config/permission.php new file mode 100644 index 0000000..8f1f452 --- /dev/null +++ b/config/permission.php @@ -0,0 +1,219 @@ + [ + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * Eloquent model should be used to retrieve your permissions. Of course, it + * is often just the "Permission" model but you may use whatever you like. + * + * The model you want to use as a Permission model needs to implement the + * `Spatie\Permission\Contracts\Permission` contract. + */ + + 'permission' => Permission::class, + + /* + * When using the "HasRoles" trait from this package, we need to know which + * Eloquent model should be used to retrieve your roles. Of course, it + * is often just the "Role" model but you may use whatever you like. + * + * The model you want to use as a Role model needs to implement the + * `Spatie\Permission\Contracts\Role` contract. + */ + + 'role' => Role::class, + + /* + * When using the "Teams" feature from this package, we need to know which + * Eloquent model should be used to retrieve your teams. Of course, it + * is often just the "Team" model but you may use whatever you like. + */ + 'team' => null, + + /* + * When using the "HasModels" trait and passing raw IDs to syncModels, + * attachModels, or detachModels, this model class will be used to + * resolve those IDs. If null, defaults to the guard's model. + */ + 'default_model' => null, + ], + + 'table_names' => [ + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your roles. We have chosen a basic + * default value but you may easily change it to any table you like. + */ + + 'roles' => 'roles', + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * table should be used to retrieve your permissions. We have chosen a basic + * default value but you may easily change it to any table you like. + */ + + 'permissions' => 'permissions', + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * table should be used to retrieve your models permissions. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'model_has_permissions' => 'model_has_permissions', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your models roles. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'model_has_roles' => 'model_has_roles', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your roles permissions. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'role_has_permissions' => 'role_has_permissions', + ], + + 'column_names' => [ + /* + * Change this if you want to name the related pivots other than defaults + */ + 'role_pivot_key' => null, // default 'role_id', + 'permission_pivot_key' => null, // default 'permission_id', + + /* + * Change this if you want to name the related model primary key other than + * `model_id`. + * + * For example, this would be nice if your primary keys are all UUIDs. In + * that case, name this `model_uuid`. + */ + + 'model_morph_key' => 'model_id', + + /* + * Change this if you want to use the teams feature and your related model's + * foreign key is other than `team_id`. + */ + + 'team_foreign_key' => 'team_id', + ], + + /* + * When set to true, the method for checking permissions will be registered on the gate. + * Set this to false if you want to implement custom logic for checking permissions. + */ + + 'register_permission_check_method' => true, + + /* + * When set to true, Laravel\Octane\Events\OperationTerminated event listener will be registered + * this will refresh permissions on every TickTerminated, TaskTerminated and RequestTerminated + * NOTE: This should not be needed in most cases, but an Octane/Vapor combination benefited from it. + */ + 'register_octane_reset_listener' => false, + + /* + * Events will fire when a role or permission is assigned/unassigned: + * \Spatie\Permission\Events\RoleAttachedEvent + * \Spatie\Permission\Events\RoleDetachedEvent + * \Spatie\Permission\Events\PermissionAttachedEvent + * \Spatie\Permission\Events\PermissionDetachedEvent + * + * To enable, set to true, and then create listeners to watch these events. + */ + 'events_enabled' => false, + + /* + * Teams Feature. + * When set to true the package implements teams using the 'team_foreign_key'. + * If you want the migrations to register the 'team_foreign_key', you must + * set this to true before doing the migration. + * If you already did the migration then you must make a new migration to also + * add 'team_foreign_key' to 'roles', 'model_has_roles', and 'model_has_permissions' + * (view the latest version of this package's migration file) + */ + + 'teams' => false, + + /* + * The class to use to resolve the permissions team id + */ + 'team_resolver' => DefaultTeamResolver::class, + + /* + * Passport Client Credentials Grant + * When set to true the package will use Passports Client to check permissions + */ + + 'use_passport_client_credentials' => false, + + /* + * When set to true, the required permission names are added to exception messages. + * This could be considered an information leak in some contexts, so the default + * setting is false here for optimum safety. + */ + + 'display_permission_in_exception' => false, + + /* + * When set to true, the required role names are added to exception messages. + * This could be considered an information leak in some contexts, so the default + * setting is false here for optimum safety. + */ + + 'display_role_in_exception' => false, + + /* + * By default wildcard permission lookups are disabled. + * See documentation to understand supported syntax. + */ + + 'enable_wildcard_permission' => false, + + /* + * The class to use for interpreting wildcard permissions. + * If you need to modify delimiters, override the class and specify its name here. + */ + // 'wildcard_permission' => Spatie\Permission\WildcardPermission::class, + + /* Cache-specific settings */ + + 'cache' => [ + + /* + * By default all permissions are cached for 24 hours to speed up performance. + * When permissions or roles are updated the cache is flushed automatically. + */ + + 'expiration_time' => DateInterval::createFromDateString('24 hours'), + + /* + * The cache key used to store all permissions. + */ + + 'key' => 'spatie.permission.cache', + + /* + * You may optionally indicate a specific cache driver to use for permission and + * role caching using any of the `store` drivers listed in the cache.php config + * file. Using 'default' here means to use the `default` set in cache.php. + */ + + 'store' => 'default', + ], +]; diff --git a/config/queue.php b/config/queue.php new file mode 100644 index 0000000..79c2c0a --- /dev/null +++ b/config/queue.php @@ -0,0 +1,129 @@ + env('QUEUE_CONNECTION', 'database'), + + /* + |-------------------------------------------------------------------------- + | Queue Connections + |-------------------------------------------------------------------------- + | + | Here you may configure the connection options for every queue backend + | used by your application. An example configuration is provided for + | each backend supported by Laravel. You're also free to add more. + | + | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", + | "deferred", "background", "failover", "null" + | + */ + + 'connections' => [ + + 'sync' => [ + 'driver' => 'sync', + ], + + 'database' => [ + 'driver' => 'database', + 'connection' => env('DB_QUEUE_CONNECTION'), + 'table' => env('DB_QUEUE_TABLE', 'jobs'), + 'queue' => env('DB_QUEUE', 'default'), + 'retry_after' => (int) env('DB_QUEUE_RETRY_AFTER', 90), + 'after_commit' => false, + ], + + 'beanstalkd' => [ + 'driver' => 'beanstalkd', + 'host' => env('BEANSTALKD_QUEUE_HOST', 'localhost'), + 'queue' => env('BEANSTALKD_QUEUE', 'default'), + 'retry_after' => (int) env('BEANSTALKD_QUEUE_RETRY_AFTER', 90), + 'block_for' => 0, + 'after_commit' => false, + ], + + 'sqs' => [ + 'driver' => 'sqs', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), + 'queue' => env('SQS_QUEUE', 'default'), + 'suffix' => env('SQS_SUFFIX'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'after_commit' => false, + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => env('REDIS_QUEUE_CONNECTION', 'default'), + 'queue' => env('REDIS_QUEUE', 'default'), + 'retry_after' => (int) env('REDIS_QUEUE_RETRY_AFTER', 90), + 'block_for' => null, + 'after_commit' => false, + ], + + 'deferred' => [ + 'driver' => 'deferred', + ], + + 'background' => [ + 'driver' => 'background', + ], + + 'failover' => [ + 'driver' => 'failover', + 'connections' => [ + 'database', + 'deferred', + ], + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Job Batching + |-------------------------------------------------------------------------- + | + | The following options configure the database and table that store job + | batching information. These options can be updated to any database + | connection and table which has been defined by your application. + | + */ + + 'batching' => [ + 'database' => env('DB_CONNECTION', 'sqlite'), + 'table' => 'job_batches', + ], + + /* + |-------------------------------------------------------------------------- + | Failed Queue Jobs + |-------------------------------------------------------------------------- + | + | These options configure the behavior of failed queue job logging so you + | can control how and where failed jobs are stored. Laravel ships with + | support for storing failed jobs in a simple file or in a database. + | + | Supported drivers: "database-uuids", "dynamodb", "file", "null" + | + */ + + 'failed' => [ + 'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'), + 'database' => env('DB_CONNECTION', 'sqlite'), + 'table' => 'failed_jobs', + ], + +]; diff --git a/config/scribe.php b/config/scribe.php new file mode 100644 index 0000000..8fdbe8a --- /dev/null +++ b/config/scribe.php @@ -0,0 +1,259 @@ + for the generated documentation. + 'title' => config('app.name').' API Documentation', + + // A short description of your API. Will be included in the docs webpage, Postman collection and OpenAPI spec. + 'description' => '', + + // Text to place in the "Introduction" section, right after the `description`. Markdown and HTML are supported. + 'intro_text' => <<<'INTRO' + This documentation aims to provide all the information you need to work with our API. + + + INTRO, + + // The base URL displayed in the docs. + // If you're using `laravel` type, you can set this to a dynamic string, like '{{ config("app.tenant_url") }}' to get a dynamic base URL. + 'base_url' => config('app.url'), + + // Routes to include in the docs + 'routes' => [ + [ + 'match' => [ + // Match only routes whose paths match this pattern (use * as a wildcard to match any characters). Example: 'users/*'. + 'prefixes' => ['api/*'], + + // Match only routes whose domains match this pattern (use * as a wildcard to match any characters). Example: 'api.*'. + 'domains' => ['*'], + ], + + // Include these routes even if they did not match the rules above. + 'include' => [ + // 'users.index', 'POST /new', '/auth/*' + ], + + // Exclude these routes even if they matched the rules above. + 'exclude' => [ + // 'GET /health', 'admin.*' + ], + ], + ], + + // The type of documentation output to generate. + // - "static" will generate a static HTMl page in the /public/docs folder, + // - "laravel" will generate the documentation as a Blade view, so you can add routing and authentication. + // - "external_static" and "external_laravel" do the same as above, but pass the OpenAPI spec as a URL to an external UI template + 'type' => 'laravel', + + // See https://scribe.knuckles.wtf/laravel/reference/config#theme for supported options + 'theme' => 'default', + + 'static' => [ + // HTML documentation, assets and Postman collection will be generated to this folder. + // Source Markdown will still be in resources/docs. + 'output_path' => 'public/docs', + ], + + 'laravel' => [ + // Whether to automatically create a docs route for you to view your generated docs. You can still set up routing manually. + 'add_routes' => true, + + // URL path to use for the docs endpoint (if `add_routes` is true). + // By default, `/docs` opens the HTML page, `/docs.postman` opens the Postman collection, and `/docs.openapi` the OpenAPI spec. + 'docs_url' => '/docs', + + // Directory within `public` in which to store CSS and JS assets. + // By default, assets are stored in `public/vendor/scribe`. + // If set, assets will be stored in `public/{{assets_directory}}` + 'assets_directory' => null, + + // Middleware to attach to the docs endpoint (if `add_routes` is true). + 'middleware' => [], + ], + + 'external' => [ + 'html_attributes' => [], + ], + + 'try_it_out' => [ + // Add a Try It Out button to your endpoints so consumers can test endpoints right from their browser. + // Don't forget to enable CORS headers for your endpoints. + 'enabled' => true, + + // The base URL to use in the API tester. Leave as null to be the same as the displayed URL (`scribe.base_url`). + 'base_url' => null, + + // [Laravel Sanctum] Fetch a CSRF token before each request, and add it as an X-XSRF-TOKEN header. + 'use_csrf' => false, + + // The URL to fetch the CSRF token from (if `use_csrf` is true). + 'csrf_url' => '/sanctum/csrf-cookie', + ], + + // How is your API authenticated? This information will be used in the displayed docs, generated examples and response calls. + 'auth' => [ + // Set this to true if ANY endpoints in your API use authentication. + 'enabled' => false, + + // Set this to true if your API should be authenticated by default. If so, you must also set `enabled` (above) to true. + // You can then use @unauthenticated or @authenticated on individual endpoints to change their status from the default. + 'default' => false, + + // Where is the auth value meant to be sent in a request? + 'in' => AuthIn::BEARER->value, + + // The name of the auth parameter (e.g. token, key, apiKey) or header (e.g. Authorization, Api-Key). + 'name' => 'key', + + // The value of the parameter to be used by Scribe to authenticate response calls. + // This will NOT be included in the generated documentation. If empty, Scribe will use a random value. + 'use_value' => env('SCRIBE_AUTH_KEY'), + + // Placeholder your users will see for the auth parameter in the example requests. + // Set this to null if you want Scribe to use a random value as placeholder instead. + 'placeholder' => '{YOUR_AUTH_KEY}', + + // Any extra authentication-related info for your users. Markdown and HTML are supported. + 'extra_info' => 'You can retrieve your token by visiting your dashboard and clicking Generate API token.', + ], + + // Example requests for each endpoint will be shown in each of these languages. + // Supported options are: bash, javascript, php, python + // To add a language of your own, see https://scribe.knuckles.wtf/laravel/advanced/example-requests + // Note: does not work for `external` docs types + 'example_languages' => [ + 'bash', + 'javascript', + ], + + // Generate a Postman collection (v2.1.0) in addition to HTML docs. + // For 'static' docs, the collection will be generated to public/docs/collection.json. + // For 'laravel' docs, it will be generated to storage/app/scribe/collection.json. + // Setting `laravel.add_routes` to true (above) will also add a route for the collection. + 'postman' => [ + 'enabled' => true, + + 'overrides' => [ + // 'info.version' => '2.0.0', + ], + ], + + // Generate an OpenAPI spec in addition to docs webpage. + // For 'static' docs, the collection will be generated to public/docs/openapi.yaml. + // For 'laravel' docs, it will be generated to storage/app/scribe/openapi.yaml. + // Setting `laravel.add_routes` to true (above) will also add a route for the spec. + 'openapi' => [ + 'enabled' => true, + + // The OpenAPI spec version to generate. Supported versions: '3.0.3', '3.1.0'. + // OpenAPI 3.1 is more compatible with JSON Schema and is becoming the dominant version. + // See https://spec.openapis.org/oas/v3.1.0 for details on 3.1 changes. + 'version' => '3.0.3', + + 'overrides' => [ + // 'info.version' => '2.0.0', + ], + + // Additional generators to use when generating the OpenAPI spec. + // Should extend `Knuckles\Scribe\Writing\OpenApiSpecGenerators\OpenApiGenerator`. + 'generators' => [], + ], + + 'groups' => [ + // Endpoints which don't have a @group will be placed in this default group. + 'default' => 'Endpoints', + + // By default, Scribe will sort groups alphabetically, and endpoints in the order their routes are defined. + // You can override this by listing the groups, subgroups and endpoints here in the order you want them. + // See https://scribe.knuckles.wtf/blog/laravel-v4#easier-sorting and https://scribe.knuckles.wtf/laravel/reference/config#order for details + // Note: does not work for `external` docs types + 'order' => [], + ], + + // Custom logo path. This will be used as the value of the src attribute for the tag, + // so make sure it points to an accessible URL or path. Set to false to not use a logo. + // For example, if your logo is in public/img: + // - 'logo' => '../img/logo.png' // for `static` type (output folder is public/docs) + // - 'logo' => 'img/logo.png' // for `laravel` type + 'logo' => false, + + // Customize the "Last updated" value displayed in the docs by specifying tokens and formats. + // Examples: + // - {date:F j Y} => March 28, 2022 + // - {git:short} => Short hash of the last Git commit + // Available tokens are `{date:}` and `{git:}`. + // The format you pass to `date` will be passed to PHP's `date()` function. + // The format you pass to `git` can be either "short" or "long". + // Note: does not work for `external` docs types + 'last_updated' => 'Last updated: {date:F j, Y}', + + 'examples' => [ + // Set this to any number to generate the same example values for parameters on each run, + 'faker_seed' => 1234, + + // With API resources and transformers, Scribe tries to generate example models to use in your API responses. + // By default, Scribe will try the model's factory, and if that fails, try fetching the first from the database. + // You can reorder or remove strategies here. + 'models_source' => ['factoryCreate', 'factoryMake', 'databaseFirst'], + ], + + // The strategies Scribe will use to extract information about your routes at each stage. + // Use configureStrategy() to specify settings for a strategy in the list. + // Use removeStrategies() to remove an included strategy. + 'strategies' => [ + 'metadata' => [ + ...Defaults::METADATA_STRATEGIES, + ], + 'headers' => [ + ...Defaults::HEADERS_STRATEGIES, + Strategies\StaticData::withSettings(data: [ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + ]), + ], + 'urlParameters' => [ + ...Defaults::URL_PARAMETERS_STRATEGIES, + ], + 'queryParameters' => [ + ...Defaults::QUERY_PARAMETERS_STRATEGIES, + ], + 'bodyParameters' => [ + ...Defaults::BODY_PARAMETERS_STRATEGIES, + ], + 'responses' => configureStrategy( + Defaults::RESPONSES_STRATEGIES, + Strategies\Responses\ResponseCalls::withSettings( + only: ['GET *'], + // Recommended: disable debug mode in response calls to avoid error stack traces in responses + config: [ + 'app.debug' => false, + ] + ) + ), + 'responseFields' => [ + ...Defaults::RESPONSE_FIELDS_STRATEGIES, + ], + ], + + // For response calls, API resource responses and transformer responses, + // Scribe will try to start database transactions, so no changes are persisted to your database. + // Tell Scribe which connections should be transacted here. If you only use one db connection, you can leave this as is. + 'database_connections_to_transact' => [config('database.default')], + + 'fractal' => [ + // If you are using a custom serializer with league/fractal, you can specify it here. + 'serializer' => null, + ], +]; diff --git a/config/services.php b/config/services.php new file mode 100644 index 0000000..6a90eb8 --- /dev/null +++ b/config/services.php @@ -0,0 +1,38 @@ + [ + 'key' => env('POSTMARK_API_KEY'), + ], + + 'resend' => [ + 'key' => env('RESEND_API_KEY'), + ], + + 'ses' => [ + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + ], + + 'slack' => [ + 'notifications' => [ + 'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'), + 'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'), + ], + ], + +]; diff --git a/config/session.php b/config/session.php new file mode 100644 index 0000000..f574482 --- /dev/null +++ b/config/session.php @@ -0,0 +1,233 @@ + env('SESSION_DRIVER', 'database'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to expire immediately when the browser is closed then you may + | indicate that via the expire_on_close configuration option. + | + */ + + 'lifetime' => (int) env('SESSION_LIFETIME', 120), + + 'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false), + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it's stored. All encryption is performed + | automatically by Laravel and you may use the session like normal. + | + */ + + 'encrypt' => env('SESSION_ENCRYPT', false), + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When utilizing the "file" session driver, the session files are placed + | on disk. The default storage location is defined here; however, you + | are free to provide another location where they should be stored. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => env('SESSION_CONNECTION'), + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table to + | be used to store sessions. Of course, a sensible default is defined + | for you; however, you're welcome to change this to another table. + | + */ + + 'table' => env('SESSION_TABLE', 'sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using one of the framework's cache driven session backends, you may + | define the cache store which should be used to store the session data + | between requests. This must match one of your defined cache stores. + | + | Affects: "dynamodb", "memcached", "redis" + | + */ + + 'store' => env('SESSION_STORE'), + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the session cookie that is created by + | the framework. Typically, you should not need to change this value + | since doing so does not grant a meaningful security improvement. + | + */ + + 'cookie' => env( + 'SESSION_COOKIE', + Str::slug((string) env('APP_NAME', 'laravel')).'-session' + ), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application, but you're free to change this when necessary. + | + */ + + 'path' => env('SESSION_PATH', '/'), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | This value determines the domain and subdomains the session cookie is + | available to. By default, the cookie will be available to the root + | domain without subdomains. Typically, this shouldn't be changed. + | + */ + + 'domain' => env('SESSION_DOMAIN'), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you when it can't be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE'), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. It's unlikely you should disable this option. + | + */ + + 'http_only' => env('SESSION_HTTP_ONLY', true), + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | will set this value to "lax" to permit secure cross-site requests. + | + | See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value + | + | Supported: "lax", "strict", "none", null + | + */ + + 'same_site' => env('SESSION_SAME_SITE', 'lax'), + + /* + |-------------------------------------------------------------------------- + | Partitioned Cookies + |-------------------------------------------------------------------------- + | + | Setting this value to true will tie the cookie to the top-level site for + | a cross-site context. Partitioned cookies are accepted by the browser + | when flagged "secure" and the Same-Site attribute is set to "none". + | + */ + + 'partitioned' => env('SESSION_PARTITIONED_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | Session Serialization + |-------------------------------------------------------------------------- + | + | This value controls the serialization strategy for session data, which + | is JSON by default. Setting this to "php" allows the storage of PHP + | objects in the session but can make an application vulnerable to + | "gadget chain" serialization attacks if the APP_KEY is leaked. + | + | Supported: "json", "php" + | + */ + + 'serialization' => 'json', + +]; diff --git a/database/.gitignore b/database/.gitignore new file mode 100644 index 0000000..9b19b93 --- /dev/null +++ b/database/.gitignore @@ -0,0 +1 @@ +*.sqlite* diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php new file mode 100644 index 0000000..7d90d53 --- /dev/null +++ b/database/factories/UserFactory.php @@ -0,0 +1,47 @@ + + */ +class UserFactory extends Factory +{ + /** + * The current password being used by the factory. + */ + protected static ?string $password; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'first_name' => fake()->firstName(), + 'last_name' => fake()->lastName(), + 'email' => fake()->unique()->safeEmail(), + 'email_verified_at' => now(), + 'password' => static::$password ??= Hash::make('password'), + 'status' => 'active', + 'remember_token' => Str::random(10), + ]; + } + + /** + * Indicate that the model's email address should be unverified. + */ + public function unverified(): static + { + return $this->state(fn (array $attributes) => [ + 'email_verified_at' => null, + ]); + } +} diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php new file mode 100644 index 0000000..4270370 --- /dev/null +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -0,0 +1,54 @@ +id(); + $table->string('first_name', 100); + $table->string('last_name', 100); + $table->string('email')->unique(); + $table->timestamp('email_verified_at')->nullable(); + $table->string('password'); + $table->string('status', 20)->default('active'); + $table->text('avatar_url')->nullable(); + $table->jsonb('meta')->default('{}'); + $table->rememberToken(); + $table->timestamps(); + $table->softDeletes(); + }); + + Schema::create('password_reset_tokens', function (Blueprint $table) { + $table->string('email')->primary(); + $table->string('token'); + $table->timestamp('created_at')->nullable(); + }); + + Schema::create('sessions', function (Blueprint $table) { + $table->string('id')->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->string('ip_address', 45)->nullable(); + $table->text('user_agent')->nullable(); + $table->longText('payload'); + $table->integer('last_activity')->index(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('users'); + Schema::dropIfExists('password_reset_tokens'); + Schema::dropIfExists('sessions'); + } +}; diff --git a/database/migrations/0001_01_01_000001_create_cache_table.php b/database/migrations/0001_01_01_000001_create_cache_table.php new file mode 100644 index 0000000..06dc7a5 --- /dev/null +++ b/database/migrations/0001_01_01_000001_create_cache_table.php @@ -0,0 +1,35 @@ +string('key')->primary(); + $table->mediumText('value'); + $table->bigInteger('expiration')->index(); + }); + + Schema::create('cache_locks', function (Blueprint $table) { + $table->string('key')->primary(); + $table->string('owner'); + $table->bigInteger('expiration')->index(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('cache'); + Schema::dropIfExists('cache_locks'); + } +}; diff --git a/database/migrations/0001_01_01_000002_create_jobs_table.php b/database/migrations/0001_01_01_000002_create_jobs_table.php new file mode 100644 index 0000000..87d3ed7 --- /dev/null +++ b/database/migrations/0001_01_01_000002_create_jobs_table.php @@ -0,0 +1,57 @@ +id(); + $table->string('queue')->index(); + $table->longText('payload'); + $table->unsignedSmallInteger('attempts'); + $table->unsignedInteger('reserved_at')->nullable(); + $table->unsignedInteger('available_at'); + $table->unsignedInteger('created_at'); + }); + + Schema::create('job_batches', function (Blueprint $table) { + $table->string('id')->primary(); + $table->string('name'); + $table->integer('total_jobs'); + $table->integer('pending_jobs'); + $table->integer('failed_jobs'); + $table->longText('failed_job_ids'); + $table->mediumText('options')->nullable(); + $table->integer('cancelled_at')->nullable(); + $table->integer('created_at'); + $table->integer('finished_at')->nullable(); + }); + + Schema::create('failed_jobs', function (Blueprint $table) { + $table->id(); + $table->string('uuid')->unique(); + $table->text('connection'); + $table->text('queue'); + $table->longText('payload'); + $table->longText('exception'); + $table->timestamp('failed_at')->useCurrent(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('jobs'); + Schema::dropIfExists('job_batches'); + Schema::dropIfExists('failed_jobs'); + } +}; diff --git a/database/migrations/2026_05_07_030358_create_permission_tables.php b/database/migrations/2026_05_07_030358_create_permission_tables.php new file mode 100644 index 0000000..8986275 --- /dev/null +++ b/database/migrations/2026_05_07_030358_create_permission_tables.php @@ -0,0 +1,137 @@ +id(); // permission id + $table->string('name'); + $table->string('guard_name'); + $table->timestamps(); + + $table->unique(['name', 'guard_name']); + }); + + /** + * See `docs/prerequisites.md` for suggested lengths on 'name' and 'guard_name' if "1071 Specified key was too long" errors are encountered. + */ + Schema::create($tableNames['roles'], static function (Blueprint $table) use ($teams, $columnNames) { + $table->id(); // role id + if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing + $table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable(); + $table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index'); + } + $table->string('name'); + $table->string('guard_name'); + $table->timestamps(); + if ($teams || config('permission.testing')) { + $table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']); + } else { + $table->unique(['name', 'guard_name']); + } + }); + + Schema::create($tableNames['model_has_permissions'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotPermission, $teams) { + $table->unsignedBigInteger($pivotPermission); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index'); + + $table->foreign($pivotPermission) + ->references('id') // permission id + ->on($tableNames['permissions']) + ->cascadeOnDelete(); + if ($teams) { + $table->unsignedBigInteger($columnNames['team_foreign_key']); + $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index'); + + $table->primary([$columnNames['team_foreign_key'], $pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary'); + } else { + $table->primary([$pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary'); + } + }); + + Schema::create($tableNames['model_has_roles'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotRole, $teams) { + $table->unsignedBigInteger($pivotRole); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index'); + + $table->foreign($pivotRole) + ->references('id') // role id + ->on($tableNames['roles']) + ->cascadeOnDelete(); + if ($teams) { + $table->unsignedBigInteger($columnNames['team_foreign_key']); + $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index'); + + $table->primary([$columnNames['team_foreign_key'], $pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary'); + } else { + $table->primary([$pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary'); + } + }); + + Schema::create($tableNames['role_has_permissions'], static function (Blueprint $table) use ($tableNames, $pivotRole, $pivotPermission) { + $table->unsignedBigInteger($pivotPermission); + $table->unsignedBigInteger($pivotRole); + + $table->foreign($pivotPermission) + ->references('id') // permission id + ->on($tableNames['permissions']) + ->cascadeOnDelete(); + + $table->foreign($pivotRole) + ->references('id') // role id + ->on($tableNames['roles']) + ->cascadeOnDelete(); + + $table->primary([$pivotPermission, $pivotRole], 'role_has_permissions_permission_id_role_id_primary'); + }); + + app('cache') + ->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null) + ->forget(config('permission.cache.key')); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + $tableNames = config('permission.table_names'); + + throw_if(empty($tableNames), 'Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.'); + + Schema::dropIfExists($tableNames['role_has_permissions']); + Schema::dropIfExists($tableNames['model_has_roles']); + Schema::dropIfExists($tableNames['model_has_permissions']); + Schema::dropIfExists($tableNames['roles']); + Schema::dropIfExists($tableNames['permissions']); + } +}; diff --git a/database/migrations/2026_05_07_030408_create_personal_access_tokens_table.php b/database/migrations/2026_05_07_030408_create_personal_access_tokens_table.php new file mode 100644 index 0000000..40ff706 --- /dev/null +++ b/database/migrations/2026_05_07_030408_create_personal_access_tokens_table.php @@ -0,0 +1,33 @@ +id(); + $table->morphs('tokenable'); + $table->text('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamp('expires_at')->nullable()->index(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('personal_access_tokens'); + } +}; diff --git a/database/migrations/2026_05_07_073316_create_settings_table.php b/database/migrations/2026_05_07_073316_create_settings_table.php new file mode 100644 index 0000000..604028a --- /dev/null +++ b/database/migrations/2026_05_07_073316_create_settings_table.php @@ -0,0 +1,30 @@ +id(); + $table->string('key')->unique(); + $table->text('value')->nullable(); + $table->string('type')->default('string'); // string, boolean, integer, json + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('settings'); + } +}; diff --git a/database/migrations/2026_05_08_073749_create_activity_log_table.php b/database/migrations/2026_05_08_073749_create_activity_log_table.php new file mode 100644 index 0000000..7c05bc8 --- /dev/null +++ b/database/migrations/2026_05_08_073749_create_activity_log_table.php @@ -0,0 +1,27 @@ +create(config('activitylog.table_name'), function (Blueprint $table) { + $table->bigIncrements('id'); + $table->string('log_name')->nullable(); + $table->text('description'); + $table->nullableMorphs('subject', 'subject'); + $table->nullableMorphs('causer', 'causer'); + $table->json('properties')->nullable(); + $table->timestamps(); + $table->index('log_name'); + }); + } + + public function down() + { + Schema::connection(config('activitylog.database_connection'))->dropIfExists(config('activitylog.table_name')); + } +} diff --git a/database/migrations/2026_05_08_073750_add_event_column_to_activity_log_table.php b/database/migrations/2026_05_08_073750_add_event_column_to_activity_log_table.php new file mode 100644 index 0000000..7b797fd --- /dev/null +++ b/database/migrations/2026_05_08_073750_add_event_column_to_activity_log_table.php @@ -0,0 +1,22 @@ +table(config('activitylog.table_name'), function (Blueprint $table) { + $table->string('event')->nullable()->after('subject_type'); + }); + } + + public function down() + { + Schema::connection(config('activitylog.database_connection'))->table(config('activitylog.table_name'), function (Blueprint $table) { + $table->dropColumn('event'); + }); + } +} diff --git a/database/migrations/2026_05_08_073751_add_batch_uuid_column_to_activity_log_table.php b/database/migrations/2026_05_08_073751_add_batch_uuid_column_to_activity_log_table.php new file mode 100644 index 0000000..8f7db66 --- /dev/null +++ b/database/migrations/2026_05_08_073751_add_batch_uuid_column_to_activity_log_table.php @@ -0,0 +1,22 @@ +table(config('activitylog.table_name'), function (Blueprint $table) { + $table->uuid('batch_uuid')->nullable()->after('properties'); + }); + } + + public function down() + { + Schema::connection(config('activitylog.database_connection'))->table(config('activitylog.table_name'), function (Blueprint $table) { + $table->dropColumn('batch_uuid'); + }); + } +} diff --git a/database/migrations/2026_05_08_082147_create_notification_logs_table.php b/database/migrations/2026_05_08_082147_create_notification_logs_table.php new file mode 100644 index 0000000..ee42c77 --- /dev/null +++ b/database/migrations/2026_05_08_082147_create_notification_logs_table.php @@ -0,0 +1,36 @@ +id(); + $table->string('title'); + $table->text('body'); + $table->string('image_url')->nullable(); + $table->string('deep_link')->nullable(); + $table->string('target_type')->default('all'); // all, individual + $table->foreignId('target_user_id')->nullable()->constrained('users')->onDelete('cascade'); + $table->foreignId('sender_id')->nullable()->constrained('users')->onDelete('set null'); + $table->string('status')->default('sent'); // sent, failed + $table->text('error_message')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('notification_logs'); + } +}; diff --git a/database/migrations/2026_05_08_090423_create_remote_configs_table.php b/database/migrations/2026_05_08_090423_create_remote_configs_table.php new file mode 100644 index 0000000..0452053 --- /dev/null +++ b/database/migrations/2026_05_08_090423_create_remote_configs_table.php @@ -0,0 +1,26 @@ +id(); + $table->string('platform')->default('android'); // android | ios | all + $table->string('latest_version'); + $table->string('min_version'); + $table->boolean('maintenance_mode')->default(false); + $table->string('store_url')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('remote_configs'); + } +}; diff --git a/database/migrations/2026_05_13_101311_add_bio_and_phone_to_users_table.php b/database/migrations/2026_05_13_101311_add_bio_and_phone_to_users_table.php new file mode 100644 index 0000000..218a015 --- /dev/null +++ b/database/migrations/2026_05_13_101311_add_bio_and_phone_to_users_table.php @@ -0,0 +1,29 @@ +string('phone')->nullable()->after('email'); + $table->text('bio')->nullable()->after('last_name'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn(['phone', 'bio']); + }); + } +}; diff --git a/database/migrations/2026_05_13_102720_create_oauth_auth_codes_table.php b/database/migrations/2026_05_13_102720_create_oauth_auth_codes_table.php new file mode 100644 index 0000000..c700b50 --- /dev/null +++ b/database/migrations/2026_05_13_102720_create_oauth_auth_codes_table.php @@ -0,0 +1,39 @@ +char('id', 80)->primary(); + $table->foreignId('user_id')->index(); + $table->foreignUuid('client_id'); + $table->text('scopes')->nullable(); + $table->boolean('revoked'); + $table->dateTime('expires_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('oauth_auth_codes'); + } + + /** + * Get the migration connection name. + */ + public function getConnection(): ?string + { + return $this->connection ?? config('passport.connection'); + } +}; diff --git a/database/migrations/2026_05_13_102721_create_oauth_access_tokens_table.php b/database/migrations/2026_05_13_102721_create_oauth_access_tokens_table.php new file mode 100644 index 0000000..3e50f7f --- /dev/null +++ b/database/migrations/2026_05_13_102721_create_oauth_access_tokens_table.php @@ -0,0 +1,41 @@ +char('id', 80)->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->foreignUuid('client_id'); + $table->string('name')->nullable(); + $table->text('scopes')->nullable(); + $table->boolean('revoked'); + $table->timestamps(); + $table->dateTime('expires_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('oauth_access_tokens'); + } + + /** + * Get the migration connection name. + */ + public function getConnection(): ?string + { + return $this->connection ?? config('passport.connection'); + } +}; diff --git a/database/migrations/2026_05_13_102722_create_oauth_refresh_tokens_table.php b/database/migrations/2026_05_13_102722_create_oauth_refresh_tokens_table.php new file mode 100644 index 0000000..afb3c55 --- /dev/null +++ b/database/migrations/2026_05_13_102722_create_oauth_refresh_tokens_table.php @@ -0,0 +1,37 @@ +char('id', 80)->primary(); + $table->char('access_token_id', 80)->index(); + $table->boolean('revoked'); + $table->dateTime('expires_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('oauth_refresh_tokens'); + } + + /** + * Get the migration connection name. + */ + public function getConnection(): ?string + { + return $this->connection ?? config('passport.connection'); + } +}; diff --git a/database/migrations/2026_05_13_102723_create_oauth_clients_table.php b/database/migrations/2026_05_13_102723_create_oauth_clients_table.php new file mode 100644 index 0000000..9794dc8 --- /dev/null +++ b/database/migrations/2026_05_13_102723_create_oauth_clients_table.php @@ -0,0 +1,42 @@ +uuid('id')->primary(); + $table->nullableMorphs('owner'); + $table->string('name'); + $table->string('secret')->nullable(); + $table->string('provider')->nullable(); + $table->text('redirect_uris'); + $table->text('grant_types'); + $table->boolean('revoked'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('oauth_clients'); + } + + /** + * Get the migration connection name. + */ + public function getConnection(): ?string + { + return $this->connection ?? config('passport.connection'); + } +}; diff --git a/database/migrations/2026_05_13_102724_create_oauth_device_codes_table.php b/database/migrations/2026_05_13_102724_create_oauth_device_codes_table.php new file mode 100644 index 0000000..ea07831 --- /dev/null +++ b/database/migrations/2026_05_13_102724_create_oauth_device_codes_table.php @@ -0,0 +1,42 @@ +char('id', 80)->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->foreignUuid('client_id')->index(); + $table->char('user_code', 8)->unique(); + $table->text('scopes'); + $table->boolean('revoked'); + $table->dateTime('user_approved_at')->nullable(); + $table->dateTime('last_polled_at')->nullable(); + $table->dateTime('expires_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('oauth_device_codes'); + } + + /** + * Get the migration connection name. + */ + public function getConnection(): ?string + { + return $this->connection ?? config('passport.connection'); + } +}; diff --git a/database/migrations/2026_05_20_154119_add_two_factor_to_users_table.php b/database/migrations/2026_05_20_154119_add_two_factor_to_users_table.php new file mode 100644 index 0000000..9ecd49d --- /dev/null +++ b/database/migrations/2026_05_20_154119_add_two_factor_to_users_table.php @@ -0,0 +1,28 @@ +string('two_factor_secret')->nullable()->after('password'); + $table->text('two_factor_recovery_codes')->nullable()->after('two_factor_secret'); + $table->timestamp('two_factor_confirmed_at')->nullable()->after('two_factor_recovery_codes'); + }); + } + + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn([ + 'two_factor_secret', + 'two_factor_recovery_codes', + 'two_factor_confirmed_at', + ]); + }); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php new file mode 100644 index 0000000..282acd0 --- /dev/null +++ b/database/seeders/DatabaseSeeder.php @@ -0,0 +1,27 @@ +call(RolesAndPermissionsSeeder::class); + + \App\Models\User::factory()->create([ + 'first_name' => 'Super', + 'last_name' => 'Admin', + 'email' => 'admin@biiskit.com', + 'password' => \Illuminate\Support\Facades\Hash::make('password'), + ])->assignRole('super-admin'); + } +} diff --git a/database/seeders/RolesAndPermissionsSeeder.php b/database/seeders/RolesAndPermissionsSeeder.php new file mode 100644 index 0000000..3477994 --- /dev/null +++ b/database/seeders/RolesAndPermissionsSeeder.php @@ -0,0 +1,50 @@ +forgetCachedPermissions(); + + $permissions = [ + 'user.view', + 'user.create', + 'user.edit', + 'user.delete', + 'role.view', + 'role.manage', + 'settings.manage', + ]; + + foreach ($permissions as $permission) { + Permission::firstOrCreate(['name' => $permission, 'guard_name' => 'web']); + Permission::firstOrCreate(['name' => $permission, 'guard_name' => 'api']); + } + + // user — read-only access + $user = Role::firstOrCreate(['name' => 'user', 'guard_name' => 'web']); + $user->syncPermissions(['user.view']); + + // admin — full user & role management, no system settings + $admin = Role::firstOrCreate(['name' => 'admin', 'guard_name' => 'web']); + $admin->syncPermissions([ + 'user.view', + 'user.create', + 'user.edit', + 'user.delete', + 'role.view', + 'role.manage', + ]); + + // super-admin — everything (Gate::before bypasses checks anyway) + $superAdmin = Role::firstOrCreate(['name' => 'super-admin', 'guard_name' => 'web']); + $superAdmin->syncPermissions(Permission::where('guard_name', 'web')->get()); + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..2d01910 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,75 @@ +services: + laravel.test: + container_name: bii-kit-web + build: + context: ./docker/8.3 + dockerfile: Dockerfile + args: + WWWGROUP: '${WWWGROUP:-1000}' + image: bii-kit-app:latest + extra_hosts: + - 'host.docker.internal:host-gateway' + ports: + - '${APP_PORT:-8000}:80' + - '${VITE_PORT:-5173}:${VITE_PORT:-5173}' + environment: + WWWUSER: '${WWWUSER:-1000}' + LARAVEL_SAIL: 1 + XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}' + XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}' + IGNITION_LOCAL_SITES_PATH: '${PWD}' + volumes: + - '.:/var/www/html' + networks: + - bii-kit-network + depends_on: + - pgsql + - redis + pgsql: + container_name: bii-kit-pgsql + image: 'postgres:15' + ports: + - '${FORWARD_DB_PORT:-5432}:5432' + environment: + POSTGRES_DB: '${DB_DATABASE:-biiskit}' + POSTGRES_USER: '${DB_USERNAME:-sail}' + POSTGRES_PASSWORD: '${DB_PASSWORD:-password}' + volumes: + - 'bii-kit-pgsql:/var/lib/postgresql/data' + networks: + - bii-kit-network + healthcheck: + test: + - CMD + - pg_isready + - '-q' + - '-d' + - '${DB_DATABASE:-biiskit}' + - '-U' + - '${DB_USERNAME:-sail}' + retries: 3 + timeout: 5s + redis: + container_name: bii-kit-redis + image: 'redis:alpine' + ports: + - '${FORWARD_REDIS_PORT:-6379}:6379' + volumes: + - 'bii-kit-redis:/data' + networks: + - bii-kit-network + healthcheck: + test: + - CMD + - redis-cli + - ping + retries: 3 + timeout: 5s +networks: + bii-kit-network: + driver: bridge +volumes: + bii-kit-pgsql: + driver: local + bii-kit-redis: + driver: local diff --git a/docker/8.0/Dockerfile b/docker/8.0/Dockerfile new file mode 100644 index 0000000..32dc7cd --- /dev/null +++ b/docker/8.0/Dockerfile @@ -0,0 +1,72 @@ +FROM ubuntu:24.04 + +LABEL maintainer="Taylor Otwell" + +ARG WWWGROUP +ARG NODE_VERSION=24 +ARG POSTGRES_VERSION=18 + +WORKDIR /var/www/html + +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=UTC +ENV LANG=C.UTF-8 +ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80" +ENV SUPERVISOR_PHP_USER="sail" + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom + +RUN apt-get update && apt-get upgrade -y \ + && mkdir -p /etc/apt/keyrings \ + && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \ + && curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /usr/share/keyrings/ppa_ondrej_php.gpg > /dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \ + && apt-get update \ + && apt-get install -y libgd3 php8.0-cli php8.0-dev \ + php8.0-pgsql php8.0-sqlite3 php8.0-gd php8.0-imagick \ + php8.0-curl php8.0-memcached php8.0-mongodb \ + php8.0-imap php8.0-mysql php8.0-mbstring \ + php8.0-xml php8.0-zip php8.0-bcmath php8.0-soap \ + php8.0-intl php8.0-readline php8.0-pcov \ + php8.0-msgpack php8.0-igbinary php8.0-ldap \ + php8.0-redis php8.0-swoole php8.0-xdebug \ + && curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ + && apt-get update \ + && apt-get install -y nodejs \ + && npm install -g npm \ + && npm install -g bun \ + && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarnkey.gpg >/dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/pgdg.gpg >/dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && apt-get install -y yarn \ + && apt-get install -y mysql-client \ + && apt-get install -y postgresql-client-$POSTGRES_VERSION \ + && apt-get -y autoremove \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN update-alternatives --set php /usr/bin/php8.0 + +RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.0 + +RUN userdel -r ubuntu +RUN groupadd --force -g $WWWGROUP sail +RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail +RUN git config --global --add safe.directory /var/www/html + +COPY start-container /usr/local/bin/start-container +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY php.ini /etc/php/8.0/cli/conf.d/99-sail.ini +RUN chmod +x /usr/local/bin/start-container + +EXPOSE 80/tcp + +ENTRYPOINT ["start-container"] diff --git a/docker/8.0/php.ini b/docker/8.0/php.ini new file mode 100644 index 0000000..0d8ce9e --- /dev/null +++ b/docker/8.0/php.ini @@ -0,0 +1,5 @@ +[PHP] +post_max_size = 100M +upload_max_filesize = 100M +variables_order = EGPCS +pcov.directory = . diff --git a/docker/8.0/start-container b/docker/8.0/start-container new file mode 100644 index 0000000..40c55df --- /dev/null +++ b/docker/8.0/start-container @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then + echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'." + exit 1 +fi + +if [ ! -z "$WWWUSER" ]; then + usermod -u $WWWUSER sail +fi + +if [ ! -d /.composer ]; then + mkdir /.composer +fi + +chmod -R ugo+rw /.composer + +if [ $# -gt 0 ]; then + if [ "$SUPERVISOR_PHP_USER" = "root" ]; then + exec "$@" + else + exec gosu $WWWUSER "$@" + fi +else + exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/docker/8.0/supervisord.conf b/docker/8.0/supervisord.conf new file mode 100644 index 0000000..656da8a --- /dev/null +++ b/docker/8.0/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:php] +command=%(ENV_SUPERVISOR_PHP_COMMAND)s +user=%(ENV_SUPERVISOR_PHP_USER)s +environment=LARAVEL_SAIL="1" +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/docker/8.1/Dockerfile b/docker/8.1/Dockerfile new file mode 100644 index 0000000..90dff44 --- /dev/null +++ b/docker/8.1/Dockerfile @@ -0,0 +1,71 @@ +FROM ubuntu:24.04 + +LABEL maintainer="Taylor Otwell" + +ARG WWWGROUP +ARG NODE_VERSION=24 +ARG POSTGRES_VERSION=18 + +WORKDIR /var/www/html + +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=UTC +ENV LANG=C.UTF-8 +ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80" +ENV SUPERVISOR_PHP_USER="sail" + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom + +RUN apt-get update && apt-get upgrade -y \ + && mkdir -p /etc/apt/keyrings \ + && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \ + && curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /usr/share/keyrings/ppa_ondrej_php.gpg > /dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \ + && apt-get update \ + && apt-get install -y libgd3 php8.1-cli php8.1-dev \ + php8.1-pgsql php8.1-sqlite3 php8.1-gd php8.1-imagick \ + php8.1-curl php8.1-mongodb \ + php8.1-imap php8.1-mysql php8.1-mbstring \ + php8.1-xml php8.1-zip php8.1-bcmath php8.1-soap \ + php8.1-intl php8.1-readline \ + php8.1-ldap \ + php8.1-msgpack php8.1-igbinary php8.1-redis php8.1-swoole \ + php8.1-memcached php8.1-pcov php8.1-xdebug \ + && curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ + && apt-get update \ + && apt-get install -y nodejs \ + && npm install -g npm \ + && npm install -g bun \ + && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarn.gpg >/dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/pgdg.gpg >/dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && apt-get install -y yarn \ + && apt-get install -y mysql-client \ + && apt-get install -y postgresql-client-$POSTGRES_VERSION \ + && apt-get -y autoremove \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.1 + +RUN userdel -r ubuntu +RUN groupadd --force -g $WWWGROUP sail +RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail +RUN git config --global --add safe.directory /var/www/html + +COPY start-container /usr/local/bin/start-container +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY php.ini /etc/php/8.1/cli/conf.d/99-sail.ini +RUN chmod +x /usr/local/bin/start-container + +EXPOSE 80/tcp + +ENTRYPOINT ["start-container"] diff --git a/docker/8.1/php.ini b/docker/8.1/php.ini new file mode 100644 index 0000000..0d8ce9e --- /dev/null +++ b/docker/8.1/php.ini @@ -0,0 +1,5 @@ +[PHP] +post_max_size = 100M +upload_max_filesize = 100M +variables_order = EGPCS +pcov.directory = . diff --git a/docker/8.1/start-container b/docker/8.1/start-container new file mode 100644 index 0000000..40c55df --- /dev/null +++ b/docker/8.1/start-container @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then + echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'." + exit 1 +fi + +if [ ! -z "$WWWUSER" ]; then + usermod -u $WWWUSER sail +fi + +if [ ! -d /.composer ]; then + mkdir /.composer +fi + +chmod -R ugo+rw /.composer + +if [ $# -gt 0 ]; then + if [ "$SUPERVISOR_PHP_USER" = "root" ]; then + exec "$@" + else + exec gosu $WWWUSER "$@" + fi +else + exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/docker/8.1/supervisord.conf b/docker/8.1/supervisord.conf new file mode 100644 index 0000000..656da8a --- /dev/null +++ b/docker/8.1/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:php] +command=%(ENV_SUPERVISOR_PHP_COMMAND)s +user=%(ENV_SUPERVISOR_PHP_USER)s +environment=LARAVEL_SAIL="1" +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/docker/8.2/Dockerfile b/docker/8.2/Dockerfile new file mode 100644 index 0000000..258a287 --- /dev/null +++ b/docker/8.2/Dockerfile @@ -0,0 +1,71 @@ +FROM ubuntu:24.04 + +LABEL maintainer="Taylor Otwell" + +ARG WWWGROUP +ARG NODE_VERSION=24 +ARG POSTGRES_VERSION=18 + +WORKDIR /var/www/html + +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=UTC +ENV LANG=C.UTF-8 +ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80" +ENV SUPERVISOR_PHP_USER="sail" + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom + +RUN apt-get update && apt-get upgrade -y \ + && mkdir -p /etc/apt/keyrings \ + && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \ + && curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg > /dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \ + && apt-get update \ + && apt-get install -y libgd3 php8.2-cli php8.2-dev \ + php8.2-pgsql php8.2-sqlite3 php8.2-gd php8.2-imagick \ + php8.2-curl php8.2-mongodb \ + php8.2-imap php8.2-mysql php8.2-mbstring \ + php8.2-xml php8.2-zip php8.2-bcmath php8.2-soap \ + php8.2-intl php8.2-readline \ + php8.2-ldap \ + php8.2-msgpack php8.2-igbinary php8.2-redis php8.2-swoole \ + php8.2-memcached php8.2-pcov php8.2-xdebug \ + && curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ + && apt-get update \ + && apt-get install -y nodejs \ + && npm install -g npm \ + && npm install -g pnpm \ + && npm install -g bun \ + && corepack enable \ + && corepack prepare yarn@stable --activate \ + && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/keyrings/pgdg.gpg >/dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && apt-get install -y mysql-client \ + && apt-get install -y postgresql-client-$POSTGRES_VERSION \ + && apt-get -y autoremove \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.2 + +RUN userdel -r ubuntu +RUN groupadd --force -g $WWWGROUP sail +RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail +RUN git config --global --add safe.directory /var/www/html + +COPY start-container /usr/local/bin/start-container +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY php.ini /etc/php/8.2/cli/conf.d/99-sail.ini +RUN chmod +x /usr/local/bin/start-container + +EXPOSE 80/tcp + +ENTRYPOINT ["start-container"] diff --git a/docker/8.2/php.ini b/docker/8.2/php.ini new file mode 100644 index 0000000..0d8ce9e --- /dev/null +++ b/docker/8.2/php.ini @@ -0,0 +1,5 @@ +[PHP] +post_max_size = 100M +upload_max_filesize = 100M +variables_order = EGPCS +pcov.directory = . diff --git a/docker/8.2/start-container b/docker/8.2/start-container new file mode 100644 index 0000000..40c55df --- /dev/null +++ b/docker/8.2/start-container @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then + echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'." + exit 1 +fi + +if [ ! -z "$WWWUSER" ]; then + usermod -u $WWWUSER sail +fi + +if [ ! -d /.composer ]; then + mkdir /.composer +fi + +chmod -R ugo+rw /.composer + +if [ $# -gt 0 ]; then + if [ "$SUPERVISOR_PHP_USER" = "root" ]; then + exec "$@" + else + exec gosu $WWWUSER "$@" + fi +else + exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/docker/8.2/supervisord.conf b/docker/8.2/supervisord.conf new file mode 100644 index 0000000..656da8a --- /dev/null +++ b/docker/8.2/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:php] +command=%(ENV_SUPERVISOR_PHP_COMMAND)s +user=%(ENV_SUPERVISOR_PHP_USER)s +environment=LARAVEL_SAIL="1" +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/docker/8.3/Dockerfile b/docker/8.3/Dockerfile new file mode 100644 index 0000000..496a52d --- /dev/null +++ b/docker/8.3/Dockerfile @@ -0,0 +1,74 @@ +FROM ubuntu:24.04 + +LABEL maintainer="Taylor Otwell" + +ARG WWWGROUP +ARG NODE_VERSION=24 +ARG MYSQL_CLIENT="mysql-client" +ARG POSTGRES_VERSION=18 + +WORKDIR /var/www/html + +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=UTC +ENV LANG=C.UTF-8 +ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80" +ENV SUPERVISOR_PHP_USER="sail" +ENV PLAYWRIGHT_BROWSERS_PATH=0 + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom + +RUN apt-get update \ + && mkdir -p /etc/apt/keyrings \ + && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \ + && curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg > /dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \ + && apt-get update \ + && apt-get install -y libgd3 php8.3-cli php8.3-dev \ + php8.3-pgsql php8.3-sqlite3 php8.3-gd \ + php8.3-curl php8.3-mongodb \ + php8.3-imap php8.3-mysql php8.3-mbstring \ + php8.3-xml php8.3-zip php8.3-bcmath php8.3-soap \ + php8.3-intl php8.3-readline \ + php8.3-ldap \ + php8.3-msgpack php8.3-igbinary php8.3-redis \ + php8.3-memcached php8.3-pcov php8.3-imagick php8.3-xdebug php8.3-swoole \ + && curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ + && apt-get update \ + && apt-get install -y nodejs \ + && npm install -g npm \ + && npm install -g pnpm \ + && npm install -g bun \ + && npx playwright install-deps \ + && corepack enable \ + && corepack prepare yarn@stable --activate \ + && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/keyrings/pgdg.gpg >/dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && apt-get install -y $MYSQL_CLIENT \ + && apt-get install -y postgresql-client-$POSTGRES_VERSION \ + && apt-get -y autoremove \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.3 + +RUN userdel -r ubuntu +RUN groupadd --force -g $WWWGROUP sail +RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail +RUN git config --global --add safe.directory /var/www/html + +COPY start-container /usr/local/bin/start-container +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY php.ini /etc/php/8.3/cli/conf.d/99-sail.ini +RUN chmod +x /usr/local/bin/start-container + +EXPOSE 80/tcp + +ENTRYPOINT ["start-container"] diff --git a/docker/8.3/php.ini b/docker/8.3/php.ini new file mode 100644 index 0000000..0d8ce9e --- /dev/null +++ b/docker/8.3/php.ini @@ -0,0 +1,5 @@ +[PHP] +post_max_size = 100M +upload_max_filesize = 100M +variables_order = EGPCS +pcov.directory = . diff --git a/docker/8.3/start-container b/docker/8.3/start-container new file mode 100644 index 0000000..40c55df --- /dev/null +++ b/docker/8.3/start-container @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then + echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'." + exit 1 +fi + +if [ ! -z "$WWWUSER" ]; then + usermod -u $WWWUSER sail +fi + +if [ ! -d /.composer ]; then + mkdir /.composer +fi + +chmod -R ugo+rw /.composer + +if [ $# -gt 0 ]; then + if [ "$SUPERVISOR_PHP_USER" = "root" ]; then + exec "$@" + else + exec gosu $WWWUSER "$@" + fi +else + exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/docker/8.3/supervisord.conf b/docker/8.3/supervisord.conf new file mode 100644 index 0000000..656da8a --- /dev/null +++ b/docker/8.3/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:php] +command=%(ENV_SUPERVISOR_PHP_COMMAND)s +user=%(ENV_SUPERVISOR_PHP_USER)s +environment=LARAVEL_SAIL="1" +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/docker/8.4/Dockerfile b/docker/8.4/Dockerfile new file mode 100644 index 0000000..71227ae --- /dev/null +++ b/docker/8.4/Dockerfile @@ -0,0 +1,74 @@ +FROM ubuntu:24.04 + +LABEL maintainer="Taylor Otwell" + +ARG WWWGROUP +ARG NODE_VERSION=24 +ARG MYSQL_CLIENT="mysql-client" +ARG POSTGRES_VERSION=18 + +WORKDIR /var/www/html + +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=UTC +ENV LANG=C.UTF-8 +ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80" +ENV SUPERVISOR_PHP_USER="sail" +ENV PLAYWRIGHT_BROWSERS_PATH=0 + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom + +RUN apt-get update && apt-get upgrade -y \ + && mkdir -p /etc/apt/keyrings \ + && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \ + && curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg > /dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \ + && apt-get update \ + && apt-get install -y libgd3 php8.4-cli php8.4-dev \ + php8.4-pgsql php8.4-sqlite3 php8.4-gd \ + php8.4-curl php8.4-mongodb \ + php8.4-imap php8.4-mysql php8.4-mbstring \ + php8.4-xml php8.4-zip php8.4-bcmath php8.4-soap \ + php8.4-intl php8.4-readline \ + php8.4-ldap \ + php8.4-msgpack php8.4-igbinary php8.4-redis php8.4-swoole \ + php8.4-memcached php8.4-pcov php8.4-imagick php8.4-xdebug \ + && curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ + && apt-get update \ + && apt-get install -y nodejs \ + && npm install -g npm \ + && npm install -g pnpm \ + && npm install -g bun \ + && npx playwright install-deps \ + && corepack enable \ + && corepack prepare yarn@stable --activate \ + && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/keyrings/pgdg.gpg >/dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && apt-get install -y $MYSQL_CLIENT \ + && apt-get install -y postgresql-client-$POSTGRES_VERSION \ + && apt-get -y autoremove \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.4 + +RUN userdel -r ubuntu +RUN groupadd --force -g $WWWGROUP sail +RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail +RUN git config --global --add safe.directory /var/www/html + +COPY start-container /usr/local/bin/start-container +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY php.ini /etc/php/8.4/cli/conf.d/99-sail.ini +RUN chmod +x /usr/local/bin/start-container + +EXPOSE 80/tcp + +ENTRYPOINT ["start-container"] diff --git a/docker/8.4/php.ini b/docker/8.4/php.ini new file mode 100644 index 0000000..0d8ce9e --- /dev/null +++ b/docker/8.4/php.ini @@ -0,0 +1,5 @@ +[PHP] +post_max_size = 100M +upload_max_filesize = 100M +variables_order = EGPCS +pcov.directory = . diff --git a/docker/8.4/start-container b/docker/8.4/start-container new file mode 100644 index 0000000..40c55df --- /dev/null +++ b/docker/8.4/start-container @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then + echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'." + exit 1 +fi + +if [ ! -z "$WWWUSER" ]; then + usermod -u $WWWUSER sail +fi + +if [ ! -d /.composer ]; then + mkdir /.composer +fi + +chmod -R ugo+rw /.composer + +if [ $# -gt 0 ]; then + if [ "$SUPERVISOR_PHP_USER" = "root" ]; then + exec "$@" + else + exec gosu $WWWUSER "$@" + fi +else + exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/docker/8.4/supervisord.conf b/docker/8.4/supervisord.conf new file mode 100644 index 0000000..656da8a --- /dev/null +++ b/docker/8.4/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:php] +command=%(ENV_SUPERVISOR_PHP_COMMAND)s +user=%(ENV_SUPERVISOR_PHP_USER)s +environment=LARAVEL_SAIL="1" +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/docker/8.5/Dockerfile b/docker/8.5/Dockerfile new file mode 100644 index 0000000..706fd3e --- /dev/null +++ b/docker/8.5/Dockerfile @@ -0,0 +1,92 @@ +FROM ubuntu:24.04 + +LABEL maintainer="Taylor Otwell" + +ARG WWWGROUP +ARG NODE_VERSION=24 +ARG MYSQL_CLIENT="mysql-client" +ARG POSTGRES_VERSION=18 + +WORKDIR /var/www/html + +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=UTC +ENV LANG=C.UTF-8 +ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80" +ENV SUPERVISOR_PHP_USER="sail" +ENV PLAYWRIGHT_BROWSERS_PATH=0 + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom + +RUN apt-get update && apt-get upgrade -y \ + && mkdir -p /etc/apt/keyrings \ + && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \ + && curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg > /dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \ + && apt-get update \ + && apt-get install -y \ + libgd3 \ + php8.5-cli \ + php8.5-dev \ + php8.5-pgsql \ + php8.5-sqlite3 \ + php8.5-gd \ + php8.5-curl \ + php8.5-mongodb \ + php8.5-imap \ + php8.5-mysql \ + php8.5-mbstring \ + php8.5-xml \ + php8.5-zip \ + php8.5-bcmath \ + php8.5-soap \ + php8.5-intl \ + php8.5-readline \ + php8.5-ldap \ + php8.5-msgpack \ + php8.5-igbinary \ + php8.5-redis \ + php8.5-swoole \ + php8.5-memcached \ + php8.5-pcov \ + php8.5-imagick \ + php8.5-xdebug \ + && curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ + && apt-get update \ + && apt-get install -y nodejs \ + && npm install -g npm \ + && npm install -g pnpm \ + && npm install -g bun \ + && npx playwright install-deps \ + && corepack enable \ + && corepack prepare yarn@stable --activate \ + && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/keyrings/pgdg.gpg >/dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && apt-get install -y $MYSQL_CLIENT \ + && apt-get install -y postgresql-client-$POSTGRES_VERSION \ + && apt-get -y autoremove \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.5 + +RUN userdel -r ubuntu +RUN groupadd --force -g $WWWGROUP sail +RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail +RUN git config --global --add safe.directory /var/www/html + +COPY start-container /usr/local/bin/start-container +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY php.ini /etc/php/8.5/cli/conf.d/99-sail.ini +RUN chmod +x /usr/local/bin/start-container + +EXPOSE 80/tcp + +ENTRYPOINT ["start-container"] diff --git a/docker/8.5/php.ini b/docker/8.5/php.ini new file mode 100644 index 0000000..0d8ce9e --- /dev/null +++ b/docker/8.5/php.ini @@ -0,0 +1,5 @@ +[PHP] +post_max_size = 100M +upload_max_filesize = 100M +variables_order = EGPCS +pcov.directory = . diff --git a/docker/8.5/start-container b/docker/8.5/start-container new file mode 100644 index 0000000..40c55df --- /dev/null +++ b/docker/8.5/start-container @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then + echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'." + exit 1 +fi + +if [ ! -z "$WWWUSER" ]; then + usermod -u $WWWUSER sail +fi + +if [ ! -d /.composer ]; then + mkdir /.composer +fi + +chmod -R ugo+rw /.composer + +if [ $# -gt 0 ]; then + if [ "$SUPERVISOR_PHP_USER" = "root" ]; then + exec "$@" + else + exec gosu $WWWUSER "$@" + fi +else + exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/docker/8.5/supervisord.conf b/docker/8.5/supervisord.conf new file mode 100644 index 0000000..656da8a --- /dev/null +++ b/docker/8.5/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:php] +command=%(ENV_SUPERVISOR_PHP_COMMAND)s +user=%(ENV_SUPERVISOR_PHP_USER)s +environment=LARAVEL_SAIL="1" +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/docker/mariadb/create-testing-database.sh b/docker/mariadb/create-testing-database.sh new file mode 100644 index 0000000..4993ba2 --- /dev/null +++ b/docker/mariadb/create-testing-database.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +/usr/bin/mariadb --user=root --password="$MYSQL_ROOT_PASSWORD" <<-EOSQL + CREATE DATABASE IF NOT EXISTS testing; +EOSQL + +if [ -n "$MYSQL_USER" ]; then +/usr/bin/mariadb --user=root --password="$MYSQL_ROOT_PASSWORD" <<-EOSQL + GRANT ALL PRIVILEGES ON \`testing%\`.* TO '$MYSQL_USER'@'%'; +EOSQL +fi diff --git a/docker/mysql/create-testing-database.sh b/docker/mysql/create-testing-database.sh new file mode 100644 index 0000000..666156d --- /dev/null +++ b/docker/mysql/create-testing-database.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +mysql --user=root --password="$MYSQL_ROOT_PASSWORD" <<-EOSQL + CREATE DATABASE IF NOT EXISTS testing; +EOSQL + +if [ -n "$MYSQL_USER" ]; then +mysql --user=root --password="$MYSQL_ROOT_PASSWORD" <<-EOSQL + GRANT ALL PRIVILEGES ON \`testing%\`.* TO '$MYSQL_USER'@'%'; +EOSQL +fi diff --git a/docker/pgsql/create-testing-database.sql b/docker/pgsql/create-testing-database.sql new file mode 100644 index 0000000..d84dc07 --- /dev/null +++ b/docker/pgsql/create-testing-database.sql @@ -0,0 +1,2 @@ +SELECT 'CREATE DATABASE testing' +WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'testing')\gexec diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..6269354 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["resources/js/*"], + "ziggy-js": ["./vendor/tightenco/ziggy"] + } + }, + "exclude": ["node_modules", "public"] +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..241a9ec --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4419 @@ +{ + "name": "kit", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@tanstack/react-query": "^5.100.9", + "@types/lodash": "^4.17.24", + "animate.css": "^4.1.1", + "chart.js": "^4.5.1", + "filepond": "^4.32.12", + "filepond-plugin-file-validate-type": "^1.2.9", + "filepond-plugin-image-preview": "^4.6.12", + "lodash": "^4.18.1", + "react-chartjs-2": "^5.3.1", + "react-filepond": "^7.1.3", + "sweetalert2": "^11.26.24", + "zod": "^4.4.3", + "zustand": "^5.0.13" + }, + "devDependencies": { + "@headlessui/react": "^2.0.0", + "@inertiajs/react": "^2.0.0", + "@tailwindcss/forms": "^0.5.3", + "@tailwindcss/vite": "^4.2.4", + "@testing-library/dom": "^10.4.1", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.2", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^4.2.0", + "autoprefixer": "^10.4.12", + "concurrently": "^9.0.1", + "jsdom": "^29.1.1", + "laravel-vite-plugin": "^3.1", + "postcss": "^8.4.31", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "tailwindcss": "^4.2.4", + "vite": "^8.0.0", + "vitest": "^4.1.5" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", + "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@asamuzakjp/css-color": { + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.11.tgz", + "integrity": "sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/generational-cache": "^1.0.1", + "@csstools/css-calc": "^3.2.0", + "@csstools/css-color-parser": "^4.1.0", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.1.1.tgz", + "integrity": "sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/generational-cache": "^1.0.1", + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.2.1", + "is-potential-custom-element-name": "^1.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/generational-cache": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/generational-cache/-/generational-cache-1.0.1.tgz", + "integrity": "sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", + "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bramus/specificity": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", + "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^3.0.0" + }, + "bin": { + "specificity": "bin/cli.js" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz", + "integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@csstools/css-calc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.0.tgz", + "integrity": "sha512-bR9e6o2BDB12jzN/gIbjHa5wLJ4UjD1CB9pM7ehlc0ddk6EBz+yYS1EV2MF55/HUxrHcB/hehAyt5vhsA3hx7w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.0.tgz", + "integrity": "sha512-U0KhLYmy2GVj6q4T3WaAe6NPuFYCPQoE3b0dRGxejWDgcPp8TP7S5rVdM5ZrFaqu4N67X8YaPBw14dQSYx3IyQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.0.2", + "@csstools/css-calc": "^3.2.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.3.tgz", + "integrity": "sha512-SH60bMfrRCJF3morcdk57WklujF4Jr/EsQUzqkarfHXEFcAR1gg7fS/chAE922Sehgzc1/+Tz5H3Ypa1HiEKrg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "peerDependencies": { + "css-tree": "^3.2.1" + }, + "peerDependenciesMeta": { + "css-tree": { + "optional": true + } + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.0.tgz", + "integrity": "sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", + "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.11" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", + "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.5", + "@floating-ui/utils": "^0.2.11" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.26.28", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.28.tgz", + "integrity": "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.1.2", + "@floating-ui/utils": "^0.2.8", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", + "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.7.6" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", + "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@headlessui/react": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.2.10.tgz", + "integrity": "sha512-5pVLNK9wlpxTUTy9GpgbX/SdcRh+HBnPktjM2wbiLTH4p+2EPHBO1aoSryUCuKUIItdDWO9ITlhUL8UnUN/oIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.26.16", + "@react-aria/focus": "^3.20.2", + "@react-aria/interactions": "^3.25.0", + "@tanstack/react-virtual": "^3.13.9", + "use-sync-external-store": "^1.5.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^18 || ^19 || ^19.0.0-rc", + "react-dom": "^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/@inertiajs/core": { + "version": "2.3.22", + "resolved": "https://registry.npmjs.org/@inertiajs/core/-/core-2.3.22.tgz", + "integrity": "sha512-zrHy0X95dOAbvHIcgRZz3ZJbGKfNbQre256Gfn3KDzyjggjQmN33HL/19uZv4ledqwRwjISAHjOMzBENhYH1iA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/lodash-es": "^4.17.12", + "axios": "^1.13.5", + "laravel-precognition": "^1.0.2", + "lodash-es": "^4.18.1", + "qs": "^6.15.0" + } + }, + "node_modules/@inertiajs/react": { + "version": "2.3.22", + "resolved": "https://registry.npmjs.org/@inertiajs/react/-/react-2.3.22.tgz", + "integrity": "sha512-NxXcR2gtIdJdwB0lPgyBzyPSR2eUE437TIrt1rEi3nrPo7rLsW9LOroXaLu+reVbgbsQdhW3QQE/Gx+mhD1V/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inertiajs/core": "2.3.22", + "@types/lodash-es": "^4.17.12", + "laravel-precognition": "^1.0.2", + "lodash-es": "^4.18.1" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@internationalized/date": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.12.1.tgz", + "integrity": "sha512-6IedsVWXyq4P9Tj+TxuU8WGWM70hYLl12nbYU8jkikVpa6WXapFazPUcHUMDMoWftIDE2ILDkFFte6W2nFCkRQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@internationalized/number": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.6.tgz", + "integrity": "sha512-iFgmQaXHE0vytNfpLZWOC2mEJCBRzcUxt53Xf/yCXG93lRvqas237i3r7X4RKMwO3txiyZD4mQjKAByFv6UGSQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@internationalized/string": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@internationalized/string/-/string-3.2.8.tgz", + "integrity": "sha512-NdbMQUSfXLYIQol5VyMtinm9pZDciiMfN7RtmSuSB78io1hqwJ0naYfxyW6vgxWBkzWymQa/3uLDlbfmshtCaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", + "license": "MIT" + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.127.0.tgz", + "integrity": "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@react-aria/focus": { + "version": "3.22.0", + "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.22.0.tgz", + "integrity": "sha512-ZfDOVuVhqDsM9mkNji3QUZ/d40JhlVgXrDkrfXylM1035QCrcTHN7m2DpbE95sU2A8EQb4wikvt5jM6K/73BPg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "react-aria": "3.48.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/interactions": { + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.28.0.tgz", + "integrity": "sha512-OXwdU1EWFdMxmr/K1CXNGJzmNlCClByb+PuCaqUyzBymHPCGVhawirLIon/CrIN5psh3AiWpHSh4H0WeJdVpng==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.34.0", + "@swc/helpers": "^0.5.0", + "react-aria": "3.48.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/shared": { + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.34.0.tgz", + "integrity": "sha512-gp6xo/s2lX54AlTjOiqwDnxA7UW79BNvI9dB9pr3LZTzRKCd1ZA+ZbgKw/ReIiWuvvVw/8QFJpnqeeFyLocMcQ==", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.17.tgz", + "integrity": "sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.17.tgz", + "integrity": "sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.17.tgz", + "integrity": "sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.17.tgz", + "integrity": "sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.17.tgz", + "integrity": "sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.17.tgz", + "integrity": "sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.17.tgz", + "integrity": "sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.17.tgz", + "integrity": "sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.17.tgz", + "integrity": "sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.17.tgz", + "integrity": "sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.17.tgz", + "integrity": "sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@swc/helpers": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.21.tgz", + "integrity": "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tailwindcss/forms": { + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.11.tgz", + "integrity": "sha512-h9wegbZDPurxG22xZSoWtdzc41/OlNEUQERNqI/0fOwa2aVlWGu7C35E/x6LDyD3lgtztFSSjKZyuVM0hxhbgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mini-svg-data-uri": "^1.2.3" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.4.tgz", + "integrity": "sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.19.0", + "jiti": "^2.6.1", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.2.4" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.4.tgz", + "integrity": "sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.2.4", + "@tailwindcss/oxide-darwin-arm64": "4.2.4", + "@tailwindcss/oxide-darwin-x64": "4.2.4", + "@tailwindcss/oxide-freebsd-x64": "4.2.4", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.4", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.4", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.4", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.4", + "@tailwindcss/oxide-linux-x64-musl": "4.2.4", + "@tailwindcss/oxide-wasm32-wasi": "4.2.4", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.4", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.4" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.4.tgz", + "integrity": "sha512-e7MOr1SAn9U8KlZzPi1ZXGZHeC5anY36qjNwmZv9pOJ8E4Q6jmD1vyEHkQFmNOIN7twGPEMXRHmitN4zCMN03g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.4.tgz", + "integrity": "sha512-tSC/Kbqpz/5/o/C2sG7QvOxAKqyd10bq+ypZNf+9Fi2TvbVbv1zNpcEptcsU7DPROaSbVgUXmrzKhurFvo5eDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.4.tgz", + "integrity": "sha512-yPyUXn3yO/ufR6+Kzv0t4fCg2qNr90jxXc5QqBpjlPNd0NqyDXcmQb/6weunH/MEDXW5dhyEi+agTDiqa3WsGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.4.tgz", + "integrity": "sha512-BoMIB4vMQtZsXdGLVc2z+P9DbETkiopogfWZKbWwM8b/1Vinbs4YcUwo+kM/KeLkX3Ygrf4/PsRndKaYhS8Eiw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.4.tgz", + "integrity": "sha512-7pIHBLTHYRAlS7V22JNuTh33yLH4VElwKtB3bwchK/UaKUPpQ0lPQiOWcbm4V3WP2I6fNIJ23vABIvoy2izdwA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.4.tgz", + "integrity": "sha512-+E4wxJ0ZGOzSH325reXTWB48l42i93kQqMvDyz5gqfRzRZ7faNhnmvlV4EPGJU3QJM/3Ab5jhJ5pCRUsKn6OQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.4.tgz", + "integrity": "sha512-bBADEGAbo4ASnppIziaQJelekCxdMaxisrk+fB7Thit72IBnALp9K6ffA2G4ruj90G9XRS2VQ6q2bCKbfFV82g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.4.tgz", + "integrity": "sha512-7Mx25E4WTfnht0TVRTyC00j3i0M+EeFe7wguMDTlX4mRxafznw0CA8WJkFjWYH5BlgELd1kSjuU2JiPnNZbJDA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.4.tgz", + "integrity": "sha512-2wwJRF7nyhOR0hhHoChc04xngV3iS+akccHTGtz965FwF0up4b2lOdo6kI1EbDaEXKgvcrFBYcYQQ/rrnWFVfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.4.tgz", + "integrity": "sha512-FQsqApeor8Fo6gUEklzmaa9994orJZZDBAlQpK2Mq+DslRKFJeD6AjHpBQ0kZFQohVr8o85PPh8eOy86VlSCmw==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.8.1", + "@emnapi/runtime": "^1.8.1", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.1", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.4.tgz", + "integrity": "sha512-L9BXqxC4ToVgwMFqj3pmZRqyHEztulpUJzCxUtLjobMCzTPsGt1Fa9enKbOpY2iIyVtaHNeNvAK8ERP/64sqGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.4.tgz", + "integrity": "sha512-ESlKG0EpVJQwRjXDDa9rLvhEAh0mhP1sF7sap9dNZT0yyl9SAG6T7gdP09EH0vIv0UNTlo6jPWyujD6559fZvw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.4.tgz", + "integrity": "sha512-pCvohwOCspk3ZFn6eJzrrX3g4n2JY73H6MmYC87XfGPyTty4YsCjYTMArRZm/zOI8dIt3+EcrLHAFPe5A4bgtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.2.4", + "@tailwindcss/oxide": "4.2.4", + "tailwindcss": "4.2.4" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.100.9", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.100.9.tgz", + "integrity": "sha512-SJSFw1S8+kQ0+knv/XGfrbocWoAlT7vDKsSImtLx3ZPQmEcR46hkDjLSvynSy25N8Ms4tIEini1FuBd5k7IscQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.100.9", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.100.9.tgz", + "integrity": "sha512-Oa44XkaI3kCNN6ME0KByU3xT3SEUNOMfZpHxL6+wFoTm+OeUFYHKdeYVe0aOXlRDm/f15sgLwEt2HDorIdW8+A==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.100.9" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, + "node_modules/@tanstack/react-virtual": { + "version": "3.13.24", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.13.24.tgz", + "integrity": "sha512-aIJvz5OSkhNIhZIpYivrxrPTKYsjW9Uzy+sP/mx0S3sev2HyvPb7xmjbYvokzEpfgYHy/HjzJ2zFAETuUfgCpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tanstack/virtual-core": "3.14.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.14.0.tgz", + "integrity": "sha512-JLANqGy/D6k4Ujmh8Tr25lGimuOXNiaVyXaCAZS0W+1390sADdGnyUdSWNIfd49gebtIxGMij4IktRVzrdr12Q==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/@testing-library/dom/node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/react": { + "version": "16.3.2", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz", + "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.17.24", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz", + "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==", + "license": "MIT" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@vitest/expect": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.5.tgz", + "integrity": "sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.5", + "@vitest/utils": "4.1.5", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.5.tgz", + "integrity": "sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.5", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.5.tgz", + "integrity": "sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.5.tgz", + "integrity": "sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.5", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.5.tgz", + "integrity": "sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.5", + "@vitest/utils": "4.1.5", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.5.tgz", + "integrity": "sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.5.tgz", + "integrity": "sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.5", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/animate.css": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz", + "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==", + "license": "MIT" + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.0.tgz", + "integrity": "sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "caniuse-lite": "^1.0.30001787", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axios": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", + "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.16.0", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.27", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.27.tgz", + "integrity": "sha512-zEs/ufmZoUd7WftKpKyXaT6RFxpQ5Qm9xytKRHvJfxFV9DFJkZph9RvJ1LcOUi0Z1ZVijMte65JbILeV+8QQEA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001792", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz", + "integrity": "sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chart.js": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.1.tgz", + "integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==", + "license": "MIT", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concurrently": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", + "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "4.1.2", + "rxjs": "7.8.2", + "shell-quote": "1.8.3", + "supports-color": "8.1.1", + "tree-kill": "1.2.2", + "yargs": "17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/data-urls": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", + "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.352", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.352.tgz", + "integrity": "sha512-9wHk8x6dyuimoe18EdiDPWKExNdxYqo4fn4FwOVVper6RxT3cmpBwBkWWfSOCYJjQdIco/nPhJhNLmn4Ufg1Yg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz", + "integrity": "sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", + "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/filepond": { + "version": "4.32.12", + "resolved": "https://registry.npmjs.org/filepond/-/filepond-4.32.12.tgz", + "integrity": "sha512-wro0/deLwua9CkL7HJygOlDaPo1c7Ov8kfzbZjH7m4hdi56gdHGDeRWnYa+qXnRm3Lty69gUGVFb3JZy/9vT8g==", + "license": "MIT" + }, + "node_modules/filepond-plugin-file-validate-type": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/filepond-plugin-file-validate-type/-/filepond-plugin-file-validate-type-1.2.9.tgz", + "integrity": "sha512-Tzv07aNdZvjUXDRA3XL16QMEvh6llDrXlcZ6W0eTHQ+taHaVg/JKJTFs/AViO+6ZcpPCcQStbhYEL2HoS+vldw==", + "license": "MIT", + "peerDependencies": { + "filepond": ">=1.x <5.x" + } + }, + "node_modules/filepond-plugin-image-preview": { + "version": "4.6.12", + "resolved": "https://registry.npmjs.org/filepond-plugin-image-preview/-/filepond-plugin-image-preview-4.6.12.tgz", + "integrity": "sha512-Y8ETX5QVV0mbPB0586UH8AUmG9tZg8PuN5bdEAIlZVJFTct5ebViJ7+Am94/VhTPjLqZjBf1zmDq5JU6XRsZKw==", + "license": "MIT", + "peerDependencies": { + "filepond": ">=4.x <5.x" + } + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fraction.js": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsdom": { + "version": "29.1.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.1.1.tgz", + "integrity": "sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^5.1.11", + "@asamuzakjp/dom-selector": "^7.1.1", + "@bramus/specificity": "^2.4.2", + "@csstools/css-syntax-patches-for-csstree": "^1.1.3", + "@exodus/bytes": "^1.15.0", + "css-tree": "^3.2.1", + "data-urls": "^7.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.3.5", + "parse5": "^8.0.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.1", + "undici": "^7.25.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.1", + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.1", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/lru-cache": { + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", + "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/laravel-precognition": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/laravel-precognition/-/laravel-precognition-1.0.2.tgz", + "integrity": "sha512-0H08JDdMWONrL/N314fvsO3FATJwGGlFKGkMF3nNmizVFJaWs17816iM+sX7Rp8d5hUjYCx6WLfsehSKfaTxjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "axios": "^1.4.0", + "lodash-es": "^4.17.21" + } + }, + "node_modules/laravel-vite-plugin": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-3.1.0.tgz", + "integrity": "sha512-Fzocl+X4eQ9jOi0RwdphYRGkUbPJ3ky1pTAST5Ot18cS2gw6d2vldK2eCrlKDVjtibCjCx5qptYDlA0373n7qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "tinyglobby": "^0.2.12", + "vite-plugin-full-reload": "^1.1.0" + }, + "bin": { + "clean-orphaned-assets": "bin/clean.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "fontaine": "^0.5.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "fontaine": { + "optional": true + } + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", + "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "dev": true, + "license": "MIT", + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.38", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz", + "integrity": "sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, + "node_modules/parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-aria": { + "version": "3.48.0", + "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.48.0.tgz", + "integrity": "sha512-jQjd4rBEIMqecBaAKYJbVGK6EqIHLa5znVQ7jwFyK5vCyljoj6KhgtiahmcIPsG5vG5vEDLw+ba+bEWn6A2P4w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.1", + "@internationalized/number": "^3.6.6", + "@internationalized/string": "^3.2.8", + "@react-types/shared": "^3.34.0", + "@swc/helpers": "^0.5.0", + "aria-hidden": "^1.2.3", + "clsx": "^2.0.0", + "react-stately": "3.46.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/react-chartjs-2": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.3.1.tgz", + "integrity": "sha512-h5IPXKg9EXpjoBzUfyWJvllMjG2mQ4EiuHQFhms/AjUm0XSZHhyRy2xVmLXHKrtcdrPO4mnGqRtYoD0vp95A0A==", + "license": "MIT", + "peerDependencies": { + "chart.js": "^4.1.1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-filepond": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/react-filepond/-/react-filepond-7.1.3.tgz", + "integrity": "sha512-uQOCZt+YXnBfYn6OxK6vsgSoUROkBu/ZahcfIJnK94c1ZeSAS84L/XKDADq/8Adx/Lz88VtVWvUpTXnNpmjHFQ==", + "license": "MIT", + "peerDependencies": { + "filepond": ">=3.7.x < 5.x", + "react": "16 - 19", + "react-dom": "16 - 19" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-stately": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.46.0.tgz", + "integrity": "sha512-OdxhWvHgs2L4OJGIs7hnuTr5WjjMM6enhNEAMRqiekhF8+ITvA2LRwNftOZwcogaoCslGYq5S2VQTQwnm0GbCA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.1", + "@internationalized/number": "^3.6.6", + "@internationalized/string": "^3.2.8", + "@react-types/shared": "^3.34.0", + "@swc/helpers": "^0.5.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rolldown": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.17.tgz", + "integrity": "sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.127.0", + "@rolldown/pluginutils": "1.0.0-rc.17" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-rc.17", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.17", + "@rolldown/binding-darwin-x64": "1.0.0-rc.17", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.17", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.17", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.17", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.17", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.17", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.17", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.17", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.17" + } + }, + "node_modules/rolldown/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.17.tgz", + "integrity": "sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==", + "dev": true, + "license": "MIT" + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", + "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/sweetalert2": { + "version": "11.26.24", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.26.24.tgz", + "integrity": "sha512-SLgukW4wicewpW5VOukSXY5Z6DL/z7HCOK2ODSjmQPiSphCN8gJAmh9npoceXOtBRNoDN0xIz+zHYthtfiHmjg==", + "license": "MIT", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/limonte" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tabbable": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", + "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tailwindcss": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.4.tgz", + "integrity": "sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz", + "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "7.0.30", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.30.tgz", + "integrity": "sha512-ELrFxuqsDdHUwoh0XxDbxuLD3Wnz49Z57IFvTtvWy1hJdcMZjXLIuonjilCiWHlT2GbE4Wlv1wKVTzDFnXH1aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.0.30" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.0.30", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.30.tgz", + "integrity": "sha512-uiHN8PIB1VmWyS98eZYja4xzlYqeFZVjb4OuYlJQnZAuJhMw4PbKQOKgHKhBdJR3FE/t5mUQ1Kd80++B+qhD1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/tough-cookie": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", + "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/undici": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", + "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/vite": { + "version": "8.0.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.10.tgz", + "integrity": "sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.10", + "rolldown": "1.0.0-rc.17", + "tinyglobby": "^0.2.16" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-plugin-full-reload": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.2.0.tgz", + "integrity": "sha512-kz18NW79x0IHbxRSHm0jttP4zoO9P9gXh+n6UTwlNKnviTTEpOlum6oS9SmecrTtSr+muHEn5TUuC75UovQzcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "picomatch": "^2.3.1" + } + }, + "node_modules/vite-plugin-full-reload/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitest": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.5.tgz", + "integrity": "sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.5", + "@vitest/mocker": "4.1.5", + "@vitest/pretty-format": "4.1.5", + "@vitest/runner": "4.1.5", + "@vitest/snapshot": "4.1.5", + "@vitest/spy": "4.1.5", + "@vitest/utils": "4.1.5", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.5", + "@vitest/browser-preview": "4.1.5", + "@vitest/browser-webdriverio": "4.1.5", + "@vitest/coverage-istanbul": "4.1.5", + "@vitest/coverage-v8": "4.1.5", + "@vitest/ui": "4.1.5", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-url": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.11.0", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/zod": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zustand": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.13.tgz", + "integrity": "sha512-efI2tVaVQPqtOh114loML/Z80Y4NP3yc+Ff0fYiZJPauNeWZeIp/bRFD7I9bfmCOYBh/PHxlglQ9+wvlwnPikQ==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..779aea0 --- /dev/null +++ b/package.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://www.schemastore.org/package.json", + "private": true, + "type": "module", + "scripts": { + "build": "vite build", + "dev": "vite", + "test": "vitest run", + "test:watch": "vitest" + }, + "devDependencies": { + "@headlessui/react": "^2.0.0", + "@inertiajs/react": "^2.0.0", + "@tailwindcss/forms": "^0.5.3", + "@tailwindcss/vite": "^4.2.4", + "@testing-library/dom": "^10.4.1", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.2", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^4.2.0", + "autoprefixer": "^10.4.12", + "concurrently": "^9.0.1", + "jsdom": "^29.1.1", + "laravel-vite-plugin": "^3.1", + "postcss": "^8.4.31", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "tailwindcss": "^4.2.4", + "vite": "^8.0.0", + "vitest": "^4.1.5" + }, + "dependencies": { + "@tanstack/react-query": "^5.100.9", + "@types/lodash": "^4.17.24", + "animate.css": "^4.1.1", + "chart.js": "^4.5.1", + "filepond": "^4.32.12", + "filepond-plugin-file-validate-type": "^1.2.9", + "filepond-plugin-image-preview": "^4.6.12", + "lodash": "^4.18.1", + "react-chartjs-2": "^5.3.1", + "react-filepond": "^7.1.3", + "sweetalert2": "^11.26.24", + "zod": "^4.4.3", + "zustand": "^5.0.13" + } +} diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..c755c75 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,39 @@ + + + + + tests/Unit + + + tests/Feature + + + + + app + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..b574a59 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,25 @@ + + + Options -MultiViews -Indexes + + + RewriteEngine On + + # Handle Authorization Header + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Handle X-XSRF-Token Header + RewriteCond %{HTTP:x-xsrf-token} . + RewriteRule .* - [E=HTTP_X_XSRF_TOKEN:%{HTTP:X-XSRF-Token}] + + # Redirect Trailing Slashes If Not A Folder... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_URI} (.+)/$ + RewriteRule ^ %1 [L,R=301] + + # Send Requests To Front Controller... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + diff --git a/public/build/assets/AuthenticatedLayout-CrB9BCoI.js b/public/build/assets/AuthenticatedLayout-CrB9BCoI.js new file mode 100644 index 0000000..b1366b5 --- /dev/null +++ b/public/build/assets/AuthenticatedLayout-CrB9BCoI.js @@ -0,0 +1,4 @@ +import{c as e,d as t,i as n,o as r,r as i,t as a}from"./app-BJ7g6sa8.js";var o=t(e(),1),s=a();function c({theme:e}){let{auth:t}=r().props,{user:n,permissions:a}=t,o=window.location.pathname,c=e=>e?a.includes(e):!0,l=`${n.first_name?.charAt(0)||``}${n.last_name?.charAt(0)||``}`.toUpperCase(),u=[{label:`Governance`,items:[{href:`/dashboard`,label:`Dashboard`,ability:null,icon:(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6`})})},{href:`/notifications`,label:`Notifications`,ability:`role.manage`,icon:(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9`})})}]},{label:`Management`,items:[{href:`/users`,label:`Users`,ability:`user.view`,icon:(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z`})})},{href:`/roles`,label:`Roles`,ability:`role.view`,icon:(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z`})})},{href:`/activity-logs`,label:`Activity Logs`,ability:`user.view`,icon:(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{d:`M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z`})})}]},{label:`Account`,items:[{href:`/settings`,label:`Settings`,ability:null,icon:(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z`})})}]},{label:`Systems`,adminOnly:!0,items:[{href:`/system-settings`,label:`System Settings`,ability:null,icon:(0,s.jsxs)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:[(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z`}),(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M15 12a3 3 0 11-6 0 3 3 0 016 0z`})]})},{href:`/documentation`,label:`Dokumentasi`,ability:null,icon:(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253`})})}]}],d=a.includes(`settings.manage`);return(0,s.jsx)(`aside`,{className:`w-[260px] h-screen p-4 shrink-0 relative z-20 flex flex-col anim-left`,children:(0,s.jsxs)(`div`,{className:`bg-[#3D4E4B] flex-1 rounded-[2rem] flex flex-col relative`,children:[(0,s.jsxs)(`div`,{className:`p-8 flex flex-col items-center text-center`,children:[(0,s.jsxs)(`div`,{className:`relative mb-4`,children:[(0,s.jsx)(`div`,{className:`w-16 h-16 rounded-full border border-[#D4A017] p-1 flex items-center justify-center`,children:(0,s.jsx)(`div`,{className:`w-full h-full rounded-full bg-[#2D3A38] overflow-hidden flex items-center justify-center font-bold text-white/40 text-lg`,children:n.avatar_url?(0,s.jsx)(`img`,{src:n.avatar_url,className:`w-full h-full object-cover`}):l})}),(0,s.jsx)(`div`,{className:`absolute bottom-0 right-0 w-4 h-4 bg-[#21A59F] border-2 border-[#3D4E4B] rounded-full`})]}),(0,s.jsxs)(`h3`,{className:`text-white text-sm font-bold tracking-tight`,children:[n.first_name,` `,n.last_name]}),(0,s.jsx)(`p`,{className:`text-[#E3EBE8]/40 text-sm font-medium mt-0.5`,children:n.email})]}),(0,s.jsx)(`nav`,{className:`flex-1 px-3 space-y-6 overflow-y-auto custom-scrollbar pb-10`,children:u.map(e=>{if(e.adminOnly&&!d)return null;let t=e.items.filter(e=>c(e.ability));return t.length===0?null:(0,s.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,s.jsx)(`div`,{className:`px-5 text-xs font-semibold text-[#E3EBE8]/30 tracking-widest uppercase mb-2`,children:e.label}),t.map(e=>{let t=o===e.href||o.startsWith(e.href+`/`);return(0,s.jsxs)(i,{href:e.href,className:`flex items-center gap-4 py-3 transition-[color,background-color,box-shadow,opacity] duration-200 relative group + ${t?`text-[#3D4E4B] bg-[#E3EBE8] dark:bg-[#1A2120] dark:text-white -mr-3 pr-6 pl-5 rounded-l-[15px] w-[calc(100%+0.75rem)] shadow-sm`:`text-[#E3EBE8]/60 hover:text-white hover:bg-white/5 px-5 rounded-[15px]`}`,children:[(0,s.jsx)(`span`,{className:`shrink-0 z-10 transition-colors duration-300 ${t?`text-[#D4A017]`:`group-hover:text-[#D4A017]`}`,children:e.icon}),(0,s.jsx)(`span`,{className:`text-sm font-semibold tracking-tight z-10`,children:e.label})]},e.href)})]},e.label)})}),(0,s.jsx)(`div`,{className:`p-6 pb-8`,children:(0,s.jsxs)(`div`,{className:`px-4 py-3 rounded-2xl bg-white/5 border border-white/5 flex items-center justify-between group hover:bg-white/10 transition-colors cursor-default`,children:[(0,s.jsx)(`span`,{className:`text-sm font-semibold tracking-tight text-[#D4A017]`,children:`biiproject kit`}),(0,s.jsx)(`span`,{className:`text-sm font-bold text-white`,children:`v2`})]})})]})})}function l({theme:e,onThemeToggle:t,onMenuToggle:a,sidebarOpen:c}){let{auth:l,system_settings:u,unread_notifications:d}=r().props,{user:f,roles:p}=l,[m,h]=(0,o.useState)(!1),g=(0,o.useRef)(null),[_,v]=(0,o.useState)(``),[y,b]=(0,o.useState)([]),[x,S]=(0,o.useState)(!1),C=(0,o.useRef)(null),w=window.location.pathname;(0,o.useEffect)(()=>{function e(e){g.current&&!g.current.contains(e.target)&&h(!1)}return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]),(0,o.useEffect)(()=>{if(_.length<2){b([]);return}let e=setTimeout(async()=>{S(!0);try{b(await(await fetch(`/api/search?query=${encodeURIComponent(_)}`)).json())}catch(e){console.error(`Search error:`,e)}finally{S(!1)}},300);return()=>clearTimeout(e)},[_]),(0,o.useEffect)(()=>{let e=e=>{(e.ctrlKey||e.metaKey)&&e.key===`k`&&(e.preventDefault(),C.current?.focus())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[]);let T=()=>{n.post(`/logout`)},E=`${f?.first_name?.charAt(0)||``}${f?.last_name?.charAt(0)||``}`.toUpperCase(),D=w.split(`/`).filter(Boolean),O=e=>e.replace(/-/g,` `).replace(/\b\w/g,e=>e.toUpperCase()),k=D.length>0?O(D[0]):`Dashboard`,A=D.length>1?D.map((e,t)=>({label:O(e),href:`/`+D.slice(0,t+1).join(`/`)})):null;return(0,s.jsxs)(`header`,{className:`h-16 flex items-center justify-between px-6 shrink-0 relative z-30 transition-colors duration-300 bg-transparent`,children:[(0,s.jsxs)(`div`,{className:`flex items-center gap-6`,children:[(0,s.jsx)(`button`,{onClick:a,className:`lg:hidden p-2 rounded-xl bg-white dark:bg-white/5 border border-gray-100 dark:border-white/5 text-gray-500 dark:text-gray-400 hover:text-[#3D4E4B] dark:hover:text-white transition-all`,"aria-label":`Toggle menu`,children:c?(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M6 18L18 6M6 6l12 12`})}):(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M4 6h16M4 12h16M4 18h16`})})}),(0,s.jsxs)(`div`,{className:`hidden lg:block`,children:[(0,s.jsx)(`h2`,{className:`text-sm font-bold text-[#3D4E4B] dark:text-white tracking-tight leading-none`,children:k}),(0,s.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs font-semibold text-gray-400 tracking-tight mt-1`,children:[(0,s.jsx)(i,{href:`/dashboard`,className:`hover:text-[#3D4E4B] dark:hover:text-white transition-colors`,children:u?.app_name||`biiproject kit`}),A?A.map((e,t)=>(0,s.jsxs)(o.Fragment,{children:[(0,s.jsx)(`svg`,{className:`w-1 h-1 shrink-0`,fill:`currentColor`,viewBox:`0 0 24 24`,children:(0,s.jsx)(`circle`,{cx:`12`,cy:`12`,r:`12`})}),t===A.length-1?(0,s.jsx)(`span`,{className:`text-[#D4A017] font-bold`,children:e.label}):(0,s.jsx)(i,{href:e.href,className:`hover:text-[#3D4E4B] dark:hover:text-white transition-colors`,children:e.label})]},e.href)):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(`svg`,{className:`w-1 h-1 shrink-0`,fill:`currentColor`,viewBox:`0 0 24 24`,children:(0,s.jsx)(`circle`,{cx:`12`,cy:`12`,r:`12`})}),(0,s.jsx)(`span`,{className:`text-[#D4A017] font-bold`,children:k})]})]})]}),(0,s.jsxs)(`div`,{className:`relative group ml-4`,children:[(0,s.jsxs)(`div`,{className:`relative w-[300px]`,children:[(0,s.jsx)(`svg`,{className:`absolute left-3.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-gray-400 pointer-events-none group-focus-within:text-[#D4A017] transition-colors`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:3,children:(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z`})}),(0,s.jsx)(`input`,{ref:C,type:`text`,placeholder:`Search anything... (Ctrl+K)`,value:_,onChange:e=>v(e.target.value),className:`w-full h-10 pl-10 pr-4 rounded-xl border border-gray-100 dark:border-white/5 bg-white dark:bg-white/5 text-xs font-bold text-[#3D4E4B] dark:text-white placeholder-gray-400 focus:outline-none focus:border-[#D4A017] focus:ring-4 focus:ring-[#D4A017]/5 transition-all`}),x&&(0,s.jsx)(`div`,{className:`absolute right-3.5 top-1/2 -translate-y-1/2`,children:(0,s.jsx)(`div`,{className:`w-3.5 h-3.5 border-2 border-[#D4A017] border-t-transparent rounded-full animate-spin`})})]}),y.length>0&&(0,s.jsx)(`div`,{className:`absolute left-0 right-0 mt-3 bg-white dark:bg-[#232D2B] rounded-2xl shadow-2xl border border-gray-100 dark:border-white/5 overflow-hidden anim-up z-50`,children:(0,s.jsx)(`div`,{className:`p-2 max-h-[400px] overflow-y-auto custom-scrollbar`,children:y.map((e,t)=>(0,s.jsxs)(i,{href:e.url,onClick:()=>v(``),className:`flex items-center gap-3 p-3 rounded-xl hover:bg-gray-50 dark:hover:bg-white/5 transition-all group`,children:[(0,s.jsxs)(`div`,{className:`w-9 h-9 rounded-lg bg-gray-100 dark:bg-white/5 flex items-center justify-center text-gray-400 group-hover:text-[#D4A017] transition-colors shrink-0`,children:[e.icon===`user`&&(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{d:`M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z`})}),e.icon===`shield`&&(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{d:`M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z`})}),e.icon===`clock`&&(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{d:`M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z`})})]}),(0,s.jsxs)(`div`,{children:[(0,s.jsx)(`div`,{className:`text-xs font-bold text-[#3D4E4B] dark:text-white tracking-tight`,children:e.title}),(0,s.jsxs)(`div`,{className:`text-[10px] text-gray-400 font-bold uppercase tracking-widest mt-0.5`,children:[e.type,` • `,e.subtitle]})]})]},t))})})]})]}),(0,s.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,s.jsx)(`button`,{onClick:t,className:`p-2.5 rounded-xl bg-white dark:bg-white/5 text-gray-400 hover:text-[#D4A017] transition-all border border-gray-100 dark:border-white/5`,title:`Switch to ${e===`dark`?`Light`:`Dark`} Mode`,children:e===`dark`?(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{d:`M12 3v1m0 16v1m9-9h-1M4 12H3m15.364-6.364l-.707.707M6.343 17.657l-.707.707m12.728 0l-.707-.707M6.343 6.343l-.707.707M12 5a7 7 0 100 14 7 7 0 000-14z`})}):(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{d:`M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z`})})}),(0,s.jsxs)(i,{href:`/notifications`,className:`relative p-2.5 rounded-xl bg-white dark:bg-white/5 text-gray-400 hover:text-[#3D4E4B] dark:hover:text-white transition-all border border-gray-100 dark:border-white/5 flex items-center justify-center`,children:[(0,s.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9`})}),d>0&&(0,s.jsx)(`span`,{className:`absolute top-1.5 right-1.5 min-w-[1rem] h-4 px-0.5 bg-red-500 rounded-full flex items-center justify-center text-[9px] font-black text-white leading-none`,children:d>99?`99+`:d})]}),(0,s.jsxs)(`div`,{className:`relative`,ref:g,children:[(0,s.jsxs)(`button`,{onClick:()=>h(!m),className:`flex items-center gap-3 p-1.5 rounded-xl bg-white dark:bg-white/5 border border-gray-100 dark:border-white/5 hover:bg-gray-50 dark:hover:bg-white/10 transition-all group`,children:[(0,s.jsx)(`div`,{className:`w-8 h-8 rounded-lg bg-[#3D4E4B] flex items-center justify-center font-bold text-white text-sm`,children:f?.avatar_url?(0,s.jsx)(`img`,{src:f.avatar_url,className:`w-full h-full object-cover rounded-lg`}):E}),(0,s.jsxs)(`div`,{className:`hidden sm:block text-left pr-2`,children:[(0,s.jsx)(`div`,{className:`text-xs font-bold text-[#3D4E4B] dark:text-white leading-none`,children:f?.first_name}),(0,s.jsx)(`div`,{className:`text-[10px] text-[#D4A017] font-black uppercase tracking-widest mt-1`,children:p?.[0]?.replace(`-`,` `)||`User`})]})]}),m&&(0,s.jsxs)(`div`,{className:`absolute right-0 mt-3 w-56 bg-white dark:bg-[#232D2B] rounded-2xl shadow-2xl border border-gray-50 dark:border-white/5 py-2 z-50 anim-up`,children:[(0,s.jsxs)(`div`,{className:`px-5 py-3 border-b border-gray-50 dark:border-white/5 mb-1`,children:[(0,s.jsxs)(`div`,{className:`text-xs font-black text-[#3D4E4B] dark:text-white tracking-tight`,children:[f?.first_name,` `,f?.last_name]}),(0,s.jsx)(`div`,{className:`text-[10px] text-gray-400 font-bold truncate mt-1 uppercase tracking-widest`,children:f?.email})]}),(0,s.jsxs)(i,{href:`/profile`,className:`flex items-center gap-2.5 px-5 py-3 text-xs font-bold text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-white/5 transition-all`,children:[(0,s.jsx)(`svg`,{className:`w-4 h-4 opacity-50`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{d:`M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z`})}),`Account Settings`]}),(0,s.jsxs)(`button`,{onClick:T,className:`w-full flex items-center gap-2.5 px-5 py-3 text-xs font-bold text-red-600 hover:bg-red-50 dark:hover:bg-red-500/10 transition-all text-left border-t border-gray-50 dark:border-white/5 mt-1`,children:[(0,s.jsx)(`svg`,{className:`w-4 h-4 opacity-50`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,s.jsx)(`path`,{d:`M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1`})}),`Sign Out Session`]})]})]})]})]})}function u({children:e}){let{system_settings:t}=r().props,n=t?.primary_color,[i,a]=o.useState(()=>typeof window<`u`&&localStorage.getItem(`theme`)||`light`),[u,d]=o.useState(!1);o.useEffect(()=>{i===`dark`?document.documentElement.classList.add(`dark`):document.documentElement.classList.remove(`dark`),localStorage.setItem(`theme`,i)},[i]);let f=r().url;return o.useEffect(()=>{d(!1)},[f]),(0,s.jsxs)(`div`,{className:`flex h-screen overflow-hidden transition-colors duration-300 bg-[#E3EBE8] dark:bg-[#1A2120]`,style:n?{"--color-primary-500":n,"--color-accent-gold":n}:{},children:[(0,s.jsx)(`div`,{onClick:()=>d(!1),className:`fixed inset-0 z-10 bg-black/40 backdrop-blur-sm lg:hidden transition-opacity duration-300 + ${u?`opacity-100 pointer-events-auto`:`opacity-0 pointer-events-none`}`}),(0,s.jsx)(`div`,{className:`hidden lg:block shrink-0`,children:(0,s.jsx)(c,{theme:i})}),(0,s.jsx)(`div`,{className:`fixed inset-y-0 left-0 z-20 lg:hidden transition-transform duration-300 ease-in-out + ${u?`translate-x-0`:`-translate-x-full`}`,children:(0,s.jsx)(c,{theme:i})}),(0,s.jsxs)(`div`,{className:`flex-1 flex flex-col min-w-0 h-full relative`,children:[(0,s.jsx)(l,{theme:i,onThemeToggle:()=>a(e=>e===`dark`?`light`:`dark`),onMenuToggle:()=>d(e=>!e),sidebarOpen:u}),(0,s.jsx)(`main`,{className:`flex-1 overflow-y-auto px-6 pt-6 pb-6 custom-scrollbar`,children:(0,s.jsx)(`div`,{className:`max-w-[1600px] mx-auto anim-page`,children:e},f)})]})]})}export{u as t}; \ No newline at end of file diff --git a/public/build/assets/Can-DIOq7dyw.js b/public/build/assets/Can-DIOq7dyw.js new file mode 100644 index 0000000..939addd --- /dev/null +++ b/public/build/assets/Can-DIOq7dyw.js @@ -0,0 +1 @@ +import{c as e,o as t,t as n}from"./app-BJ7g6sa8.js";e();var r=n();function i({ability:e,children:n,fallback:i=null}){let{permissions:a}=t().props.auth;return(Array.isArray(e)?e:[e]).some(e=>a.includes(e))?(0,r.jsx)(r.Fragment,{children:n}):(0,r.jsx)(r.Fragment,{children:i})}export{i as t}; \ No newline at end of file diff --git a/public/build/assets/Challenge-DaBnX94x.js b/public/build/assets/Challenge-DaBnX94x.js new file mode 100644 index 0000000..6fcd17d --- /dev/null +++ b/public/build/assets/Challenge-DaBnX94x.js @@ -0,0 +1,2 @@ +import{a as e,c as t,d as n,n as r,t as i}from"./app-BJ7g6sa8.js";var a=n(t(),1),o=i();function s(){let[t,n]=(0,a.useState)(!1),{data:i,setData:s,post:c,processing:l,errors:u}=e({code:``});return(0,o.jsxs)(`div`,{className:`min-h-screen bg-[#E3EBE8] flex items-center justify-center p-4`,children:[(0,o.jsx)(r,{title:`Two-Factor Authentication`}),(0,o.jsxs)(`div`,{className:`w-full max-w-sm`,children:[(0,o.jsxs)(`div`,{className:`text-center mb-8`,children:[(0,o.jsx)(`div`,{className:`inline-flex items-center justify-center w-14 h-14 rounded-2xl bg-[#3D4E4B] mb-4`,children:(0,o.jsx)(`svg`,{className:`w-7 h-7 text-[#D4A017]`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,o.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z`})})}),(0,o.jsx)(`h1`,{className:`text-xl font-black text-[#3D4E4B] tracking-tight`,children:`Two-Factor Authentication`}),(0,o.jsx)(`p`,{className:`text-sm text-gray-500 font-medium mt-1`,children:t?`Enter a recovery code to continue`:`Enter the 6-digit code from your authenticator app`})]}),(0,o.jsxs)(`div`,{className:`bg-white rounded-2xl shadow-sm border border-gray-100 p-8`,children:[(0,o.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),c(route(`two-factor.verify`),{preserveScroll:!0})},className:`space-y-5`,children:[(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`label`,{className:`block text-xs font-bold text-gray-500 uppercase tracking-widest mb-2`,children:t?`Recovery Code`:`Authentication Code`}),(0,o.jsx)(`input`,{type:`text`,inputMode:t?`text`:`numeric`,maxLength:t?21:6,value:i.code,onChange:e=>s(`code`,e.target.value),autoFocus:!0,className:`w-full h-12 border rounded-xl px-4 text-center font-mono font-bold text-lg tracking-[0.4em] outline-none transition-all + ${u.code?`border-red-300 bg-red-50`:`border-gray-200 focus:border-[#3D4E4B] focus:ring-2 focus:ring-[#3D4E4B]/10`}`,placeholder:t?`xxxxxxxxxx-xxxxxxxxxx`:`000000`}),u.code&&(0,o.jsx)(`p`,{className:`text-xs text-red-500 font-semibold mt-1.5`,children:u.code})]}),(0,o.jsx)(`button`,{type:`submit`,disabled:l||i.code.length<(t?5:6),className:`w-full h-11 bg-[#3D4E4B] text-white text-sm font-bold rounded-xl hover:bg-[#2D3A38] transition-all disabled:opacity-60`,children:l?`Verifying...`:`Continue`})]}),(0,o.jsx)(`div`,{className:`mt-6 text-center`,children:(0,o.jsx)(`button`,{onClick:()=>{n(!t),s(`code`,``)},className:`text-xs font-bold text-[#3D4E4B] hover:underline`,children:t?`Use authenticator code instead`:`Use a recovery code`})})]}),(0,o.jsx)(`div`,{className:`mt-6 text-center`,children:(0,o.jsx)(`a`,{href:`/login`,className:`text-xs font-semibold text-gray-400 hover:text-[#3D4E4B]`,children:`← Back to login`})})]})]})}export{s as default}; \ No newline at end of file diff --git a/public/build/assets/ConfirmPassword-Ducw29r7.js b/public/build/assets/ConfirmPassword-Ducw29r7.js new file mode 100644 index 0000000..142f217 --- /dev/null +++ b/public/build/assets/ConfirmPassword-Ducw29r7.js @@ -0,0 +1 @@ +import{a as e,c as t,n,t as r}from"./app-BJ7g6sa8.js";import{t as i}from"./GuestLayout-CN-YY0cs.js";t();var a=r();function o(){let{data:t,setData:r,post:o,processing:s,errors:c,reset:l}=e({password:``});return(0,a.jsxs)(i,{children:[(0,a.jsx)(n,{title:`Confirm password`}),(0,a.jsxs)(`div`,{className:`mb-8 anim-down`,children:[(0,a.jsx)(`div`,{className:`w-12 h-12 bg-[#3D4E4B]/5 rounded-2xl flex items-center justify-center mb-6`,children:(0,a.jsx)(`svg`,{className:`w-5 h-5 text-[#3D4E4B]`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2,children:(0,a.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z`})})}),(0,a.jsx)(`h1`,{className:`text-2xl font-bold text-[#1A2421] tracking-tight`,children:`Confirm your password`}),(0,a.jsx)(`p`,{className:`mt-1.5 text-sm text-gray-400 font-medium leading-relaxed`,children:`For your security, please confirm your password to continue.`})]}),(0,a.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),o(route(`password.confirm`),{onFinish:()=>l(`password`)})},className:`anim-up`,style:{animationDelay:`0.1s`},children:[(0,a.jsxs)(`div`,{children:[(0,a.jsx)(`label`,{htmlFor:`password`,className:`block text-sm font-semibold text-gray-600 mb-1.5`,children:`Password`}),(0,a.jsx)(`input`,{id:`password`,type:`password`,autoComplete:`current-password`,autoFocus:!0,value:t.password,onChange:e=>r(`password`,e.target.value),placeholder:`••••••••`,className:`auth-input${c.password?` !border-red-300 !bg-red-50/50`:``}`}),c.password&&(0,a.jsx)(`p`,{className:`mt-1.5 text-xs font-semibold text-red-500`,children:c.password})]}),(0,a.jsx)(`button`,{type:`submit`,disabled:s,className:`mt-6 w-full h-11 rounded-xl bg-[#3D4E4B] hover:bg-[#2D3A38] text-white text-sm font-bold tracking-tight transition-colors duration-200 flex items-center justify-center gap-2 disabled:opacity-60 disabled:cursor-not-allowed`,children:s?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(`svg`,{className:`w-4 h-4 animate-spin text-white/60`,fill:`none`,viewBox:`0 0 24 24`,children:[(0,a.jsx)(`circle`,{className:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,strokeWidth:`4`}),(0,a.jsx)(`path`,{className:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z`})]}),`Confirming…`]}):`Confirm password`})]})]})}export{o as default}; \ No newline at end of file diff --git a/public/build/assets/Dashboard-DZOwY3RZ.js b/public/build/assets/Dashboard-DZOwY3RZ.js new file mode 100644 index 0000000..327e629 --- /dev/null +++ b/public/build/assets/Dashboard-DZOwY3RZ.js @@ -0,0 +1,3 @@ +import{c as e,d as t,n,r,t as i}from"./app-BJ7g6sa8.js";import{t as a}from"./AuthenticatedLayout-CrB9BCoI.js";var o=t(e(),1);function s(e){return e+.5|0}var c=(e,t,n)=>Math.max(Math.min(e,n),t);function l(e){return c(s(e*2.55),0,255)}function u(e){return c(s(e*255),0,255)}function d(e){return c(s(e/2.55)/100,0,1)}function f(e){return c(s(e*100),0,100)}var p={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},m=[...`0123456789ABCDEF`],h=e=>m[e&15],g=e=>m[(e&240)>>4]+m[e&15],_=e=>(e&240)>>4==(e&15),v=e=>_(e.r)&&_(e.g)&&_(e.b)&&_(e.a);function y(e){var t=e.length,n;return e[0]===`#`&&(t===4||t===5?n={r:255&p[e[1]]*17,g:255&p[e[2]]*17,b:255&p[e[3]]*17,a:t===5?p[e[4]]*17:255}:(t===7||t===9)&&(n={r:p[e[1]]<<4|p[e[2]],g:p[e[3]]<<4|p[e[4]],b:p[e[5]]<<4|p[e[6]],a:t===9?p[e[7]]<<4|p[e[8]]:255})),n}var b=(e,t)=>e<255?t(e):``;function x(e){var t=v(e)?h:g;return e?`#`+t(e.r)+t(e.g)+t(e.b)+b(e.a,t):void 0}var S=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function C(e,t,n){let r=t*Math.min(n,1-n),i=(t,i=(t+e/30)%12)=>n-r*Math.max(Math.min(i-3,9-i,1),-1);return[i(0),i(8),i(4)]}function w(e,t,n){let r=(r,i=(r+e/60)%6)=>n-n*t*Math.max(Math.min(i,4-i,1),0);return[r(5),r(3),r(1)]}function T(e,t,n){let r=C(e,1,.5),i;for(t+n>1&&(i=1/(t+n),t*=i,n*=i),i=0;i<3;i++)r[i]*=1-t-n,r[i]+=t;return r}function E(e,t,n,r,i){return e===i?(t-n)/r+(t.5?l/(2-i-a):l/(i+a),s=E(t,n,r,l,i),s=s*60+.5),[s|0,c||0,o]}function ee(e,t,n,r){return(Array.isArray(t)?e(t[0],t[1],t[2]):e(t,n,r)).map(u)}function O(e,t,n){return ee(C,e,t,n)}function te(e,t,n){return ee(T,e,t,n)}function ne(e,t,n){return ee(w,e,t,n)}function re(e){return(e%360+360)%360}function ie(e){let t=S.exec(e),n=255,r;if(!t)return;t[5]!==r&&(n=t[6]?l(+t[5]):u(+t[5]));let i=re(+t[2]),a=t[3]/100,o=t[4]/100;return r=t[1]===`hwb`?te(i,a,o):t[1]===`hsv`?ne(i,a,o):O(i,a,o),{r:r[0],g:r[1],b:r[2],a:n}}function ae(e,t){var n=D(e);n[0]=re(n[0]+t),n=O(n),e.r=n[0],e.g=n[1],e.b=n[2]}function oe(e){if(!e)return;let t=D(e),n=t[0],r=f(t[1]),i=f(t[2]);return e.a<255?`hsla(${n}, ${r}%, ${i}%, ${d(e.a)})`:`hsl(${n}, ${r}%, ${i}%)`}var se={x:`dark`,Z:`light`,Y:`re`,X:`blu`,W:`gr`,V:`medium`,U:`slate`,A:`ee`,T:`ol`,S:`or`,B:`ra`,C:`lateg`,D:`ights`,R:`in`,Q:`turquois`,E:`hi`,P:`ro`,O:`al`,N:`le`,M:`de`,L:`yello`,F:`en`,K:`ch`,G:`arks`,H:`ea`,I:`ightg`,J:`wh`},ce={OiceXe:`f0f8ff`,antiquewEte:`faebd7`,aqua:`ffff`,aquamarRe:`7fffd4`,azuY:`f0ffff`,beige:`f5f5dc`,bisque:`ffe4c4`,black:`0`,blanKedOmond:`ffebcd`,Xe:`ff`,XeviTet:`8a2be2`,bPwn:`a52a2a`,burlywood:`deb887`,caMtXe:`5f9ea0`,KartYuse:`7fff00`,KocTate:`d2691e`,cSO:`ff7f50`,cSnflowerXe:`6495ed`,cSnsilk:`fff8dc`,crimson:`dc143c`,cyan:`ffff`,xXe:`8b`,xcyan:`8b8b`,xgTMnPd:`b8860b`,xWay:`a9a9a9`,xgYF:`6400`,xgYy:`a9a9a9`,xkhaki:`bdb76b`,xmagFta:`8b008b`,xTivegYF:`556b2f`,xSange:`ff8c00`,xScEd:`9932cc`,xYd:`8b0000`,xsOmon:`e9967a`,xsHgYF:`8fbc8f`,xUXe:`483d8b`,xUWay:`2f4f4f`,xUgYy:`2f4f4f`,xQe:`ced1`,xviTet:`9400d3`,dAppRk:`ff1493`,dApskyXe:`bfff`,dimWay:`696969`,dimgYy:`696969`,dodgerXe:`1e90ff`,fiYbrick:`b22222`,flSOwEte:`fffaf0`,foYstWAn:`228b22`,fuKsia:`ff00ff`,gaRsbSo:`dcdcdc`,ghostwEte:`f8f8ff`,gTd:`ffd700`,gTMnPd:`daa520`,Way:`808080`,gYF:`8000`,gYFLw:`adff2f`,gYy:`808080`,honeyMw:`f0fff0`,hotpRk:`ff69b4`,RdianYd:`cd5c5c`,Rdigo:`4b0082`,ivSy:`fffff0`,khaki:`f0e68c`,lavFMr:`e6e6fa`,lavFMrXsh:`fff0f5`,lawngYF:`7cfc00`,NmoncEffon:`fffacd`,ZXe:`add8e6`,ZcSO:`f08080`,Zcyan:`e0ffff`,ZgTMnPdLw:`fafad2`,ZWay:`d3d3d3`,ZgYF:`90ee90`,ZgYy:`d3d3d3`,ZpRk:`ffb6c1`,ZsOmon:`ffa07a`,ZsHgYF:`20b2aa`,ZskyXe:`87cefa`,ZUWay:`778899`,ZUgYy:`778899`,ZstAlXe:`b0c4de`,ZLw:`ffffe0`,lime:`ff00`,limegYF:`32cd32`,lRF:`faf0e6`,magFta:`ff00ff`,maPon:`800000`,VaquamarRe:`66cdaa`,VXe:`cd`,VScEd:`ba55d3`,VpurpN:`9370db`,VsHgYF:`3cb371`,VUXe:`7b68ee`,VsprRggYF:`fa9a`,VQe:`48d1cc`,VviTetYd:`c71585`,midnightXe:`191970`,mRtcYam:`f5fffa`,mistyPse:`ffe4e1`,moccasR:`ffe4b5`,navajowEte:`ffdead`,navy:`80`,Tdlace:`fdf5e6`,Tive:`808000`,TivedBb:`6b8e23`,Sange:`ffa500`,SangeYd:`ff4500`,ScEd:`da70d6`,pOegTMnPd:`eee8aa`,pOegYF:`98fb98`,pOeQe:`afeeee`,pOeviTetYd:`db7093`,papayawEp:`ffefd5`,pHKpuff:`ffdab9`,peru:`cd853f`,pRk:`ffc0cb`,plum:`dda0dd`,powMrXe:`b0e0e6`,purpN:`800080`,YbeccapurpN:`663399`,Yd:`ff0000`,Psybrown:`bc8f8f`,PyOXe:`4169e1`,saddNbPwn:`8b4513`,sOmon:`fa8072`,sandybPwn:`f4a460`,sHgYF:`2e8b57`,sHshell:`fff5ee`,siFna:`a0522d`,silver:`c0c0c0`,skyXe:`87ceeb`,UXe:`6a5acd`,UWay:`708090`,UgYy:`708090`,snow:`fffafa`,sprRggYF:`ff7f`,stAlXe:`4682b4`,tan:`d2b48c`,teO:`8080`,tEstN:`d8bfd8`,tomato:`ff6347`,Qe:`40e0d0`,viTet:`ee82ee`,JHt:`f5deb3`,wEte:`ffffff`,wEtesmoke:`f5f5f5`,Lw:`ffff00`,LwgYF:`9acd32`};function le(){let e={},t=Object.keys(ce),n=Object.keys(se),r,i,a,o,s;for(r=0;r>16&255,a>>8&255,a&255]}return e}var ue;function de(e){ue||(ue=le(),ue.transparent=[0,0,0,0]);let t=ue[e.toLowerCase()];return t&&{r:t[0],g:t[1],b:t[2],a:t.length===4?t[3]:255}}var fe=/^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;function pe(e){let t=fe.exec(e),n=255,r,i,a;if(t){if(t[7]!==r){let e=+t[7];n=t[8]?l(e):c(e*255,0,255)}return r=+t[1],i=+t[3],a=+t[5],r=255&(t[2]?l(r):c(r,0,255)),i=255&(t[4]?l(i):c(i,0,255)),a=255&(t[6]?l(a):c(a,0,255)),{r,g:i,b:a,a:n}}}function me(e){return e&&(e.a<255?`rgba(${e.r}, ${e.g}, ${e.b}, ${d(e.a)})`:`rgb(${e.r}, ${e.g}, ${e.b})`)}var he=e=>e<=.0031308?e*12.92:e**(1/2.4)*1.055-.055,ge=e=>e<=.04045?e/12.92:((e+.055)/1.055)**2.4;function _e(e,t,n){let r=ge(d(e.r)),i=ge(d(e.g)),a=ge(d(e.b));return{r:u(he(r+n*(ge(d(t.r))-r))),g:u(he(i+n*(ge(d(t.g))-i))),b:u(he(a+n*(ge(d(t.b))-a))),a:e.a+n*(t.a-e.a)}}function ve(e,t,n){if(e){let r=D(e);r[t]=Math.max(0,Math.min(r[t]+r[t]*n,t===0?360:1)),r=O(r),e.r=r[0],e.g=r[1],e.b=r[2]}}function ye(e,t){return e&&Object.assign(t||{},e)}function be(e){var t={r:0,g:0,b:0,a:255};return Array.isArray(e)?e.length>=3&&(t={r:e[0],g:e[1],b:e[2],a:255},e.length>3&&(t.a=u(e[3]))):(t=ye(e,{r:0,g:0,b:0,a:1}),t.a=u(t.a)),t}function xe(e){return e.charAt(0)===`r`?pe(e):ie(e)}var Se=class e{constructor(t){if(t instanceof e)return t;let n=typeof t,r;n===`object`?r=be(t):n===`string`&&(r=y(t)||de(t)||xe(t)),this._rgb=r,this._valid=!!r}get valid(){return this._valid}get rgb(){var e=ye(this._rgb);return e&&(e.a=d(e.a)),e}set rgb(e){this._rgb=be(e)}rgbString(){return this._valid?me(this._rgb):void 0}hexString(){return this._valid?x(this._rgb):void 0}hslString(){return this._valid?oe(this._rgb):void 0}mix(e,t){if(e){let n=this.rgb,r=e.rgb,i,a=t===i?.5:t,o=2*a-1,s=n.a-r.a,c=((o*s===-1?o:(o+s)/(1+o*s))+1)/2;i=1-c,n.r=255&c*n.r+i*r.r+.5,n.g=255&c*n.g+i*r.g+.5,n.b=255&c*n.b+i*r.b+.5,n.a=a*n.a+(1-a)*r.a,this.rgb=n}return this}interpolate(e,t){return e&&(this._rgb=_e(this._rgb,e._rgb,t)),this}clone(){return new e(this.rgb)}alpha(e){return this._rgb.a=u(e),this}clearer(e){let t=this._rgb;return t.a*=1-e,this}greyscale(){let e=this._rgb;return e.r=e.g=e.b=s(e.r*.3+e.g*.59+e.b*.11),this}opaquer(e){let t=this._rgb;return t.a*=1+e,this}negate(){let e=this._rgb;return e.r=255-e.r,e.g=255-e.g,e.b=255-e.b,this}lighten(e){return ve(this._rgb,2,e),this}darken(e){return ve(this._rgb,2,-e),this}saturate(e){return ve(this._rgb,1,e),this}desaturate(e){return ve(this._rgb,1,-e),this}rotate(e){return ae(this._rgb,e),this}};function Ce(){}var we=(()=>{let e=0;return()=>e++})();function k(e){return e==null}function A(e){if(Array.isArray&&Array.isArray(e))return!0;let t=Object.prototype.toString.call(e);return t.slice(0,7)===`[object`&&t.slice(-6)===`Array]`}function j(e){return e!==null&&Object.prototype.toString.call(e)===`[object Object]`}function M(e){return(typeof e==`number`||e instanceof Number)&&isFinite(+e)}function N(e,t){return M(e)?e:t}function P(e,t){return e===void 0?t:e}var Te=(e,t)=>typeof e==`string`&&e.endsWith(`%`)?parseFloat(e)/100:+e/t,Ee=(e,t)=>typeof e==`string`&&e.endsWith(`%`)?parseFloat(e)/100*t:+e;function F(e,t,n){if(e&&typeof e.call==`function`)return e.apply(n,t)}function I(e,t,n,r){let i,a,o;if(A(e))if(a=e.length,r)for(i=a-1;i>=0;i--)t.call(n,e[i],i);else for(i=0;ie,x:e=>e.x,y:e=>e.y};function Fe(e){let t=e.split(`.`),n=[],r=``;for(let e of t)r+=e,r.endsWith(`\\`)?r=r.slice(0,-1)+`.`:(n.push(r),r=``);return n}function Ie(e){let t=Fe(e);return e=>{for(let n of t){if(n===``)break;e&&=e[n]}return e}}function Le(e,t){return(Pe[t]||(Pe[t]=Ie(t)))(e)}function Re(e){return e.charAt(0).toUpperCase()+e.slice(1)}var ze=e=>e!==void 0,Be=e=>typeof e==`function`,Ve=(e,t)=>{if(e.size!==t.size)return!1;for(let n of e)if(!t.has(n))return!1;return!0};function He(e){return e.type===`mouseup`||e.type===`click`||e.type===`contextmenu`}var L=Math.PI,R=2*L,Ue=R+L,We=1/0,Ge=L/180,z=L/2,Ke=L/4,qe=L*2/3,Je=Math.log10,B=Math.sign;function Ye(e,t,n){return Math.abs(e-t)e-t).pop(),t}function Qe(e){return typeof e==`symbol`||typeof e==`object`&&!!e&&!(Symbol.toPrimitive in e||`toString`in e||`valueOf`in e)}function $e(e){return!Qe(e)&&!isNaN(parseFloat(e))&&isFinite(e)}function et(e,t){let n=Math.round(e);return n-t<=e&&n+t>=e}function tt(e,t,n){let r,i,a;for(r=0,i=e.length;rc&&l=Math.min(t,n)-r&&e<=Math.max(t,n)+r}function ut(e,t,n){n||=(n=>e[n]1;)a=i+r>>1,n(a)?i=a:r=a;return{lo:i,hi:r}}var dt=(e,t,n,r)=>ut(e,n,r?r=>{let i=e[r][t];return ie[r][t]ut(e,n,r=>e[r][t]>=n);function pt(e,t,n){let r=0,i=e.length;for(;rr&&e[i-1]>n;)i--;return r>0||i{let n=`_onData`+Re(t),r=e[t];Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value(...t){let i=r.apply(this,t);return e._chartjs.listeners.forEach(e=>{typeof e[n]==`function`&&e[n](...t)}),i}})})}function gt(e,t){let n=e._chartjs;if(!n)return;let r=n.listeners,i=r.indexOf(t);i!==-1&&r.splice(i,1),!(r.length>0)&&(mt.forEach(t=>{delete e[t]}),delete e._chartjs)}function _t(e){let t=new Set(e);return t.size===e.length?e:Array.from(t)}var vt=function(){return typeof window>`u`?function(e){return e()}:window.requestAnimationFrame}();function yt(e,t){let n=[],r=!1;return function(...i){n=i,r||(r=!0,vt.call(window,()=>{r=!1,e.apply(t,n)}))}}function bt(e,t){let n;return function(...r){return t?(clearTimeout(n),n=setTimeout(e,t,r)):e.apply(this,r),t}}var xt=e=>e===`start`?`left`:e===`end`?`right`:`center`,W=(e,t,n)=>e===`start`?t:e===`end`?n:(t+n)/2,St=(e,t,n,r)=>e===(r?`left`:`right`)?n:e===`center`?(t+n)/2:t;function Ct(e,t,n){let r=t.length,i=0,a=r;if(e._sorted){let{iScale:o,vScale:s,_parsed:c}=e,l=e.dataset&&e.dataset.options?e.dataset.options.spanGaps:null,u=o.axis,{min:d,max:f,minDefined:p,maxDefined:m}=o.getUserBounds();if(p){if(i=Math.min(dt(c,u,d).lo,n?r:dt(t,u,o.getPixelForValue(d)).lo),l){let e=c.slice(0,i+1).reverse().findIndex(e=>!k(e[s.axis]));i-=Math.max(0,e)}i=U(i,0,r-1)}if(m){let e=Math.max(dt(c,o.axis,f,!0).hi+1,n?0:dt(t,u,o.getPixelForValue(f),!0).hi+1);if(l){let t=c.slice(e-1).findIndex(e=>!k(e[s.axis]));e+=Math.max(0,t)}a=U(e,i,r)-i}else a=r-i}return{start:i,count:a}}function wt(e){let{xScale:t,yScale:n,_scaleRanges:r}=e,i={xmin:t.min,xmax:t.max,ymin:n.min,ymax:n.max};if(!r)return e._scaleRanges=i,!0;let a=r.xmin!==t.min||r.xmax!==t.max||r.ymin!==n.min||r.ymax!==n.max;return Object.assign(r,i),a}var Tt=e=>e===0||e===1,Et=(e,t,n)=>-(2**(10*--e)*Math.sin((e-t)*R/n)),Dt=(e,t,n)=>2**(-10*e)*Math.sin((e-t)*R/n)+1,Ot={linear:e=>e,easeInQuad:e=>e*e,easeOutQuad:e=>-e*(e-2),easeInOutQuad:e=>(e/=.5)<1?.5*e*e:-.5*(--e*(e-2)-1),easeInCubic:e=>e*e*e,easeOutCubic:e=>--e*e*e+1,easeInOutCubic:e=>(e/=.5)<1?.5*e*e*e:.5*((e-=2)*e*e+2),easeInQuart:e=>e*e*e*e,easeOutQuart:e=>-(--e*e*e*e-1),easeInOutQuart:e=>(e/=.5)<1?.5*e*e*e*e:-.5*((e-=2)*e*e*e-2),easeInQuint:e=>e*e*e*e*e,easeOutQuint:e=>--e*e*e*e*e+1,easeInOutQuint:e=>(e/=.5)<1?.5*e*e*e*e*e:.5*((e-=2)*e*e*e*e+2),easeInSine:e=>-Math.cos(e*z)+1,easeOutSine:e=>Math.sin(e*z),easeInOutSine:e=>-.5*(Math.cos(L*e)-1),easeInExpo:e=>e===0?0:2**(10*(e-1)),easeOutExpo:e=>e===1?1:-(2**(-10*e))+1,easeInOutExpo:e=>Tt(e)?e:e<.5?.5*2**(10*(e*2-1)):.5*(-(2**(-10*(e*2-1)))+2),easeInCirc:e=>e>=1?e:-(Math.sqrt(1-e*e)-1),easeOutCirc:e=>Math.sqrt(1- --e*e),easeInOutCirc:e=>(e/=.5)<1?-.5*(Math.sqrt(1-e*e)-1):.5*(Math.sqrt(1-(e-=2)*e)+1),easeInElastic:e=>Tt(e)?e:Et(e,.075,.3),easeOutElastic:e=>Tt(e)?e:Dt(e,.075,.3),easeInOutElastic(e){let t=.1125,n=.45;return Tt(e)?e:e<.5?.5*Et(e*2,t,n):.5+.5*Dt(e*2-1,t,n)},easeInBack(e){let t=1.70158;return e*e*((t+1)*e-t)},easeOutBack(e){let t=1.70158;return--e*e*((t+1)*e+t)+1},easeInOutBack(e){let t=1.70158;return(e/=.5)<1?.5*(e*e*(((t*=1.525)+1)*e-t)):.5*((e-=2)*e*(((t*=1.525)+1)*e+t)+2)},easeInBounce:e=>1-Ot.easeOutBounce(1-e),easeOutBounce(e){let t=7.5625,n=2.75;return e<1/n?t*e*e:e<2/n?t*(e-=1.5/n)*e+.75:e<2.5/n?t*(e-=2.25/n)*e+.9375:t*(e-=2.625/n)*e+.984375},easeInOutBounce:e=>e<.5?Ot.easeInBounce(e*2)*.5:Ot.easeOutBounce(e*2-1)*.5+.5};function kt(e){if(e&&typeof e==`object`){let t=e.toString();return t===`[object CanvasPattern]`||t===`[object CanvasGradient]`}return!1}function At(e){return kt(e)?e:new Se(e)}function jt(e){return kt(e)?e:new Se(e).saturate(.5).darken(.1).hexString()}var Mt=[`x`,`y`,`borderWidth`,`radius`,`tension`],Nt=[`color`,`borderColor`,`backgroundColor`];function Pt(e){e.set(`animation`,{delay:void 0,duration:1e3,easing:`easeOutQuart`,fn:void 0,from:void 0,loop:void 0,to:void 0,type:void 0}),e.describe(`animation`,{_fallback:!1,_indexable:!1,_scriptable:e=>e!==`onProgress`&&e!==`onComplete`&&e!==`fn`}),e.set(`animations`,{colors:{type:`color`,properties:Nt},numbers:{type:`number`,properties:Mt}}),e.describe(`animations`,{_fallback:`animation`}),e.set(`transitions`,{active:{animation:{duration:400}},resize:{animation:{duration:0}},show:{animations:{colors:{from:`transparent`},visible:{type:`boolean`,duration:0}}},hide:{animations:{colors:{to:`transparent`},visible:{type:`boolean`,easing:`linear`,fn:e=>e|0}}}})}function Ft(e){e.set(`layout`,{autoPadding:!0,padding:{top:0,right:0,bottom:0,left:0}})}var It=new Map;function Lt(e,t){t||={};let n=e+JSON.stringify(t),r=It.get(n);return r||(r=new Intl.NumberFormat(e,t),It.set(n,r)),r}function Rt(e,t,n){return Lt(t,n).format(e)}var zt={values(e){return A(e)?e:``+e},numeric(e,t,n){if(e===0)return`0`;let r=this.chart.options.locale,i,a=e;if(n.length>1){let t=Math.max(Math.abs(n[0].value),Math.abs(n[n.length-1].value));(t<1e-4||t>0x38d7ea4c68000)&&(i=`scientific`),a=Bt(e,n)}let o=Je(Math.abs(a)),s=isNaN(o)?1:Math.max(Math.min(-1*Math.floor(o),20),0),c={notation:i,minimumFractionDigits:s,maximumFractionDigits:s};return Object.assign(c,this.options.ticks.format),Rt(e,r,c)},logarithmic(e,t,n){if(e===0)return`0`;let r=n[t].significand||e/10**Math.floor(Je(e));return[1,2,3,5,10,15].includes(r)||t>.8*n.length?zt.numeric.call(this,e,t,n):``}};function Bt(e,t){let n=t.length>3?t[2].value-t[1].value:t[1].value-t[0].value;return Math.abs(n)>=1&&e!==Math.floor(e)&&(n=e-Math.floor(e)),n}var Vt={formatters:zt};function Ht(e){e.set(`scale`,{display:!0,offset:!1,reverse:!1,beginAtZero:!1,bounds:`ticks`,clip:!0,grace:0,grid:{display:!0,lineWidth:1,drawOnChartArea:!0,drawTicks:!0,tickLength:8,tickWidth:(e,t)=>t.lineWidth,tickColor:(e,t)=>t.color,offset:!1},border:{display:!0,dash:[],dashOffset:0,width:1},title:{display:!1,text:``,padding:{top:4,bottom:4}},ticks:{minRotation:0,maxRotation:50,mirror:!1,textStrokeWidth:0,textStrokeColor:``,padding:3,display:!0,autoSkip:!0,autoSkipPadding:3,labelOffset:0,callback:Vt.formatters.values,minor:{},major:{},align:`center`,crossAlign:`near`,showLabelBackdrop:!1,backdropColor:`rgba(255, 255, 255, 0.75)`,backdropPadding:2}}),e.route(`scale.ticks`,`color`,``,`color`),e.route(`scale.grid`,`color`,``,`borderColor`),e.route(`scale.border`,`color`,``,`borderColor`),e.route(`scale.title`,`color`,``,`color`),e.describe(`scale`,{_fallback:!1,_scriptable:e=>!e.startsWith(`before`)&&!e.startsWith(`after`)&&e!==`callback`&&e!==`parser`,_indexable:e=>e!==`borderDash`&&e!==`tickBorderDash`&&e!==`dash`}),e.describe(`scales`,{_fallback:`scale`}),e.describe(`scale.ticks`,{_scriptable:e=>e!==`backdropPadding`&&e!==`callback`,_indexable:e=>e!==`backdropPadding`})}var Ut=Object.create(null),Wt=Object.create(null);function Gt(e,t){if(!t)return e;let n=t.split(`.`);for(let t=0,r=n.length;te.chart.platform.getDevicePixelRatio(),this.elements={},this.events=[`mousemove`,`mouseout`,`click`,`touchstart`,`touchmove`],this.font={family:`'Helvetica Neue', 'Helvetica', 'Arial', sans-serif`,size:12,style:`normal`,lineHeight:1.2,weight:null},this.hover={},this.hoverBackgroundColor=(e,t)=>jt(t.backgroundColor),this.hoverBorderColor=(e,t)=>jt(t.borderColor),this.hoverColor=(e,t)=>jt(t.color),this.indexAxis=`x`,this.interaction={mode:`nearest`,intersect:!0,includeInvisible:!1},this.maintainAspectRatio=!0,this.onHover=null,this.onClick=null,this.parsing=!0,this.plugins={},this.responsive=!0,this.scale=void 0,this.scales={},this.showLine=!0,this.drawActiveElementsOnTop=!0,this.describe(e),this.apply(t)}set(e,t){return Kt(this,e,t)}get(e){return Gt(this,e)}describe(e,t){return Kt(Wt,e,t)}override(e,t){return Kt(Ut,e,t)}route(e,t,n,r){let i=Gt(this,e),a=Gt(this,n),o=`_`+t;Object.defineProperties(i,{[o]:{value:i[t],writable:!0},[t]:{enumerable:!0,get(){let e=this[o],t=a[r];return j(e)?Object.assign({},t,e):P(e,t)},set(e){this[o]=e}}})}apply(e){e.forEach(e=>e(this))}}({_scriptable:e=>!e.startsWith(`on`),_indexable:e=>e!==`events`,hover:{_fallback:`interaction`},interaction:{_scriptable:!1,_indexable:!1}},[Pt,Ft,Ht]);function qt(e){return!e||k(e.size)||k(e.family)?null:(e.style?e.style+` `:``)+(e.weight?e.weight+` `:``)+e.size+`px `+e.family}function Jt(e,t,n,r,i){let a=t[i];return a||(a=t[i]=e.measureText(i).width,n.push(i)),a>r&&(r=a),r}function Yt(e,t,n,r){r||={};let i=r.data=r.data||{},a=r.garbageCollect=r.garbageCollect||[];r.font!==t&&(i=r.data={},a=r.garbageCollect=[],r.font=t),e.save(),e.font=t;let o=0,s=n.length,c,l,u,d,f;for(c=0;cn.length){for(c=0;c0&&e.stroke()}}function en(e,t,n){return n||=.5,!t||e&&e.x>t.left-n&&e.xt.top-n&&e.y0&&a.strokeColor!==``,c,l;for(e.save(),e.font=i.string,on(e,a),c=0;c+e||0;function hn(e,t){let n={},r=j(t),i=r?Object.keys(t):t,a=j(e)?r?n=>P(e[n],e[t[n]]):t=>e[t]:()=>e;for(let e of i)n[e]=mn(a(e));return n}function gn(e){return hn(e,{top:`y`,right:`x`,bottom:`y`,left:`x`})}function _n(e){return hn(e,[`topLeft`,`topRight`,`bottomLeft`,`bottomRight`])}function K(e){let t=gn(e);return t.width=t.left+t.right,t.height=t.top+t.bottom,t}function q(e,t){e||={},t||=G.font;let n=P(e.size,t.size);typeof n==`string`&&(n=parseInt(n,10));let r=P(e.style,t.style);r&&!(``+r).match(fn)&&(console.warn(`Invalid font style specified: "`+r+`"`),r=void 0);let i={family:P(e.family,t.family),lineHeight:pn(P(e.lineHeight,t.lineHeight),n),size:n,style:r,weight:P(e.weight,t.weight),string:``};return i.string=qt(i),i}function vn(e,t,n,r){let i=!0,a,o,s;for(a=0,o=e.length;an&&e===0?0:e+t;return{min:o(r,-Math.abs(a)),max:o(i,a)}}function bn(e,t){return Object.assign(Object.create(e),t)}function xn(e,t=[``],n,r,i=()=>e[0]){let a=n||e;return r===void 0&&(r=Ln(`_fallback`,e)),new Proxy({[Symbol.toStringTag]:`Object`,_cacheable:!0,_scopes:e,_rootScopes:a,_fallback:r,_getTarget:i,override:n=>xn([n,...e],t,a,r)},{deleteProperty(t,n){return delete t[n],delete t._keys,delete e[0][n],!0},get(n,r){return En(n,r,()=>In(r,t,e,n))},getOwnPropertyDescriptor(e,t){return Reflect.getOwnPropertyDescriptor(e._scopes[0],t)},getPrototypeOf(){return Reflect.getPrototypeOf(e[0])},has(e,t){return Rn(e).includes(t)},ownKeys(e){return Rn(e)},set(e,t,n){let r=e._storage||=i();return e[t]=r[t]=n,delete e._keys,!0}})}function Sn(e,t,n,r){let i={_cacheable:!1,_proxy:e,_context:t,_subProxy:n,_stack:new Set,_descriptors:Cn(e,r),setContext:t=>Sn(e,t,n,r),override:i=>Sn(e.override(i),t,n,r)};return new Proxy(i,{deleteProperty(t,n){return delete t[n],delete e[n],!0},get(e,t,n){return En(e,t,()=>Dn(e,t,n))},getOwnPropertyDescriptor(t,n){return t._descriptors.allKeys?Reflect.has(e,n)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(e,n)},getPrototypeOf(){return Reflect.getPrototypeOf(e)},has(t,n){return Reflect.has(e,n)},ownKeys(){return Reflect.ownKeys(e)},set(t,n,r){return e[n]=r,delete t[n],!0}})}function Cn(e,t={scriptable:!0,indexable:!0}){let{_scriptable:n=t.scriptable,_indexable:r=t.indexable,_allKeys:i=t.allKeys}=e;return{allKeys:i,scriptable:n,indexable:r,isScriptable:Be(n)?n:()=>n,isIndexable:Be(r)?r:()=>r}}var wn=(e,t)=>e?e+Re(t):t,Tn=(e,t)=>j(t)&&e!==`adapters`&&(Object.getPrototypeOf(t)===null||t.constructor===Object);function En(e,t,n){if(Object.prototype.hasOwnProperty.call(e,t)||t===`constructor`)return e[t];let r=n();return e[t]=r,r}function Dn(e,t,n){let{_proxy:r,_context:i,_subProxy:a,_descriptors:o}=e,s=r[t];return Be(s)&&o.isScriptable(t)&&(s=On(t,s,e,n)),A(s)&&s.length&&(s=kn(t,s,e,o.isIndexable)),Tn(t,s)&&(s=Sn(s,i,a&&a[t],o)),s}function On(e,t,n,r){let{_proxy:i,_context:a,_subProxy:o,_stack:s}=n;if(s.has(e))throw Error(`Recursion detected: `+Array.from(s).join(`->`)+`->`+e);s.add(e);let c=t(a,o||r);return s.delete(e),Tn(e,c)&&(c=Nn(i._scopes,i,e,c)),c}function kn(e,t,n,r){let{_proxy:i,_context:a,_subProxy:o,_descriptors:s}=n;if(a.index!==void 0&&r(e))return t[a.index%t.length];if(j(t[0])){let n=t,r=i._scopes.filter(e=>e!==n);t=[];for(let c of n){let n=Nn(r,i,e,c);t.push(Sn(n,a,o&&o[e],s))}}return t}function An(e,t,n){return Be(e)?e(t,n):e}var jn=(e,t)=>e===!0?t:typeof e==`string`?Le(t,e):void 0;function Mn(e,t,n,r,i){for(let a of t){let t=jn(n,a);if(t){e.add(t);let a=An(t._fallback,n,i);if(a!==void 0&&a!==n&&a!==r)return a}else if(t===!1&&r!==void 0&&n!==r)return null}return!1}function Nn(e,t,n,r){let i=t._rootScopes,a=An(t._fallback,n,r),o=[...e,...i],s=new Set;s.add(r);let c=Pn(s,o,n,a||n,r);return c===null||a!==void 0&&a!==n&&(c=Pn(s,o,a,c,r),c===null)?!1:xn(Array.from(s),[``],i,a,()=>Fn(t,n,r))}function Pn(e,t,n,r,i){for(;n;)n=Mn(e,t,n,r,i);return n}function Fn(e,t,n){let r=e._getTarget();t in r||(r[t]={});let i=r[t];return A(i)&&j(n)?n:i||{}}function In(e,t,n,r){let i;for(let a of t)if(i=Ln(wn(a,e),n),i!==void 0)return Tn(e,i)?Nn(n,r,e,i):i}function Ln(e,t){for(let n of t){if(!n)continue;let t=n[e];if(t!==void 0)return t}}function Rn(e){let t=e._keys;return t||=e._keys=zn(e._scopes),t}function zn(e){let t=new Set;for(let n of e)for(let e of Object.keys(n).filter(e=>!e.startsWith(`_`)))t.add(e);return Array.from(t)}var Bn=2**-52||1e-14,Vn=(e,t)=>te===`x`?`y`:`x`;function Un(e,t,n,r){let i=e.skip?t:e,a=t,o=n.skip?t:n,s=at(a,i),c=at(o,a),l=s/(s+c),u=c/(s+c);l=isNaN(l)?0:l,u=isNaN(u)?0:u;let d=r*l,f=r*u;return{previous:{x:a.x-d*(o.x-i.x),y:a.y-d*(o.y-i.y)},next:{x:a.x+f*(o.x-i.x),y:a.y+f*(o.y-i.y)}}}function Wn(e,t,n){let r=e.length,i,a,o,s,c,l=Vn(e,0);for(let u=0;u!e.skip)),t.cubicInterpolationMode===`monotone`)Kn(e,i);else{let n=r?e[e.length-1]:e[0];for(a=0,o=e.length;ae.ownerDocument.defaultView.getComputedStyle(e,null);function er(e,t){return $n(e).getPropertyValue(t)}var tr=[`top`,`right`,`bottom`,`left`];function nr(e,t,n){let r={};n=n?`-`+n:``;for(let i=0;i<4;i++){let a=tr[i];r[a]=parseFloat(e[t+`-`+a+n])||0}return r.width=r.left+r.right,r.height=r.top+r.bottom,r}var rr=(e,t,n)=>(e>0||t>0)&&(!n||!n.shadowRoot);function ir(e,t){let n=e.touches,r=n&&n.length?n[0]:e,{offsetX:i,offsetY:a}=r,o=!1,s,c;if(rr(i,a,e.target))s=i,c=a;else{let e=t.getBoundingClientRect();s=r.clientX-e.left,c=r.clientY-e.top,o=!0}return{x:s,y:c,box:o}}function ar(e,t){if(`native`in e)return e;let{canvas:n,currentDevicePixelRatio:r}=t,i=$n(n),a=i.boxSizing===`border-box`,o=nr(i,`padding`),s=nr(i,`border`,`width`),{x:c,y:l,box:u}=ir(e,n),d=o.left+(u&&s.left),f=o.top+(u&&s.top),{width:p,height:m}=t;return a&&(p-=o.width+s.width,m-=o.height+s.height),{x:Math.round((c-d)/p*n.width/r),y:Math.round((l-f)/m*n.height/r)}}function or(e,t,n){let r,i;if(t===void 0||n===void 0){let a=e&&Zn(e);if(!a)t=e.clientWidth,n=e.clientHeight;else{let e=a.getBoundingClientRect(),o=$n(a),s=nr(o,`border`,`width`),c=nr(o,`padding`);t=e.width-c.width-s.width,n=e.height-c.height-s.height,r=Qn(o.maxWidth,a,`clientWidth`),i=Qn(o.maxHeight,a,`clientHeight`)}}return{width:t,height:n,maxWidth:r||We,maxHeight:i||We}}var sr=e=>Math.round(e*10)/10;function cr(e,t,n,r){let i=$n(e),a=nr(i,`margin`),o=Qn(i.maxWidth,e,`clientWidth`)||We,s=Qn(i.maxHeight,e,`clientHeight`)||We,c=or(e,t,n),{width:l,height:u}=c;if(i.boxSizing===`content-box`){let e=nr(i,`border`,`width`),t=nr(i,`padding`);l-=t.width+e.width,u-=t.height+e.height}return l=Math.max(0,l-a.width),u=Math.max(0,r?l/r:u-a.height),l=sr(Math.min(l,o,c.maxWidth)),u=sr(Math.min(u,s,c.maxHeight)),l&&!u&&(u=sr(l/2)),(t!==void 0||n!==void 0)&&r&&c.height&&u>c.height&&(u=c.height,l=sr(Math.floor(u*r))),{width:l,height:u}}function lr(e,t,n){let r=t||1,i=sr(e.height*r),a=sr(e.width*r);e.height=sr(e.height),e.width=sr(e.width);let o=e.canvas;return o.style&&(n||!o.style.height&&!o.style.width)&&(o.style.height=`${e.height}px`,o.style.width=`${e.width}px`),e.currentDevicePixelRatio!==r||o.height!==i||o.width!==a?(e.currentDevicePixelRatio=r,o.height=i,o.width=a,e.ctx.setTransform(r,0,0,r,0,0),!0):!1}var ur=function(){let e=!1;try{let t={get passive(){return e=!0,!1}};Xn()&&(window.addEventListener(`test`,null,t),window.removeEventListener(`test`,null,t))}catch{}return e}();function dr(e,t){let n=er(e,t),r=n&&n.match(/^(\d+)(\.\d+)?px$/);return r?+r[1]:void 0}function fr(e,t,n,r){return{x:e.x+n*(t.x-e.x),y:e.y+n*(t.y-e.y)}}function pr(e,t,n,r){return{x:e.x+n*(t.x-e.x),y:r===`middle`?n<.5?e.y:t.y:r===`after`?n<1?e.y:t.y:n>0?t.y:e.y}}function mr(e,t,n,r){let i={x:e.cp2x,y:e.cp2y},a={x:t.cp1x,y:t.cp1y},o=fr(e,i,n),s=fr(i,a,n),c=fr(a,t,n);return fr(fr(o,s,n),fr(s,c,n),n)}var hr=function(e,t){return{x(n){return e+e+t-n},setWidth(e){t=e},textAlign(e){return e===`center`?e:e===`right`?`left`:`right`},xPlus(e,t){return e-t},leftForLtr(e,t){return e-t}}},gr=function(){return{x(e){return e},setWidth(e){},textAlign(e){return e},xPlus(e,t){return e+t},leftForLtr(e,t){return e}}};function _r(e,t,n){return e?hr(t,n):gr()}function vr(e,t){let n,r;(t===`ltr`||t===`rtl`)&&(n=e.canvas.style,r=[n.getPropertyValue(`direction`),n.getPropertyPriority(`direction`)],n.setProperty(`direction`,t,`important`),e.prevTextDirection=r)}function yr(e,t){t!==void 0&&(delete e.prevTextDirection,e.canvas.style.setProperty(`direction`,t[0],t[1]))}function br(e){return e===`angle`?{between:st,compare:ot,normalize:H}:{between:lt,compare:(e,t)=>e-t,normalize:e=>e}}function xr({start:e,end:t,count:n,loop:r,style:i}){return{start:e%n,end:t%n,loop:r&&(t-e+1)%n===0,style:i}}function Sr(e,t,n){let{property:r,start:i,end:a}=n,{between:o,normalize:s}=br(r),c=t.length,{start:l,end:u,loop:d}=e,f,p;if(d){for(l+=c,u+=c,f=0,p=c;fc(i,y,_)&&s(i,y)!==0,x=()=>s(a,_)===0||c(a,y,_),S=()=>h||b(),C=()=>!h||x();for(let e=u,n=u;e<=d;++e)v=t[e%o],!v.skip&&(_=l(v[r]),_!==y&&(h=c(_,i,a),g===null&&S()&&(g=s(_,i)===0?e:n),g!==null&&C()&&(m.push(xr({start:g,end:e,loop:f,count:o,style:p})),g=null),n=e,y=_));return g!==null&&m.push(xr({start:g,end:d,loop:f,count:o,style:p})),m}function wr(e,t){let n=[],r=e.segments;for(let i=0;ii&&e[a%t].skip;)a--;return a%=t,{start:i,end:a}}function Er(e,t,n,r){let i=e.length,a=[],o=t,s=e[t],c;for(c=t+1;c<=n;++c){let n=e[c%i];n.skip||n.stop?s.skip||(r=!1,a.push({start:t%i,end:(c-1)%i,loop:r}),t=o=n.stop?c:null):(o=c,s.skip&&(t=c)),s=n}return o!==null&&a.push({start:t%i,end:o%i,loop:r}),a}function Dr(e,t){let n=e.points,r=e.options.spanGaps,i=n.length;if(!i)return[];let a=!!e._loop,{start:o,end:s}=Tr(n,i,a,r);return r===!0?Or(e,[{start:o,end:s,loop:a}],n,t):Or(e,Er(n,o,sr({chart:e,initial:t.initial,numSteps:a,currentStep:Math.min(n-t.start,a)}))}_refresh(){this._request||=(this._running=!0,vt.call(window,()=>{this._update(),this._request=null,this._running&&this._refresh()}))}_update(e=Date.now()){let t=0;this._charts.forEach((n,r)=>{if(!n.running||!n.items.length)return;let i=n.items,a=i.length-1,o=!1,s;for(;a>=0;--a)s=i[a],s._active?(s._total>n.duration&&(n.duration=s._total),s.tick(e),o=!0):(i[a]=i[i.length-1],i.pop());o&&(r.draw(),this._notify(r,n,e,`progress`)),i.length||(n.running=!1,this._notify(r,n,e,`complete`),n.initial=!1),t+=i.length}),this._lastDate=e,t===0&&(this._running=!1)}_getAnims(e){let t=this._charts,n=t.get(e);return n||(n={running:!1,initial:!0,items:[],listeners:{complete:[],progress:[]}},t.set(e,n)),n}listen(e,t,n){this._getAnims(e).listeners[t].push(n)}add(e,t){!t||!t.length||this._getAnims(e).items.push(...t)}has(e){return this._getAnims(e).items.length>0}start(e){let t=this._charts.get(e);t&&(t.running=!0,t.start=Date.now(),t.duration=t.items.reduce((e,t)=>Math.max(e,t._duration),0),this._refresh())}running(e){if(!this._running)return!1;let t=this._charts.get(e);return!(!t||!t.running||!t.items.length)}stop(e){let t=this._charts.get(e);if(!t||!t.items.length)return;let n=t.items,r=n.length-1;for(;r>=0;--r)n[r].cancel();t.items=[],this._notify(e,t,Date.now(),`complete`)}remove(e){return this._charts.delete(e)}},Ir=`transparent`,Lr={boolean(e,t,n){return n>.5?t:e},color(e,t,n){let r=At(e||Ir),i=r.valid&&At(t||Ir);return i&&i.valid?i.mix(r,n).hexString():t},number(e,t,n){return e+(t-e)*n}},Rr=class{constructor(e,t,n,r){let i=t[n];r=vn([e.to,r,i,e.from]);let a=vn([e.from,i,r]);this._active=!0,this._fn=e.fn||Lr[e.type||typeof a],this._easing=Ot[e.easing]||Ot.linear,this._start=Math.floor(Date.now()+(e.delay||0)),this._duration=this._total=Math.floor(e.duration),this._loop=!!e.loop,this._target=t,this._prop=n,this._from=a,this._to=r,this._promises=void 0}active(){return this._active}update(e,t,n){if(this._active){this._notify(!1);let r=this._target[this._prop],i=n-this._start,a=this._duration-i;this._start=n,this._duration=Math.floor(Math.max(a,e.duration)),this._total+=i,this._loop=!!e.loop,this._to=vn([e.to,t,r,e.from]),this._from=vn([e.from,r,t])}}cancel(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}tick(e){let t=e-this._start,n=this._duration,r=this._prop,i=this._from,a=this._loop,o=this._to,s;if(this._active=i!==o&&(a||t1?2-s:s,s=this._easing(Math.min(1,Math.max(0,s))),this._target[r]=this._fn(i,o,s)}wait(){let e=this._promises||=[];return new Promise((t,n)=>{e.push({res:t,rej:n})})}_notify(e){let t=e?`res`:`rej`,n=this._promises||[];for(let e=0;e{let i=e[r];if(!j(i))return;let a={};for(let e of t)a[e]=i[e];(A(i.properties)&&i.properties||[r]).forEach(e=>{(e===r||!n.has(e))&&n.set(e,a)})})}_animateOptions(e,t){let n=t.options,r=Vr(e,n);if(!r)return[];let i=this._createAnimations(r,n);return n.$shared&&Br(e.options.$animations,n).then(()=>{e.options=n},()=>{}),i}_createAnimations(e,t){let n=this._properties,r=[],i=e.$animations||={},a=Object.keys(t),o=Date.now(),s;for(s=a.length-1;s>=0;--s){let c=a[s];if(c.charAt(0)===`$`)continue;if(c===`options`){r.push(...this._animateOptions(e,t));continue}let l=t[c],u=i[c],d=n.get(c);if(u)if(d&&u.active()){u.update(d,l,o);continue}else u.cancel();if(!d||!d.duration){e[c]=l;continue}i[c]=u=new Rr(d,e,c,l),r.push(u)}return r}update(e,t){if(this._properties.size===0){Object.assign(e,t);return}let n=this._createAnimations(e,t);if(n.length)return Fr.add(this._chart,n),!0}};function Br(e,t){let n=[],r=Object.keys(t);for(let t=0;t0||!n&&t<0)return i.index}return null}function $r(e,t){let{chart:n,_cachedMeta:r}=e,i=n._stacks||={},{iScale:a,vScale:o,index:s}=r,c=a.axis,l=o.axis,u=Yr(a,o,r),d=t.length,f;for(let e=0;en[e].axis===t).shift()}function ti(e,t){return bn(e,{active:!1,dataset:void 0,datasetIndex:t,index:t,mode:`default`,type:`dataset`})}function ni(e,t,n){return bn(e,{active:!1,dataIndex:t,parsed:void 0,raw:void 0,element:n,index:t,mode:`default`,type:`data`})}function ri(e,t){let n=e.controller.index,r=e.vScale&&e.vScale.axis;if(r){t||=e._parsed;for(let e of t){let t=e._stacks;if(!t||t[r]===void 0||t[r][n]===void 0)return;delete t[r][n],t[r]._visualValues!==void 0&&t[r]._visualValues[n]!==void 0&&delete t[r]._visualValues[n]}}}var ii=e=>e===`reset`||e===`none`,ai=(e,t)=>t?e:Object.assign({},e),oi=(e,t,n)=>e&&!t.hidden&&t._stacked&&{keys:Gr(n,!0),values:null},si=class{static defaults={};static datasetElementType=null;static dataElementType=null;constructor(e,t){this.chart=e,this._ctx=e.ctx,this.index=t,this._cachedDataOpts={},this._cachedMeta=this.getMeta(),this._type=this._cachedMeta.type,this.options=void 0,this._parsing=!1,this._data=void 0,this._objectData=void 0,this._sharedOptions=void 0,this._drawStart=void 0,this._drawCount=void 0,this.enableOptionSharing=!1,this.supportsDecimation=!1,this.$context=void 0,this._syncList=[],this.datasetElementType=new.target.datasetElementType,this.dataElementType=new.target.dataElementType,this.initialize()}initialize(){let e=this._cachedMeta;this.configure(),this.linkScales(),e._stacked=Jr(e.vScale,e),this.addElements(),this.options.fill&&!this.chart.isPluginEnabled(`filler`)&&console.warn(`Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options`)}updateIndex(e){this.index!==e&&ri(this._cachedMeta),this.index=e}linkScales(){let e=this.chart,t=this._cachedMeta,n=this.getDataset(),r=(e,t,n,r)=>e===`x`?t:e===`r`?r:n,i=t.xAxisID=P(n.xAxisID,ei(e,`x`)),a=t.yAxisID=P(n.yAxisID,ei(e,`y`)),o=t.rAxisID=P(n.rAxisID,ei(e,`r`)),s=t.indexAxis,c=t.iAxisID=r(s,i,a,o),l=t.vAxisID=r(s,a,i,o);t.xScale=this.getScaleForId(i),t.yScale=this.getScaleForId(a),t.rScale=this.getScaleForId(o),t.iScale=this.getScaleForId(c),t.vScale=this.getScaleForId(l)}getDataset(){return this.chart.data.datasets[this.index]}getMeta(){return this.chart.getDatasetMeta(this.index)}getScaleForId(e){return this.chart.scales[e]}_getOtherScale(e){let t=this._cachedMeta;return e===t.iScale?t.vScale:t.iScale}reset(){this._update(`reset`)}_destroy(){let e=this._cachedMeta;this._data&>(this._data,this),e._stacked&&ri(e)}_dataCheck(){let e=this.getDataset(),t=e.data||=[],n=this._data;if(j(t)){let e=this._cachedMeta;this._data=qr(t,e)}else if(n!==t){if(n){gt(n,this);let e=this._cachedMeta;ri(e),e._parsed=[]}t&&Object.isExtensible(t)&&ht(t,this),this._syncList=[],this._data=t}}addElements(){let e=this._cachedMeta;this._dataCheck(),this.datasetElementType&&(e.dataset=new this.datasetElementType)}buildOrUpdateElements(e){let t=this._cachedMeta,n=this.getDataset(),r=!1;this._dataCheck();let i=t._stacked;t._stacked=Jr(t.vScale,t),t.stack!==n.stack&&(r=!0,ri(t),t.stack=n.stack),this._resyncElements(e),(r||i!==t._stacked)&&($r(this,t._parsed),t._stacked=Jr(t.vScale,t))}configure(){let e=this.chart.config,t=e.datasetScopeKeys(this._type),n=e.getOptionScopes(this.getDataset(),t,!0);this.options=e.createResolver(n,this.getContext()),this._parsing=this.options.parsing,this._cachedDataOpts={}}parse(e,t){let{_cachedMeta:n,_data:r}=this,{iScale:i,_stacked:a}=n,o=i.axis,s=e===0&&t===r.length?!0:n._sorted,c=e>0&&n._parsed[e-1],l,u,d;if(this._parsing===!1)n._parsed=r,n._sorted=!0,d=r;else{d=A(r[e])?this.parseArrayData(n,r,e,t):j(r[e])?this.parseObjectData(n,r,e,t):this.parsePrimitiveData(n,r,e,t);let i=()=>u[o]===null||c&&u[o]t||u=0;--d)if(!p()){this.updateRangeFromParsed(c,e,f,s);break}}return c}getAllParsedValues(e){let t=this._cachedMeta._parsed,n=[],r,i,a;for(r=0,i=t.length;r=0&&ethis.getContext(n,r,t),u);return p.$shared&&(p.$shared=s,i[a]=Object.freeze(ai(p,s))),p}_resolveAnimations(e,t,n){let r=this.chart,i=this._cachedDataOpts,a=`animation-${t}`,o=i[a];if(o)return o;let s;if(r.options.animation!==!1){let r=this.chart.config,i=r.datasetAnimationScopeKeys(this._type,t),a=r.getOptionScopes(this.getDataset(),i);s=r.createResolver(a,this.getContext(e,n,t))}let c=new zr(r,s&&s.animations);return s&&s._cacheable&&(i[a]=Object.freeze(c)),c}getSharedOptions(e){if(e.$shared)return this._sharedOptions||=Object.assign({},e)}includeOptions(e,t){return!t||ii(e)||this.chart._animationsDisabled}_getSharedOptions(e,t){let n=this.resolveDataElementOptions(e,t),r=this._sharedOptions,i=this.getSharedOptions(n),a=this.includeOptions(t,i)||i!==r;return this.updateSharedOptions(i,t,n),{sharedOptions:i,includeOptions:a}}updateElement(e,t,n,r){ii(r)?Object.assign(e,n):this._resolveAnimations(t,r).update(e,n)}updateSharedOptions(e,t,n){e&&!ii(t)&&this._resolveAnimations(void 0,t).update(e,n)}_setStyle(e,t,n,r){e.active=r;let i=this.getStyle(t,r);this._resolveAnimations(t,n,r).update(e,{options:!r&&this.getSharedOptions(i)||i})}removeHoverStyle(e,t,n){this._setStyle(e,n,`active`,!1)}setHoverStyle(e,t,n){this._setStyle(e,n,`active`,!0)}_removeDatasetHoverStyle(){let e=this._cachedMeta.dataset;e&&this._setStyle(e,void 0,`active`,!1)}_setDatasetHoverStyle(){let e=this._cachedMeta.dataset;e&&this._setStyle(e,void 0,`active`,!0)}_resyncElements(e){let t=this._data,n=this._cachedMeta.data;for(let[e,t,n]of this._syncList)this[e](t,n);this._syncList=[];let r=n.length,i=t.length,a=Math.min(i,r);a&&this.parse(0,a),i>r?this._insertElements(r,i-r,e):i{for(e.length+=t,o=e.length-1;o>=a;o--)e[o]=e[o-t]};for(s(i),o=e;oe-t))}return e._cache.$bar}function li(e){let t=e.iScale,n=ci(t,e.type),r=t._length,i,a,o,s,c=()=>{o===32767||o===-32768||(ze(s)&&(r=Math.min(r,Math.abs(o-s)||r)),s=o)};for(i=0,a=n.length;i0?i[e-1]:null,s=eMath.abs(s)&&(c=s,l=o),t[n.axis]=l,t._custom={barStart:c,barEnd:l,start:i,end:a,min:o,max:s}}function pi(e,t,n,r){return A(e)?fi(e,t,n,r):t[n.axis]=n.parse(e,r),t}function mi(e,t,n,r){let i=e.iScale,a=e.vScale,o=i.getLabels(),s=i===a,c=[],l,u,d,f;for(l=n,u=n+r;l=n?1:-1):B(e)}function _i(e){let t,n,r,i,a;return e.horizontal?(t=e.base>e.x,n=`left`,r=`right`):(t=e.basee.controller.options.grouped),i=n.options.stacked,a=[],o=this._cachedMeta.controller.getParsed(t),s=o&&o[n.axis],c=e=>{let t=e._parsed.find(e=>e[n.axis]===s),r=t&&t[e.vScale.axis];if(k(r)||isNaN(r))return!0};for(let n of r)if(!(t!==void 0&&c(n))&&((i===!1||a.indexOf(n.stack)===-1||i===void 0&&n.stack===void 0)&&a.push(n.stack),n.index===e))break;return a.length||a.push(void 0),a}_getStackCount(e){return this._getStacks(void 0,e).length}_getAxisCount(){return this._getAxis().length}getFirstScaleIdForIndexAxis(){let e=this.chart.scales,t=this.chart.options.indexAxis;return Object.keys(e).filter(n=>e[n].axis===t).shift()}_getAxis(){let e={},t=this.getFirstScaleIdForIndexAxis();for(let n of this.chart.data.datasets)e[P(this.chart.options.indexAxis===`x`?n.xAxisID:n.yAxisID,t)]=!0;return Object.keys(e)}_getStackIndex(e,t,n){let r=this._getStacks(e,n),i=t===void 0?-1:r.indexOf(t);return i===-1?r.length-1:i}_getRuler(){let e=this.options,t=this._cachedMeta,n=t.iScale,r=[],i,a;for(i=0,a=t.data.length;ist(e,s,c,!0)?1:Math.max(t,t*n,r,r*n),m=(e,t,r)=>st(e,s,c,!0)?-1:Math.min(t,t*n,r,r*n),h=p(0,l,d),g=p(z,u,f),_=m(L,l,d),v=m(L+z,u,f);r=(h-_)/2,i=(g-v)/2,a=-(h+_)/2,o=-(g+v)/2}return{ratioX:r,ratioY:i,offsetX:a,offsetY:o}}var Ti=class extends si{static id=`doughnut`;static defaults={datasetElementType:!1,dataElementType:`arc`,animation:{animateRotate:!0,animateScale:!1},animations:{numbers:{type:`number`,properties:[`circumference`,`endAngle`,`innerRadius`,`outerRadius`,`startAngle`,`x`,`y`,`offset`,`borderWidth`,`spacing`]}},cutout:`50%`,rotation:0,circumference:360,radius:`100%`,spacing:0,indexAxis:`r`};static descriptors={_scriptable:e=>e!==`spacing`,_indexable:e=>e!==`spacing`&&!e.startsWith(`borderDash`)&&!e.startsWith(`hoverBorderDash`)};static overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(e){let t=e.data,{labels:{pointStyle:n,textAlign:r,color:i,useBorderRadius:a,borderRadius:o}}=e.legend.options;return t.labels.length&&t.datasets.length?t.labels.map((t,s)=>{let c=e.getDatasetMeta(0).controller.getStyle(s);return{text:t,fillStyle:c.backgroundColor,fontColor:i,hidden:!e.getDataVisibility(s),lineDash:c.borderDash,lineDashOffset:c.borderDashOffset,lineJoin:c.borderJoinStyle,lineWidth:c.borderWidth,strokeStyle:c.borderColor,textAlign:r,pointStyle:n,borderRadius:a&&(o||c.borderRadius),index:s}}):[]}},onClick(e,t,n){n.chart.toggleDataVisibility(t.index),n.chart.update()}}}};constructor(e,t){super(e,t),this.enableOptionSharing=!0,this.innerRadius=void 0,this.outerRadius=void 0,this.offsetX=void 0,this.offsetY=void 0}linkScales(){}parse(e,t){let n=this.getDataset().data,r=this._cachedMeta;if(this._parsing===!1)r._parsed=n;else{let i=e=>+n[e];if(j(n[e])){let{key:e=`value`}=this._parsing;i=t=>+Le(n[t],e)}let a,o;for(a=e,o=e+t;a0&&!isNaN(e)?Math.abs(e)/t*R:0}getLabelAndValue(e){let t=this._cachedMeta,n=this.chart,r=n.data.labels||[],i=Rt(t._parsed[e],n.options.locale);return{label:r[e]||``,value:i}}getMaxBorderWidth(e){let t=0,n=this.chart,r,i,a,o,s;if(!e){for(r=0,i=n.data.datasets.length;r0&&this.getParsed(t-1);for(let n=0;n=_){v.skip=!0;continue}let b=this.getParsed(n),x=k(b[f]),S=v[d]=a.getPixelForValue(b[d],n),C=v[f]=i||x?o.getBasePixel():o.getPixelForValue(s?this.applyStack(o,b,s):b[f],n);v.skip=isNaN(S)||isNaN(C)||x,v.stop=n>0&&Math.abs(b[d]-y[d])>h,m&&(v.parsed=b,v.raw=c.data[n]),u&&(v.options=l||this.resolveDataElementOptions(n,p.active?`active`:r)),g||this.updateElement(p,n,v,r),y=b}}getMaxOverflow(){let e=this._cachedMeta,t=e.dataset,n=t.options&&t.options.borderWidth||0,r=e.data||[];if(!r.length)return n;let i=r[0].size(this.resolveDataElementOptions(0)),a=r[r.length-1].size(this.resolveDataElementOptions(r.length-1));return Math.max(n,i,a)/2}draw(){let e=this._cachedMeta;e.dataset.updateControlPoints(this.chart.chartArea,e.iScale.axis),super.draw()}};function Di(){throw Error(`This method is not implemented: Check that a complete date adapter is provided.`)}var Oi={_date:class e{static override(t){Object.assign(e.prototype,t)}options;constructor(e){this.options=e||{}}init(){}formats(){return Di()}parse(){return Di()}format(){return Di()}add(){return Di()}diff(){return Di()}startOf(){return Di()}endOf(){return Di()}}};function ki(e,t,n,r){let{controller:i,data:a,_sorted:o}=e,s=i._cachedMeta.iScale,c=e.dataset&&e.dataset.options?e.dataset.options.spanGaps:null;if(s&&t===s.axis&&t!==`r`&&o&&a.length){let o=s._reversePixels?ft:dt;if(!r){let r=o(a,t,n);if(c){let{vScale:t}=i._cachedMeta,{_parsed:n}=e,a=n.slice(0,r.lo+1).reverse().findIndex(e=>!k(e[t.axis]));r.lo-=Math.max(0,a);let o=n.slice(r.hi).findIndex(e=>!k(e[t.axis]));r.hi+=Math.max(0,o)}return r}else if(i._sharedOptions){let e=a[0],r=typeof e.getRange==`function`&&e.getRange(t);if(r){let e=o(a,t,n-r),i=o(a,t,n+r);return{lo:e.lo,hi:i.hi}}}}return{lo:0,hi:a.length-1}}function Ai(e,t,n,r,i){let a=e.getSortedVisibleDatasetMetas(),o=n[t];for(let e=0,n=a.length;e{e[o]&&e[o](t[n],i)&&(a.push({element:e,datasetIndex:r,index:c}),s||=e.inRange(t.x,t.y,i))}),r&&!s?[]:a}var Li={evaluateInteractionItems:Ai,modes:{index(e,t,n,r){let i=ar(t,e),a=n.axis||`x`,o=n.includeInvisible||!1,s=n.intersect?Mi(e,i,a,r,o):Fi(e,i,a,!1,r,o),c=[];return s.length?(e.getSortedVisibleDatasetMetas().forEach(e=>{let t=s[0].index,n=e.data[t];n&&!n.skip&&c.push({element:n,datasetIndex:e.index,index:t})}),c):[]},dataset(e,t,n,r){let i=ar(t,e),a=n.axis||`xy`,o=n.includeInvisible||!1,s=n.intersect?Mi(e,i,a,r,o):Fi(e,i,a,!1,r,o);if(s.length>0){let t=s[0].datasetIndex,n=e.getDatasetMeta(t).data;s=[];for(let e=0;ee.pos===t)}function Bi(e,t){return e.filter(e=>Ri.indexOf(e.pos)===-1&&e.box.axis===t)}function Vi(e,t){return e.sort((e,n)=>{let r=t?n:e,i=t?e:n;return r.weight===i.weight?r.index-i.index:r.weight-i.weight})}function Hi(e){let t=[],n,r,i,a,o,s;for(n=0,r=(e||[]).length;ne.box.fullSize),!0),r=Vi(zi(t,`left`),!0),i=Vi(zi(t,`right`)),a=Vi(zi(t,`top`),!0),o=Vi(zi(t,`bottom`)),s=Bi(t,`x`),c=Bi(t,`y`);return{fullSize:n,leftAndTop:r.concat(a),rightAndBottom:i.concat(c).concat(o).concat(s),chartArea:zi(t,`chartArea`),vertical:r.concat(i).concat(c),horizontal:a.concat(o).concat(s)}}function Ki(e,t,n,r){return Math.max(e[n],t[n])+Math.max(e[r],t[r])}function qi(e,t){e.top=Math.max(e.top,t.top),e.left=Math.max(e.left,t.left),e.bottom=Math.max(e.bottom,t.bottom),e.right=Math.max(e.right,t.right)}function Ji(e,t,n,r){let{pos:i,box:a}=n,o=e.maxPadding;if(!j(i)){n.size&&(e[i]-=n.size);let t=r[n.stack]||{size:0,count:1};t.size=Math.max(t.size,n.horizontal?a.height:a.width),n.size=t.size/t.count,e[i]+=n.size}a.getPadding&&qi(o,a.getPadding());let s=Math.max(0,t.outerWidth-Ki(o,e,`left`,`right`)),c=Math.max(0,t.outerHeight-Ki(o,e,`top`,`bottom`)),l=s!==e.w,u=c!==e.h;return e.w=s,e.h=c,n.horizontal?{same:l,other:u}:{same:u,other:l}}function Yi(e){let t=e.maxPadding;function n(n){let r=Math.max(t[n]-e[n],0);return e[n]+=r,r}e.y+=n(`top`),e.x+=n(`left`),n(`right`),n(`bottom`)}function Xi(e,t){let n=t.maxPadding;function r(e){let r={left:0,top:0,right:0,bottom:0};return e.forEach(e=>{r[e]=Math.max(t[e],n[e])}),r}return r(e?[`left`,`right`]:[`top`,`bottom`])}function Zi(e,t,n,r){let i=[],a,o,s,c,l,u;for(a=0,o=e.length,l=0;a{typeof e.beforeLayout==`function`&&e.beforeLayout()});let u=c.reduce((e,t)=>t.box.options&&t.box.options.display===!1?e:e+1,0)||1,d=Object.freeze({outerWidth:t,outerHeight:n,padding:i,availableWidth:a,availableHeight:o,vBoxMaxWidth:a/2/u,hBoxMaxHeight:o/2}),f=Object.assign({},i);qi(f,K(r));let p=Object.assign({maxPadding:f,w:a,h:o,x:i.left,y:i.top},i),m=Wi(c.concat(l),d);Zi(s.fullSize,p,d,m),Zi(c,p,d,m),Zi(l,p,d,m)&&Zi(c,p,d,m),Yi(p),$i(s.leftAndTop,p,d,m),p.x+=p.w,p.y+=p.h,$i(s.rightAndBottom,p,d,m),e.chartArea={left:p.left,top:p.top,right:p.left+p.w,bottom:p.top+p.h,height:p.h,width:p.w},I(s.chartArea,t=>{let n=t.box;Object.assign(n,e.chartArea),n.update(p.w,p.h,{left:0,top:0,right:0,bottom:0})})}},ea=class{acquireContext(e,t){}releaseContext(e){return!1}addEventListener(e,t,n){}removeEventListener(e,t,n){}getDevicePixelRatio(){return 1}getMaximumSize(e,t,n,r){return t=Math.max(0,t||e.width),n||=e.height,{width:t,height:Math.max(0,r?Math.floor(t/r):n)}}isAttached(e){return!0}updateConfig(e){}},ta=class extends ea{acquireContext(e){return e&&e.getContext&&e.getContext(`2d`)||null}updateConfig(e){e.options.animation=!1}},na=`$chartjs`,ra={touchstart:`mousedown`,touchmove:`mousemove`,touchend:`mouseup`,pointerenter:`mouseenter`,pointerdown:`mousedown`,pointermove:`mousemove`,pointerup:`mouseup`,pointerleave:`mouseout`,pointerout:`mouseout`},ia=e=>e===null||e===``;function aa(e,t){let n=e.style,r=e.getAttribute(`height`),i=e.getAttribute(`width`);if(e[na]={initial:{height:r,width:i,style:{display:n.display,height:n.height,width:n.width}}},n.display=n.display||`block`,n.boxSizing=n.boxSizing||`border-box`,ia(i)){let t=dr(e,`width`);t!==void 0&&(e.width=t)}if(ia(r))if(e.style.height===``)e.height=e.width/(t||2);else{let t=dr(e,`height`);t!==void 0&&(e.height=t)}return e}var oa=ur?{passive:!0}:!1;function sa(e,t,n){e&&e.addEventListener(t,n,oa)}function ca(e,t,n){e&&e.canvas&&e.canvas.removeEventListener(t,n,oa)}function la(e,t){let n=ra[e.type]||e.type,{x:r,y:i}=ar(e,t);return{type:n,chart:t,native:e,x:r===void 0?null:r,y:i===void 0?null:i}}function ua(e,t){for(let n of e)if(n===t||n.contains(t))return!0}function da(e,t,n){let r=e.canvas,i=new MutationObserver(e=>{let t=!1;for(let n of e)t||=ua(n.addedNodes,r),t&&=!ua(n.removedNodes,r);t&&n()});return i.observe(document,{childList:!0,subtree:!0}),i}function fa(e,t,n){let r=e.canvas,i=new MutationObserver(e=>{let t=!1;for(let n of e)t||=ua(n.removedNodes,r),t&&=!ua(n.addedNodes,r);t&&n()});return i.observe(document,{childList:!0,subtree:!0}),i}var pa=new Map,ma=0;function ha(){let e=window.devicePixelRatio;e!==ma&&(ma=e,pa.forEach((t,n)=>{n.currentDevicePixelRatio!==e&&t()}))}function ga(e,t){pa.size||window.addEventListener(`resize`,ha),pa.set(e,t)}function _a(e){pa.delete(e),pa.size||window.removeEventListener(`resize`,ha)}function va(e,t,n){let r=e.canvas,i=r&&Zn(r);if(!i)return;let a=yt((e,t)=>{let r=i.clientWidth;n(e,t),r{let t=e[0],n=t.contentRect.width,r=t.contentRect.height;n===0&&r===0||a(n,r)});return o.observe(i),ga(e,a),o}function ya(e,t,n){n&&n.disconnect(),t===`resize`&&_a(e)}function ba(e,t,n){let r=e.canvas,i=yt(t=>{e.ctx!==null&&n(la(t,e))},e);return sa(r,t,i),i}var xa=class extends ea{acquireContext(e,t){let n=e&&e.getContext&&e.getContext(`2d`);return n&&n.canvas===e?(aa(e,t),n):null}releaseContext(e){let t=e.canvas;if(!t[na])return!1;let n=t[na].initial;[`height`,`width`].forEach(e=>{let r=n[e];k(r)?t.removeAttribute(e):t.setAttribute(e,r)});let r=n.style||{};return Object.keys(r).forEach(e=>{t.style[e]=r[e]}),t.width=t.width,delete t[na],!0}addEventListener(e,t,n){this.removeEventListener(e,t);let r=e.$proxies||={};r[t]=({attach:da,detach:fa,resize:va}[t]||ba)(e,t,n)}removeEventListener(e,t){let n=e.$proxies||={},r=n[t];r&&(({attach:ya,detach:ya,resize:ya}[t]||ca)(e,t,r),n[t]=void 0)}getDevicePixelRatio(){return window.devicePixelRatio}getMaximumSize(e,t,n,r){return cr(e,t,n,r)}isAttached(e){let t=e&&Zn(e);return!!(t&&t.isConnected)}};function Sa(e){return!Xn()||typeof OffscreenCanvas<`u`&&e instanceof OffscreenCanvas?ta:xa}var Ca=class{static defaults={};static defaultRoutes=void 0;x;y;active=!1;options;$animations;tooltipPosition(e){let{x:t,y:n}=this.getProps([`x`,`y`],e);return{x:t,y:n}}hasValue(){return $e(this.x)&&$e(this.y)}getProps(e,t){let n=this.$animations;if(!t||!n)return this;let r={};return e.forEach(e=>{r[e]=n[e]&&n[e].active()?n[e]._to:this[e]}),r}};function wa(e,t){let n=e.options.ticks,r=Ta(e),i=Math.min(n.maxTicksLimit||r,r),a=n.major.enabled?Da(t):[],o=a.length,s=a[0],c=a[o-1],l=[];if(o>i)return Oa(t,l,a,o/i),l;let u=Ea(a,t,i);if(o>0){let e,n,r=o>1?Math.round((c-s)/(o-1)):null;for(ka(t,l,u,k(r)?0:s-r,s),e=0,n=o-1;ei)return t}return Math.max(i,1)}function Da(e){let t=[],n,r;for(n=0,r=e.length;ne===`left`?`right`:e===`right`?`left`:e,Ma=(e,t,n)=>t===`top`||t===`left`?e[t]+n:e[t]-n,Na=(e,t)=>Math.min(t||e,e);function Pa(e,t){let n=[],r=e.length/t,i=e.length,a=0;for(;ao+s)))return c}function Ia(e,t){I(e,e=>{let n=e.gc,r=n.length/2,i;if(r>t){for(i=0;in?n:t,n=r&&t>n?t:n,{min:N(t,N(n,t)),max:N(n,N(t,n))}}getPadding(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}getTicks(){return this.ticks}getLabels(){let e=this.chart.data;return this.options.labels||(this.isHorizontal()?e.xLabels:e.yLabels)||e.labels||[]}getLabelItems(e=this.chart.chartArea){return this._labelItems||=this._computeLabelItems(e)}beforeLayout(){this._cache={},this._dataLimitsCached=!1}beforeUpdate(){F(this.options.beforeUpdate,[this])}update(e,t,n){let{beginAtZero:r,grace:i,ticks:a}=this.options,o=a.sampleSize;this.beforeUpdate(),this.maxWidth=e,this.maxHeight=t,this._margins=n=Object.assign({left:0,right:0,top:0,bottom:0},n),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+n.left+n.right:this.height+n.top+n.bottom,this._dataLimitsCached||=(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=yn(this,i,r),!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();let s=o=i||n<=1||!this.isHorizontal()){this.labelRotation=r;return}let l=this._getLabelSizes(),u=l.widest.width,d=l.highest.height,f=U(this.chart.width-u,0,this.maxWidth);o=e.offset?this.maxWidth/n:f/(n-1),u+6>o&&(o=f/(n-(e.offset?.5:1)),s=this.maxHeight-La(e.grid)-t.padding-Ra(e.title,this.chart.options.font),c=Math.sqrt(u*u+d*d),a=nt(Math.min(Math.asin(U((l.highest.height+6)/o,-1,1)),Math.asin(U(s/c,-1,1))-Math.asin(U(d/c,-1,1)))),a=Math.max(r,Math.min(i,a))),this.labelRotation=a}afterCalculateLabelRotation(){F(this.options.afterCalculateLabelRotation,[this])}afterAutoSkip(){}beforeFit(){F(this.options.beforeFit,[this])}fit(){let e={width:0,height:0},{chart:t,options:{ticks:n,title:r,grid:i}}=this,a=this._isVisible(),o=this.isHorizontal();if(a){let a=Ra(r,t.options.font);if(o?(e.width=this.maxWidth,e.height=La(i)+a):(e.height=this.maxHeight,e.width=La(i)+a),n.display&&this.ticks.length){let{first:t,last:r,widest:i,highest:a}=this._getLabelSizes(),s=n.padding*2,c=V(this.labelRotation),l=Math.cos(c),u=Math.sin(c);if(o){let t=n.mirror?0:u*i.width+l*a.height;e.height=Math.min(this.maxHeight,e.height+t+s)}else{let t=n.mirror?0:l*i.width+u*a.height;e.width=Math.min(this.maxWidth,e.width+t+s)}this._calculatePadding(t,r,u,l)}}this._handleMargins(),o?(this.width=this._length=t.width-this._margins.left-this._margins.right,this.height=e.height):(this.width=e.width,this.height=this._length=t.height-this._margins.top-this._margins.bottom)}_calculatePadding(e,t,n,r){let{ticks:{align:i,padding:a},position:o}=this.options,s=this.labelRotation!==0,c=o!==`top`&&this.axis===`x`;if(this.isHorizontal()){let o=this.getPixelForTick(0)-this.left,l=this.right-this.getPixelForTick(this.ticks.length-1),u=0,d=0;s?c?(u=r*e.width,d=n*t.height):(u=n*e.height,d=r*t.width):i===`start`?d=t.width:i===`end`?u=e.width:i!==`inner`&&(u=e.width/2,d=t.width/2),this.paddingLeft=Math.max((u-o+a)*this.width/(this.width-o),0),this.paddingRight=Math.max((d-l+a)*this.width/(this.width-l),0)}else{let n=t.height/2,r=e.height/2;i===`start`?(n=0,r=e.height):i===`end`&&(n=t.height,r=0),this.paddingTop=n+a,this.paddingBottom=r+a}}_handleMargins(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}afterFit(){F(this.options.afterFit,[this])}isHorizontal(){let{axis:e,position:t}=this.options;return t===`top`||t===`bottom`||e===`x`}isFullSize(){return this.options.fullSize}_convertTicksToLabels(e){this.beforeTickToLabelConversion(),this.generateTickLabels(e);let t,n;for(t=0,n=e.length;t({width:a[e]||0,height:o[e]||0});return{first:C(0),last:C(t-1),widest:C(x),highest:C(S),widths:a,heights:o}}getLabelForValue(e){return e}getPixelForValue(e,t){return NaN}getValueForPixel(e){}getPixelForTick(e){let t=this.ticks;return e<0||e>t.length-1?null:this.getPixelForValue(t[e].value)}getPixelForDecimal(e){this._reversePixels&&(e=1-e);let t=this._startPixel+e*this._length;return ct(this._alignToPixels?Xt(this.chart,t,0):t)}getDecimalForPixel(e){let t=(e-this._startPixel)/this._length;return this._reversePixels?1-t:t}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){let{min:e,max:t}=this;return e<0&&t<0?t:e>0&&t>0?e:0}getContext(e){let t=this.ticks||[];if(e>=0&&eo*r?o/n:s/r:s*r0:!!e}_computeGridLineItems(e){let t=this.axis,n=this.chart,r=this.options,{grid:i,position:a,border:o}=r,s=i.offset,c=this.isHorizontal(),l=this.ticks.length+ +!!s,u=La(i),d=[],f=o.setContext(this.getContext()),p=f.display?f.width:0,m=p/2,h=function(e){return Xt(n,e,p)},g,_,v,y,b,x,S,C,w,T,E,D;if(a===`top`)g=h(this.bottom),x=this.bottom-u,C=g-m,T=h(e.top)+m,D=e.bottom;else if(a===`bottom`)g=h(this.top),T=e.top,D=h(e.bottom)-m,x=g+m,C=this.top+u;else if(a===`left`)g=h(this.right),b=this.right-u,S=g-m,w=h(e.left)+m,E=e.right;else if(a===`right`)g=h(this.left),w=e.left,E=h(e.right)-m,b=g+m,S=this.left+u;else if(t===`x`){if(a===`center`)g=h((e.top+e.bottom)/2+.5);else if(j(a)){let e=Object.keys(a)[0],t=a[e];g=h(this.chart.scales[e].getPixelForValue(t))}T=e.top,D=e.bottom,x=g+m,C=x+u}else if(t===`y`){if(a===`center`)g=h((e.left+e.right)/2);else if(j(a)){let e=Object.keys(a)[0],t=a[e];g=h(this.chart.scales[e].getPixelForValue(t))}b=g-m,S=b-u,w=e.left,E=e.right}let ee=P(r.ticks.maxTicksLimit,l),O=Math.max(1,Math.ceil(l/ee));for(_=0;_0&&(a-=r/2);break}f={left:a,top:i,width:r+t.width,height:n+t.height,color:e.backdropColor}}h.push({label:y,font:w,textOffset:D,options:{rotation:m,color:n,strokeColor:s,strokeWidth:l,textAlign:d,textBaseline:ee,translation:[b,x],backdrop:f}})}return h}_getXAxisLabelAlignment(){let{position:e,ticks:t}=this.options;if(-V(this.labelRotation))return e===`top`?`left`:`right`;let n=`center`;return t.align===`start`?n=`left`:t.align===`end`?n=`right`:t.align===`inner`&&(n=`inner`),n}_getYAxisLabelAlignment(e){let{position:t,ticks:{crossAlign:n,mirror:r,padding:i}}=this.options,a=this._getLabelSizes(),o=e+i,s=a.widest.width,c,l;return t===`left`?r?(l=this.right+i,n===`near`?c=`left`:n===`center`?(c=`center`,l+=s/2):(c=`right`,l+=s)):(l=this.right-o,n===`near`?c=`right`:n===`center`?(c=`center`,l-=s/2):(c=`left`,l=this.left)):t===`right`?r?(l=this.left+i,n===`near`?c=`right`:n===`center`?(c=`center`,l-=s/2):(c=`left`,l-=s)):(l=this.left+o,n===`near`?c=`left`:n===`center`?(c=`center`,l+=s/2):(c=`right`,l=this.right)):c=`right`,{textAlign:c,x:l}}_computeLabelArea(){if(this.options.ticks.mirror)return;let e=this.chart,t=this.options.position;if(t===`left`||t===`right`)return{top:0,left:this.left,bottom:e.height,right:this.right};if(t===`top`||t===`bottom`)return{top:this.top,left:0,bottom:this.bottom,right:e.width}}drawBackground(){let{ctx:e,options:{backgroundColor:t},left:n,top:r,width:i,height:a}=this;t&&(e.save(),e.fillStyle=t,e.fillRect(n,r,i,a),e.restore())}getLineWidthForValue(e){let t=this.options.grid;if(!this._isVisible()||!t.display)return 0;let n=this.ticks.findIndex(t=>t.value===e);return n>=0?t.setContext(this.getContext(n)).lineWidth:0}drawGrid(e){let t=this.options.grid,n=this.ctx,r=this._gridLineItems||=this._computeGridLineItems(e),i,a,o=(e,t,r)=>{!r.width||!r.color||(n.save(),n.lineWidth=r.width,n.strokeStyle=r.color,n.setLineDash(r.borderDash||[]),n.lineDashOffset=r.borderDashOffset,n.beginPath(),n.moveTo(e.x,e.y),n.lineTo(t.x,t.y),n.stroke(),n.restore())};if(t.display)for(i=0,a=r.length;i{this.draw(e)}}]:[{z:r,draw:e=>{this.drawBackground(),this.drawGrid(e),this.drawTitle()}},{z:i,draw:()=>{this.drawBorder()}},{z:n,draw:e=>{this.drawLabels(e)}}]}getMatchingVisibleMetas(e){let t=this.chart.getSortedVisibleDatasetMetas(),n=this.axis+`AxisID`,r=[],i,a;for(i=0,a=t.length;i{let r=n.split(`.`),i=r.pop(),a=[e].concat(r).join(`.`),o=t[n].split(`.`),s=o.pop(),c=o.join(`.`);G.route(a,i,c,s)})}function qa(e){return`id`in e&&`defaults`in e}var Y=new class{constructor(){this.controllers=new Wa(si,`datasets`,!0),this.elements=new Wa(Ca,`elements`),this.plugins=new Wa(Object,`plugins`),this.scales=new Wa(Ua,`scales`),this._typedRegistries=[this.controllers,this.scales,this.elements]}add(...e){this._each(`register`,e)}remove(...e){this._each(`unregister`,e)}addControllers(...e){this._each(`register`,e,this.controllers)}addElements(...e){this._each(`register`,e,this.elements)}addPlugins(...e){this._each(`register`,e,this.plugins)}addScales(...e){this._each(`register`,e,this.scales)}getController(e){return this._get(e,this.controllers,`controller`)}getElement(e){return this._get(e,this.elements,`element`)}getPlugin(e){return this._get(e,this.plugins,`plugin`)}getScale(e){return this._get(e,this.scales,`scale`)}removeControllers(...e){this._each(`unregister`,e,this.controllers)}removeElements(...e){this._each(`unregister`,e,this.elements)}removePlugins(...e){this._each(`unregister`,e,this.plugins)}removeScales(...e){this._each(`unregister`,e,this.scales)}_each(e,t,n){[...t].forEach(t=>{let r=n||this._getRegistryForType(t);n||r.isForType(t)||r===this.plugins&&t.id?this._exec(e,r,t):I(t,t=>{let r=n||this._getRegistryForType(t);this._exec(e,r,t)})})}_exec(e,t,n){let r=Re(e);F(n[`before`+r],[],n),t[e](n),F(n[`after`+r],[],n)}_getRegistryForType(e){for(let t=0;te.filter(e=>!t.some(t=>e.plugin.id===t.plugin.id));this._notify(r(t,n),e,`stop`),this._notify(r(n,t),e,`start`)}};function Ya(e){let t={},n=[],r=Object.keys(Y.plugins.items);for(let e=0;e1&&no(e[0].toLowerCase());if(t)return t}throw Error(`Cannot determine type of '${e}' axis. Please provide 'axis' or 'position' option.`)}function ao(e,t,n){if(n[t+`AxisID`]===e)return{axis:t}}function oo(e,t){if(t.data&&t.data.datasets){let n=t.data.datasets.filter(t=>t.xAxisID===e||t.yAxisID===e);if(n.length)return ao(e,`x`,n[0])||ao(e,`y`,n[0])}return{}}function so(e,t){let n=Ut[e.type]||{scales:{}},r=t.scales||{},i=$a(e.type,t),a=Object.create(null);return Object.keys(r).forEach(t=>{let o=r[t];if(!j(o))return console.error(`Invalid scale configuration for scale: ${t}`);if(o._proxy)return console.warn(`Ignoring resolver passed as options for scale: ${t}`);let s=io(t,o,oo(t,e),G.scales[o.type]),c=to(s,i),l=n.scales||{};a[t]=Me(Object.create(null),[{axis:s},o,l[s],l[c]])}),e.data.datasets.forEach(n=>{let i=n.type||e.type,o=n.indexAxis||$a(i,t),s=(Ut[i]||{}).scales||{};Object.keys(s).forEach(e=>{let t=eo(e,o),i=n[t+`AxisID`]||t;a[i]=a[i]||Object.create(null),Me(a[i],[{axis:t},r[i],s[e]])})}),Object.keys(a).forEach(e=>{let t=a[e];Me(t,[G.scales[t.type],G.scale])}),a}function co(e){let t=e.options||={};t.plugins=P(t.plugins,{}),t.scales=so(e,t)}function lo(e){return e||={},e.datasets=e.datasets||[],e.labels=e.labels||[],e}function uo(e){return e||={},e.data=lo(e.data),co(e),e}var fo=new Map,po=new Set;function mo(e,t){let n=fo.get(e);return n||(n=t(),fo.set(e,n),po.add(n)),n}var ho=(e,t,n)=>{let r=Le(t,n);r!==void 0&&e.add(r)},go=class{constructor(e){this._config=uo(e),this._scopeCache=new Map,this._resolverCache=new Map}get platform(){return this._config.platform}get type(){return this._config.type}set type(e){this._config.type=e}get data(){return this._config.data}set data(e){this._config.data=lo(e)}get options(){return this._config.options}set options(e){this._config.options=e}get plugins(){return this._config.plugins}update(){let e=this._config;this.clearCache(),co(e)}clearCache(){this._scopeCache.clear(),this._resolverCache.clear()}datasetScopeKeys(e){return mo(e,()=>[[`datasets.${e}`,``]])}datasetAnimationScopeKeys(e,t){return mo(`${e}.transition.${t}`,()=>[[`datasets.${e}.transitions.${t}`,`transitions.${t}`],[`datasets.${e}`,``]])}datasetElementScopeKeys(e,t){return mo(`${e}-${t}`,()=>[[`datasets.${e}.elements.${t}`,`datasets.${e}`,`elements.${t}`,``]])}pluginScopeKeys(e){let t=e.id,n=this.type;return mo(`${n}-plugin-${t}`,()=>[[`plugins.${t}`,...e.additionalOptionScopes||[]]])}_cachedScopes(e,t){let n=this._scopeCache,r=n.get(e);return(!r||t)&&(r=new Map,n.set(e,r)),r}getOptionScopes(e,t,n){let{options:r,type:i}=this,a=this._cachedScopes(e,n),o=a.get(t);if(o)return o;let s=new Set;t.forEach(t=>{e&&(s.add(e),t.forEach(t=>ho(s,e,t))),t.forEach(e=>ho(s,r,e)),t.forEach(e=>ho(s,Ut[i]||{},e)),t.forEach(e=>ho(s,G,e)),t.forEach(e=>ho(s,Wt,e))});let c=Array.from(s);return c.length===0&&c.push(Object.create(null)),po.has(t)&&a.set(t,c),c}chartOptionScopes(){let{options:e,type:t}=this;return[e,Ut[t]||{},G.datasets[t]||{},{type:t},G,Wt]}resolveNamedOptions(e,t,n,r=[``]){let i={$shared:!0},{resolver:a,subPrefixes:o}=_o(this._resolverCache,e,r),s=a;if(yo(a,t)){i.$shared=!1,n=Be(n)?n():n;let t=this.createResolver(e,n,o);s=Sn(a,n,t)}for(let e of t)i[e]=s[e];return i}createResolver(e,t,n=[``],r){let{resolver:i}=_o(this._resolverCache,e,n);return j(t)?Sn(i,t,void 0,r):i}};function _o(e,t,n){let r=e.get(t);r||(r=new Map,e.set(t,r));let i=n.join(),a=r.get(i);return a||(a={resolver:xn(t,n),subPrefixes:n.filter(e=>!e.toLowerCase().includes(`hover`))},r.set(i,a)),a}var vo=e=>j(e)&&Object.getOwnPropertyNames(e).some(t=>Be(e[t]));function yo(e,t){let{isScriptable:n,isIndexable:r}=Cn(e);for(let i of t){let t=n(i),a=r(i),o=(a||t)&&e[i];if(t&&(Be(o)||vo(o))||a&&A(o))return!0}return!1}var bo=`4.5.1`,xo=[`top`,`bottom`,`left`,`right`,`chartArea`];function So(e,t){return e===`top`||e===`bottom`||xo.indexOf(e)===-1&&t===`x`}function Co(e,t){return function(n,r){return n[e]===r[e]?n[t]-r[t]:n[e]-r[e]}}function wo(e){let t=e.chart,n=t.options.animation;t.notifyPlugins(`afterRender`),F(n&&n.onComplete,[e],t)}function To(e){let t=e.chart,n=t.options.animation;F(n&&n.onProgress,[e],t)}function Eo(e){return Xn()&&typeof e==`string`?e=document.getElementById(e):e&&e.length&&(e=e[0]),e&&e.canvas&&(e=e.canvas),e}var Do={},Oo=e=>{let t=Eo(e);return Object.values(Do).filter(e=>e.canvas===t).pop()};function ko(e,t,n){let r=Object.keys(e);for(let i of r){let r=+i;if(r>=t){let a=e[i];delete e[i],(n>0||r>t)&&(e[r+n]=a)}}}function Ao(e,t,n,r){return!n||e.type===`mouseout`?null:r?t:e}var jo=class{static defaults=G;static instances=Do;static overrides=Ut;static registry=Y;static version=bo;static getChart=Oo;static register(...e){Y.add(...e),Mo()}static unregister(...e){Y.remove(...e),Mo()}constructor(e,t){let n=this.config=new go(t),r=Eo(e),i=Oo(r);if(i)throw Error(`Canvas is already in use. Chart with ID '`+i.id+`' must be destroyed before the canvas with ID '`+i.canvas.id+`' can be reused.`);let a=n.createResolver(n.chartOptionScopes(),this.getContext());this.platform=new(n.platform||(Sa(r))),this.platform.updateConfig(n);let o=this.platform.acquireContext(r,a.aspectRatio),s=o&&o.canvas,c=s&&s.height,l=s&&s.width;if(this.id=we(),this.ctx=o,this.canvas=s,this.width=l,this.height=c,this._options=a,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new Ja,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=bt(e=>this.update(e),a.resizeDelay||0),this._dataChanges=[],Do[this.id]=this,!o||!s){console.error(`Failed to create chart: can't acquire context from the given item`);return}Fr.listen(this,`complete`,wo),Fr.listen(this,`progress`,To),this._initialize(),this.attached&&this.update()}get aspectRatio(){let{options:{aspectRatio:e,maintainAspectRatio:t},width:n,height:r,_aspectRatio:i}=this;return k(e)?t&&i?i:r?n/r:null:e}get data(){return this.config.data}set data(e){this.config.data=e}get options(){return this._options}set options(e){this.config.options=e}get registry(){return Y}_initialize(){return this.notifyPlugins(`beforeInit`),this.options.responsive?this.resize():lr(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins(`afterInit`),this}clear(){return Zt(this.canvas,this.ctx),this}stop(){return Fr.stop(this),this}resize(e,t){Fr.running(this)?this._resizeBeforeDraw={width:e,height:t}:this._resize(e,t)}_resize(e,t){let n=this.options,r=this.canvas,i=n.maintainAspectRatio&&this.aspectRatio,a=this.platform.getMaximumSize(r,e,t,i),o=n.devicePixelRatio||this.platform.getDevicePixelRatio(),s=this.width?`resize`:`attach`;this.width=a.width,this.height=a.height,this._aspectRatio=this.aspectRatio,lr(this,o,!0)&&(this.notifyPlugins(`resize`,{size:a}),F(n.onResize,[this,a],this),this.attached&&this._doResize(s)&&this.render())}ensureScalesHaveIDs(){I(this.options.scales||{},(e,t)=>{e.id=t})}buildOrUpdateScales(){let e=this.options,t=e.scales,n=this.scales,r=Object.keys(n).reduce((e,t)=>(e[t]=!1,e),{}),i=[];t&&(i=i.concat(Object.keys(t).map(e=>{let n=t[e],r=io(e,n),i=r===`r`,a=r===`x`;return{options:n,dposition:i?`chartArea`:a?`bottom`:`left`,dtype:i?`radialLinear`:a?`category`:`linear`}}))),I(i,t=>{let i=t.options,a=i.id,o=io(a,i),s=P(i.type,t.dtype);(i.position===void 0||So(i.position,o)!==So(t.dposition))&&(i.position=t.dposition),r[a]=!0;let c=null;a in n&&n[a].type===s?c=n[a]:(c=new(Y.getScale(s))({id:a,type:s,ctx:this.ctx,chart:this}),n[c.id]=c),c.init(i,e)}),I(r,(e,t)=>{e||delete n[t]}),I(n,e=>{J.configure(this,e,e.options),J.addBox(this,e)})}_updateMetasets(){let e=this._metasets,t=this.data.datasets.length,n=e.length;if(e.sort((e,t)=>e.index-t.index),n>t){for(let e=t;et.length&&delete this._stacks,e.forEach((e,n)=>{t.filter(t=>t===e._dataset).length===0&&this._destroyDatasetMeta(n)})}buildOrUpdateControllers(){let e=[],t=this.data.datasets,n,r;for(this._removeUnreferencedMetasets(),n=0,r=t.length;n{this.getDatasetMeta(t).controller.reset()},this)}reset(){this._resetElements(),this.notifyPlugins(`reset`)}update(e){let t=this.config;t.update();let n=this._options=t.createResolver(t.chartOptionScopes(),this.getContext()),r=this._animationsDisabled=!n.animation;if(this._updateScales(),this._checkEventBindings(),this._updateHiddenIndices(),this._plugins.invalidate(),this.notifyPlugins(`beforeUpdate`,{mode:e,cancelable:!0})===!1)return;let i=this.buildOrUpdateControllers();this.notifyPlugins(`beforeElementsUpdate`);let a=0;for(let e=0,t=this.data.datasets.length;e{e.reset()}),this._updateDatasets(e),this.notifyPlugins(`afterUpdate`,{mode:e}),this._layers.sort(Co(`z`,`_idx`));let{_active:o,_lastEvent:s}=this;s?this._eventHandler(s,!0):o.length&&this._updateHoverStyles(o,o,!0),this.render()}_updateScales(){I(this.scales,e=>{J.removeBox(this,e)}),this.ensureScalesHaveIDs(),this.buildOrUpdateScales()}_checkEventBindings(){let e=this.options;(!Ve(new Set(Object.keys(this._listeners)),new Set(e.events))||!!this._responsiveListeners!==e.responsive)&&(this.unbindEvents(),this.bindEvents())}_updateHiddenIndices(){let{_hiddenIndices:e}=this,t=this._getUniformDataChanges()||[];for(let{method:n,start:r,count:i}of t)ko(e,r,n===`_removeElements`?-i:i)}_getUniformDataChanges(){let e=this._dataChanges;if(!e||!e.length)return;this._dataChanges=[];let t=this.data.datasets.length,n=t=>new Set(e.filter(e=>e[0]===t).map((e,t)=>t+`,`+e.splice(1).join(`,`))),r=n(0);for(let e=1;ee.split(`,`)).map(e=>({method:e[1],start:+e[2],count:+e[3]}))}_updateLayout(e){if(this.notifyPlugins(`beforeLayout`,{cancelable:!0})===!1)return;J.update(this,this.width,this.height,e);let t=this.chartArea,n=t.width<=0||t.height<=0;this._layers=[],I(this.boxes,e=>{n&&e.position===`chartArea`||(e.configure&&e.configure(),this._layers.push(...e._layers()))},this),this._layers.forEach((e,t)=>{e._idx=t}),this.notifyPlugins(`afterLayout`)}_updateDatasets(e){if(this.notifyPlugins(`beforeDatasetsUpdate`,{mode:e,cancelable:!0})!==!1){for(let e=0,t=this.data.datasets.length;e=0;--t)this._drawDataset(e[t]);this.notifyPlugins(`afterDatasetsDraw`)}_drawDataset(e){let t=this.ctx,n={meta:e,index:e.index,cancelable:!0},r=Pr(this,e);this.notifyPlugins(`beforeDatasetDraw`,n)!==!1&&(r&&tn(t,r),e.controller.draw(),r&&nn(t),n.cancelable=!1,this.notifyPlugins(`afterDatasetDraw`,n))}isPointInArea(e){return en(e,this.chartArea,this._minPadding)}getElementsAtEventForMode(e,t,n,r){let i=Li.modes[t];return typeof i==`function`?i(this,e,n,r):[]}getDatasetMeta(e){let t=this.data.datasets[e],n=this._metasets,r=n.filter(e=>e&&e._dataset===t).pop();return r||(r={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:t&&t.order||0,index:e,_dataset:t,_parsed:[],_sorted:!1},n.push(r)),r}getContext(){return this.$context||=bn(null,{chart:this,type:`chart`})}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(e){let t=this.data.datasets[e];if(!t)return!1;let n=this.getDatasetMeta(e);return typeof n.hidden==`boolean`?!n.hidden:!t.hidden}setDatasetVisibility(e,t){let n=this.getDatasetMeta(e);n.hidden=!t}toggleDataVisibility(e){this._hiddenIndices[e]=!this._hiddenIndices[e]}getDataVisibility(e){return!this._hiddenIndices[e]}_updateVisibility(e,t,n){let r=n?`show`:`hide`,i=this.getDatasetMeta(e),a=i.controller._resolveAnimations(void 0,r);ze(t)?(i.data[t].hidden=!n,this.update()):(this.setDatasetVisibility(e,n),a.update(i,{visible:n}),this.update(t=>t.datasetIndex===e?r:void 0))}hide(e,t){this._updateVisibility(e,t,!1)}show(e,t){this._updateVisibility(e,t,!0)}_destroyDatasetMeta(e){let t=this._metasets[e];t&&t.controller&&t.controller._destroy(),delete this._metasets[e]}_stop(){let e,t;for(this.stop(),Fr.remove(this),e=0,t=this.data.datasets.length;e{t.addEventListener(this,n,r),e[n]=r},r=(e,t,n)=>{e.offsetX=t,e.offsetY=n,this._eventHandler(e)};I(this.options.events,e=>n(e,r))}bindResponsiveEvents(){this._responsiveListeners||={};let e=this._responsiveListeners,t=this.platform,n=(n,r)=>{t.addEventListener(this,n,r),e[n]=r},r=(n,r)=>{e[n]&&(t.removeEventListener(this,n,r),delete e[n])},i=(e,t)=>{this.canvas&&this.resize(e,t)},a,o=()=>{r(`attach`,o),this.attached=!0,this.resize(),n(`resize`,i),n(`detach`,a)};a=()=>{this.attached=!1,r(`resize`,i),this._stop(),this._resize(0,0),n(`attach`,o)},t.isAttached(this.canvas)?o():a()}unbindEvents(){I(this._listeners,(e,t)=>{this.platform.removeEventListener(this,t,e)}),this._listeners={},I(this._responsiveListeners,(e,t)=>{this.platform.removeEventListener(this,t,e)}),this._responsiveListeners=void 0}updateHoverStyle(e,t,n){let r=n?`set`:`remove`,i,a,o,s;for(t===`dataset`&&(i=this.getDatasetMeta(e[0].datasetIndex),i.controller[`_`+r+`DatasetHoverStyle`]()),o=0,s=e.length;o{let n=this.getDatasetMeta(e);if(!n)throw Error(`No dataset found at index `+e);return{datasetIndex:e,element:n.data[t],index:t}});De(n,t)||(this._active=n,this._lastEvent=null,this._updateHoverStyles(n,t))}notifyPlugins(e,t,n){return this._plugins.notify(this,e,t,n)}isPluginEnabled(e){return this._plugins._cache.filter(t=>t.plugin.id===e).length===1}_updateHoverStyles(e,t,n){let r=this.options.hover,i=(e,t)=>e.filter(e=>!t.some(t=>e.datasetIndex===t.datasetIndex&&e.index===t.index)),a=i(t,e),o=n?e:i(e,t);a.length&&this.updateHoverStyle(a,r.mode,!1),o.length&&r.mode&&this.updateHoverStyle(o,r.mode,!0)}_eventHandler(e,t){let n={event:e,replay:t,cancelable:!0,inChartArea:this.isPointInArea(e)},r=t=>(t.options.events||this.options.events).includes(e.native.type);if(this.notifyPlugins(`beforeEvent`,n,r)===!1)return;let i=this._handleEvent(e,t,n.inChartArea);return n.cancelable=!1,this.notifyPlugins(`afterEvent`,n,r),(i||n.changed)&&this.render(),this}_handleEvent(e,t,n){let{_active:r=[],options:i}=this,a=t,o=this._getActiveElements(e,r,n,a),s=He(e),c=Ao(e,this._lastEvent,n,s);n&&(this._lastEvent=null,F(i.onHover,[e,o,this],this),s&&F(i.onClick,[e,o,this],this));let l=!De(o,r);return(l||t)&&(this._active=o,this._updateHoverStyles(o,r,t)),this._lastEvent=c,l}_getActiveElements(e,t,n,r){if(e.type===`mouseout`)return[];if(!n)return t;let i=this.options.hover;return this.getElementsAtEventForMode(e,i.mode,i,r)}};function Mo(){return I(jo.instances,e=>e._plugins.invalidate())}function No(e,t,n){let{startAngle:r,x:i,y:a,outerRadius:o,innerRadius:s,options:c}=t,{borderWidth:l,borderJoinStyle:u}=c,d=Math.min(l/o,H(r-n));if(e.beginPath(),e.arc(i,a,o-l/2,r+d/2,n-d/2),s>0){let t=Math.min(l/s,H(r-n));e.arc(i,a,s+l/2,n-t/2,r+t/2,!0)}else{let t=Math.min(l/2,o*H(r-n));if(u===`round`)e.arc(i,a,t,n-L/2,r+L/2,!0);else if(u===`bevel`){let o=2*t*t,s=-o*Math.cos(n+L/2)+i,c=-o*Math.sin(n+L/2)+a,l=o*Math.cos(r+L/2)+i,u=o*Math.sin(r+L/2)+a;e.lineTo(s,c),e.lineTo(l,u)}}e.closePath(),e.moveTo(0,0),e.rect(0,0,e.canvas.width,e.canvas.height),e.clip(`evenodd`)}function Po(e,t,n){let{startAngle:r,pixelMargin:i,x:a,y:o,outerRadius:s,innerRadius:c}=t,l=i/s;e.beginPath(),e.arc(a,o,s,r-l,n+l),c>i?(l=i/c,e.arc(a,o,c,n+l,r-l,!0)):e.arc(a,o,i,n+z,r-z),e.closePath(),e.clip()}function Fo(e){return hn(e,[`outerStart`,`outerEnd`,`innerStart`,`innerEnd`])}function Io(e,t,n,r){let i=Fo(e.options.borderRadius),a=(n-t)/2,o=Math.min(a,r*t/2),s=e=>{let t=(n-Math.min(a,e))*r/2;return U(e,0,Math.min(a,t))};return{outerStart:s(i.outerStart),outerEnd:s(i.outerEnd),innerStart:U(i.innerStart,0,o),innerEnd:U(i.innerEnd,0,o)}}function Lo(e,t,n,r){return{x:n+e*Math.cos(t),y:r+e*Math.sin(t)}}function Ro(e,t,n,r,i,a){let{x:o,y:s,startAngle:c,pixelMargin:l,innerRadius:u}=t,d=Math.max(t.outerRadius+r+n-l,0),f=u>0?u+r+n+l:0,p=0,m=i-c;if(r){let e=((u>0?u-r:0)+(d>0?d-r:0))/2;p=(m-(e===0?m:m*e/(e+r)))/2}let h=(m-Math.max(.001,m*d-n/L)/d)/2,g=c+h+p,_=i-h-p,{outerStart:v,outerEnd:y,innerStart:b,innerEnd:x}=Io(t,f,d,_-g),S=d-v,C=d-y,w=g+v/S,T=_-y/C,E=f+b,D=f+x,ee=g+b/E,O=_-x/D;if(e.beginPath(),a){let t=(w+T)/2;if(e.arc(o,s,d,w,t),e.arc(o,s,d,t,T),y>0){let t=Lo(C,T,o,s);e.arc(t.x,t.y,y,T,_+z)}let n=Lo(D,_,o,s);if(e.lineTo(n.x,n.y),x>0){let t=Lo(D,O,o,s);e.arc(t.x,t.y,x,_+z,O+Math.PI)}let r=(_-x/f+(g+b/f))/2;if(e.arc(o,s,f,_-x/f,r,!0),e.arc(o,s,f,r,g+b/f,!0),b>0){let t=Lo(E,ee,o,s);e.arc(t.x,t.y,b,ee+Math.PI,g-z)}let i=Lo(S,g,o,s);if(e.lineTo(i.x,i.y),v>0){let t=Lo(S,w,o,s);e.arc(t.x,t.y,v,g-z,w)}}else{e.moveTo(o,s);let t=Math.cos(w)*d+o,n=Math.sin(w)*d+s;e.lineTo(t,n);let r=Math.cos(T)*d+o,i=Math.sin(T)*d+s;e.lineTo(r,i)}e.closePath()}function zo(e,t,n,r,i){let{fullCircles:a,startAngle:o,circumference:s}=t,c=t.endAngle;if(a){Ro(e,t,n,r,c,i);for(let t=0;t=L&&p===0&&u!==`miter`&&No(e,t,h),a||(Ro(e,t,n,r,h,i),e.stroke())}var Vo=class extends Ca{static id=`arc`;static defaults={borderAlign:`center`,borderColor:`#fff`,borderDash:[],borderDashOffset:0,borderJoinStyle:void 0,borderRadius:0,borderWidth:2,offset:0,spacing:0,angle:void 0,circular:!0,selfJoin:!1};static defaultRoutes={backgroundColor:`backgroundColor`};static descriptors={_scriptable:!0,_indexable:e=>e!==`borderDash`};circumference;endAngle;fullCircles;innerRadius;outerRadius;pixelMargin;startAngle;constructor(e){super(),this.options=void 0,this.circumference=void 0,this.startAngle=void 0,this.endAngle=void 0,this.innerRadius=void 0,this.outerRadius=void 0,this.pixelMargin=0,this.fullCircles=0,e&&Object.assign(this,e)}inRange(e,t,n){let{angle:r,distance:i}=it(this.getProps([`x`,`y`],n),{x:e,y:t}),{startAngle:a,endAngle:o,innerRadius:s,outerRadius:c,circumference:l}=this.getProps([`startAngle`,`endAngle`,`innerRadius`,`outerRadius`,`circumference`],n),u=(this.options.spacing+this.options.borderWidth)/2,d=P(l,o-a),f=st(r,a,o)&&a!==o,p=d>=R||f,m=lt(i,s+u,c+u);return p&&m}getCenterPoint(e){let{x:t,y:n,startAngle:r,endAngle:i,innerRadius:a,outerRadius:o}=this.getProps([`x`,`y`,`startAngle`,`endAngle`,`innerRadius`,`outerRadius`],e),{offset:s,spacing:c}=this.options,l=(r+i)/2,u=(a+o+c+s)/2;return{x:t+Math.cos(l)*u,y:n+Math.sin(l)*u}}tooltipPosition(e){return this.getCenterPoint(e)}draw(e){let{options:t,circumference:n}=this,r=(t.offset||0)/4,i=(t.spacing||0)/2,a=t.circular;if(this.pixelMargin=t.borderAlign===`inner`?.33:0,this.fullCircles=n>R?Math.floor(n/R):0,n===0||this.innerRadius<0||this.outerRadius<0)return;e.save();let o=(this.startAngle+this.endAngle)/2;e.translate(Math.cos(o)*r,Math.sin(o)*r);let s=r*(1-Math.sin(Math.min(L,n||0)));e.fillStyle=t.backgroundColor,e.strokeStyle=t.borderColor,zo(e,this,s,i,a),Bo(e,this,s,i,a),e.restore()}};function Ho(e,t,n=t){e.lineCap=P(n.borderCapStyle,t.borderCapStyle),e.setLineDash(P(n.borderDash,t.borderDash)),e.lineDashOffset=P(n.borderDashOffset,t.borderDashOffset),e.lineJoin=P(n.borderJoinStyle,t.borderJoinStyle),e.lineWidth=P(n.borderWidth,t.borderWidth),e.strokeStyle=P(n.borderColor,t.borderColor)}function Uo(e,t,n){e.lineTo(n.x,n.y)}function Wo(e){return e.stepped?rn:e.tension||e.cubicInterpolationMode===`monotone`?an:Uo}function Go(e,t,n={}){let r=e.length,{start:i=0,end:a=r-1}=n,{start:o,end:s}=t,c=Math.max(i,o),l=Math.min(a,s),u=is&&a>s;return{count:r,start:c,loop:t.loop,ilen:l(o+(l?s-e:e))%a,y=()=>{h!==g&&(e.lineTo(u,g),e.lineTo(u,h),e.lineTo(u,_))};for(c&&(p=i[v(0)],e.moveTo(p.x,p.y)),f=0;f<=s;++f){if(p=i[v(f)],p.skip)continue;let t=p.x,n=p.y,r=t|0;r===m?(ng&&(g=n),u=(d*u+t)/++d):(y(),e.lineTo(t,n),m=r,d=0,h=g=n),_=n}y()}function Jo(e){let t=e.options,n=t.borderDash&&t.borderDash.length;return!e._decimated&&!e._loop&&!t.tension&&t.cubicInterpolationMode!==`monotone`&&!t.stepped&&!n?qo:Ko}function Yo(e){return e.stepped?pr:e.tension||e.cubicInterpolationMode===`monotone`?mr:fr}function Xo(e,t,n,r){let i=t._path;i||(i=t._path=new Path2D,t.path(i,n,r)&&i.closePath()),Ho(e,t.options),e.stroke(i)}function Zo(e,t,n,r){let{segments:i,options:a}=t,o=Jo(t);for(let s of i)Ho(e,a,s.style),e.beginPath(),o(e,t,s,{start:n,end:n+r-1})&&e.closePath(),e.stroke()}var Qo=typeof Path2D==`function`;function $o(e,t,n,r){Qo&&!t.options.segment?Xo(e,t,n,r):Zo(e,t,n,r)}var es=class extends Ca{static id=`line`;static defaults={borderCapStyle:`butt`,borderDash:[],borderDashOffset:0,borderJoinStyle:`miter`,borderWidth:3,capBezierPoints:!0,cubicInterpolationMode:`default`,fill:!1,spanGaps:!1,stepped:!1,tension:0};static defaultRoutes={backgroundColor:`backgroundColor`,borderColor:`borderColor`};static descriptors={_scriptable:!0,_indexable:e=>e!==`borderDash`&&e!==`fill`};constructor(e){super(),this.animated=!0,this.options=void 0,this._chart=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,this._datasetIndex=void 0,e&&Object.assign(this,e)}updateControlPoints(e,t){let n=this.options;if((n.tension||n.cubicInterpolationMode===`monotone`)&&!n.stepped&&!this._pointsUpdated){let r=n.spanGaps?this._loop:this._fullLoop;Yn(this._points,n,e,r,t),this._pointsUpdated=!0}}set points(e){this._points=e,delete this._segments,delete this._path,this._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||=Dr(this,this.options.segment)}first(){let e=this.segments,t=this.points;return e.length&&t[e[0].start]}last(){let e=this.segments,t=this.points,n=e.length;return n&&t[e[n-1].end]}interpolate(e,t){let n=this.options,r=e[t],i=this.points,a=wr(this,{property:t,start:r,end:r});if(!a.length)return;let o=[],s=Yo(n),c,l;for(c=0,l=a.length;c{t=gs(e,t,i);let o=i[e],s=i[t];r===null?n!==null&&(a.push({x:n,y:o.y}),a.push({x:n,y:s.y})):(a.push({x:o.x,y:r}),a.push({x:s.x,y:r}))}),a}function gs(e,t,n){for(;t>e;t--){let e=n[t];if(!isNaN(e.x)&&!isNaN(e.y))break}return t}function _s(e,t,n,r){return e&&t?r(e[n],t[n]):e?e[n]:t?t[n]:0}function vs(e,t){let n=[],r=!1;return A(e)?(r=!0,n=e):n=hs(e,t),n.length?new es({points:n,options:{tension:0},_loop:r,_fullLoop:r}):null}function ys(e){return e&&e.fill!==!1}function bs(e,t,n){let r=e[t].fill,i=[t],a;if(!n)return r;for(;r!==!1&&i.indexOf(r)===-1;){if(!M(r))return r;if(a=e[r],!a)return!1;if(a.visible)return r;i.push(r),r=a.fill}return!1}function xs(e,t,n){let r=Ts(e);if(j(r))return isNaN(r.value)?!1:r;let i=parseFloat(r);return M(i)&&Math.floor(i)===i?Ss(r[0],t,i,n):[`origin`,`start`,`end`,`stack`,`shape`].indexOf(r)>=0&&r}function Ss(e,t,n,r){return(e===`-`||e===`+`)&&(n=t+n),n===t||n<0||n>=r?!1:n}function Cs(e,t){let n=null;return e===`start`?n=t.bottom:e===`end`?n=t.top:j(e)?n=t.getPixelForValue(e.value):t.getBasePixel&&(n=t.getBasePixel()),n}function ws(e,t,n){let r;return r=e===`start`?n:e===`end`?t.options.reverse?t.min:t.max:j(e)?e.value:t.getBaseValue(),r}function Ts(e){let t=e.options,n=t.fill,r=P(n&&n.target,n);return r===void 0&&(r=!!t.backgroundColor),r===!1||r===null?!1:r===!0?`origin`:r}function Es(e){let{scale:t,index:n,line:r}=e,i=[],a=r.segments,o=r.points,s=Ds(t,n);s.push(vs({x:null,y:t.bottom},r));for(let e=0;e=0;--t){let n=i[t].$filler;n&&(n.line.updateControlPoints(a,n.axis),r&&n.fill&&Is(e.ctx,n,a))}},beforeDatasetsDraw(e,t,n){if(n.drawTime!==`beforeDatasetsDraw`)return;let r=e.getSortedVisibleDatasetMetas();for(let t=r.length-1;t>=0;--t){let n=r[t].$filler;ys(n)&&Is(e.ctx,n,e.chartArea)}},beforeDatasetDraw(e,t,n){let r=t.meta.$filler;!ys(r)||n.drawTime!==`beforeDatasetDraw`||Is(e.ctx,r,e.chartArea)},defaults:{propagate:!0,drawTime:`beforeDatasetDraw`}},Ws=(e,t)=>{let{boxHeight:n=t,boxWidth:r=t}=e;return e.usePointStyle&&(n=Math.min(n,t),r=e.pointStyleWidth||Math.min(r,t)),{boxWidth:r,boxHeight:n,itemHeight:Math.max(t,n)}},Gs=(e,t)=>e!==null&&t!==null&&e.datasetIndex===t.datasetIndex&&e.index===t.index,Ks=class extends Ca{constructor(e){super(),this._added=!1,this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1,this.chart=e.chart,this.options=e.options,this.ctx=e.ctx,this.legendItems=void 0,this.columnSizes=void 0,this.lineWidths=void 0,this.maxHeight=void 0,this.maxWidth=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.height=void 0,this.width=void 0,this._margins=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(e,t,n){this.maxWidth=e,this.maxHeight=t,this._margins=n,this.setDimensions(),this.buildLabels(),this.fit()}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}buildLabels(){let e=this.options.labels||{},t=F(e.generateLabels,[this.chart],this)||[];e.filter&&(t=t.filter(t=>e.filter(t,this.chart.data))),e.sort&&(t=t.sort((t,n)=>e.sort(t,n,this.chart.data))),this.options.reverse&&t.reverse(),this.legendItems=t}fit(){let{options:e,ctx:t}=this;if(!e.display){this.width=this.height=0;return}let n=e.labels,r=q(n.font),i=r.size,a=this._computeTitleHeight(),{boxWidth:o,itemHeight:s}=Ws(n,i),c,l;t.font=r.string,this.isHorizontal()?(c=this.maxWidth,l=this._fitRows(a,i,o,s)+10):(l=this.maxHeight,c=this._fitCols(a,r,o,s)+10),this.width=Math.min(c,e.maxWidth||this.maxWidth),this.height=Math.min(l,e.maxHeight||this.maxHeight)}_fitRows(e,t,n,r){let{ctx:i,maxWidth:a,options:{labels:{padding:o}}}=this,s=this.legendHitBoxes=[],c=this.lineWidths=[0],l=r+o,u=e;i.textAlign=`left`,i.textBaseline=`middle`;let d=-1,f=-l;return this.legendItems.forEach((e,p)=>{let m=n+t/2+i.measureText(e.text).width;(p===0||c[c.length-1]+m+2*o>a)&&(u+=l,c[c.length-(p>0?0:1)]=0,f+=l,d++),s[p]={left:0,top:f,row:d,width:m,height:r},c[c.length-1]+=m+o}),u}_fitCols(e,t,n,r){let{ctx:i,maxHeight:a,options:{labels:{padding:o}}}=this,s=this.legendHitBoxes=[],c=this.columnSizes=[],l=a-e,u=o,d=0,f=0,p=0,m=0;return this.legendItems.forEach((e,a)=>{let{itemWidth:h,itemHeight:g}=qs(n,t,i,e,r);a>0&&f+g+2*o>l&&(u+=d+o,c.push({width:d,height:f}),p+=d+o,m++,d=f=0),s[a]={left:p,top:f,col:m,width:h,height:g},d=Math.max(d,h),f+=g+o}),u+=d,c.push({width:d,height:f}),u}adjustHitBoxes(){if(!this.options.display)return;let e=this._computeTitleHeight(),{legendHitBoxes:t,options:{align:n,labels:{padding:r},rtl:i}}=this,a=_r(i,this.left,this.width);if(this.isHorizontal()){let i=0,o=W(n,this.left+r,this.right-this.lineWidths[i]);for(let s of t)i!==s.row&&(i=s.row,o=W(n,this.left+r,this.right-this.lineWidths[i])),s.top+=this.top+e+r,s.left=a.leftForLtr(a.x(o),s.width),o+=s.width+r}else{let i=0,o=W(n,this.top+e+r,this.bottom-this.columnSizes[i].height);for(let s of t)s.col!==i&&(i=s.col,o=W(n,this.top+e+r,this.bottom-this.columnSizes[i].height)),s.top=o,s.left+=this.left+r,s.left=a.leftForLtr(a.x(s.left),s.width),o+=s.height+r}}isHorizontal(){return this.options.position===`top`||this.options.position===`bottom`}draw(){if(this.options.display){let e=this.ctx;tn(e,this),this._draw(),nn(e)}}_draw(){let{options:e,columnSizes:t,lineWidths:n,ctx:r}=this,{align:i,labels:a}=e,o=G.color,s=_r(e.rtl,this.left,this.width),c=q(a.font),{padding:l}=a,u=c.size,d=u/2,f;this.drawTitle(),r.textAlign=s.textAlign(`left`),r.textBaseline=`middle`,r.lineWidth=.5,r.font=c.string;let{boxWidth:p,boxHeight:m,itemHeight:h}=Ws(a,u),g=function(e,t,n){if(isNaN(p)||p<=0||isNaN(m)||m<0)return;r.save();let i=P(n.lineWidth,1);if(r.fillStyle=P(n.fillStyle,o),r.lineCap=P(n.lineCap,`butt`),r.lineDashOffset=P(n.lineDashOffset,0),r.lineJoin=P(n.lineJoin,`miter`),r.lineWidth=i,r.strokeStyle=P(n.strokeStyle,o),r.setLineDash(P(n.lineDash,[])),a.usePointStyle)$t(r,{radius:m*Math.SQRT2/2,pointStyle:n.pointStyle,rotation:n.rotation,borderWidth:i},s.xPlus(e,p/2),t+d,a.pointStyleWidth&&p);else{let a=t+Math.max((u-m)/2,0),o=s.leftForLtr(e,p),c=_n(n.borderRadius);r.beginPath(),Object.values(c).some(e=>e!==0)?un(r,{x:o,y:a,w:p,h:m,radius:c}):r.rect(o,a,p,m),r.fill(),i!==0&&r.stroke()}r.restore()},_=function(e,t,n){ln(r,n.text,e,t+h/2,c,{strikethrough:n.hidden,textAlign:s.textAlign(n.textAlign)})},v=this.isHorizontal(),y=this._computeTitleHeight();f=v?{x:W(i,this.left+l,this.right-n[0]),y:this.top+l+y,line:0}:{x:this.left+l,y:W(i,this.top+y+l,this.bottom-t[0].height),line:0},vr(this.ctx,e.textDirection);let b=h+l;this.legendItems.forEach((o,u)=>{r.strokeStyle=o.fontColor,r.fillStyle=o.fontColor;let m=r.measureText(o.text).width,h=s.textAlign(o.textAlign||=a.textAlign),x=p+d+m,S=f.x,C=f.y;if(s.setWidth(this.width),v?u>0&&S+x+l>this.right&&(C=f.y+=b,f.line++,S=f.x=W(i,this.left+l,this.right-n[f.line])):u>0&&C+b>this.bottom&&(S=f.x=S+t[f.line].width+l,f.line++,C=f.y=W(i,this.top+y+l,this.bottom-t[f.line].height)),g(s.x(S),C,o),S=St(h,S+p+d,v?S+x:this.right,e.rtl),_(s.x(S),C,o),v)f.x+=x+l;else if(typeof o.text!=`string`){let e=c.lineHeight;f.y+=Xs(o,e)+l}else f.y+=b}),yr(this.ctx,e.textDirection)}drawTitle(){let e=this.options,t=e.title,n=q(t.font),r=K(t.padding);if(!t.display)return;let i=_r(e.rtl,this.left,this.width),a=this.ctx,o=t.position,s=n.size/2,c=r.top+s,l,u=this.left,d=this.width;if(this.isHorizontal())d=Math.max(...this.lineWidths),l=this.top+c,u=W(e.align,u,this.right-d);else{let t=this.columnSizes.reduce((e,t)=>Math.max(e,t.height),0);l=c+W(e.align,this.top,this.bottom-t-e.labels.padding-this._computeTitleHeight())}let f=W(o,u,u+d);a.textAlign=i.textAlign(xt(o)),a.textBaseline=`middle`,a.strokeStyle=t.color,a.fillStyle=t.color,a.font=n.string,ln(a,t.text,f,l,n)}_computeTitleHeight(){let e=this.options.title,t=q(e.font),n=K(e.padding);return e.display?t.lineHeight+n.height:0}_getLegendItemAt(e,t){let n,r,i;if(lt(e,this.left,this.right)&<(t,this.top,this.bottom)){for(i=this.legendHitBoxes,n=0;ne.length>t.length?e:t)),t+n.size/2+r.measureText(i).width}function Ys(e,t,n){let r=e;return typeof t.text!=`string`&&(r=Xs(t,n)),r}function Xs(e,t){return t*(e.text?e.text.length:0)}function Zs(e,t){return!!((e===`mousemove`||e===`mouseout`)&&(t.onHover||t.onLeave)||t.onClick&&(e===`click`||e===`mouseup`))}var Qs={id:`legend`,_element:Ks,start(e,t,n){let r=e.legend=new Ks({ctx:e.ctx,options:n,chart:e});J.configure(e,r,n),J.addBox(e,r)},stop(e){J.removeBox(e,e.legend),delete e.legend},beforeUpdate(e,t,n){let r=e.legend;J.configure(e,r,n),r.options=n},afterUpdate(e){let t=e.legend;t.buildLabels(),t.adjustHitBoxes()},afterEvent(e,t){t.replay||e.legend.handleEvent(t.event)},defaults:{display:!0,position:`top`,align:`center`,fullSize:!0,reverse:!1,weight:1e3,onClick(e,t,n){let r=t.datasetIndex,i=n.chart;i.isDatasetVisible(r)?(i.hide(r),t.hidden=!0):(i.show(r),t.hidden=!1)},onHover:null,onLeave:null,labels:{color:e=>e.chart.options.color,boxWidth:40,padding:10,generateLabels(e){let t=e.data.datasets,{labels:{usePointStyle:n,pointStyle:r,textAlign:i,color:a,useBorderRadius:o,borderRadius:s}}=e.legend.options;return e._getSortedDatasetMetas().map(e=>{let c=e.controller.getStyle(n?0:void 0),l=K(c.borderWidth);return{text:t[e.index].label,fillStyle:c.backgroundColor,fontColor:a,hidden:!e.visible,lineCap:c.borderCapStyle,lineDash:c.borderDash,lineDashOffset:c.borderDashOffset,lineJoin:c.borderJoinStyle,lineWidth:(l.width+l.height)/4,strokeStyle:c.borderColor,pointStyle:r||c.pointStyle,rotation:c.rotation,textAlign:i||c.textAlign,borderRadius:o&&(s||c.borderRadius),datasetIndex:e.index}},this)}},title:{color:e=>e.chart.options.color,display:!1,position:`center`,text:``}},descriptors:{_scriptable:e=>!e.startsWith(`on`),labels:{_scriptable:e=>![`generateLabels`,`filter`,`sort`].includes(e)}}},$s=class extends Ca{constructor(e){super(),this.chart=e.chart,this.options=e.options,this.ctx=e.ctx,this._padding=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(e,t){let n=this.options;if(this.left=0,this.top=0,!n.display){this.width=this.height=this.right=this.bottom=0;return}this.width=this.right=e,this.height=this.bottom=t;let r=A(n.text)?n.text.length:1;this._padding=K(n.padding);let i=r*q(n.font).lineHeight+this._padding.height;this.isHorizontal()?this.height=i:this.width=i}isHorizontal(){let e=this.options.position;return e===`top`||e===`bottom`}_drawArgs(e){let{top:t,left:n,bottom:r,right:i,options:a}=this,o=a.align,s=0,c,l,u;return this.isHorizontal()?(l=W(o,n,i),u=t+e,c=i-n):(a.position===`left`?(l=n+e,u=W(o,r,t),s=L*-.5):(l=i-e,u=W(o,t,r),s=L*.5),c=r-t),{titleX:l,titleY:u,maxWidth:c,rotation:s}}draw(){let e=this.ctx,t=this.options;if(!t.display)return;let n=q(t.font),r=n.lineHeight/2+this._padding.top,{titleX:i,titleY:a,maxWidth:o,rotation:s}=this._drawArgs(r);ln(e,t.text,0,0,n,{color:t.color,maxWidth:o,rotation:s,textAlign:xt(t.align),textBaseline:`middle`,translation:[i,a]})}};function ec(e,t){let n=new $s({ctx:e.ctx,options:t,chart:e});J.configure(e,n,t),J.addBox(e,n),e.titleBlock=n}var tc={id:`title`,_element:$s,start(e,t,n){ec(e,n)},stop(e){let t=e.titleBlock;J.removeBox(e,t),delete e.titleBlock},beforeUpdate(e,t,n){let r=e.titleBlock;J.configure(e,r,n),r.options=n},defaults:{align:`center`,display:!1,font:{weight:`bold`},fullSize:!0,padding:10,position:`top`,text:``,weight:2e3},defaultRoutes:{color:`color`},descriptors:{_scriptable:!0,_indexable:!1}},nc={average(e){if(!e.length)return!1;let t,n,r=new Set,i=0,a=0;for(t=0,n=e.length;te+t)/r.size,y:i/a}},nearest(e,t){if(!e.length)return!1;let n=t.x,r=t.y,i=1/0,a,o,s;for(a=0,o=e.length;a-1?e.split(` +`):e}function ic(e,t){let{element:n,datasetIndex:r,index:i}=t,a=e.getDatasetMeta(r).controller,{label:o,value:s}=a.getLabelAndValue(i);return{chart:e,label:o,parsed:a.getParsed(i),raw:e.data.datasets[r].data[i],formattedValue:s,dataset:a.getDataset(),dataIndex:i,datasetIndex:r,element:n}}function ac(e,t){let n=e.chart.ctx,{body:r,footer:i,title:a}=e,{boxWidth:o,boxHeight:s}=t,c=q(t.bodyFont),l=q(t.titleFont),u=q(t.footerFont),d=a.length,f=i.length,p=r.length,m=K(t.padding),h=m.height,g=0,_=r.reduce((e,t)=>e+t.before.length+t.lines.length+t.after.length,0);if(_+=e.beforeBody.length+e.afterBody.length,d&&(h+=d*l.lineHeight+(d-1)*t.titleSpacing+t.titleMarginBottom),_){let e=t.displayColors?Math.max(s,c.lineHeight):c.lineHeight;h+=p*e+(_-p)*c.lineHeight+(_-1)*t.bodySpacing}f&&(h+=t.footerMarginTop+f*u.lineHeight+(f-1)*t.footerSpacing);let v=0,y=function(e){g=Math.max(g,n.measureText(e).width+v)};return n.save(),n.font=l.string,I(e.title,y),n.font=c.string,I(e.beforeBody.concat(e.afterBody),y),v=t.displayColors?o+2+t.boxPadding:0,I(r,e=>{I(e.before,y),I(e.lines,y),I(e.after,y)}),v=0,n.font=u.string,I(e.footer,y),n.restore(),g+=m.width,{width:g,height:h}}function oc(e,t){let{y:n,height:r}=t;return ne.height-r/2?`bottom`:`center`}function sc(e,t,n,r){let{x:i,width:a}=r,o=n.caretSize+n.caretPadding;if(e===`left`&&i+a+o>t.width||e===`right`&&i-a-o<0)return!0}function cc(e,t,n,r){let{x:i,width:a}=n,{width:o,chartArea:{left:s,right:c}}=e,l=`center`;return r===`center`?l=i<=(s+c)/2?`left`:`right`:i<=a/2?l=`left`:i>=o-a/2&&(l=`right`),sc(l,e,t,n)&&(l=`center`),l}function lc(e,t,n){let r=n.yAlign||t.yAlign||oc(e,n);return{xAlign:n.xAlign||t.xAlign||cc(e,t,n,r),yAlign:r}}function uc(e,t){let{x:n,width:r}=e;return t===`right`?n-=r:t===`center`&&(n-=r/2),n}function dc(e,t,n){let{y:r,height:i}=e;return t===`top`?r+=n:t===`bottom`?r-=i+n:r-=i/2,r}function fc(e,t,n,r){let{caretSize:i,caretPadding:a,cornerRadius:o}=e,{xAlign:s,yAlign:c}=n,l=i+a,{topLeft:u,topRight:d,bottomLeft:f,bottomRight:p}=_n(o),m=uc(t,s),h=dc(t,c,l);return c===`center`?s===`left`?m+=l:s===`right`&&(m-=l):s===`left`?m-=Math.max(u,f)+i:s===`right`&&(m+=Math.max(d,p)+i),{x:U(m,0,r.width-t.width),y:U(h,0,r.height-t.height)}}function pc(e,t,n){let r=K(n.padding);return t===`center`?e.x+e.width/2:t===`right`?e.x+e.width-r.right:e.x+r.left}function mc(e){return X([],rc(e))}function hc(e,t,n){return bn(e,{tooltip:t,tooltipItems:n,type:`tooltip`})}function gc(e,t){let n=t&&t.dataset&&t.dataset.tooltip&&t.dataset.tooltip.callbacks;return n?e.override(n):e}var _c={beforeTitle:Ce,title(e){if(e.length>0){let t=e[0],n=t.chart.data.labels,r=n?n.length:0;if(this&&this.options&&this.options.mode===`dataset`)return t.dataset.label||``;if(t.label)return t.label;if(r>0&&t.dataIndex{let t={before:[],lines:[],after:[]},i=gc(n,e);X(t.before,rc(Z(i,`beforeLabel`,this,e))),X(t.lines,Z(i,`label`,this,e)),X(t.after,rc(Z(i,`afterLabel`,this,e))),r.push(t)}),r}getAfterBody(e,t){return mc(Z(t.callbacks,`afterBody`,this,e))}getFooter(e,t){let{callbacks:n}=t,r=Z(n,`beforeFooter`,this,e),i=Z(n,`footer`,this,e),a=Z(n,`afterFooter`,this,e),o=[];return o=X(o,rc(r)),o=X(o,rc(i)),o=X(o,rc(a)),o}_createItems(e){let t=this._active,n=this.chart.data,r=[],i=[],a=[],o=[],s,c;for(s=0,c=t.length;se.filter(t,r,i,n))),e.itemSort&&(o=o.sort((t,r)=>e.itemSort(t,r,n))),I(o,t=>{let n=gc(e.callbacks,t);r.push(Z(n,`labelColor`,this,t)),i.push(Z(n,`labelPointStyle`,this,t)),a.push(Z(n,`labelTextColor`,this,t))}),this.labelColors=r,this.labelPointStyles=i,this.labelTextColors=a,this.dataPoints=o,o}update(e,t){let n=this.options.setContext(this.getContext()),r=this._active,i,a=[];if(!r.length)this.opacity!==0&&(i={opacity:0});else{let e=nc[n.position].call(this,r,this._eventPosition);a=this._createItems(n),this.title=this.getTitle(a,n),this.beforeBody=this.getBeforeBody(a,n),this.body=this.getBody(a,n),this.afterBody=this.getAfterBody(a,n),this.footer=this.getFooter(a,n);let t=this._size=ac(this,n),o=Object.assign({},e,t),s=lc(this.chart,n,o),c=fc(n,o,s,this.chart);this.xAlign=s.xAlign,this.yAlign=s.yAlign,i={opacity:1,x:c.x,y:c.y,width:t.width,height:t.height,caretX:e.x,caretY:e.y}}this._tooltipItems=a,this.$context=void 0,i&&this._resolveAnimations().update(this,i),e&&n.external&&n.external.call(this,{chart:this.chart,tooltip:this,replay:t})}drawCaret(e,t,n,r){let i=this.getCaretPosition(e,n,r);t.lineTo(i.x1,i.y1),t.lineTo(i.x2,i.y2),t.lineTo(i.x3,i.y3)}getCaretPosition(e,t,n){let{xAlign:r,yAlign:i}=this,{caretSize:a,cornerRadius:o}=n,{topLeft:s,topRight:c,bottomLeft:l,bottomRight:u}=_n(o),{x:d,y:f}=e,{width:p,height:m}=t,h,g,_,v,y,b;return i===`center`?(y=f+m/2,r===`left`?(h=d,g=h-a,v=y+a,b=y-a):(h=d+p,g=h+a,v=y-a,b=y+a),_=h):(g=r===`left`?d+Math.max(s,l)+a:r===`right`?d+p-Math.max(c,u)-a:this.caretX,i===`top`?(v=f,y=v-a,h=g-a,_=g+a):(v=f+m,y=v+a,h=g+a,_=g-a),b=v),{x1:h,x2:g,x3:_,y1:v,y2:y,y3:b}}drawTitle(e,t,n){let r=this.title,i=r.length,a,o,s;if(i){let c=_r(n.rtl,this.x,this.width);for(e.x=pc(this,n.titleAlign,n),t.textAlign=c.textAlign(n.titleAlign),t.textBaseline=`middle`,a=q(n.titleFont),o=n.titleSpacing,t.fillStyle=n.titleColor,t.font=a.string,s=0;se!==0)?(e.beginPath(),e.fillStyle=i.multiKeyBackground,un(e,{x:t,y:p,w:c,h:s,radius:o}),e.fill(),e.stroke(),e.fillStyle=a.backgroundColor,e.beginPath(),un(e,{x:n,y:p+1,w:c-2,h:s-2,radius:o}),e.fill()):(e.fillStyle=i.multiKeyBackground,e.fillRect(t,p,c,s),e.strokeRect(t,p,c,s),e.fillStyle=a.backgroundColor,e.fillRect(n,p+1,c-2,s-2))}e.fillStyle=this.labelTextColors[n]}drawBody(e,t,n){let{body:r}=this,{bodySpacing:i,bodyAlign:a,displayColors:o,boxHeight:s,boxWidth:c,boxPadding:l}=n,u=q(n.bodyFont),d=u.lineHeight,f=0,p=_r(n.rtl,this.x,this.width),m=function(n){t.fillText(n,p.x(e.x+f),e.y+d/2),e.y+=d+i},h=p.textAlign(a),g,_,v,y,b,x,S;for(t.textAlign=a,t.textBaseline=`middle`,t.font=u.string,e.x=pc(this,h,n),t.fillStyle=n.bodyColor,I(this.beforeBody,m),f=o&&h!==`right`?a===`center`?c/2+l:c+2+l:0,y=0,x=r.length;y0&&t.stroke()}_updateAnimationTarget(e){let t=this.chart,n=this.$animations,r=n&&n.x,i=n&&n.y;if(r||i){let n=nc[e.position].call(this,this._active,this._eventPosition);if(!n)return;let a=this._size=ac(this,e),o=Object.assign({},n,this._size),s=lc(t,e,o),c=fc(e,o,s,t);(r._to!==c.x||i._to!==c.y)&&(this.xAlign=s.xAlign,this.yAlign=s.yAlign,this.width=a.width,this.height=a.height,this.caretX=n.x,this.caretY=n.y,this._resolveAnimations().update(this,c))}}_willRender(){return!!this.opacity}draw(e){let t=this.options.setContext(this.getContext()),n=this.opacity;if(!n)return;this._updateAnimationTarget(t);let r={width:this.width,height:this.height},i={x:this.x,y:this.y};n=Math.abs(n)<.001?0:n;let a=K(t.padding),o=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;t.enabled&&o&&(e.save(),e.globalAlpha=n,this.drawBackground(i,e,r,t),vr(e,t.textDirection),i.y+=a.top,this.drawTitle(i,e,t),this.drawBody(i,e,t),this.drawFooter(i,e,t),yr(e,t.textDirection),e.restore())}getActiveElements(){return this._active||[]}setActiveElements(e,t){let n=this._active,r=e.map(({datasetIndex:e,index:t})=>{let n=this.chart.getDatasetMeta(e);if(!n)throw Error(`Cannot find a dataset at index `+e);return{datasetIndex:e,element:n.data[t],index:t}}),i=!De(n,r),a=this._positionChanged(r,t);(i||a)&&(this._active=r,this._eventPosition=t,this._ignoreReplayEvents=!0,this.update(!0))}handleEvent(e,t,n=!0){if(t&&this._ignoreReplayEvents)return!1;this._ignoreReplayEvents=!1;let r=this.options,i=this._active||[],a=this._getActiveElements(e,i,t,n),o=this._positionChanged(a,e),s=t||!De(a,i)||o;return s&&(this._active=a,(r.enabled||r.external)&&(this._eventPosition={x:e.x,y:e.y},this.update(!0,t))),s}_getActiveElements(e,t,n,r){let i=this.options;if(e.type===`mouseout`)return[];if(!r)return t.filter(e=>this.chart.data.datasets[e.datasetIndex]&&this.chart.getDatasetMeta(e.datasetIndex).controller.getParsed(e.index)!==void 0);let a=this.chart.getElementsAtEventForMode(e,i.mode,i,n);return i.reverse&&a.reverse(),a}_positionChanged(e,t){let{caretX:n,caretY:r,options:i}=this,a=nc[i.position].call(this,e,t);return a!==!1&&(n!==a.x||r!==a.y)}},yc={id:`tooltip`,_element:vc,positioners:nc,afterInit(e,t,n){n&&(e.tooltip=new vc({chart:e,options:n}))},beforeUpdate(e,t,n){e.tooltip&&e.tooltip.initialize(n)},reset(e,t,n){e.tooltip&&e.tooltip.initialize(n)},afterDraw(e){let t=e.tooltip;if(t&&t._willRender()){let n={tooltip:t};if(e.notifyPlugins(`beforeTooltipDraw`,{...n,cancelable:!0})===!1)return;t.draw(e.ctx),e.notifyPlugins(`afterTooltipDraw`,n)}},afterEvent(e,t){if(e.tooltip){let n=t.replay;e.tooltip.handleEvent(t.event,n,t.inChartArea)&&(t.changed=!0)}},defaults:{enabled:!0,external:null,position:`average`,backgroundColor:`rgba(0,0,0,0.8)`,titleColor:`#fff`,titleFont:{weight:`bold`},titleSpacing:2,titleMarginBottom:6,titleAlign:`left`,bodyColor:`#fff`,bodySpacing:2,bodyFont:{},bodyAlign:`left`,footerColor:`#fff`,footerSpacing:2,footerMarginTop:6,footerFont:{weight:`bold`},footerAlign:`left`,padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(e,t)=>t.bodyFont.size,boxWidth:(e,t)=>t.bodyFont.size,multiKeyBackground:`#fff`,displayColors:!0,boxPadding:0,borderColor:`rgba(0,0,0,0)`,borderWidth:0,animation:{duration:400,easing:`easeOutQuart`},animations:{numbers:{type:`number`,properties:[`x`,`y`,`width`,`height`,`caretX`,`caretY`]},opacity:{easing:`linear`,duration:200}},callbacks:_c},defaultRoutes:{bodyFont:`font`,footerFont:`font`,titleFont:`font`},descriptors:{_scriptable:e=>e!==`filter`&&e!==`itemSort`&&e!==`external`,_indexable:!1,callbacks:{_scriptable:!1,_indexable:!1},animation:{_fallback:!1},animations:{_fallback:`animation`}},additionalOptionScopes:[`interaction`]},bc=(e,t,n,r)=>(typeof t==`string`?(n=e.push(t)-1,r.unshift({index:n,label:t})):isNaN(t)&&(n=null),n);function xc(e,t,n,r){let i=e.indexOf(t);return i===-1?bc(e,t,n,r):i===e.lastIndexOf(t)?i:n}var Sc=(e,t)=>e===null?null:U(Math.round(e),0,t);function Cc(e){let t=this.getLabels();return e>=0&&et.length-1?null:this.getPixelForValue(t[e].value)}getValueForPixel(e){return Math.round(this._startValue+this.getDecimalForPixel(e)*this._valueRange)}getBasePixel(){return this.bottom}};function Tc(e,t){let n=[],{bounds:r,step:i,min:a,max:o,precision:s,count:c,maxTicks:l,maxDigits:u,includeBounds:d}=e,f=i||1,p=l-1,{min:m,max:h}=t,g=!k(a),_=!k(o),v=!k(c),y=(h-m)/(u+1),b=Xe((h-m)/p/f)*f,x,S,C,w;if(b<1e-14&&!g&&!_)return[{value:m},{value:h}];w=Math.ceil(h/b)-Math.floor(m/b),w>p&&(b=Xe(w*b/p/f)*f),k(s)||(x=10**s,b=Math.ceil(b*x)/x),r===`ticks`?(S=Math.floor(m/b)*b,C=Math.ceil(h/b)*b):(S=m,C=h),g&&_&&i&&et((o-a)/i,b/1e3)?(w=Math.round(Math.min((o-a)/b,l)),b=(o-a)/w,S=a,C=o):v?(S=g?a:S,C=_?o:C,w=c-1,b=(C-S)/w):(w=(C-S)/b,w=Ye(w,Math.round(w),b/1e3)?Math.round(w):Math.ceil(w));let T=Math.max(rt(b),rt(S));x=10**(k(s)?T:s),S=Math.round(S*x)/x,C=Math.round(C*x)/x;let E=0;for(g&&(d&&S!==a?(n.push({value:a}),So)break;n.push({value:e})}return _&&d&&C!==o?n.length&&Ye(n[n.length-1].value,o,Ec(o,y,e))?n[n.length-1].value=o:n.push({value:o}):(!_||C===o)&&n.push({value:C}),n}function Ec(e,t,{horizontal:n,minRotation:r}){let i=V(r),a=(n?Math.sin(i):Math.cos(i))||.001,o=.75*t*(``+e).length;return Math.min(t/a,o)}var Dc=class extends Ua{constructor(e){super(e),this.start=void 0,this.end=void 0,this._startValue=void 0,this._endValue=void 0,this._valueRange=0}parse(e,t){return k(e)||(typeof e==`number`||e instanceof Number)&&!isFinite(+e)?null:+e}handleTickRangeOptions(){let{beginAtZero:e}=this.options,{minDefined:t,maxDefined:n}=this.getUserBounds(),{min:r,max:i}=this,a=e=>r=t?r:e,o=e=>i=n?i:e;if(e){let e=B(r),t=B(i);e<0&&t<0?o(0):e>0&&t>0&&a(0)}if(r===i){let t=i===0?1:Math.abs(i*.05);o(i+t),e||a(r-t)}this.min=r,this.max=i}getTickLimit(){let{maxTicksLimit:e,stepSize:t}=this.options.ticks,n;return t?(n=Math.ceil(this.max/t)-Math.floor(this.min/t)+1,n>1e3&&(console.warn(`scales.${this.id}.ticks.stepSize: ${t} would result generating up to ${n} ticks. Limiting to 1000.`),n=1e3)):(n=this.computeTickLimit(),e||=11),e&&(n=Math.min(e,n)),n}computeTickLimit(){return 1/0}buildTicks(){let e=this.options,t=e.ticks,n=this.getTickLimit();n=Math.max(2,n);let r=Tc({maxTicks:n,bounds:e.bounds,min:e.min,max:e.max,precision:t.precision,step:t.stepSize,count:t.count,maxDigits:this._maxDigits(),horizontal:this.isHorizontal(),minRotation:t.minRotation||0,includeBounds:t.includeBounds!==!1},this._range||this);return e.bounds===`ticks`&&tt(r,this,`value`),e.reverse?(r.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),r}configure(){let e=this.ticks,t=this.min,n=this.max;if(super.configure(),this.options.offset&&e.length){let r=(n-t)/Math.max(e.length-1,1)/2;t-=r,n+=r}this._startValue=t,this._endValue=n,this._valueRange=n-t}getLabelForValue(e){return Rt(e,this.chart.options.locale,this.options.ticks.format)}},Oc=class extends Dc{static id=`linear`;static defaults={ticks:{callback:Vt.formatters.numeric}};determineDataLimits(){let{min:e,max:t}=this.getMinMax(!0);this.min=M(e)?e:0,this.max=M(t)?t:1,this.handleTickRangeOptions()}computeTickLimit(){let e=this.isHorizontal(),t=e?this.width:this.height,n=V(this.options.ticks.minRotation),r=(e?Math.sin(n):Math.cos(n))||.001,i=this._resolveTickFontOptions(0);return Math.ceil(t/Math.min(40,i.lineHeight/r))}getPixelForValue(e){return e===null?NaN:this.getPixelForDecimal((e-this._startValue)/this._valueRange)}getValueForPixel(e){return this._startValue+this.getDecimalForPixel(e)*this._valueRange}},kc=e=>Math.floor(Je(e)),Ac=(e,t)=>10**(kc(e)+t);function jc(e){return e/10**kc(e)==1}function Mc(e,t,n){let r=10**n,i=Math.floor(e/r);return Math.ceil(t/r)-i}function Nc(e,t){let n=kc(t-e);for(;Mc(e,t,n)>10;)n++;for(;Mc(e,t,n)<10;)n--;return Math.min(n,kc(e))}function Pc(e,{min:t,max:n}){t=N(e.min,t);let r=[],i=kc(t),a=Nc(t,n),o=a<0?10**Math.abs(a):1,s=10**a,c=i>a?10**i:0,l=Math.round((t-c)*o)/o,u=Math.floor((t-c)/s/10)*s*10,d=Math.floor((l-u)/10**a),f=N(e.min,Math.round((c+u+d*10**a)*o)/o);for(;f=10?d=d<15?15:20:d++,d>=20&&(a++,d=2,o=a>=0?1:o),f=Math.round((c+u+d*10**a)*o)/o;let p=N(e.max,f);return r.push({value:p,major:jc(p),significand:d}),r}(class extends Ua{static id=`logarithmic`;static defaults={ticks:{callback:Vt.formatters.logarithmic,major:{enabled:!0}}};constructor(e){super(e),this.start=void 0,this.end=void 0,this._startValue=void 0,this._valueRange=0}parse(e,t){let n=Dc.prototype.parse.apply(this,[e,t]);if(n===0){this._zero=!0;return}return M(n)&&n>0?n:null}determineDataLimits(){let{min:e,max:t}=this.getMinMax(!0);this.min=M(e)?Math.max(0,e):null,this.max=M(t)?Math.max(0,t):null,this.options.beginAtZero&&(this._zero=!0),this._zero&&this.min!==this._suggestedMin&&!M(this._userMin)&&(this.min=e===Ac(this.min,0)?Ac(this.min,-1):Ac(this.min,0)),this.handleTickRangeOptions()}handleTickRangeOptions(){let{minDefined:e,maxDefined:t}=this.getUserBounds(),n=this.min,r=this.max,i=t=>n=e?n:t,a=e=>r=t?r:e;n===r&&(n<=0?(i(1),a(10)):(i(Ac(n,-1)),a(Ac(r,1)))),n<=0&&i(Ac(r,-1)),r<=0&&a(Ac(n,1)),this.min=n,this.max=r}buildTicks(){let e=this.options,t=Pc({min:this._userMin,max:this._userMax},this);return e.bounds===`ticks`&&tt(t,this,`value`),e.reverse?(t.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),t}getLabelForValue(e){return e===void 0?`0`:Rt(e,this.chart.options.locale,this.options.ticks.format)}configure(){let e=this.min;super.configure(),this._startValue=Je(e),this._valueRange=Je(this.max)-Je(e)}getPixelForValue(e){return(e===void 0||e===0)&&(e=this.min),e===null||isNaN(e)?NaN:this.getPixelForDecimal(e===this.min?0:(Je(e)-this._startValue)/this._valueRange)}getValueForPixel(e){let t=this.getDecimalForPixel(e);return 10**(this._startValue+t*this._valueRange)}});function Fc(e){let t=e.ticks;if(t.display&&e.display){let e=K(t.backdropPadding);return P(t.font&&t.font.size,G.font.size)+e.height}return 0}function Ic(e,t,n){return n=A(n)?n:[n],{w:Yt(e,t.string,n),h:n.length*t.lineHeight}}function Lc(e,t,n,r,i){return e===r||e===i?{start:t-n/2,end:t+n/2}:ei?{start:t-n,end:t}:{start:t,end:t+n}}function Rc(e){let t={l:e.left+e._padding.left,r:e.right-e._padding.right,t:e.top+e._padding.top,b:e.bottom-e._padding.bottom},n=Object.assign({},t),r=[],i=[],a=e._pointLabels.length,o=e.options.pointLabels,s=o.centerPointLabels?L/a:0;for(let c=0;ct.r&&(s=(r.end-t.r)/a,e.r=Math.max(e.r,t.r+s)),i.startt.b&&(c=(i.end-t.b)/o,e.b=Math.max(e.b,t.b+c))}function Bc(e,t,n){let r=e.drawingArea,{extra:i,additionalAngle:a,padding:o,size:s}=n,c=e.getPointPosition(t,r+i+o,a),l=Math.round(nt(H(c.angle+z))),u=Gc(c.y,s.h,l),d=Uc(l),f=Wc(c.x,s.w,d);return{visible:!0,x:c.x,y:u,textAlign:d,left:f,top:u,right:f+s.w,bottom:u+s.h}}function Vc(e,t){if(!t)return!0;let{left:n,top:r,right:i,bottom:a}=e;return!(en({x:n,y:r},t)||en({x:n,y:a},t)||en({x:i,y:r},t)||en({x:i,y:a},t))}function Hc(e,t,n){let r=[],i=e._pointLabels.length,a=e.options,{centerPointLabels:o,display:s}=a.pointLabels,c={extra:Fc(a)/2,additionalAngle:o?L/i:0},l;for(let a=0;a270||n<90)&&(e-=t),e}function Kc(e,t,n){let{left:r,top:i,right:a,bottom:o}=n,{backdropColor:s}=t;if(!k(s)){let n=_n(t.borderRadius),c=K(t.backdropPadding);e.fillStyle=s;let l=r-c.left,u=i-c.top,d=a-r+c.width,f=o-i+c.height;Object.values(n).some(e=>e!==0)?(e.beginPath(),un(e,{x:l,y:u,w:d,h:f,radius:n}),e.fill()):e.fillRect(l,u,d,f)}}function qc(e,t){let{ctx:n,options:{pointLabels:r}}=e;for(let i=t-1;i>=0;i--){let t=e._pointLabelItems[i];if(!t.visible)continue;let a=r.setContext(e.getPointLabelContext(i));Kc(n,a,t);let o=q(a.font),{x:s,y:c,textAlign:l}=t;ln(n,e._pointLabels[i],s,c+o.lineHeight/2,o,{color:a.color,textAlign:l,textBaseline:`middle`})}}function Jc(e,t,n,r){let{ctx:i}=e;if(n)i.arc(e.xCenter,e.yCenter,t,0,R);else{let n=e.getPointPosition(0,t);i.moveTo(n.x,n.y);for(let a=1;a{let n=F(this.options.pointLabels.callback,[e,t],this);return n||n===0?n:``}).filter((e,t)=>this.chart.getDataVisibility(t))}fit(){let e=this.options;e.display&&e.pointLabels.display?Rc(this):this.setCenterPoint(0,0,0,0)}setCenterPoint(e,t,n,r){this.xCenter+=Math.floor((e-t)/2),this.yCenter+=Math.floor((n-r)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(e,t,n,r))}getIndexAngle(e){let t=R/(this._pointLabels.length||1),n=this.options.startAngle||0;return H(e*t+V(n))}getDistanceFromCenterForValue(e){if(k(e))return NaN;let t=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-e)*t:(e-this.min)*t}getValueForDistanceFromCenter(e){if(k(e))return NaN;let t=e/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-t:this.min+t}getPointLabelContext(e){let t=this._pointLabels||[];if(e>=0&&e{if(t!==0||t===0&&this.min<0){s=this.getDistanceFromCenterForValue(e.value);let n=this.getContext(t),o=r.setContext(n),c=i.setContext(n);Yc(this,o,s,a,c)}}),n.display){for(e.save(),o=a-1;o>=0;o--){let r=n.setContext(this.getPointLabelContext(o)),{color:i,lineWidth:a}=r;!a||!i||(e.lineWidth=a,e.strokeStyle=i,e.setLineDash(r.borderDash),e.lineDashOffset=r.borderDashOffset,s=this.getDistanceFromCenterForValue(t.reverse?this.min:this.max),c=this.getPointPosition(o,s),e.beginPath(),e.moveTo(this.xCenter,this.yCenter),e.lineTo(c.x,c.y),e.stroke())}e.restore()}}drawBorder(){}drawLabels(){let e=this.ctx,t=this.options,n=t.ticks;if(!n.display)return;let r=this.getIndexAngle(0),i,a;e.save(),e.translate(this.xCenter,this.yCenter),e.rotate(r),e.textAlign=`center`,e.textBaseline=`middle`,this.ticks.forEach((r,o)=>{if(o===0&&this.min>=0&&!t.reverse)return;let s=n.setContext(this.getContext(o)),c=q(s.font);if(i=this.getDistanceFromCenterForValue(this.ticks[o].value),s.showLabelBackdrop){e.font=c.string,a=e.measureText(r.label).width,e.fillStyle=s.backdropColor;let t=K(s.backdropPadding);e.fillRect(-a/2-t.left,-i-c.size/2-t.top,a+t.width,c.size+t.height)}ln(e,r.label,0,-i,c,{color:s.color,strokeColor:s.textStrokeColor,strokeWidth:s.textStrokeWidth})}),e.restore()}drawTitle(){}});var Zc={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},Q=Object.keys(Zc);function Qc(e,t){return e-t}function $c(e,t){if(k(t))return null;let n=e._adapter,{parser:r,round:i,isoWeekday:a}=e._parseOpts,o=t;return typeof r==`function`&&(o=r(o)),M(o)||(o=typeof r==`string`?n.parse(o,r):n.parse(o)),o===null?null:(i&&(o=i===`week`&&($e(a)||a===!0)?n.startOf(o,`isoWeek`,a):n.startOf(o,i)),+o)}function el(e,t,n,r){let i=Q.length;for(let a=Q.indexOf(e);a=Q.indexOf(n);a--){let n=Q[a];if(Zc[n].common&&e._adapter.diff(i,r,n)>=t-1)return n}return Q[n?Q.indexOf(n):0]}function nl(e){for(let t=Q.indexOf(e)+1,n=Q.length;t=t?n[r]:n[i];e[a]=!0}}function il(e,t,n,r){let i=e._adapter,a=+i.startOf(t[0].value,r),o=t[t.length-1].value,s,c;for(s=a;s<=o;s=+i.add(s,1,r))c=n[s],c>=0&&(t[c].major=!0);return t}function al(e,t,n){let r=[],i={},a=t.length,o,s;for(o=0;o+e.value))}initOffsets(e=[]){let t=0,n=0,r,i;this.options.offset&&e.length&&(r=this.getDecimalForValue(e[0]),t=e.length===1?1-r:(this.getDecimalForValue(e[1])-r)/2,i=this.getDecimalForValue(e[e.length-1]),n=e.length===1?i:(i-this.getDecimalForValue(e[e.length-2]))/2);let a=e.length<3?.5:.25;t=U(t,0,a),n=U(n,0,a),this._offsets={start:t,end:n,factor:1/(t+1+n)}}_generate(){let e=this._adapter,t=this.min,n=this.max,r=this.options,i=r.time,a=i.unit||el(i.minUnit,t,n,this._getLabelCapacity(t)),o=P(r.ticks.stepSize,1),s=a===`week`?i.isoWeekday:!1,c=$e(s)||s===!0,l={},u=t,d,f;if(c&&(u=+e.startOf(u,`isoWeek`,s)),u=+e.startOf(u,c?`day`:a),e.diff(n,t,a)>1e5*o)throw Error(t+` and `+n+` are too far apart with stepSize of `+o+` `+a);let p=r.ticks.source===`data`&&this.getDataTimestamps();for(d=u,f=0;d+e)}getLabelForValue(e){let t=this._adapter,n=this.options.time;return n.tooltipFormat?t.format(e,n.tooltipFormat):t.format(e,n.displayFormats.datetime)}format(e,t){let n=this.options.time.displayFormats,r=this._unit,i=t||n[r];return this._adapter.format(e,i)}_tickFormatFunction(e,t,n,r){let i=this.options,a=i.ticks.callback;if(a)return F(a,[e,t,n],this);let o=i.time.displayFormats,s=this._unit,c=this._majorUnit,l=s&&o[s],u=c&&o[c],d=n[t],f=c&&u&&d&&d.major;return this._adapter.format(e,r||(f?u:l))}generateTickLabels(e){let t,n,r;for(t=0,n=e.length;t0?o:1}getDataTimestamps(){let e=this._cache.data||[],t,n;if(e.length)return e;let r=this.getMatchingVisibleMetas();if(this._normalized&&r.length)return this._cache.data=r[0].controller.getAllParsedValues(this);for(t=0,n=r.length;t=e[r].pos&&t<=e[i].pos&&({lo:r,hi:i}=dt(e,`pos`,t)),{pos:a,time:s}=e[r],{pos:o,time:c}=e[i]):(t>=e[r].time&&t<=e[i].time&&({lo:r,hi:i}=dt(e,`time`,t)),{time:a,pos:s}=e[r],{time:o,pos:c}=e[i]);let l=o-a;return l?s+(c-s)*(t-a)/l:s}(class extends ol{static id=`timeseries`;static defaults=ol.defaults;constructor(e){super(e),this._table=[],this._minPos=void 0,this._tableRange=void 0}initOffsets(){let e=this._getTimestampsForTable(),t=this._table=this.buildLookupTable(e);this._minPos=sl(t,this.min),this._tableRange=sl(t,this.max)-this._minPos,super.initOffsets(e)}buildLookupTable(e){let{min:t,max:n}=this,r=[],i=[],a,o,s,c,l;for(a=0,o=e.length;a=t&&c<=n&&r.push(c);if(r.length<2)return[{time:t,pos:0},{time:n,pos:1}];for(a=0,o=r.length;ae-t)}_getTimestampsForTable(){let e=this._cache.all||[];if(e.length)return e;let t=this.getDataTimestamps(),n=this.getLabelTimestamps();return e=t.length&&n.length?this.normalize(t.concat(n)):t.length?t:n,e=this._cache.all=e,e}getDecimalForValue(e){return(sl(this._table,e)-this._minPos)/this._tableRange}getValueForPixel(e){let t=this._offsets,n=this.getDecimalForPixel(e)/t.factor-t.end;return sl(this._table,n*this._tableRange+this._minPos,!0)}});var $=i(),cl=`label`;function ll(e,t){typeof e==`function`?e(t):e&&(e.current=t)}function ul(e,t){let n=e.options;n&&t&&Object.assign(n,t)}function dl(e,t){e.labels=t}function fl(e,t,n=cl){let r=[];e.datasets=t.map(t=>{let i=e.datasets.find(e=>e[n]===t[n]);return!i||!t.data||r.includes(i)?{...t}:(r.push(i),Object.assign(i,t),i)})}function pl(e,t=cl){let n={labels:[],datasets:[]};return dl(n,e.labels),fl(n,e.datasets,t),n}function ml(e,t){let{height:n=150,width:r=300,redraw:i=!1,datasetIdKey:a,type:s,data:c,options:l,plugins:u=[],fallbackContent:d,updateMode:f,...p}=e,m=(0,o.useRef)(null),h=(0,o.useRef)(null),g=()=>{m.current&&(h.current=new jo(m.current,{type:s,data:pl(c,a),options:l&&{...l},plugins:u}),ll(t,h.current))},_=()=>{ll(t,null),h.current&&=(h.current.destroy(),null)};return(0,o.useEffect)(()=>{!i&&h.current&&l&&ul(h.current,l)},[i,l]),(0,o.useEffect)(()=>{!i&&h.current&&dl(h.current.config.data,c.labels)},[i,c.labels]),(0,o.useEffect)(()=>{!i&&h.current&&c.datasets&&fl(h.current.config.data,c.datasets,a)},[i,c.datasets]),(0,o.useEffect)(()=>{h.current&&(i?(_(),setTimeout(g)):h.current.update(f))},[i,l,c.labels,c.datasets,f]),(0,o.useEffect)(()=>{h.current&&(_(),setTimeout(g))},[s]),(0,o.useEffect)(()=>(g(),()=>_()),[]),(0,$.jsx)(`canvas`,{ref:m,role:`img`,height:n,width:r,...p,children:d})}var hl=(0,o.forwardRef)(ml);function gl(e,t){return jo.register(t),(0,o.forwardRef)((t,n)=>(0,$.jsx)(hl,{...t,ref:n,type:e}))}var _l=gl(`line`,Ei),vl=gl(`bar`,Ci),yl=gl(`doughnut`,Ti);jo.register(wc,Oc,ns,es,fs,Vo,tc,yc,Qs,Us);function bl({label:e,value:t,sub:n,icon:r,variant:i=`white`,delay:a=`0s`}){return(0,$.jsxs)(`div`,{className:`relative rounded-2xl p-6 anim-up shadow-sm hover:-translate-y-0.5 transition-transform duration-200 ${{white:`bg-white text-[#3D4E4B] border border-gray-100`,dark:`bg-[#3D4E4B] text-white border border-[#3D4E4B]`,gold:`bg-[#D4A017] text-white border border-[#D4A017]`,teal:`bg-[#21A59F] text-white border border-[#21A59F]`}[i]}`,style:{animationDelay:a},children:[(0,$.jsxs)(`div`,{className:`flex items-start justify-between mb-4`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`p`,{className:`text-sm font-semibold opacity-60`,children:e}),(0,$.jsx)(`p`,{className:`text-3xl font-bold tracking-tighter mt-1`,children:typeof t==`number`?t.toLocaleString():t})]}),(0,$.jsx)(`div`,{className:`w-10 h-10 rounded-xl bg-black/5 border border-white/10 flex items-center justify-center shrink-0`,children:r})]}),(0,$.jsx)(`p`,{className:`text-sm font-semibold opacity-60`,children:n})]})}function xl({stats:e}){let{totalUsers:t,activeUsers:i,totalRoles:o,recentUsers:s,charts:c}=e,l=t-i,u={labels:c.userGrowth.map(e=>e.label),datasets:[{label:`New Registrations`,data:c.userGrowth.map(e=>e.value),borderColor:`#D4A017`,backgroundColor:`rgba(212, 160, 23, 0.1)`,fill:!0,tension:.4,pointRadius:4,pointBackgroundColor:`#D4A017`}]},d={labels:c.activityStats.map(e=>e.label),datasets:[{label:`System Activity`,data:c.activityStats.map(e=>e.value),backgroundColor:`#3D4E4B`,borderRadius:8}]},f={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{display:!1},tooltip:{backgroundColor:`#3D4E4B`,titleFont:{size:12,weight:`bold`},padding:12,cornerRadius:12}},scales:{x:{grid:{display:!1},ticks:{font:{size:10,weight:`bold`},color:`#9ca3af`}},y:{border:{display:!1},ticks:{font:{size:10,weight:`bold`},color:`#9ca3af`},grid:{color:`#f3f4f6`}}}};return(0,$.jsxs)(a,{children:[(0,$.jsx)(n,{title:`Dashboard`}),(0,$.jsxs)(`div`,{className:`space-y-6`,children:[(0,$.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4`,children:[(0,$.jsx)(bl,{label:`Total Users`,value:t,sub:`All registered accounts`,variant:`gold`,delay:`0s`,icon:(0,$.jsx)(`svg`,{className:`w-5 h-5`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,$.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z`})})}),(0,$.jsx)(bl,{label:`Active Users`,value:i,sub:`${t>0?Math.round(i/t*100):0}% of total`,variant:`dark`,delay:`0.08s`,icon:(0,$.jsx)(`svg`,{className:`w-5 h-5`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,$.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z`})})}),(0,$.jsx)(bl,{label:`Inactive Users`,value:l,sub:`Suspended or deactivated`,variant:`teal`,delay:`0.16s`,icon:(0,$.jsx)(`svg`,{className:`w-5 h-5`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,$.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636`})})}),(0,$.jsx)(bl,{label:`Roles`,value:o,sub:`Defined permission sets`,variant:`white`,delay:`0.24s`,icon:(0,$.jsx)(`svg`,{className:`w-5 h-5`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,$.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z`})})})]}),(0,$.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-12 gap-6`,children:[(0,$.jsxs)(`div`,{className:`lg:col-span-8 bg-white rounded-2xl border border-gray-100 shadow-sm p-8 anim-up`,style:{animationDelay:`0.32s`},children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between mb-8`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`h3`,{className:`text-base font-black text-[#3D4E4B] tracking-tight leading-none`,children:`User Growth`}),(0,$.jsx)(`p`,{className:`text-xs font-bold text-gray-400 mt-2 tracking-tight`,children:`Registration metrics over the last 6 months`})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(`span`,{className:`w-2.5 h-2.5 rounded-full bg-[#D4A017]`}),(0,$.jsx)(`span`,{className:`text-[10px] font-black uppercase tracking-widest text-[#D4A017]`,children:`Accounts`})]})]}),(0,$.jsx)(`div`,{className:`h-[300px]`,children:(0,$.jsx)(_l,{data:u,options:f})})]}),(0,$.jsxs)(`div`,{className:`lg:col-span-4 bg-[#3D4E4B] rounded-2xl p-8 text-white anim-up shadow-lg shadow-[#3D4E4B]/20`,style:{animationDelay:`0.4s`},children:[(0,$.jsx)(`h3`,{className:`text-base font-black tracking-tight leading-none mb-2`,children:`Account Integrity`}),(0,$.jsx)(`p`,{className:`text-xs font-bold text-white/40 tracking-tight mb-8 uppercase tracking-widest`,children:`Global Status Registry`}),(0,$.jsxs)(`div`,{className:`flex flex-col items-center`,children:[(0,$.jsx)(`div`,{className:`w-48 h-48 mb-8`,children:(0,$.jsx)(yl,{data:{labels:[`Active`,`Inactive`],datasets:[{data:[i,l],backgroundColor:[`#D4A017`,`rgba(255,255,255,0.1)`],borderWidth:0,cutout:`75%`}]},options:{plugins:{legend:{display:!1}},maintainAspectRatio:!1}})}),(0,$.jsxs)(`div`,{className:`w-full space-y-4`,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between p-4 rounded-xl bg-white/5 border border-white/5`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,$.jsx)(`div`,{className:`w-2 h-2 rounded-full bg-[#D4A017]`}),(0,$.jsx)(`span`,{className:`text-xs font-bold opacity-60`,children:`Verified Active`})]}),(0,$.jsx)(`span`,{className:`text-sm font-black`,children:i})]}),(0,$.jsxs)(`div`,{className:`flex items-center justify-between p-4 rounded-xl bg-white/5 border border-white/5`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,$.jsx)(`div`,{className:`w-2 h-2 rounded-full bg-white/20`}),(0,$.jsx)(`span`,{className:`text-xs font-bold opacity-60`,children:`Restricted/Inactive`})]}),(0,$.jsx)(`span`,{className:`text-sm font-black`,children:l})]})]})]})]})]}),(0,$.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-12 gap-6`,children:[(0,$.jsxs)(`div`,{className:`lg:col-span-4 bg-white rounded-2xl border border-gray-100 shadow-sm p-8 anim-up`,style:{animationDelay:`0.48s`},children:[(0,$.jsx)(`h3`,{className:`text-base font-black text-[#3D4E4B] tracking-tight leading-none mb-8`,children:`System Pulse`}),(0,$.jsx)(`div`,{className:`h-[250px]`,children:(0,$.jsx)(vl,{data:d,options:f})})]}),(0,$.jsxs)(`div`,{className:`lg:col-span-8 bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden anim-up`,style:{animationDelay:`0.56s`},children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between px-8 py-6 border-b border-gray-50`,children:[(0,$.jsx)(`div`,{children:(0,$.jsx)(`h3`,{className:`text-sm font-black text-[#3D4E4B] tracking-tight uppercase tracking-widest`,children:`Recent Registry`})}),(0,$.jsx)(r,{href:`/users`,className:`text-[10px] font-black uppercase tracking-widest text-[#D4A017] hover:text-[#B88B14] transition-colors`,children:`View Full Archive →`})]}),(0,$.jsx)(`div`,{className:`divide-y divide-gray-50`,children:s.map(e=>{let t=`${e.first_name?.charAt(0)??``}${e.last_name?.charAt(0)??``}`.toUpperCase();return(0,$.jsxs)(`div`,{className:`flex items-center justify-between px-8 py-5 hover:bg-gray-50/30 transition-colors group`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,$.jsx)(`div`,{className:`w-10 h-10 rounded-2xl bg-[#3D4E4B] text-white text-[10px] font-black flex items-center justify-center border-2 border-white shadow-lg shadow-[#3D4E4B]/10 overflow-hidden`,children:e.avatar_url?(0,$.jsx)(`img`,{src:e.avatar_url,className:`w-full h-full object-cover`,alt:``}):t}),(0,$.jsxs)(`div`,{children:[(0,$.jsxs)(`p`,{className:`text-sm font-black text-[#3D4E4B] tracking-tight`,children:[e.first_name,` `,e.last_name]}),(0,$.jsx)(`p`,{className:`text-[10px] font-bold text-gray-300 uppercase tracking-widest mt-1`,children:e.email})]})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-6`,children:[(0,$.jsx)(`span`,{className:`px-3 py-1 rounded-full text-[9px] font-black uppercase tracking-widest border ${e.status===`active`?`text-emerald-600 border-emerald-100 bg-emerald-50/50`:`text-gray-400 border-gray-100 bg-gray-50/50`}`,children:e.status}),(0,$.jsx)(r,{href:route(`users.show`,e.id),className:`w-8 h-8 rounded-xl bg-gray-50 flex items-center justify-center text-gray-400 hover:bg-[#3D4E4B] hover:text-white transition-all`,children:(0,$.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,$.jsx)(`path`,{d:`M9 5l7 7-7 7`})})})]})]},e.id)})})]})]})]})]})}export{xl as default}; \ No newline at end of file diff --git a/public/build/assets/DeleteUserForm-DLkG3tvo.js b/public/build/assets/DeleteUserForm-DLkG3tvo.js new file mode 100644 index 0000000..1c38bdc --- /dev/null +++ b/public/build/assets/DeleteUserForm-DLkG3tvo.js @@ -0,0 +1 @@ +import{a as e,c as t,d as n,s as r,t as i,u as a}from"./app-BJ7g6sa8.js";import{C as o,S as s,_ as c,a as l,b as u,c as d,d as f,f as p,g as m,h,i as g,l as ee,m as _,n as v,o as y,p as b,r as x,s as te,t as S,u as C,v as w,x as T,y as E}from"./TextInput-DV7QeRn3.js";var D=i();function O({className:e=``,disabled:t,children:n,...r}){return(0,D.jsx)(`button`,{...r,className:`inline-flex items-center rounded-md border border-transparent bg-red-600 px-4 py-2 text-xs font-semibold uppercase tracking-widest text-white transition duration-150 ease-in-out hover:bg-red-500 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 active:bg-red-700 ${t&&`opacity-25`} `+e,disabled:t,children:n})}function k(e){return T.isServer?null:e==null?document:e?.ownerDocument??document}function A(e){return T.isServer?null:e==null?document:(e?.getRootNode)?.call(e)??document}function ne(e){return A(e)?.activeElement??null}function re(e){return ne(e)===e}var j=n(t(),1);function M(e){return(0,j.useMemo)(()=>e,Object.values(e))}var N=(0,j.createContext)(void 0);function ie(){return(0,j.useContext)(N)}var P=`span`,F=(e=>(e[e.None=1]=`None`,e[e.Focusable=2]=`Focusable`,e[e.Hidden=4]=`Hidden`,e))(F||{});function ae(e,t){let{features:n=1,...r}=e,i={ref:t,"aria-hidden":(n&2)==2?!0:r[`aria-hidden`]??void 0,hidden:(n&4)==4?!0:void 0,style:{position:`fixed`,top:1,left:1,width:1,height:0,padding:0,margin:-1,overflow:`hidden`,clip:`rect(0, 0, 0, 0)`,whiteSpace:`nowrap`,borderWidth:`0`,...(n&4)==4&&(n&2)!=2&&{display:`none`}}};return p()({ourProps:i,theirProps:r,slot:{},defaultTag:P,name:`Hidden`})}var oe=b(ae);function se(e){return typeof e!=`object`||!e?!1:`nodeType`in e}function I(e){return se(e)&&`tagName`in e}function L(e){return I(e)&&`accessKey`in e}function R(e){return I(e)&&`tabIndex`in e}function z(e){return I(e)&&`style`in e}function ce(e){return L(e)&&e.nodeName===`IFRAME`}function le(e){return L(e)&&e.nodeName===`INPUT`}var ue=(0,j.createContext)(null);ue.displayName=`DescriptionContext`;function de(){let e=(0,j.useContext)(ue);if(e===null){let e=Error(`You used a component, but it is not inside a relevant parent.`);throw Error.captureStackTrace&&Error.captureStackTrace(e,de),e}return e}function fe(){let[e,t]=(0,j.useState)([]);return[e.length>0?e.join(` `):void 0,(0,j.useMemo)(()=>function(e){let n=h(e=>(t(t=>[...t,e]),()=>t(t=>{let n=t.slice(),r=n.indexOf(e);return r!==-1&&n.splice(r,1),n}))),r=(0,j.useMemo)(()=>({register:n,slot:e.slot,name:e.name,props:e.props,value:e.value}),[n,e.slot,e.name,e.props,e.value]);return j.createElement(ue.Provider,{value:r},e.children)},[t])]}var pe=`p`;function me(e,t){let n=(0,j.useId)(),r=ie(),{id:i=`headlessui-description-${n}`,...a}=e,o=de(),s=C(t);c(()=>o.register(i),[i,o.register]);let l=M({...o.slot,disabled:r||!1}),u={ref:s,...o.props,id:i};return p()({ourProps:u,theirProps:a,slot:l,defaultTag:pe,name:o.name||`Description`})}var he=b(me),ge=Object.assign(he,{}),_e=(e=>(e.Space=` `,e.Enter=`Enter`,e.Escape=`Escape`,e.Backspace=`Backspace`,e.Delete=`Delete`,e.ArrowLeft=`ArrowLeft`,e.ArrowUp=`ArrowUp`,e.ArrowRight=`ArrowRight`,e.ArrowDown=`ArrowDown`,e.Home=`Home`,e.End=`End`,e.PageUp=`PageUp`,e.PageDown=`PageDown`,e.Tab=`Tab`,e))(_e||{}),ve=(0,j.createContext)(()=>{});function ye({value:e,children:t}){return j.createElement(ve.Provider,{value:e},t)}var be=class extends Map{constructor(e){super(),this.factory=e}get(e){let t=super.get(e);return t===void 0&&(t=this.factory(e),this.set(e,t)),t}},xe=Object.defineProperty,Se=(e,t,n)=>t in e?xe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Ce=(e,t,n)=>(Se(e,typeof t==`symbol`?t:t+``,n),n),we=(e,t,n)=>{if(!t.has(e))throw TypeError(`Cannot `+n)},B=(e,t,n)=>(we(e,t,`read from private field`),n?n.call(e):t.get(e)),Te=(e,t,n)=>{if(t.has(e))throw TypeError(`Cannot add the same private member more than once`);t instanceof WeakSet?t.add(e):t.set(e,n)},Ee=(e,t,n,r)=>(we(e,t,`write to private field`),r?r.call(e,n):t.set(e,n),n),V,H,U,De=class{constructor(e){Te(this,V,{}),Te(this,H,new be(()=>new Set)),Te(this,U,new Set),Ce(this,`disposables`,E()),Ee(this,V,e),T.isServer&&this.disposables.microTask(()=>{this.dispose()})}dispose(){this.disposables.dispose()}get state(){return B(this,V)}subscribe(e,t){if(T.isServer)return()=>{};let n={selector:e,callback:t,current:e(B(this,V))};return B(this,U).add(n),this.disposables.add(()=>{B(this,U).delete(n)})}on(e,t){return T.isServer?()=>{}:(B(this,H).get(e).add(t),this.disposables.add(()=>{B(this,H).get(e).delete(t)}))}send(e){let t=this.reduce(B(this,V),e);if(t!==B(this,V)){Ee(this,V,t);for(let e of B(this,U)){let t=e.selector(B(this,V));Oe(e.current,t)||(e.current=t,e.callback(t))}for(let t of B(this,H).get(e.type))t(B(this,V),e)}}};V=new WeakMap,H=new WeakMap,U=new WeakMap;function Oe(e,t){return Object.is(e,t)?!0:typeof e!=`object`||!e||typeof t!=`object`||!t?!1:Array.isArray(e)&&Array.isArray(t)?e.length===t.length?ke(e[Symbol.iterator](),t[Symbol.iterator]()):!1:e instanceof Map&&t instanceof Map||e instanceof Set&&t instanceof Set?e.size===t.size?ke(e.entries(),t.entries()):!1:Ae(e)&&Ae(t)?ke(Object.entries(e)[Symbol.iterator](),Object.entries(t)[Symbol.iterator]()):!1}function ke(e,t){do{let n=e.next(),r=t.next();if(n.done&&r.done)return!0;if(n.done||r.done||!Object.is(n.value,r.value))return!1}while(!0)}function Ae(e){if(Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);return t===null||Object.getPrototypeOf(t)===null}var je=Object.defineProperty,Me=(e,t,n)=>t in e?je(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Ne=(e,t,n)=>(Me(e,typeof t==`symbol`?t:t+``,n),n),Pe=(e=>(e[e.Push=0]=`Push`,e[e.Pop=1]=`Pop`,e))(Pe||{}),Fe={0(e,t){let n=t.id,r=e.stack,i=e.stack.indexOf(n);if(i!==-1){let t=e.stack.slice();return t.splice(i,1),t.push(n),r=t,{...e,stack:r}}return{...e,stack:[...e.stack,n]}},1(e,t){let n=t.id,r=e.stack.indexOf(n);if(r===-1)return e;let i=e.stack.slice();return i.splice(r,1),{...e,stack:i}}},Ie=class e extends De{constructor(){super(...arguments),Ne(this,`actions`,{push:e=>this.send({type:0,id:e}),pop:e=>this.send({type:1,id:e})}),Ne(this,`selectors`,{isTop:(e,t)=>e.stack[e.stack.length-1]===t,inStack:(e,t)=>e.stack.includes(t)})}static new(){return new e({stack:[]})}reduce(e,t){return _(t.type,Fe,e,t)}},Le=new be(()=>Ie.new()),Re=a((e=>{var n=t();function r(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var i=typeof Object.is==`function`?Object.is:r,a=n.useSyncExternalStore,o=n.useRef,s=n.useEffect,c=n.useMemo,l=n.useDebugValue;e.useSyncExternalStoreWithSelector=function(e,t,n,r,u){var d=o(null);if(d.current===null){var f={hasValue:!1,value:null};d.current=f}else f=d.current;d=c(function(){function e(e){if(!a){if(a=!0,o=e,e=r(e),u!==void 0&&f.hasValue){var t=f.value;if(u(t,e))return s=t}return s=e}if(t=s,i(o,e))return t;var n=r(e);return u!==void 0&&u(t,n)?(o=e,t):(o=e,s=n)}var a=!1,o,s,c=n===void 0?null:n;return[function(){return e(t())},c===null?void 0:function(){return e(c())}]},[t,n,r,u]);var p=a(e,d[0],d[1]);return s(function(){f.hasValue=!0,f.value=p},[p]),l(p),p}})),ze=a(((e,t)=>{t.exports=Re()}))();function Be(e,t,n=Oe){return(0,ze.useSyncExternalStoreWithSelector)(h(t=>e.subscribe(Ve,t)),h(()=>e.state),h(()=>e.state),h(t),n)}function Ve(e){return e}function W(e,t){let n=(0,j.useId)(),r=Le.get(t),[i,a]=Be(r,(0,j.useCallback)(e=>[r.selectors.isTop(e,n),r.selectors.inStack(e,n)],[r,n]));return c(()=>{if(e)return r.actions.push(n),()=>r.actions.pop(n)},[r,e,n]),e?a?i:!0:!1}var He=new Map,G=new Map;function Ue(e){let t=G.get(e)??0;return G.set(e,t+1),t===0?(He.set(e,{"aria-hidden":e.getAttribute(`aria-hidden`),inert:e.inert}),e.setAttribute(`aria-hidden`,`true`),e.inert=!0,()=>We(e)):()=>We(e)}function We(e){let t=G.get(e)??1;if(t===1?G.delete(e):G.set(e,t-1),t!==1)return;let n=He.get(e);n&&(n[`aria-hidden`]===null?e.removeAttribute(`aria-hidden`):e.setAttribute(`aria-hidden`,n[`aria-hidden`]),e.inert=n.inert,He.delete(e))}function Ge(e,{allowed:t,disallowed:n}={}){let r=W(e,`inert-others`);c(()=>{if(!r)return;let e=E();for(let t of n?.()??[])t&&e.add(Ue(t));let i=t?.()??[];for(let t of i){if(!t)continue;let n=k(t);if(!n)continue;let r=t.parentElement;for(;r&&r!==n.body;){for(let t of r.children)i.some(e=>t.contains(e))||e.add(Ue(t));r=r.parentElement}}return e.dispose},[r,t,n])}function Ke(e,t,n){let r=m(e=>{let t=e.getBoundingClientRect();t.x===0&&t.y===0&&t.width===0&&t.height===0&&n()});(0,j.useEffect)(()=>{if(!e)return;let n=t===null?null:L(t)?t:t.current;if(!n)return;let i=E();if(typeof ResizeObserver<`u`){let e=new ResizeObserver(()=>r.current(n));e.observe(n),i.add(()=>e.disconnect())}if(typeof IntersectionObserver<`u`){let e=new IntersectionObserver(()=>r.current(n));e.observe(n),i.add(()=>e.disconnect())}return()=>i.dispose()},[t,r,e])}var K=[`[contentEditable=true]`,`[tabindex]`,`a[href]`,`area[href]`,`button:not([disabled])`,`iframe`,`input:not([disabled])`,`select:not([disabled])`,`details>summary`,`textarea:not([disabled])`].map(e=>`${e}:not([tabindex='-1'])`).join(`,`),qe=[`[data-autofocus]`].map(e=>`${e}:not([tabindex='-1'])`).join(`,`),q=(e=>(e[e.First=1]=`First`,e[e.Previous=2]=`Previous`,e[e.Next=4]=`Next`,e[e.Last=8]=`Last`,e[e.WrapAround=16]=`WrapAround`,e[e.NoScroll=32]=`NoScroll`,e[e.AutoFocus=64]=`AutoFocus`,e))(q||{}),Je=(e=>(e[e.Error=0]=`Error`,e[e.Overflow=1]=`Overflow`,e[e.Success=2]=`Success`,e[e.Underflow=3]=`Underflow`,e))(Je||{}),Ye=(e=>(e[e.Previous=-1]=`Previous`,e[e.Next=1]=`Next`,e))(Ye||{});function Xe(e=document.body){return e==null?[]:Array.from(e.querySelectorAll(K)).sort((e,t)=>Math.sign((e.tabIndex||2**53-1)-(t.tabIndex||2**53-1)))}function Ze(e=document.body){return e==null?[]:Array.from(e.querySelectorAll(qe)).sort((e,t)=>Math.sign((e.tabIndex||2**53-1)-(t.tabIndex||2**53-1)))}var Qe=(e=>(e[e.Strict=0]=`Strict`,e[e.Loose=1]=`Loose`,e))(Qe||{});function $e(e,t=0){return e===k(e)?.body?!1:_(t,{0(){return e.matches(K)},1(){let t=e;for(;t!==null;){if(t.matches(K))return!0;t=t.parentElement}return!1}})}var et=(e=>(e[e.Keyboard=0]=`Keyboard`,e[e.Mouse=1]=`Mouse`,e))(et||{});typeof window<`u`&&typeof document<`u`&&(document.addEventListener(`keydown`,e=>{e.metaKey||e.altKey||e.ctrlKey||(document.documentElement.dataset.headlessuiFocusVisible=``)},!0),document.addEventListener(`click`,e=>{e.detail===1?delete document.documentElement.dataset.headlessuiFocusVisible:e.detail===0&&(document.documentElement.dataset.headlessuiFocusVisible=``)},!0));function J(e){e?.focus({preventScroll:!0})}var tt=[`textarea`,`input`].join(`,`);function nt(e){return(e?.matches)?.call(e,tt)??!1}function rt(e,t=e=>e){return e.slice().sort((e,n)=>{let r=t(e),i=t(n);if(r===null||i===null)return 0;let a=r.compareDocumentPosition(i);return a&Node.DOCUMENT_POSITION_FOLLOWING?-1:a&Node.DOCUMENT_POSITION_PRECEDING?1:0})}function Y(e,t,{sorted:n=!0,relativeTo:r=null,skipElements:i=[]}={}){let a=Array.isArray(e)?e.length>0?A(e[0]):document:A(e),o=Array.isArray(e)?n?rt(e):e:t&64?Ze(e):Xe(e);i.length>0&&o.length>1&&(o=o.filter(e=>!i.some(t=>t!=null&&`current`in t?t?.current===e:t===e))),r??=a?.activeElement;let s=(()=>{if(t&5)return 1;if(t&10)return-1;throw Error(`Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last`)})(),c=(()=>{if(t&1)return 0;if(t&2)return Math.max(0,o.indexOf(r))-1;if(t&4)return Math.max(0,o.indexOf(r))+1;if(t&8)return o.length-1;throw Error(`Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last`)})(),l=t&32?{preventScroll:!0}:{},u=0,d=o.length,f;do{if(u>=d||u+d<=0)return 0;let e=c+u;if(t&16)e=(e+d)%d;else{if(e<0)return 3;if(e>=d)return 1}f=o[e],f?.focus(l),u+=s}while(f!==ne(f));return t&6&&nt(f)&&f.select(),2}function it(){return/iPhone/gi.test(window.navigator.platform)||/Mac/gi.test(window.navigator.platform)&&window.navigator.maxTouchPoints>0}function at(){return/Android/gi.test(window.navigator.userAgent)}function ot(){return it()||at()}function st(e,t,n,r){let i=m(n);(0,j.useEffect)(()=>{if(!e)return;function n(e){i.current(e)}return document.addEventListener(t,n,r),()=>document.removeEventListener(t,n,r)},[e,t,r])}function ct(e,t,n,r){let i=m(n);(0,j.useEffect)(()=>{if(!e)return;function n(e){i.current(e)}return window.addEventListener(t,n,r),()=>window.removeEventListener(t,n,r)},[e,t,r])}var lt=30;function ut(e,t,n){let r=m(n),i=(0,j.useCallback)(function(e,n){if(e.defaultPrevented)return;let i=n(e);if(i===null||!i.getRootNode().contains(i)||!i.isConnected)return;let a=function e(t){return typeof t==`function`?e(t()):Array.isArray(t)||t instanceof Set?t:[t]}(t);for(let t of a)if(t!==null&&(t.contains(i)||e.composed&&e.composedPath().includes(t)))return;return!$e(i,Qe.Loose)&&i.tabIndex!==-1&&e.preventDefault(),r.current(e,i)},[r,t]),a=(0,j.useRef)(null);st(e,`pointerdown`,e=>{ot()||(a.current=e.composedPath?.call(e)?.[0]||e.target)},!0),st(e,`pointerup`,e=>{if(ot()||!a.current)return;let t=a.current;return a.current=null,i(e,()=>t)},!0);let o=(0,j.useRef)({x:0,y:0});st(e,`touchstart`,e=>{o.current.x=e.touches[0].clientX,o.current.y=e.touches[0].clientY},!0),st(e,`touchend`,e=>{let t={x:e.changedTouches[0].clientX,y:e.changedTouches[0].clientY};if(!(Math.abs(t.x-o.current.x)>=lt||Math.abs(t.y-o.current.y)>=lt))return i(e,()=>R(e.target)?e.target:null)},!0),ct(e,`blur`,e=>i(e,()=>ce(window.document.activeElement)?window.document.activeElement:null),!0)}function dt(...e){return(0,j.useMemo)(()=>k(...e),[...e])}function ft(e,t,n,r){let i=m(n);(0,j.useEffect)(()=>{e??=window;function n(e){i.current(e)}return e.addEventListener(t,n,r),()=>e.removeEventListener(t,n,r)},[e,t,r])}function pt(e){return(0,j.useSyncExternalStore)(e.subscribe,e.getSnapshot,e.getSnapshot)}function mt(e,t){let n=e(),r=new Set;return{getSnapshot(){return n},subscribe(e){return r.add(e),()=>r.delete(e)},dispatch(e,...i){let a=t[e].call(n,...i);a&&(n=a,r.forEach(e=>e()))}}}function ht(){let e;return{before({doc:t}){let n=t.documentElement,r=t.defaultView??window;e=Math.max(0,r.innerWidth-n.clientWidth)},after({doc:t,d:n}){let r=t.documentElement,i=Math.max(0,r.clientWidth-r.offsetWidth),a=Math.max(0,e-i);n.style(r,`paddingRight`,`${a}px`)}}}function gt(){return it()?{before({doc:e,d:t,meta:n}){function r(e){for(let t of n().containers)for(let n of t())if(n.contains(e))return!0;return!1}t.microTask(()=>{if(window.getComputedStyle(e.documentElement).scrollBehavior!==`auto`){let n=E();n.style(e.documentElement,`scrollBehavior`,`auto`),t.add(()=>t.microTask(()=>n.dispose()))}let n=window.scrollY??window.pageYOffset,i=null;t.addEventListener(e,`click`,t=>{if(R(t.target))try{let n=t.target.closest(`a`);if(!n)return;let{hash:a}=new URL(n.href),o=e.querySelector(a);R(o)&&!r(o)&&(i=o)}catch{}},!0),t.group(n=>{t.addEventListener(e,`touchstart`,e=>{if(n.dispose(),R(e.target)&&z(e.target))if(r(e.target)){let t=e.target;for(;t.parentElement&&r(t.parentElement);)t=t.parentElement;n.style(t,`overscrollBehavior`,`contain`)}else n.style(e.target,`touchAction`,`none`)})}),t.addEventListener(e,`touchmove`,e=>{if(R(e.target)){if(le(e.target))return;if(r(e.target)){let t=e.target;for(;t.parentElement&&t.dataset.headlessuiPortal!==``&&!(t.scrollHeight>t.clientHeight||t.scrollWidth>t.clientWidth);)t=t.parentElement;t.dataset.headlessuiPortal===``&&e.preventDefault()}else e.preventDefault()}},{passive:!1}),t.add(()=>{n!==(window.scrollY??window.pageYOffset)&&window.scrollTo(0,n),i&&i.isConnected&&(i.scrollIntoView({block:`nearest`}),i=null)})})}}:{}}function _t(){return{before({doc:e,d:t}){t.style(e.documentElement,`overflow`,`hidden`)}}}function vt(e){let t={};for(let n of e)Object.assign(t,n(t));return t}var X=mt(()=>new Map,{PUSH(e,t){let n=this.get(e)??{doc:e,count:0,d:E(),meta:new Set,computedMeta:{}};return n.count++,n.meta.add(t),n.computedMeta=vt(n.meta),this.set(e,n),this},POP(e,t){let n=this.get(e);return n&&(n.count--,n.meta.delete(t),n.computedMeta=vt(n.meta)),this},SCROLL_PREVENT(e){let t={doc:e.doc,d:e.d,meta(){return e.computedMeta}},n=[gt(),ht(),_t()];n.forEach(({before:e})=>e?.(t)),n.forEach(({after:e})=>e?.(t))},SCROLL_ALLOW({d:e}){e.dispose()},TEARDOWN({doc:e}){this.delete(e)}});X.subscribe(()=>{let e=X.getSnapshot(),t=new Map;for(let[n]of e)t.set(n,n.documentElement.style.overflow);for(let n of e.values()){let e=t.get(n.doc)===`hidden`,r=n.count!==0;(r&&!e||!r&&e)&&X.dispatch(n.count>0?`SCROLL_PREVENT`:`SCROLL_ALLOW`,n),n.count===0&&X.dispatch(`TEARDOWN`,n)}});function yt(e,t,n=()=>({containers:[]})){let r=pt(X),i=t?r.get(t):void 0,a=i?i.count>0:!1;return c(()=>{if(!(!t||!e))return X.dispatch(`PUSH`,t,n),()=>X.dispatch(`POP`,t,n)},[e,t]),a}function bt(e,t,n=()=>[document.body]){yt(W(e,`scroll-lock`),t,e=>({containers:[...e.containers??[],n]}))}function xt(e,t){let n=(0,j.useRef)([]),r=h(e);(0,j.useEffect)(()=>{let e=[...n.current];for(let[i,a]of t.entries())if(n.current[i]!==a){let i=r(t,e);return n.current=t,i}},[r,...t])}function St(e){function t(){document.readyState!==`loading`&&(e(),document.removeEventListener(`DOMContentLoaded`,t))}typeof window<`u`&&typeof document<`u`&&(document.addEventListener(`DOMContentLoaded`,t),t())}var Z=[];St(()=>{function e(e){if(!R(e.target)||e.target===document.body||Z[0]===e.target)return;let t=e.target;t=t.closest(K),Z.unshift(t??e.target),Z=Z.filter(e=>e!=null&&e.isConnected),Z.splice(10)}window.addEventListener(`click`,e,{capture:!0}),window.addEventListener(`mousedown`,e,{capture:!0}),window.addEventListener(`focus`,e,{capture:!0}),document.body.addEventListener(`click`,e,{capture:!0}),document.body.addEventListener(`mousedown`,e,{capture:!0}),document.body.addEventListener(`focus`,e,{capture:!0})});function Ct(e){let t=h(e),n=(0,j.useRef)(!1);(0,j.useEffect)(()=>(n.current=!1,()=>{n.current=!0,u(()=>{n.current&&t()})}),[t])}var wt=(0,j.createContext)(!1);function Tt(){return(0,j.useContext)(wt)}function Et(e){return j.createElement(wt.Provider,{value:e.force},e.children)}var Dt=n(r(),1);function Ot(e){let t=Tt(),n=(0,j.useContext)(Nt),[r,i]=(0,j.useState)(()=>{if(!t&&n!==null)return n.current??null;if(T.isServer)return null;let r=e?.getElementById(`headlessui-portal-root`);if(r)return r;if(e===null)return null;let i=e.createElement(`div`);return i.setAttribute(`id`,`headlessui-portal-root`),e.body.appendChild(i)});return(0,j.useEffect)(()=>{r!==null&&(e!=null&&e.body.contains(r)||e==null||e.body.appendChild(r))},[r,e]),(0,j.useEffect)(()=>{t||n!==null&&i(n.current)},[n,i,t]),r}var kt=j.Fragment,At=b(function(e,t){let{ownerDocument:n=null,...r}=e,i=(0,j.useRef)(null),a=C(ee(e=>{i.current=e}),t),o=dt(i.current),s=Ot(n??o),c=(0,j.useContext)(Ft),u=w(),d=l(),f=p();return Ct(()=>{var e;s&&s.childNodes.length<=0&&((e=s.parentElement)==null||e.removeChild(s))}),!s||!d?null:(0,Dt.createPortal)(j.createElement(`div`,{"data-headlessui-portal":``,ref:e=>{u.dispose(),c&&e&&u.add(c.register(e))}},f({ourProps:{ref:a},theirProps:r,slot:{},defaultTag:kt,name:`Portal`})),s)});function jt(e,t){let n=C(t),{enabled:r=!0,ownerDocument:i,...a}=e,o=p();return r?j.createElement(At,{...a,ownerDocument:i,ref:n}):o({ourProps:{ref:n},theirProps:a,slot:{},defaultTag:kt,name:`Portal`})}var Mt=j.Fragment,Nt=(0,j.createContext)(null);function Pt(e,t){let{target:n,...r}=e,i={ref:C(t)},a=p();return j.createElement(Nt.Provider,{value:n},a({ourProps:i,theirProps:r,defaultTag:Mt,name:`Popover.Group`}))}var Ft=(0,j.createContext)(null);function It(){let e=(0,j.useContext)(Ft),t=(0,j.useRef)([]),n=h(n=>(t.current.push(n),e&&e.register(n),()=>r(n))),r=h(n=>{let r=t.current.indexOf(n);r!==-1&&t.current.splice(r,1),e&&e.unregister(n)}),i=(0,j.useMemo)(()=>({register:n,unregister:r,portals:t}),[n,r,t]);return[t,(0,j.useMemo)(()=>function({children:e}){return j.createElement(Ft.Provider,{value:i},e)},[i])]}var Lt=b(jt),Rt=b(Pt),zt=Object.assign(Lt,{Group:Rt});function Bt(e,t=typeof document<`u`?document.defaultView:null,n){let r=W(e,`escape`);ft(t,`keydown`,e=>{r&&(e.defaultPrevented||e.key===_e.Escape&&n(e))})}function Vt(){let[e]=(0,j.useState)(()=>typeof window<`u`&&typeof window.matchMedia==`function`?window.matchMedia(`(pointer: coarse)`):null),[t,n]=(0,j.useState)(e?.matches??!1);return c(()=>{if(!e)return;function t(e){n(e.matches)}return e.addEventListener(`change`,t),()=>e.removeEventListener(`change`,t)},[e]),t}function Ht({defaultContainers:e=[],portals:t,mainTreeNode:n}={}){let r=h(()=>{let r=k(n),i=[];for(let t of e)t!==null&&(I(t)?i.push(t):`current`in t&&I(t.current)&&i.push(t.current));if(t!=null&&t.current)for(let e of t.current)i.push(e);for(let e of r?.querySelectorAll(`html > *, body > *`)??[])e!==document.body&&e!==document.head&&I(e)&&e.id!==`headlessui-portal-root`&&(n&&(e.contains(n)||e.contains(n?.getRootNode()?.host))||i.some(t=>e.contains(t))||i.push(e));return i});return{resolveContainers:r,contains:h(e=>r().some(t=>t.contains(e)))}}var Ut=(0,j.createContext)(null);function Wt({children:e,node:t}){let[n,r]=(0,j.useState)(null),i=Gt(t??n);return j.createElement(Ut.Provider,{value:i},e,i===null&&j.createElement(oe,{features:F.Hidden,ref:e=>{if(e){for(let t of k(e)?.querySelectorAll(`html > *, body > *`)??[])if(t!==document.body&&t!==document.head&&I(t)&&t!=null&&t.contains(e)){r(t);break}}}}))}function Gt(e=null){return(0,j.useContext)(Ut)??e}var Q=(e=>(e[e.Forwards=0]=`Forwards`,e[e.Backwards=1]=`Backwards`,e))(Q||{});function Kt(){let e=(0,j.useRef)(0);return ct(!0,`keydown`,t=>{t.key===`Tab`&&(e.current=+!!t.shiftKey)},!0),e}function qt(e){if(!e)return new Set;if(typeof e==`function`)return new Set(e());let t=new Set;for(let n of e.current)I(n.current)&&t.add(n.current);return t}var Jt=`div`,$=(e=>(e[e.None=0]=`None`,e[e.InitialFocus=1]=`InitialFocus`,e[e.TabLock=2]=`TabLock`,e[e.FocusLock=4]=`FocusLock`,e[e.RestoreFocus=8]=`RestoreFocus`,e[e.AutoFocus=16]=`AutoFocus`,e))($||{});function Yt(e,t){let n=(0,j.useRef)(null),r=C(n,t),{initialFocus:i,initialFocusFallback:a,containers:o,features:s=15,...c}=e;l()||(s=0);let u=dt(n.current);$t(s,{ownerDocument:u});let d=en(s,{ownerDocument:u,container:n,initialFocus:i,initialFocusFallback:a});tn(s,{ownerDocument:u,container:n,containers:o,previousActiveElement:d});let f=Kt(),m=h(e=>{if(!L(n.current))return;let t=n.current;(e=>e())(()=>{_(f.current,{[Q.Forwards]:()=>{Y(t,q.First,{skipElements:[e.relatedTarget,a]})},[Q.Backwards]:()=>{Y(t,q.Last,{skipElements:[e.relatedTarget,a]})}})})}),g=W(!!(s&2),`focus-trap#tab-lock`),ee=w(),v=(0,j.useRef)(!1),y={ref:r,onKeyDown(e){e.key==`Tab`&&(v.current=!0,ee.requestAnimationFrame(()=>{v.current=!1}))},onBlur(e){if(!(s&4))return;let t=qt(o);L(n.current)&&t.add(n.current);let r=e.relatedTarget;R(r)&&r.dataset.headlessuiFocusGuard!==`true`&&(nn(t,r)||(v.current?Y(n.current,_(f.current,{[Q.Forwards]:()=>q.Next,[Q.Backwards]:()=>q.Previous})|q.WrapAround,{relativeTo:e.target}):R(e.target)&&J(e.target)))}},b=p();return j.createElement(j.Fragment,null,g&&j.createElement(oe,{as:`button`,type:`button`,"data-headlessui-focus-guard":!0,onFocus:m,features:F.Focusable}),b({ourProps:y,theirProps:c,defaultTag:Jt,name:`FocusTrap`}),g&&j.createElement(oe,{as:`button`,type:`button`,"data-headlessui-focus-guard":!0,onFocus:m,features:F.Focusable}))}var Xt=b(Yt),Zt=Object.assign(Xt,{features:$});function Qt(e=!0){let t=(0,j.useRef)(Z.slice());return xt(([e],[n])=>{n===!0&&e===!1&&u(()=>{t.current.splice(0)}),n===!1&&e===!0&&(t.current=Z.slice())},[e,Z,t]),h(()=>t.current.find(e=>e!=null&&e.isConnected)??null)}function $t(e,{ownerDocument:t}){let n=!!(e&8),r=Qt(n);xt(()=>{n||re(t?.body)&&J(r())},[n]),Ct(()=>{n&&J(r())})}function en(e,{ownerDocument:t,container:n,initialFocus:r,initialFocusFallback:i}){let a=(0,j.useRef)(null),o=W(!!(e&1),`focus-trap#initial-focus`),s=g();return xt(()=>{if(e===0)return;if(!o){i!=null&&i.current&&J(i.current);return}let c=n.current;c&&u(()=>{if(!s.current)return;let n=t?.activeElement;if(r!=null&&r.current){if(r?.current===n){a.current=n;return}}else if(c.contains(n)){a.current=n;return}if(r!=null&&r.current)J(r.current);else{if(e&16){if(Y(c,q.First|q.AutoFocus)!==Je.Error)return}else if(Y(c,q.First)!==Je.Error)return;if(i!=null&&i.current&&(J(i.current),t?.activeElement===i.current))return;console.warn(`There are no focusable elements inside the `)}a.current=t?.activeElement})},[i,o,e]),a}function tn(e,{ownerDocument:t,container:n,containers:r,previousActiveElement:i}){let a=g(),o=!!(e&4);ft(t?.defaultView,`focus`,e=>{if(!o||!a.current)return;let t=qt(r);L(n.current)&&t.add(n.current);let s=i.current;if(!s)return;let c=e.target;L(c)?nn(t,c)?(i.current=c,J(c)):(e.preventDefault(),e.stopPropagation(),J(s)):J(i.current)},!0)}function nn(e,t){for(let n of e)if(n.contains(t))return!0;return!1}var rn=(e=>(e[e.Open=0]=`Open`,e[e.Closed=1]=`Closed`,e))(rn||{}),an=(e=>(e[e.SetTitleId=0]=`SetTitleId`,e))(an||{}),on={0(e,t){return e.titleId===t.id?e:{...e,titleId:t.id}}},sn=(0,j.createContext)(null);sn.displayName=`DialogContext`;function cn(e){let t=(0,j.useContext)(sn);if(t===null){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,cn),t}return t}function ln(e,t){return _(t.type,on,e,t)}var un=b(function(e,t){let n=(0,j.useId)(),{id:r=`headlessui-dialog-${n}`,open:i,onClose:a,initialFocus:o,role:s=`dialog`,autoFocus:u=!0,__demoMode:f=!1,unmount:m=!1,...g}=e,ee=(0,j.useRef)(!1);s=function(){return s===`dialog`||s===`alertdialog`?s:(ee.current||(ee.current=!0,console.warn(`Invalid role [${s}] passed to . Only \`dialog\` and and \`alertdialog\` are supported. Using \`dialog\` instead.`)),`dialog`)}();let _=d();i===void 0&&_!==null&&(i=(_&y.Open)===y.Open);let v=(0,j.useRef)(null),b=C(v,t),x=dt(v.current),S=+!i,[w,T]=(0,j.useReducer)(ln,{titleId:null,descriptionId:null,panelRef:(0,j.createRef)()}),E=h(()=>a(!1)),D=h(e=>T({type:0,id:e})),O=l()?S===0:!1,[k,A]=It(),ne={get current(){return w.panelRef.current??v.current}},re=Gt(),{resolveContainers:N}=Ht({mainTreeNode:re,portals:k,defaultContainers:[ne]}),ie=_===null?!1:(_&y.Closing)===y.Closing;Ge(f||ie?!1:O,{allowed:h(()=>[v.current?.closest(`[data-headlessui-portal]`)??null]),disallowed:h(()=>[re?.closest(`body > *:not(#headlessui-portal-root)`)??null])});let P=Le.get(null);c(()=>{if(O)return P.actions.push(r),()=>P.actions.pop(r)},[P,r,O]);let F=Be(P,(0,j.useCallback)(e=>P.selectors.isTop(e,r),[P,r]));ut(F,N,e=>{e.preventDefault(),E()}),Bt(F,x?.defaultView,e=>{e.preventDefault(),e.stopPropagation(),document.activeElement&&`blur`in document.activeElement&&typeof document.activeElement.blur==`function`&&document.activeElement.blur(),E()}),bt(f||ie?!1:O,x,N),Ke(O,v,E);let[ae,oe]=fe(),se=(0,j.useMemo)(()=>[{dialogState:S,close:E,setTitleId:D,unmount:m},w],[S,E,D,m,w]),I=M({open:S===0}),L={ref:b,id:r,role:s,tabIndex:-1,"aria-modal":f?void 0:S===0?!0:void 0,"aria-labelledby":w.titleId,"aria-describedby":ae,unmount:m},R=!Vt(),z=$.None;O&&!f&&(z|=$.RestoreFocus,z|=$.TabLock,u&&(z|=$.AutoFocus),R&&(z|=$.InitialFocus));let ce=p();return j.createElement(te,null,j.createElement(Et,{force:!0},j.createElement(zt,null,j.createElement(sn.Provider,{value:se},j.createElement(Rt,{target:v},j.createElement(Et,{force:!1},j.createElement(oe,{slot:I},j.createElement(A,null,j.createElement(Zt,{initialFocus:o,initialFocusFallback:v,containers:N,features:z},j.createElement(ye,{value:E},ce({ourProps:L,theirProps:g,slot:I,defaultTag:dn,features:fn,visible:S===0,name:`Dialog`})))))))))))}),dn=`div`,fn=f.RenderStrategy|f.Static;function pn(e,t){let{transition:n=!1,open:r,...i}=e,a=d(),o=e.hasOwnProperty(`open`)||a!==null,s=e.hasOwnProperty(`onClose`);if(!o&&!s)throw Error("You have to provide an `open` and an `onClose` prop to the `Dialog` component.");if(!o)throw Error("You provided an `onClose` prop to the `Dialog`, but forgot an `open` prop.");if(!s)throw Error("You provided an `open` prop to the `Dialog`, but forgot an `onClose` prop.");if(!a&&typeof e.open!=`boolean`)throw Error(`You provided an \`open\` prop to the \`Dialog\`, but the value is not a boolean. Received: ${e.open}`);if(typeof e.onClose!=`function`)throw Error(`You provided an \`onClose\` prop to the \`Dialog\`, but the value is not a function. Received: ${e.onClose}`);return(r!==void 0||n)&&!i.static?j.createElement(Wt,null,j.createElement(v,{show:r,transition:n,unmount:i.unmount},j.createElement(un,{ref:t,...i}))):j.createElement(Wt,null,j.createElement(un,{ref:t,open:r,...i}))}var mn=`div`;function hn(e,t){let n=(0,j.useId)(),{id:r=`headlessui-dialog-panel-${n}`,transition:i=!1,...a}=e,[{dialogState:o,unmount:s},c]=cn(`Dialog.Panel`),l=C(t,c.panelRef),u=M({open:o===0}),d={ref:l,id:r,onClick:h(e=>{e.stopPropagation()})},f=i?x:j.Fragment,m=i?{unmount:s}:{},g=p();return j.createElement(f,{...m},g({ourProps:d,theirProps:a,slot:u,defaultTag:mn,name:`Dialog.Panel`}))}var gn=`div`;function _n(e,t){let{transition:n=!1,...r}=e,[{dialogState:i,unmount:a}]=cn(`Dialog.Backdrop`),o=M({open:i===0}),s={ref:t,"aria-hidden":!0},c=n?x:j.Fragment,l=n?{unmount:a}:{},u=p();return j.createElement(c,{...l},u({ourProps:s,theirProps:r,slot:o,defaultTag:gn,name:`Dialog.Backdrop`}))}var vn=`h2`;function yn(e,t){let n=(0,j.useId)(),{id:r=`headlessui-dialog-title-${n}`,...i}=e,[{dialogState:a,setTitleId:o}]=cn(`Dialog.Title`),s=C(t);(0,j.useEffect)(()=>(o(r),()=>o(null)),[r,o]);let c=M({open:a===0}),l={ref:s,id:r};return p()({ourProps:l,theirProps:i,slot:c,defaultTag:vn,name:`Dialog.Title`})}var bn=b(pn),xn=b(hn);b(_n);var Sn=b(yn),Cn=Object.assign(bn,{Panel:xn,Title:Sn,Description:ge});function wn({children:e,show:t=!1,maxWidth:n=`2xl`,closeable:r=!0,onClose:i=()=>{}}){let a=()=>{r&&i()},o={sm:`sm:max-w-sm`,md:`sm:max-w-md`,lg:`sm:max-w-lg`,xl:`sm:max-w-xl`,"2xl":`sm:max-w-2xl`}[n];return(0,D.jsx)(v,{show:t,leave:`duration-200`,children:(0,D.jsxs)(Cn,{as:`div`,id:`modal`,className:`fixed inset-0 z-50 flex transform items-center overflow-y-auto px-4 py-6 transition-all sm:px-0`,onClose:a,children:[(0,D.jsx)(x,{enter:`ease-out duration-300`,enterFrom:`opacity-0`,enterTo:`opacity-100`,leave:`ease-in duration-200`,leaveFrom:`opacity-100`,leaveTo:`opacity-0`,children:(0,D.jsx)(`div`,{className:`absolute inset-0 bg-gray-500/75`})}),(0,D.jsx)(x,{enter:`ease-out duration-300`,enterFrom:`opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95`,enterTo:`opacity-100 translate-y-0 sm:scale-100`,leave:`ease-in duration-200`,leaveFrom:`opacity-100 translate-y-0 sm:scale-100`,leaveTo:`opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95`,children:(0,D.jsx)(xn,{className:`mb-6 transform overflow-hidden rounded-lg bg-white shadow-xl transition-all sm:mx-auto sm:w-full ${o}`,children:e})})]})})}function Tn({type:e=`button`,className:t=``,disabled:n,children:r,...i}){return(0,D.jsx)(`button`,{...i,type:e,className:`inline-flex items-center rounded-xl border border-gray-200 bg-white px-4 py-2 text-sm font-bold tracking-tight text-[#3D4E4B] transition-all hover:bg-gray-50 hover:border-gray-300 focus:outline-none focus:ring-2 focus:ring-[#D4A017] focus:ring-offset-2 disabled:opacity-25 ${n&&`opacity-25`} `+t,disabled:n,children:r})}function En({className:t=``}){let[n,r]=(0,j.useState)(!1),i=(0,j.useRef)(),{data:a,setData:c,delete:l,processing:u,reset:d,errors:f,clearErrors:p}=e({password:``}),m=()=>{r(!0)},h=e=>{e.preventDefault(),l(route(`profile.destroy`),{preserveScroll:!0,onSuccess:()=>g(),onError:()=>i.current.focus(),onFinish:()=>d()})},g=()=>{r(!1),p(),d()};return(0,D.jsxs)(`section`,{className:`space-y-6 ${t}`,children:[(0,D.jsxs)(`header`,{children:[(0,D.jsx)(`h2`,{className:`text-lg font-medium text-gray-900`,children:`Delete Account`}),(0,D.jsx)(`p`,{className:`mt-1 text-sm text-gray-600`,children:`Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.`})]}),(0,D.jsx)(O,{onClick:m,children:`Delete Account`}),(0,D.jsx)(wn,{show:n,onClose:g,children:(0,D.jsxs)(`form`,{onSubmit:h,className:`p-6`,children:[(0,D.jsx)(`h2`,{className:`text-lg font-medium text-gray-900`,children:`Are you sure you want to delete your account?`}),(0,D.jsx)(`p`,{className:`mt-1 text-sm text-gray-600`,children:`Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.`}),(0,D.jsxs)(`div`,{className:`mt-6`,children:[(0,D.jsx)(s,{htmlFor:`password`,value:`Password`,className:`sr-only`}),(0,D.jsx)(S,{id:`password`,type:`password`,name:`password`,ref:i,value:a.password,onChange:e=>c(`password`,e.target.value),className:`mt-1 block w-3/4`,isFocused:!0,placeholder:`Password`}),(0,D.jsx)(o,{message:f.password,className:`mt-2`})]}),(0,D.jsxs)(`div`,{className:`mt-6 flex justify-end`,children:[(0,D.jsx)(Tn,{onClick:g,children:`Cancel`}),(0,D.jsx)(O,{className:`ms-3`,disabled:u,children:`Delete Account`})]})]})})]})}export{En as default}; \ No newline at end of file diff --git a/public/build/assets/Edit-BCh5fCTK.js b/public/build/assets/Edit-BCh5fCTK.js new file mode 100644 index 0000000..7edf1c0 --- /dev/null +++ b/public/build/assets/Edit-BCh5fCTK.js @@ -0,0 +1,2 @@ +import{a as e,c as t,d as n,i as r,n as i,o as a,t as o}from"./app-BJ7g6sa8.js";import{t as s}from"./AuthenticatedLayout-CrB9BCoI.js";import{t as c}from"./swal-DZXjpqDE.js";import{n as l,r as u,t as d}from"./filepond-plugin-file-validate-type-CBUe71W_.js";var f=n(t(),1),p=u(),m=n(l(),1),h=n(d(),1),g=o();(0,p.registerPlugin)(m.default,h.default);function _({title:e,description:t,children:n,delay:r=`0s`}){return(0,g.jsxs)(`div`,{className:`bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden h-full flex flex-col anim-up`,style:{animationDelay:r},children:[(0,g.jsxs)(`div`,{className:`px-6 py-4 border-b border-gray-50 bg-gray-50/30`,children:[(0,g.jsx)(`h2`,{className:`text-sm font-bold text-[#3D4E4B] tracking-tight`,children:e}),(0,g.jsx)(`p`,{className:`text-xs text-gray-400 font-semibold tracking-tight mt-1`,children:t})]}),(0,g.jsx)(`div`,{className:`p-6 flex-1`,children:n})]})}function v({label:e,id:t,type:n=`text`,value:r,onChange:i,error:a,placeholder:o,required:s=!1,...c}){return(0,g.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,g.jsxs)(`label`,{htmlFor:t,className:`block text-xs font-bold text-gray-400 tracking-tight ml-1`,children:[e,` `,s&&(0,g.jsx)(`span`,{className:`text-red-500`,children:`*`})]}),(0,g.jsx)(`input`,{id:t,type:n,value:r,onChange:i,placeholder:o,className:`w-full px-4 py-2.5 rounded-xl border text-sm font-bold transition-all outline-none + ${a?`border-red-300 bg-red-50`:`border-gray-100 bg-gray-50/30 focus:border-[#D4A017] focus:bg-white`}`,...c}),a&&(0,g.jsx)(`p`,{className:`text-sm text-red-500 font-bold ml-1`,children:a})]})}function y({mustVerifyEmail:t,status:n}){let{auth:o}=a().props,{user:l}=o,[u,d]=(0,f.useState)([]),m=e({first_name:l.first_name||``,last_name:l.last_name||``,email:l.email||``,phone:l.phone||``,bio:l.bio||``,avatar_file:null,_method:`PATCH`}),h=e({current_password:``,password:``,password_confirmation:``}),y=e=>{e.preventDefault(),m.post(route(`profile.update`),{preserveScroll:!0,onSuccess:()=>c.success(`Success`,`Profile identity synchronized.`)})},b=e=>{e.preventDefault(),h.put(route(`password.update`),{preserveScroll:!0,onSuccess:()=>{h.reset(),c.success(`Success`,`Security token updated.`)}})},x=`${l.first_name?.charAt(0)||``}${l.last_name?.charAt(0)||``}`.toUpperCase();return(0,g.jsxs)(s,{children:[(0,g.jsx)(i,{title:`Account Settings`}),(0,g.jsxs)(`div`,{className:`mb-6 anim-down`,children:[(0,g.jsx)(`h1`,{className:`text-lg font-bold text-[#3D4E4B] dark:text-white tracking-tight leading-none`,children:`Account Settings`}),(0,g.jsx)(`p`,{className:`text-xs font-semibold text-gray-400 tracking-tight mt-2`,children:`Personal Identity & Security Governance`})]}),(0,g.jsxs)(`div`,{className:`w-full grid grid-cols-1 lg:grid-cols-2 gap-6 pb-20`,children:[(0,g.jsx)(`div`,{className:`space-y-6`,children:(0,g.jsx)(_,{title:`Identity Configuration`,description:`Manage your personal credentials`,delay:`0s`,children:(0,g.jsxs)(`form`,{onSubmit:y,className:`space-y-6`,children:[(0,g.jsxs)(`div`,{className:`flex flex-col sm:flex-row items-center gap-6 mb-4`,children:[(0,g.jsx)(`div`,{className:`w-24 h-24 rounded-2xl flex items-center justify-center text-white text-3xl font-bold shrink-0 border border-gray-100 dark:border-white/5 ${l.avatar_url?`bg-white dark:bg-white/5`:`bg-[#3D4E4B]`}`,children:l.avatar_url?(0,g.jsx)(`img`,{src:l.avatar_url,className:`w-full h-full object-cover rounded-2xl`}):x}),(0,g.jsxs)(`div`,{className:`flex-1 w-full`,children:[(0,g.jsx)(`label`,{className:`text-[10px] font-black text-gray-400 uppercase tracking-widest mb-2 block`,children:`Identity Portrait`}),(0,g.jsx)(p.FilePond,{files:u,onupdatefiles:e=>{d(e),m.setData(`avatar_file`,e[0]?.file||null)},allowMultiple:!1,maxFiles:1,labelIdle:`Portrait update`})]})]}),(0,g.jsxs)(`div`,{className:`grid grid-cols-2 gap-4`,children:[(0,g.jsx)(v,{label:`First Designation`,id:`first_name`,value:m.data.first_name,onChange:e=>m.setData(`first_name`,e.target.value),error:m.errors.first_name,required:!0,placeholder:`e.g. Alex`}),(0,g.jsx)(v,{label:`Last Designation`,id:`last_name`,value:m.data.last_name,onChange:e=>m.setData(`last_name`,e.target.value),error:m.errors.last_name,required:!0,placeholder:`e.g. Johnson`})]}),(0,g.jsxs)(`div`,{className:`grid grid-cols-2 gap-4`,children:[(0,g.jsx)(v,{label:`Communication Channel (Email)`,id:`email`,type:`email`,value:m.data.email,onChange:e=>m.setData(`email`,e.target.value),error:m.errors.email,required:!0,placeholder:`alex@company.com`}),(0,g.jsx)(v,{label:`Contact Number (Phone)`,id:`phone`,type:`tel`,value:m.data.phone,onChange:e=>m.setData(`phone`,e.target.value),error:m.errors.phone,placeholder:`+62...`})]}),(0,g.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,g.jsx)(`label`,{className:`block text-[10px] font-black text-gray-400 uppercase tracking-widest ml-1`,children:`Professional Bio`}),(0,g.jsx)(`textarea`,{value:m.data.bio,onChange:e=>m.setData(`bio`,e.target.value),rows:4,className:`input-field py-3 resize-none`,placeholder:`Tell us about yourself...`})]}),(0,g.jsx)(`div`,{className:`flex justify-end pt-2`,children:(0,g.jsx)(`button`,{type:`submit`,disabled:m.processing,className:`px-8 py-3 bg-[#3D4E4B] text-white text-sm font-bold tracking-tight rounded-xl hover:bg-[#2D3A38] transition-all shadow-lg shadow-[#3D4E4B]/20`,children:m.processing?`Synchronizing...`:`Update Identity`})})]})})}),(0,g.jsxs)(`div`,{className:`space-y-6 flex flex-col`,children:[(0,g.jsx)(_,{title:`Security Protocols`,description:`Authentication & Token Lifecycle`,delay:`0.1s`,children:(0,g.jsxs)(`form`,{onSubmit:b,className:`space-y-4`,children:[(0,g.jsx)(v,{label:`Current Security Token`,id:`current_password`,type:`password`,value:h.data.current_password,onChange:e=>h.setData(`current_password`,e.target.value),error:h.errors.current_password,required:!0,placeholder:`••••••••`}),(0,g.jsx)(v,{label:`New Security Token`,id:`password`,type:`password`,value:h.data.password,onChange:e=>h.setData(`password`,e.target.value),error:h.errors.password,required:!0,placeholder:`••••••••`}),(0,g.jsx)(v,{label:`Verify Token`,id:`password_confirmation`,type:`password`,value:h.data.password_confirmation,onChange:e=>h.setData(`password_confirmation`,e.target.value),error:h.errors.password_confirmation,required:!0,placeholder:`••••••••`}),(0,g.jsx)(`div`,{className:`pt-4`,children:(0,g.jsx)(`button`,{type:`submit`,disabled:h.processing,className:`w-full py-3 bg-[#D4A017] text-white text-sm font-bold tracking-tight rounded-xl hover:bg-[#B88B14] transition-all`,children:h.processing?`...`:`Rotate Security Tokens`})})]})}),(0,g.jsxs)(`div`,{className:`bg-white rounded-2xl border border-red-100 p-6 shadow-sm anim-up`,style:{animationDelay:`0.2s`},children:[(0,g.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,g.jsx)(`h3`,{className:`text-sm font-bold text-red-800 tracking-tight`,children:`Termination Zone`}),(0,g.jsx)(`span`,{className:`px-2 py-0.5 bg-red-50 text-red-600 text-sm font-bold rounded-md border border-red-100`,children:`Critical`})]}),(0,g.jsx)(`p`,{className:`text-xs text-red-600 font-semibold leading-relaxed mb-4`,children:`Once account liquidation is initiated, the process is irreversible. All associated data assets will be purged.`}),(0,g.jsx)(`button`,{onClick:()=>{c.confirmDelete(`Your Entire Account`).then(e=>{e.isConfirmed&&r.delete(route(`profile.destroy`))})},className:`w-full py-3 border border-red-100 text-red-600 text-xs font-bold tracking-tight rounded-xl hover:bg-red-50 transition-colors`,children:`Initiate Liquidation`})]})]})]})]})}export{y as default}; \ No newline at end of file diff --git a/public/build/assets/Error-rwcY_Rc-.js b/public/build/assets/Error-rwcY_Rc-.js new file mode 100644 index 0000000..9f9d4df --- /dev/null +++ b/public/build/assets/Error-rwcY_Rc-.js @@ -0,0 +1 @@ +import{c as e,n as t,r as n,t as r}from"./app-BJ7g6sa8.js";e();var i=r(),a={403:{title:`Access Denied`,description:`You don't have permission to access this resource.`},404:{title:`Page Not Found`,description:`The page you're looking for doesn't exist or has been moved.`},419:{title:`Session Expired`,description:`Your session has expired. Please refresh and try again.`},500:{title:`Server Error`,description:`Something went wrong on our end. Please try again later.`},503:{title:`Under Maintenance`,description:`The system is temporarily unavailable. Please check back soon.`}};function o({status:e}){let{title:r,description:o}=a[e]??{title:`Unexpected Error`,description:`An unexpected error occurred.`};return(0,i.jsxs)(`div`,{className:`min-h-screen bg-[#E3EBE8] flex items-center justify-center p-6`,children:[(0,i.jsx)(t,{title:`${e} — ${r}`}),(0,i.jsxs)(`div`,{className:`w-full max-w-md`,children:[(0,i.jsxs)(`div`,{className:`bg-white rounded-3xl border border-gray-100 shadow-sm overflow-hidden`,children:[(0,i.jsxs)(`div`,{className:`bg-[#3D4E4B] px-8 py-10 text-center`,children:[(0,i.jsx)(`div`,{className:`text-7xl font-black text-white/10 tracking-tighter leading-none select-none`,children:e}),(0,i.jsx)(`div`,{className:`mt-2 text-xl font-bold text-white tracking-tight`,children:r})]}),(0,i.jsxs)(`div`,{className:`px-8 py-8 text-center space-y-6`,children:[(0,i.jsx)(`p`,{className:`text-sm font-semibold text-gray-400 leading-relaxed`,children:o}),(0,i.jsxs)(`div`,{className:`flex flex-col sm:flex-row gap-3 justify-center`,children:[e===419?(0,i.jsxs)(`button`,{onClick:()=>window.location.reload(),className:`h-10 px-6 bg-[#3D4E4B] text-white text-sm font-bold tracking-tight rounded-xl hover:bg-[#2D3A38] transition-all flex items-center justify-center gap-2`,children:[(0,i.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,i.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15`})}),`Refresh Page`]}):(0,i.jsxs)(n,{href:`/dashboard`,className:`h-10 px-6 bg-[#3D4E4B] text-white text-sm font-bold tracking-tight rounded-xl hover:bg-[#2D3A38] transition-all flex items-center justify-center gap-2`,children:[(0,i.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,i.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6`})}),`Back to Dashboard`]}),(0,i.jsx)(`button`,{onClick:()=>window.history.back(),className:`h-10 px-6 bg-white border border-gray-100 text-gray-500 text-sm font-bold tracking-tight rounded-xl hover:bg-gray-50 transition-all`,children:`Go Back`})]})]})]}),(0,i.jsxs)(`p`,{className:`text-center text-xs font-bold text-gray-400 uppercase tracking-widest mt-6`,children:[`Error `,e]})]})]})}export{o as default}; \ No newline at end of file diff --git a/public/build/assets/ForgotPassword-BmQrO4Bp.js b/public/build/assets/ForgotPassword-BmQrO4Bp.js new file mode 100644 index 0000000..c3593af --- /dev/null +++ b/public/build/assets/ForgotPassword-BmQrO4Bp.js @@ -0,0 +1 @@ +import{a as e,c as t,n,r,t as i}from"./app-BJ7g6sa8.js";import{t as a}from"./GuestLayout-CN-YY0cs.js";t();var o=i();function s({status:t}){let{data:i,setData:s,post:c,processing:l,errors:u}=e({email:``});return(0,o.jsxs)(a,{children:[(0,o.jsx)(n,{title:`Forgot password`}),(0,o.jsxs)(`div`,{className:`mb-8 anim-down`,children:[(0,o.jsx)(`h1`,{className:`text-2xl font-bold text-[#1A2421] tracking-tight`,children:`Forgot password?`}),(0,o.jsx)(`p`,{className:`mt-1.5 text-sm text-gray-400 font-medium`,children:`Enter your email and we'll send a reset link.`})]}),t&&(0,o.jsx)(`div`,{className:`mb-6 px-4 py-3 rounded-xl bg-emerald-50 border border-emerald-100 text-sm font-semibold text-emerald-700 anim-fade`,children:t}),(0,o.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),c(route(`password.email`))},className:`anim-up`,style:{animationDelay:`0.1s`},children:[(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`label`,{htmlFor:`email`,className:`block text-sm font-semibold text-gray-600 mb-1.5`,children:`Email address`}),(0,o.jsx)(`input`,{id:`email`,type:`email`,autoComplete:`email`,autoFocus:!0,value:i.email,onChange:e=>s(`email`,e.target.value),placeholder:`you@company.com`,className:`auth-input${u.email?` !border-red-300 !bg-red-50/50`:``}`}),u.email&&(0,o.jsx)(`p`,{className:`mt-1.5 text-xs font-semibold text-red-500`,children:u.email})]}),(0,o.jsx)(`button`,{type:`submit`,disabled:l,className:`mt-6 w-full h-11 rounded-xl bg-[#3D4E4B] hover:bg-[#2D3A38] text-white text-sm font-bold tracking-tight transition-colors duration-200 flex items-center justify-center gap-2 disabled:opacity-60 disabled:cursor-not-allowed`,children:l?(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(`svg`,{className:`w-4 h-4 animate-spin text-white/60`,fill:`none`,viewBox:`0 0 24 24`,children:[(0,o.jsx)(`circle`,{className:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,strokeWidth:`4`}),(0,o.jsx)(`path`,{className:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z`})]}),`Sending…`]}):`Send reset link`})]}),(0,o.jsx)(`p`,{className:`mt-7 text-center text-sm text-gray-400 font-medium anim-fade`,style:{animationDelay:`0.18s`},children:(0,o.jsx)(r,{href:route(`login`),className:`text-[#3D4E4B] font-semibold hover:text-[#D4A017] transition-colors duration-200`,children:`← Back to sign in`})})]})}export{s as default}; \ No newline at end of file diff --git a/public/build/assets/GuestLayout-CN-YY0cs.js b/public/build/assets/GuestLayout-CN-YY0cs.js new file mode 100644 index 0000000..91cc858 --- /dev/null +++ b/public/build/assets/GuestLayout-CN-YY0cs.js @@ -0,0 +1 @@ +import{c as e,o as t,r as n,t as r}from"./app-BJ7g6sa8.js";e();var i=r();function a({children:e}){let{system_settings:r}=t().props,a=r?.app_name||`biiproject kit v2`,o=r?.app_logo,s=r?.app_logo_text||`BK`;return(0,i.jsxs)(`div`,{className:`min-h-screen flex font-sans`,children:[(0,i.jsxs)(`div`,{className:`hidden lg:flex lg:w-[44%] bg-[#3D4E4B] flex-col justify-between p-14 relative overflow-hidden shrink-0`,children:[(0,i.jsxs)(`svg`,{className:`absolute inset-0 w-full h-full pointer-events-none`,xmlns:`http://www.w3.org/2000/svg`,children:[(0,i.jsx)(`defs`,{children:(0,i.jsx)(`pattern`,{id:`dots`,x:`0`,y:`0`,width:`28`,height:`28`,patternUnits:`userSpaceOnUse`,children:(0,i.jsx)(`circle`,{cx:`1.5`,cy:`1.5`,r:`1.5`,fill:`white`,fillOpacity:`0.07`})})}),(0,i.jsx)(`rect`,{width:`100%`,height:`100%`,fill:`url(#dots)`})]}),(0,i.jsx)(`div`,{className:`absolute -bottom-40 -right-40 w-[480px] h-[480px] rounded-full border border-white/[0.06] pointer-events-none`}),(0,i.jsx)(`div`,{className:`absolute -bottom-64 -right-64 w-[700px] h-[700px] rounded-full border border-white/[0.04] pointer-events-none`}),(0,i.jsx)(`div`,{className:`absolute top-[-60px] left-[-60px] w-[300px] h-[300px] rounded-full border border-white/[0.04] pointer-events-none`}),(0,i.jsx)(`div`,{className:`relative z-10 anim-fade`,children:(0,i.jsxs)(n,{href:`/`,className:`inline-flex items-center gap-3 group`,children:[(0,i.jsx)(`div`,{className:`w-10 h-10 rounded-[0.75rem] flex items-center justify-center overflow-hidden text-sm font-bold text-white shrink-0 ${o?`bg-white/10`:`bg-[#D4A017]`}`,children:o?(0,i.jsx)(`img`,{src:o,alt:a,className:`w-full h-full object-contain`}):s}),(0,i.jsx)(`span`,{className:`text-white font-bold text-base tracking-tight`,children:a})]})}),(0,i.jsxs)(`div`,{className:`relative z-10 anim-up`,style:{animationDelay:`0.1s`},children:[(0,i.jsx)(`p`,{className:`text-[#D4A017] text-xs font-bold uppercase tracking-[0.18em] mb-5`,children:`Enterprise Platform`}),(0,i.jsxs)(`h2`,{className:`text-white text-[2rem] font-bold leading-[1.2] tracking-tight`,children:[`Manage your`,(0,i.jsx)(`br`,{}),`organization`,(0,i.jsx)(`br`,{}),`with precision.`]}),(0,i.jsx)(`p`,{className:`mt-5 text-[#E3EBE8]/45 text-sm leading-relaxed max-w-xs`,children:`Access control, user management, and system configuration — unified in one secure interface.`}),(0,i.jsx)(`div`,{className:`mt-9 flex flex-col gap-3`,children:[`Role-based access control`,`Real-time audit logs`,`Multi-level permissions`].map(e=>(0,i.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,i.jsx)(`div`,{className:`w-1.5 h-1.5 rounded-full bg-[#D4A017] shrink-0`}),(0,i.jsx)(`span`,{className:`text-[#E3EBE8]/55 text-sm font-medium`,children:e})]},e))})]}),(0,i.jsx)(`div`,{className:`relative z-10 anim-fade`,style:{animationDelay:`0.2s`},children:(0,i.jsxs)(`p`,{className:`text-[#E3EBE8]/25 text-xs`,children:[`© `,new Date().getFullYear(),` `,a,`. All rights reserved.`]})})]}),(0,i.jsxs)(`div`,{className:`flex-1 flex flex-col items-center justify-center bg-white px-8 py-12 min-h-screen`,children:[(0,i.jsxs)(`div`,{className:`lg:hidden mb-10 flex items-center gap-3 anim-down`,children:[(0,i.jsx)(`div`,{className:`w-9 h-9 rounded-[0.6rem] flex items-center justify-center text-sm font-bold overflow-hidden ${o?``:`bg-[#3D4E4B] text-white`}`,children:o?(0,i.jsx)(`img`,{src:o,alt:a,className:`w-full h-full object-contain`}):s}),(0,i.jsx)(`span`,{className:`text-[#3D4E4B] font-bold text-base tracking-tight`,children:a})]}),(0,i.jsx)(`div`,{className:`w-full max-w-[360px]`,children:e}),(0,i.jsx)(`div`,{className:`mt-10 anim-fade`,style:{animationDelay:`0.35s`},children:(0,i.jsxs)(n,{href:`/`,className:`inline-flex items-center gap-1.5 text-xs font-semibold text-gray-300 hover:text-[#3D4E4B] transition-colors duration-200 tracking-tight`,children:[(0,i.jsx)(`svg`,{className:`w-3.5 h-3.5`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,i.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M10 19l-7-7m0 0l7-7m-7 7h18`})}),`Back to home`]})})]})]})}export{a as t}; \ No newline at end of file diff --git a/public/build/assets/Index-A9YntmU6.js b/public/build/assets/Index-A9YntmU6.js new file mode 100644 index 0000000..ded5490 --- /dev/null +++ b/public/build/assets/Index-A9YntmU6.js @@ -0,0 +1 @@ +import{a as e,c as t,d as n,l as r,n as i,o as a,t as o}from"./app-BJ7g6sa8.js";import{t as s}from"./AuthenticatedLayout-CrB9BCoI.js";import{t as c}from"./swal-DZXjpqDE.js";import{n as l,r as u,t as d}from"./filepond-plugin-file-validate-type-CBUe71W_.js";var f=n(t(),1),p=u(),m=n(l(),1),h=n(d(),1),g=o();(0,p.registerPlugin)(m.default,h.default);function _({title:e,description:t,children:n,delay:r=`0s`}){return(0,g.jsxs)(`div`,{className:`bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden h-full flex flex-col anim-up`,style:{animationDelay:r},children:[(0,g.jsxs)(`div`,{className:`px-6 py-4 border-b border-gray-50 bg-gray-50/30`,children:[(0,g.jsx)(`h2`,{className:`text-sm font-bold text-[#3D4E4B] tracking-tight`,children:e}),(0,g.jsx)(`p`,{className:`text-xs text-gray-400 font-semibold tracking-tight mt-1`,children:t})]}),(0,g.jsx)(`div`,{className:`p-8 flex-1`,children:n})]})}function v({label:e,description:t,checked:n,onChange:r}){return(0,g.jsxs)(`div`,{className:`flex items-center justify-between py-3 border-b border-gray-50 last:border-0 hover:bg-gray-50/30 px-2 -mx-2 rounded-xl transition-colors group`,children:[(0,g.jsxs)(`div`,{children:[(0,g.jsx)(`div`,{className:`text-sm font-bold text-[#3D4E4B] tracking-tight group-hover:text-[#D4A017] transition-colors`,children:e}),(0,g.jsx)(`div`,{className:`text-xs text-gray-400 font-medium`,children:t})]}),(0,g.jsxs)(`label`,{className:`relative inline-flex items-center cursor-pointer`,children:[(0,g.jsx)(`input`,{type:`checkbox`,className:`sr-only peer`,checked:n,onChange:e=>r(e.target.checked)}),(0,g.jsx)(`div`,{className:`w-10 h-5 bg-gray-300 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-400 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-[#D4A017] peer-checked:after:border-[#D4A017] border border-gray-200`})]})]})}function y({label:e,value:t,onChange:n,type:r=`text`,placeholder:i=``,error:a=``,required:o=!1,maxLength:s,id:c}){return(0,g.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,g.jsxs)(`label`,{htmlFor:c,className:`block text-xs font-semibold text-gray-500 tracking-tight ml-1`,children:[e,` `,o&&(0,g.jsx)(`span`,{className:`text-red-500`,children:`*`})]}),(0,g.jsx)(`input`,{id:c,type:r,value:t,onChange:e=>n(e.target.value),placeholder:i,maxLength:s,className:`input-field${a?` is-error`:``}`}),a&&(0,g.jsx)(`p`,{className:`text-xs text-red-500 font-semibold ml-1 mt-1`,children:a})]})}var b=[`general`,`security`,`email`,`mobile`];function x(){let e=window.location.hash.replace(`#`,``);return b.includes(e)?e:`general`}function S({settings:t}){let[n,o]=(0,f.useState)(x);(0,f.useEffect)(()=>{let e=()=>o(x());return window.addEventListener(`hashchange`,e),()=>window.removeEventListener(`hashchange`,e)},[]);let l=e=>{window.location.hash=e,o(e)},{auth:u}=a().props,[d,m]=(0,f.useState)(u?.user?.email||``),[h,b]=(0,f.useState)(!1),S=async()=>{if(d){b(!0);try{let e=await r.post(route(`system.settings.test-email`),{recipient:d,mail_host:C.settings.mail_host,mail_port:C.settings.mail_port,mail_username:C.settings.mail_username,mail_password:C.settings.mail_password,mail_encryption:C.settings.mail_encryption,mail_from_address:C.settings.mail_from_address,mail_from_name:C.settings.mail_from_name});e.data.success?c.success(`Success`,e.data.message||`Test email sent successfully!`):c.error(`SMTP Error`,e.data.message||`Failed to send test email.`)}catch(e){c.error(`Error`,e.response?.data?.message||e.message||`An error occurred.`)}finally{b(!1)}}},{data:C,setData:w,post:T,processing:E,errors:D}=e({settings:{app_name:t.app_name||``,app_logo_text:t.app_logo_text||`B`,app_description:t.app_description||``,allow_registration:t.allow_registration===`1`||t.allow_registration===!0,require_email_verification:t.require_email_verification===`1`||t.require_email_verification===!0,password_minimum_length:parseInt(t.password_minimum_length)||8,password_require_symbols:t.password_require_symbols===`1`||t.password_require_symbols===!0,password_require_numbers:t.password_require_numbers===`1`||t.password_require_numbers===!0,password_require_mixed_case:t.password_require_mixed_case===`1`||t.password_require_mixed_case===!0,oauth_google_enabled:t.oauth_google_enabled===`1`||t.oauth_google_enabled===!0,oauth_google_client_id:t.oauth_google_client_id||``,oauth_google_client_secret:t.oauth_google_client_secret||``,oauth_github_enabled:t.oauth_github_enabled===`1`||t.oauth_github_enabled===!0,oauth_github_client_id:t.oauth_github_client_id||``,oauth_github_client_secret:t.oauth_github_client_secret||``,mail_host:t.mail_host||``,mail_port:t.mail_port||``,mail_username:t.mail_username||``,mail_password:t.mail_password||``,mail_encryption:t.mail_encryption||`tls`,mail_from_address:t.mail_from_address||``,mail_from_name:t.mail_from_name||``,primary_color:t.primary_color||`#D4A017`,android_latest_version:t.android_latest_version||`1.0.0`,android_min_version:t.android_min_version||`1.0.0`,android_maintenance_mode:t.android_maintenance_mode===`1`||t.android_maintenance_mode===!0,android_playstore_url:t.android_playstore_url||``},logo_file:null,_method:`PATCH`}),[O,k]=(0,f.useState)([]),A=(e,t)=>{w(`settings`,{...C.settings,[e]:t})};return(0,g.jsxs)(s,{children:[(0,g.jsx)(i,{title:`System Settings`}),(0,g.jsxs)(`div`,{className:`flex items-center justify-between mb-8 anim-down`,children:[(0,g.jsxs)(`div`,{children:[(0,g.jsx)(`h1`,{className:`text-xl font-bold text-[#3D4E4B] tracking-tight leading-none`,children:`System Configuration`}),(0,g.jsx)(`p`,{className:`text-sm font-semibold text-gray-400 tracking-tight mt-2`,children:`Manage global application behavior and external protocols`})]}),(0,g.jsx)(`button`,{onClick:e=>{e.preventDefault(),T(route(`system.settings.update`),{preserveScroll:!0,onSuccess:()=>c.success(`Saved`,`System settings updated successfully.`)})},disabled:E,className:`h-10 px-8 bg-[#3D4E4B] text-white text-sm font-bold tracking-tight rounded-xl hover:bg-[#2D3A38] transition-all shadow-lg shadow-[#3D4E4B]/20 disabled:opacity-60 disabled:cursor-not-allowed`,children:E?`Saving...`:`Save Configuration`})]}),(0,g.jsxs)(`div`,{className:`flex items-center gap-1 border-b border-gray-100 w-full mb-8 anim-down`,style:{animationDelay:`0.05s`},children:[(0,g.jsxs)(`button`,{type:`button`,onClick:()=>l(`general`),className:`relative pb-3 px-1 mr-8 text-sm font-bold tracking-tight transition-colors ${n===`general`?`text-[#3D4E4B]`:`text-gray-400 hover:text-[#3D4E4B]`}`,children:[`General & Branding`,n===`general`&&(0,g.jsx)(`span`,{className:`absolute bottom-0 left-0 w-full h-0.5 bg-[#D4A017] rounded-t-full`})]}),(0,g.jsxs)(`button`,{type:`button`,onClick:()=>l(`security`),className:`relative pb-3 px-1 mr-8 text-sm font-bold tracking-tight transition-colors ${n===`security`?`text-[#3D4E4B]`:`text-gray-400 hover:text-[#3D4E4B]`}`,children:[`Security & OAuth`,n===`security`&&(0,g.jsx)(`span`,{className:`absolute bottom-0 left-0 w-full h-0.5 bg-[#D4A017] rounded-t-full`})]}),(0,g.jsxs)(`button`,{type:`button`,onClick:()=>l(`email`),className:`relative pb-3 px-1 mr-8 text-sm font-bold tracking-tight transition-colors ${n===`email`?`text-[#3D4E4B]`:`text-gray-400 hover:text-[#3D4E4B]`}`,children:[`Email Protocol`,n===`email`&&(0,g.jsx)(`span`,{className:`absolute bottom-0 left-0 w-full h-0.5 bg-[#D4A017] rounded-t-full`})]}),(0,g.jsxs)(`button`,{type:`button`,onClick:()=>l(`mobile`),className:`relative pb-3 px-1 text-sm font-bold tracking-tight transition-colors ${n===`mobile`?`text-[#3D4E4B]`:`text-gray-400 hover:text-[#3D4E4B]`}`,children:[`Mobile App Control`,n===`mobile`&&(0,g.jsx)(`span`,{className:`absolute bottom-0 left-0 w-full h-0.5 bg-[#D4A017] rounded-t-full`})]})]}),(0,g.jsxs)(`div`,{className:`space-y-8 pb-20`,children:[n===`general`&&(0,g.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-2 gap-8 anim-fade`,children:[(0,g.jsx)(_,{title:`Application Branding`,description:`Logo and visual identity`,delay:`0.1s`,children:(0,g.jsxs)(`div`,{className:`space-y-8`,children:[(0,g.jsxs)(`div`,{className:`flex flex-col sm:flex-row items-center gap-8`,children:[(0,g.jsx)(`div`,{className:`w-24 h-24 rounded-2xl flex items-center justify-center text-white text-3xl font-bold shrink-0 border border-gray-100 shadow-sm ${t.app_logo?`bg-white`:`bg-[#3D4E4B]`}`,children:t.app_logo?(0,g.jsx)(`img`,{src:t.app_logo,className:`w-full h-full object-contain`}):C.settings.app_logo_text||`B`}),(0,g.jsx)(`div`,{className:`flex-1 w-full`,children:(0,g.jsx)(p.FilePond,{files:O,onupdatefiles:e=>{k(e),w(`logo_file`,e[0]?.file||null)},allowMultiple:!1,maxFiles:1,labelIdle:`Drop Logo here`})})]}),(0,g.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-6`,children:[(0,g.jsx)(y,{label:`App Name`,value:C.settings.app_name,onChange:e=>A(`app_name`,e),required:!0,placeholder:`e.g. Biiskit Platform`}),(0,g.jsx)(y,{label:`Logo Text`,value:C.settings.app_logo_text,onChange:e=>A(`app_logo_text`,e),maxLength:3,required:!0,placeholder:`e.g. B`})]})]})}),(0,g.jsx)(_,{title:`Public Policy`,description:`Manage open registration and access`,delay:`0.15s`,children:(0,g.jsxs)(`div`,{className:`space-y-2`,children:[(0,g.jsx)(v,{label:`Public Registration`,description:`Allow new users to create accounts`,checked:C.settings.allow_registration,onChange:e=>A(`allow_registration`,e)}),(0,g.jsx)(v,{label:`Email Verification`,description:`Require email validation for new accounts`,checked:C.settings.require_email_verification,onChange:e=>A(`require_email_verification`,e)})]})})]}),n===`security`&&(0,g.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-2 gap-8 anim-fade`,children:[(0,g.jsx)(_,{title:`Password Standards`,description:`Complexity requirements for user access`,delay:`0.1s`,children:(0,g.jsxs)(`div`,{className:`space-y-2`,children:[(0,g.jsx)(v,{label:`Require Symbols`,description:`Include special characters (!@#$)`,checked:C.settings.password_require_symbols,onChange:e=>A(`password_require_symbols`,e)}),(0,g.jsx)(v,{label:`Require Numbers`,description:`Include numerical digits (0-9)`,checked:C.settings.password_require_numbers,onChange:e=>A(`password_require_numbers`,e)}),(0,g.jsx)(v,{label:`Require Mixed Case`,description:`Force Uppercase and Lowercase letters`,checked:C.settings.password_require_mixed_case,onChange:e=>A(`password_require_mixed_case`,e)}),(0,g.jsxs)(`div`,{className:`flex items-center justify-between py-4 mt-2 border-t border-gray-50`,children:[(0,g.jsx)(`span`,{className:`text-sm font-bold text-[#3D4E4B]`,children:`Minimum Length`}),(0,g.jsx)(`input`,{type:`number`,value:C.settings.password_minimum_length,onChange:e=>A(`password_minimum_length`,parseInt(e.target.value)),className:`w-16 h-10 input-field text-center px-2 text-[#D4A017] font-bold`})]})]})}),(0,g.jsx)(_,{title:`OAuth Providers`,description:`Third-party authentication protocols`,delay:`0.15s`,children:(0,g.jsx)(`div`,{className:`space-y-6`,children:[`google`,`github`].map(e=>(0,g.jsxs)(`div`,{className:`p-6 rounded-2xl bg-gray-50/50 border border-gray-100`,children:[(0,g.jsxs)(`div`,{className:`flex items-center justify-between mb-6`,children:[(0,g.jsxs)(`div`,{className:`text-sm font-bold text-[#3D4E4B] tracking-tight capitalize flex items-center gap-2`,children:[(0,g.jsx)(`span`,{className:`w-2 h-2 rounded-full ${C.settings[`oauth_${e}_enabled`]?`bg-green-500`:`bg-gray-300`}`}),e,` Login`]}),(0,g.jsxs)(`label`,{className:`relative inline-flex items-center cursor-pointer scale-90`,children:[(0,g.jsx)(`input`,{type:`checkbox`,className:`sr-only peer`,checked:C.settings[`oauth_${e}_enabled`],onChange:t=>A(`oauth_${e}_enabled`,t.target.checked)}),(0,g.jsx)(`div`,{className:`w-10 h-5 bg-gray-300 rounded-full peer peer-checked:bg-[#D4A017] after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-400 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:after:translate-x-full border border-gray-200`})]})]}),(0,g.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-4`,children:[(0,g.jsx)(y,{label:`Client ID`,value:C.settings[`oauth_${e}_client_id`],onChange:t=>A(`oauth_${e}_client_id`,t),placeholder:`Enter ${e} Client ID`}),(0,g.jsx)(y,{label:`Client Secret`,type:`password`,value:C.settings[`oauth_${e}_client_secret`],onChange:t=>A(`oauth_${e}_client_secret`,t),placeholder:`••••••••`})]})]},e))})})]}),n===`email`&&(0,g.jsxs)(`div`,{className:`max-w-5xl space-y-8 anim-fade`,children:[(0,g.jsx)(_,{title:`Mail Transmission`,description:`SMTP server configuration for system notifications`,delay:`0.1s`,children:(0,g.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-3 gap-8`,children:[(0,g.jsxs)(`div`,{className:`md:col-span-2 space-y-6`,children:[(0,g.jsxs)(`div`,{className:`grid grid-cols-3 gap-6`,children:[(0,g.jsx)(`div`,{className:`col-span-2`,children:(0,g.jsx)(y,{label:`Mail Host`,value:C.settings.mail_host,onChange:e=>A(`mail_host`,e),placeholder:`e.g. smtp.mailtrap.io`,required:!0})}),(0,g.jsx)(y,{label:`Port`,value:C.settings.mail_port,onChange:e=>A(`mail_port`,e),placeholder:`e.g. 587`,required:!0})]}),(0,g.jsxs)(`div`,{className:`grid grid-cols-2 gap-6`,children:[(0,g.jsx)(y,{label:`Username`,value:C.settings.mail_username,onChange:e=>A(`mail_username`,e),placeholder:`e.g. user_key_123`}),(0,g.jsx)(y,{label:`Password`,type:`password`,value:C.settings.mail_password,onChange:e=>A(`mail_password`,e),placeholder:`••••••••`})]})]}),(0,g.jsxs)(`div`,{className:`space-y-6 pt-6 md:pt-0 border-t md:border-t-0 md:border-l border-gray-100 md:pl-8`,children:[(0,g.jsx)(y,{label:`Sender Address`,value:C.settings.mail_from_address,onChange:e=>A(`mail_from_address`,e),placeholder:`e.g. no-reply@app.com`,required:!0}),(0,g.jsx)(y,{label:`Sender Name`,value:C.settings.mail_from_name,onChange:e=>A(`mail_from_name`,e),placeholder:`e.g. System Admin`,required:!0})]})]})}),(0,g.jsx)(_,{title:`SMTP Connection Test`,description:`Verify your SMTP transmission parameters by sending a test email`,delay:`0.15s`,children:(0,g.jsxs)(`div`,{className:`max-w-xl space-y-6`,children:[(0,g.jsxs)(`div`,{className:`p-4 rounded-xl bg-gray-50/50 border border-gray-100 flex items-start gap-3`,children:[(0,g.jsx)(`svg`,{className:`w-5 h-5 text-[#D4A017] mt-0.5 shrink-0`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,g.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`})}),(0,g.jsx)(`p`,{className:`text-xs text-[#3D4E4B] font-semibold leading-relaxed`,children:`This test will use the SMTP values entered in the form above. You don't need to save the configuration first to test it.`})]}),(0,g.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-3 gap-6 items-end`,children:[(0,g.jsx)(`div`,{className:`sm:col-span-2`,children:(0,g.jsx)(y,{label:`Recipient Email Address`,value:d,onChange:m,placeholder:`e.g. you@example.com`,required:!0})}),(0,g.jsx)(`button`,{type:`button`,onClick:S,disabled:h||!d,className:`h-10 px-6 bg-[#3D4E4B] text-white text-xs font-bold tracking-tight rounded-xl hover:bg-[#2D3A38] transition-all shadow-md shadow-[#3D4E4B]/10 disabled:opacity-60 disabled:cursor-not-allowed flex items-center justify-center gap-2`,children:h?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsxs)(`svg`,{className:`animate-spin h-4 w-4 text-white`,fill:`none`,viewBox:`0 0 24 24`,children:[(0,g.jsx)(`circle`,{className:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,strokeWidth:`4`}),(0,g.jsx)(`path`,{className:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z`})]}),(0,g.jsx)(`span`,{children:`Transmitting...`})]}):`Send Test Email`})]})]})})]}),n===`mobile`&&(0,g.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-2 gap-8 anim-fade`,children:[(0,g.jsx)(_,{title:`Version Management`,description:`Control Android application lifecycle`,delay:`0.1s`,children:(0,g.jsxs)(`div`,{className:`space-y-8`,children:[(0,g.jsxs)(`div`,{className:`grid grid-cols-2 gap-6`,children:[(0,g.jsx)(y,{label:`Latest Version`,value:C.settings.android_latest_version,onChange:e=>A(`android_latest_version`,e),placeholder:`e.g. 1.2.0`}),(0,g.jsx)(y,{label:`Min Required Version`,value:C.settings.android_min_version,onChange:e=>A(`android_min_version`,e),placeholder:`e.g. 1.0.5`})]}),(0,g.jsx)(y,{label:`Play Store URL`,value:C.settings.android_playstore_url,onChange:e=>A(`android_playstore_url`,e),placeholder:`https://play.google.com/store/apps/details?id=...`})]})}),(0,g.jsx)(_,{title:`Mobile Availability`,description:`Control API accessibility for devices`,delay:`0.15s`,children:(0,g.jsxs)(`div`,{className:`space-y-4`,children:[(0,g.jsx)(v,{label:`Maintenance Mode`,description:`Block Android API access for maintenance`,checked:C.settings.android_maintenance_mode,onChange:e=>A(`android_maintenance_mode`,e)}),(0,g.jsxs)(`div`,{className:`p-4 rounded-xl bg-amber-50 border border-amber-100 mt-4`,children:[(0,g.jsx)(`p`,{className:`text-[10px] font-bold text-amber-800 leading-relaxed uppercase tracking-widest mb-1`,children:`Warning`}),(0,g.jsx)(`p`,{className:`text-[11px] text-amber-700 font-medium`,children:`Enabling maintenance mode will return a 503 error to all mobile devices connecting to the API.`})]})]})})]})]})]})}export{S as default}; \ No newline at end of file diff --git a/public/build/assets/Index-Bnf5l0xj.js b/public/build/assets/Index-Bnf5l0xj.js new file mode 100644 index 0000000..1b8d26e --- /dev/null +++ b/public/build/assets/Index-Bnf5l0xj.js @@ -0,0 +1 @@ +import{c as e,d as t,i as n,n as r,t as i}from"./app-BJ7g6sa8.js";import{t as a}from"./AuthenticatedLayout-CrB9BCoI.js";import{t as o}from"./Portal-DJbp1s68.js";import{t as s}from"./swal-DZXjpqDE.js";import{t as c}from"./Can-DIOq7dyw.js";var l=t(e(),1),u=i();function d({roles:e,permissions:t}){let i=[...new Set(t.map(e=>e.group))],[d,f]=(0,l.useState)(()=>{let t={};return e.forEach(e=>{t[e.id]=[...e.permissions]}),t}),[p,m]=(0,l.useState)({}),[h,g]=(0,l.useState)({}),[_,v]=(0,l.useState)(!1),[y,b]=(0,l.useState)(``),x=(e,t)=>{f(n=>{let r=n[e]||[],i=r.includes(t)?r.filter(e=>e!==t):[...r,t];return{...n,[e]:i}}),m(t=>({...t,[e]:!0}))},S=async e=>{g(t=>({...t,[e.id]:!0})),n.patch(`/roles/${e.id}/permissions`,{permissions:d[e.id]||[]},{preserveScroll:!0,onSuccess:()=>{m(t=>({...t,[e.id]:!1})),g(t=>({...t,[e.id]:!1})),s.success(`Saved`,`Permissions updated for "${e.name}"`)},onError:()=>{g(t=>({...t,[e.id]:!1})),s.error(`Error`,`Failed to update permissions.`)}})},C=e=>{e.preventDefault(),y.trim()&&n.post(`/roles`,{name:y.trim()},{onSuccess:()=>{v(!1),b(``),s.success(`Created`,`New role created successfully.`)},onError:()=>s.error(`Error`,`Failed to create role.`)})},w=async e=>{(await s.confirmDelete(e.name)).isConfirmed&&n.delete(`/roles/${e.id}`,{onSuccess:()=>s.success(`Deleted`,`Role "${e.name}" has been deleted.`),onError:()=>s.error(`Error`,`Failed to delete role.`)})};return(0,u.jsxs)(a,{children:[(0,u.jsx)(r,{title:`Roles & Permissions`}),(0,u.jsxs)(`div`,{className:`flex items-center justify-between mb-8 anim-down`,children:[(0,u.jsxs)(`div`,{children:[(0,u.jsx)(`h1`,{className:`text-xl font-bold text-[#3D4E4B] tracking-tight leading-none`,children:`Access Control`}),(0,u.jsx)(`p`,{className:`text-sm font-semibold text-gray-400 tracking-tight mt-2`,children:`Configure hierarchical roles and granular permissions`})]}),(0,u.jsx)(c,{ability:`role.manage`,children:(0,u.jsx)(`button`,{onClick:()=>v(!0),className:`h-10 px-6 rounded-xl bg-[#D4A017] text-white text-sm font-bold tracking-tight hover:bg-[#B88B14] transition-all shadow-lg shadow-[#D4A017]/20`,children:`New Role`})})]}),(0,u.jsx)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 mb-8`,children:e.map((e,n)=>{let r=(d[e.id]||[]).length,i=e.name===`super-admin`;return(0,u.jsxs)(`div`,{className:`bg-white rounded-2xl border border-gray-100 p-6 shadow-sm anim-up`,style:{animationDelay:`${n*.05}s`},children:[(0,u.jsxs)(`div`,{className:`flex items-center justify-between mb-6`,children:[(0,u.jsx)(`span`,{className:`px-3 py-1 text-[10px] font-black uppercase tracking-widest rounded-lg border ${i?`bg-[#3D4E4B] text-white border-[#3D4E4B]`:`bg-white text-gray-500 border-gray-100`}`,children:e.name}),!i&&(0,u.jsx)(c,{ability:`role.manage`,children:(0,u.jsx)(`button`,{onClick:()=>w(e),className:`w-8 h-8 rounded-lg flex items-center justify-center text-gray-300 hover:text-red-500 hover:bg-red-50 transition-all`,children:(0,u.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,u.jsx)(`path`,{d:`M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16`})})})})]}),(0,u.jsxs)(`div`,{className:`text-3xl font-black text-[#3D4E4B] tracking-tighter`,children:[r,(0,u.jsxs)(`span`,{className:`text-sm text-gray-200 font-bold ml-1 tracking-normal`,children:[`/ `,t.length,` perms`]})]}),(0,u.jsxs)(`div`,{className:`text-[10px] font-black text-gray-300 uppercase tracking-widest mt-2`,children:[e.users_count,` Total Active Users`]}),(0,u.jsx)(`div`,{className:`mt-6 h-1.5 bg-gray-50 rounded-full overflow-hidden`,children:(0,u.jsx)(`div`,{className:`h-full bg-[#D4A017] transition-all duration-700`,style:{width:`${r/t.length*100}%`}})}),p[e.id]&&(0,u.jsx)(`button`,{onClick:()=>S(e),disabled:h[e.id],className:`mt-6 w-full h-10 bg-[#3D4E4B] text-white text-xs font-black uppercase tracking-widest rounded-xl anim-fade shadow-lg shadow-[#3D4E4B]/20 disabled:opacity-60`,children:h[e.id]?`Saving…`:`Apply Changes`})]},e.id)})}),(0,u.jsxs)(`div`,{className:`bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden mb-20 anim-up`,style:{animationDelay:`0.2s`},children:[(0,u.jsx)(`div`,{className:`px-8 py-6 border-b border-gray-50 bg-gray-50/20`,children:(0,u.jsx)(`h3`,{className:`text-sm font-black text-[#3D4E4B] uppercase tracking-widest`,children:`Permissions Matrix`})}),(0,u.jsx)(`div`,{className:`overflow-x-auto custom-scrollbar`,children:(0,u.jsxs)(`table`,{className:`w-full text-left border-collapse`,children:[(0,u.jsx)(`thead`,{children:(0,u.jsxs)(`tr`,{className:`bg-white`,children:[(0,u.jsx)(`th`,{className:`px-8 py-5 text-[10px] font-black text-gray-400 uppercase tracking-widest w-72 sticky left-0 bg-white z-10 border-b border-gray-50`,children:`Functional Permission`}),e.map(e=>(0,u.jsx)(`th`,{className:`px-8 py-5 text-center text-[10px] font-black text-[#3D4E4B] uppercase tracking-widest border-b border-gray-50 bg-gray-50/30`,children:e.name},e.id))]})}),(0,u.jsx)(`tbody`,{className:`divide-y divide-gray-50`,children:i.map(n=>(0,u.jsxs)(l.Fragment,{children:[(0,u.jsx)(`tr`,{className:`bg-gray-50/10`,children:(0,u.jsx)(`td`,{colSpan:e.length+1,className:`px-8 py-3`,children:(0,u.jsxs)(`span`,{className:`text-[10px] font-black text-[#D4A017] uppercase tracking-[0.2em]`,children:[n,` Module`]})})}),t.filter(e=>e.group===n).map(t=>(0,u.jsxs)(`tr`,{className:`hover:bg-gray-50/30 transition-colors`,children:[(0,u.jsxs)(`td`,{className:`px-8 py-4 sticky left-0 bg-white group border-r border-gray-50/50`,children:[(0,u.jsx)(`div`,{className:`text-sm font-bold text-[#3D4E4B] tracking-tight capitalize`,children:t.name.replace(`.`,` `)}),(0,u.jsx)(`div`,{className:`text-[9px] text-gray-300 font-bold uppercase tracking-widest mt-1`,children:t.name})]}),e.map(e=>{let n=(d[e.id]||[]).includes(t.name),r=e.name===`super-admin`;return(0,u.jsx)(`td`,{className:`px-8 py-4 text-center`,children:(0,u.jsx)(`button`,{onClick:()=>!r&&x(e.id,t.name),disabled:r,className:`w-8 h-8 rounded-xl transition-all flex items-center justify-center mx-auto border-2 ${r?`bg-gray-50 text-[#3D4E4B] border-gray-100 opacity-40`:n?`bg-[#3D4E4B] text-white shadow-lg shadow-[#3D4E4B]/20 border-[#3D4E4B]`:`bg-white text-gray-100 hover:text-[#D4A017] border-gray-100 hover:border-[#D4A017]`}`,children:n?(0,u.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:4,children:(0,u.jsx)(`path`,{d:`M5 13l4 4L19 7`})}):(0,u.jsx)(`div`,{className:`w-1.5 h-1.5 rounded-full bg-current`})})},`${e.id}-${t.id}`)})]},t.id))]},n))})]})})]}),_&&(0,u.jsx)(o,{children:(0,u.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-[#3D4E4B]/60 backdrop-blur-md anim-fade`,children:(0,u.jsxs)(`div`,{className:`relative bg-white rounded-3xl shadow-2xl w-full max-w-sm overflow-hidden anim-zoom border border-gray-100`,children:[(0,u.jsx)(`div`,{className:`px-8 py-6 border-b border-gray-50`,children:(0,u.jsx)(`h3`,{className:`text-base font-black text-[#3D4E4B] tracking-tight`,children:`Provision New Role`})}),(0,u.jsxs)(`form`,{onSubmit:C,className:`p-8 space-y-8`,children:[(0,u.jsxs)(`div`,{className:`space-y-2`,children:[(0,u.jsx)(`label`,{className:`text-xs font-black text-gray-400 uppercase tracking-widest ml-1`,children:`Internal Role Name`}),(0,u.jsx)(`input`,{type:`text`,value:y,onChange:e=>b(e.target.value),placeholder:`e.g. auditor`,className:`input-field`,required:!0,autoFocus:!0})]}),(0,u.jsxs)(`div`,{className:`flex gap-4`,children:[(0,u.jsx)(`button`,{type:`button`,onClick:()=>v(!1),className:`flex-1 h-11 bg-white text-gray-400 text-xs font-black uppercase tracking-widest border border-gray-100 rounded-2xl hover:bg-gray-50 transition-all`,children:`Cancel`}),(0,u.jsx)(`button`,{type:`submit`,className:`flex-1 h-11 bg-[#3D4E4B] text-white text-xs font-black uppercase tracking-widest rounded-2xl hover:bg-[#2D3A38] transition-all shadow-lg shadow-[#3D4E4B]/20`,children:`Provision`})]})]})]})})})]})}export{d as default}; \ No newline at end of file diff --git a/public/build/assets/Index-CgghpLIe.js b/public/build/assets/Index-CgghpLIe.js new file mode 100644 index 0000000..6811a79 --- /dev/null +++ b/public/build/assets/Index-CgghpLIe.js @@ -0,0 +1,84 @@ +import{c as e,d as t,n,t as r}from"./app-BJ7g6sa8.js";import{t as i}from"./AuthenticatedLayout-CrB9BCoI.js";var a=t(e(),1),o=r(),s=[{id:`intro`,label:`Pendahuluan`,icon:(0,o.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,o.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`})})},{id:`quickstart`,label:`Quick Start`,icon:(0,o.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,o.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M13 10V3L4 14h7v7l9-11h-7z`})})},{id:`stack`,label:`Tech Stack`,icon:(0,o.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,o.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10`})})},{id:`auth`,label:`Autentikasi`,icon:(0,o.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,o.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z`})})},{id:`roles`,label:`Roles & Permission`,icon:(0,o.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,o.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z`})})},{id:`features`,label:`Fitur Lengkap`,icon:(0,o.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,o.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M4 6h16M4 10h16M4 14h16M4 18h7`})})},{id:`api`,label:`REST API`,icon:(0,o.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,o.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z`})})},{id:`2fa`,label:`Two-Factor Auth`,icon:(0,o.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,o.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z`})})},{id:`settings`,label:`System Settings`,icon:(0,o.jsxs)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:[(0,o.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z`}),(0,o.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M15 12a3 3 0 11-6 0 3 3 0 016 0z`})]})},{id:`structure`,label:`Struktur Folder`,icon:(0,o.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,o.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z`})})}];function c({children:e,color:t=`gray`}){return(0,o.jsx)(`span`,{className:`inline-flex items-center px-2.5 py-0.5 rounded-lg text-[10px] font-bold uppercase tracking-widest ${{green:`bg-emerald-50 text-emerald-700 border border-emerald-200`,blue:`bg-blue-50 text-blue-700 border border-blue-200`,amber:`bg-amber-50 text-amber-700 border border-amber-200`,red:`bg-red-50 text-red-700 border border-red-200`,gray:`bg-gray-50 text-gray-600 border border-gray-200`,purple:`bg-purple-50 text-purple-700 border border-purple-200`}[t]}`,children:e})}function l({children:e,lang:t=`bash`}){let[n,r]=(0,a.useState)(!1);return(0,o.jsxs)(`div`,{className:`relative group mt-3`,children:[(0,o.jsxs)(`div`,{className:`flex items-center justify-between bg-[#1E2A28] rounded-t-xl px-4 py-2 border-b border-white/5`,children:[(0,o.jsx)(`span`,{className:`text-[10px] text-gray-400 font-mono font-bold uppercase tracking-widest`,children:t}),(0,o.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(e),r(!0),setTimeout(()=>r(!1),2e3)},className:`text-[10px] text-gray-400 font-bold hover:text-white transition-colors`,children:n?`✓ Copied`:`Copy`})]}),(0,o.jsx)(`pre`,{className:`bg-[#152320] text-emerald-300 text-xs font-mono p-4 rounded-b-xl overflow-x-auto leading-relaxed`,children:(0,o.jsx)(`code`,{children:e})})]})}function u({id:e,title:t,badge:n,badgeColor:r}){return(0,o.jsxs)(`div`,{id:e,className:`flex items-center gap-3 mb-6 pt-2 scroll-mt-6`,children:[(0,o.jsx)(`h2`,{className:`text-base font-black text-[#3D4E4B] dark:text-white tracking-tight`,children:t}),n&&(0,o.jsx)(c,{color:r,children:n}),(0,o.jsx)(`div`,{className:`flex-1 h-px bg-gray-100 dark:bg-white/10`})]})}function d({method:e,path:t,desc:n,auth:r=!0}){return(0,o.jsxs)(`div`,{className:`flex items-center gap-3 py-3 border-b border-gray-50 last:border-0`,children:[(0,o.jsx)(`span`,{className:`shrink-0 px-2.5 py-1 rounded-lg text-[10px] font-black tracking-widest uppercase ${{GET:`bg-blue-100 text-blue-700`,POST:`bg-emerald-100 text-emerald-700`,PATCH:`bg-amber-100 text-amber-700`,DELETE:`bg-red-100 text-red-700`,PUT:`bg-purple-100 text-purple-700`}[e]??`bg-gray-100 text-gray-600`}`,children:e}),(0,o.jsx)(`code`,{className:`flex-1 text-xs font-mono text-[#3D4E4B] font-bold`,children:t}),(0,o.jsx)(`span`,{className:`text-xs text-gray-400 font-medium hidden md:block`,children:n}),r&&(0,o.jsx)(`span`,{className:`shrink-0 text-[10px] text-amber-600 font-bold`,children:`🔒 Auth`})]})}function f(){let[e,t]=(0,a.useState)(`intro`),r=(0,a.useRef)(null);(0,a.useEffect)(()=>{let e=s.map(e=>e.id),n=new IntersectionObserver(e=>{let n=e.filter(e=>e.isIntersecting).sort((e,t)=>e.boundingClientRect.top-t.boundingClientRect.top);n.length>0&&t(n[0].target.id)},{rootMargin:`-20% 0px -70% 0px`,threshold:0});return e.forEach(e=>{let t=document.getElementById(e);t&&n.observe(t)}),()=>n.disconnect()},[]);let f=e=>{document.getElementById(e)?.scrollIntoView({behavior:`smooth`,block:`start`})};return(0,o.jsxs)(i,{children:[(0,o.jsx)(n,{title:`Dokumentasi biiproject kit v2`}),(0,o.jsxs)(`div`,{className:`flex items-center justify-between mb-8 anim-down`,children:[(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`h1`,{className:`text-xl font-bold text-[#3D4E4B] dark:text-white tracking-tight leading-none`,children:`Dokumentasi`}),(0,o.jsx)(`p`,{className:`text-sm font-semibold text-gray-400 tracking-tight mt-2`,children:`Panduan lengkap biiproject kit v2`})]}),(0,o.jsx)(c,{color:`green`,children:`v2.0`})]}),(0,o.jsxs)(`div`,{className:`flex gap-8 anim-up`,children:[(0,o.jsx)(`aside`,{className:`hidden lg:block w-52 shrink-0`,children:(0,o.jsx)(`div`,{className:`sticky top-6 bg-white dark:bg-[#1A2120] rounded-2xl border border-gray-100 dark:border-white/10 shadow-sm p-3 space-y-0.5`,children:s.map(t=>(0,o.jsxs)(`button`,{onClick:()=>f(t.id),className:`w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-xs font-bold text-left transition-all ${e===t.id?`bg-[#3D4E4B] text-white`:`text-gray-500 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-white/5 hover:text-[#3D4E4B] dark:hover:text-white`}`,children:[(0,o.jsx)(`span`,{className:`shrink-0 ${e===t.id?`text-[#D4A017]`:``}`,children:t.icon}),t.label]},t.id))})}),(0,o.jsxs)(`div`,{ref:r,className:`flex-1 min-w-0 space-y-12 pb-20`,children:[(0,o.jsxs)(`section`,{children:[(0,o.jsx)(u,{id:`intro`,title:`Pendahuluan`,badge:`Starter Kit`,badgeColor:`blue`}),(0,o.jsxs)(`div`,{className:`bg-white dark:bg-[#1A2120] rounded-2xl border border-gray-100 dark:border-white/10 shadow-sm p-8 space-y-4`,children:[(0,o.jsxs)(`p`,{className:`text-sm text-gray-600 dark:text-gray-300 font-medium leading-relaxed`,children:[(0,o.jsx)(`strong`,{className:`text-[#3D4E4B] dark:text-white`,children:`biiproject kit v2`}),` adalah starter kit enterprise berbasis `,(0,o.jsx)(`strong`,{children:`Laravel 13 + React (Inertia.js)`}),` yang dirancang untuk mempercepat pembangunan aplikasi web dengan fitur manajemen pengguna, hak akses berbasis peran, monitoring aktivitas, notifikasi, dan konfigurasi sistem yang lengkap.`]}),(0,o.jsx)(`div`,{className:`grid grid-cols-2 md:grid-cols-4 gap-4 pt-2`,children:[{label:`Users & Roles`,icon:`👥`},{label:`Activity Logs`,icon:`📋`},{label:`System Settings`,icon:`⚙️`},{label:`Two-Factor Auth`,icon:`🔒`},{label:`REST API v1`,icon:`🔌`},{label:`Dark Mode`,icon:`🌙`},{label:`Notifikasi`,icon:`🔔`},{label:`Mobile Ready`,icon:`📱`}].map(e=>(0,o.jsxs)(`div`,{className:`p-4 bg-gray-50 dark:bg-white/5 rounded-xl text-center`,children:[(0,o.jsx)(`div`,{className:`text-2xl mb-1`,children:e.icon}),(0,o.jsx)(`div`,{className:`text-[11px] font-bold text-[#3D4E4B] dark:text-white`,children:e.label})]},e.label))})]})]}),(0,o.jsxs)(`section`,{children:[(0,o.jsx)(u,{id:`quickstart`,title:`Quick Start`,badge:`Setup`,badgeColor:`green`}),(0,o.jsxs)(`div`,{className:`bg-white dark:bg-[#1A2120] rounded-2xl border border-gray-100 dark:border-white/10 shadow-sm p-8 space-y-6`,children:[(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`h3`,{className:`text-xs font-black text-[#3D4E4B] dark:text-white uppercase tracking-widest mb-2`,children:`1. Clone & Install`}),(0,o.jsx)(l,{lang:`bash`,children:`git clone https://github.com/your-org/biiskit.git +cd biiskit +composer install +npm install`})]}),(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`h3`,{className:`text-xs font-black text-[#3D4E4B] dark:text-white uppercase tracking-widest mb-2`,children:`2. Konfigurasi Environment`}),(0,o.jsx)(l,{lang:`bash`,children:`cp .env.example .env +php artisan key:generate + +# Edit .env sesuai konfigurasi database +DB_CONNECTION=pgsql +DB_HOST=127.0.0.1 +DB_PORT=5432 +DB_DATABASE=biiskit +DB_USERNAME=your_user +DB_PASSWORD=your_password`})]}),(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`h3`,{className:`text-xs font-black text-[#3D4E4B] dark:text-white uppercase tracking-widest mb-2`,children:`3. Migrasi & Seeder`}),(0,o.jsx)(l,{lang:`bash`,children:`php artisan migrate --seed`}),(0,o.jsxs)(`p`,{className:`text-xs text-gray-400 font-medium mt-2`,children:[`Seeder akan membuat 3 akun default: `,(0,o.jsx)(`code`,{className:`bg-gray-100 dark:bg-white/10 px-1.5 py-0.5 rounded font-mono`,children:`superadmin`}),`, `,(0,o.jsx)(`code`,{className:`bg-gray-100 dark:bg-white/10 px-1.5 py-0.5 rounded font-mono`,children:`admin`}),`, dan `,(0,o.jsx)(`code`,{className:`bg-gray-100 dark:bg-white/10 px-1.5 py-0.5 rounded font-mono`,children:`user`}),`.`]})]}),(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`h3`,{className:`text-xs font-black text-[#3D4E4B] dark:text-white uppercase tracking-widest mb-2`,children:`4. Jalankan Server`}),(0,o.jsx)(l,{lang:`bash`,children:`# Terminal 1 — Laravel +php artisan serve + +# Terminal 2 — Vite dev server +npm run dev`})]}),(0,o.jsx)(`div`,{className:`p-4 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700/40 rounded-xl`,children:(0,o.jsxs)(`p`,{className:`text-xs font-bold text-amber-700 dark:text-amber-400`,children:[`Akses aplikasi di `,(0,o.jsx)(`code`,{className:`font-mono`,children:`http://localhost:8000`}),` — redirect otomatis ke halaman login.`]})})]})]}),(0,o.jsxs)(`section`,{children:[(0,o.jsx)(u,{id:`stack`,title:`Tech Stack`}),(0,o.jsx)(`div`,{className:`bg-white dark:bg-[#1A2120] rounded-2xl border border-gray-100 dark:border-white/10 shadow-sm p-8`,children:(0,o.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4`,children:[{layer:`Backend`,items:[`Laravel 13`,`PHP 8.3`,`PostgreSQL`,`Laravel Sanctum`,`Spatie Permission`,`Spatie Activity Log`]},{layer:`Frontend`,items:[`React 18`,`Inertia.js v2`,`TypeScript`,`Tailwind CSS v4`,`Vite 6`,`Chart.js`]},{layer:`Keamanan`,items:[`RBAC (Role-Based Access Control)`,`Two-Factor Auth (TOTP)`,`Sanctum API Tokens`,`Gate::before super-admin bypass`,`Bcrypt Password Hashing`]},{layer:`DevOps`,items:[`PostgreSQL + Redis (Docker ready)`,`Laravel Queue (database)`,`Cache: database driver`,`Pest PHP testing suite`]}].map(e=>(0,o.jsxs)(`div`,{className:`p-5 bg-gray-50 dark:bg-white/5 rounded-xl`,children:[(0,o.jsx)(`div`,{className:`text-xs font-black text-[#D4A017] uppercase tracking-widest mb-3`,children:e.layer}),(0,o.jsx)(`div`,{className:`space-y-1.5`,children:e.items.map(e=>(0,o.jsxs)(`div`,{className:`flex items-center gap-2 text-xs font-semibold text-gray-600 dark:text-gray-300`,children:[(0,o.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-[#3D4E4B] dark:bg-[#D4A017] shrink-0`}),e]},e))})]},e.layer))})})]}),(0,o.jsxs)(`section`,{children:[(0,o.jsx)(u,{id:`auth`,title:`Autentikasi`,badge:`Web + API`,badgeColor:`purple`}),(0,o.jsxs)(`div`,{className:`bg-white dark:bg-[#1A2120] rounded-2xl border border-gray-100 dark:border-white/10 shadow-sm p-8 space-y-6`,children:[(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`h3`,{className:`text-xs font-black text-[#3D4E4B] dark:text-white uppercase tracking-widest mb-4`,children:`Akun Bawaan (Seeder)`}),(0,o.jsx)(`div`,{className:`overflow-x-auto`,children:(0,o.jsxs)(`table`,{className:`w-full text-xs`,children:[(0,o.jsx)(`thead`,{children:(0,o.jsxs)(`tr`,{className:`border-b border-gray-100 dark:border-white/10`,children:[(0,o.jsx)(`th`,{className:`text-left font-black text-gray-400 uppercase tracking-widest py-2 pr-6`,children:`Email`}),(0,o.jsx)(`th`,{className:`text-left font-black text-gray-400 uppercase tracking-widest py-2 pr-6`,children:`Password`}),(0,o.jsx)(`th`,{className:`text-left font-black text-gray-400 uppercase tracking-widest py-2`,children:`Role`})]})}),(0,o.jsx)(`tbody`,{children:[{email:`superadmin@biiskit.com`,pw:`password`,role:`super-admin`,color:`red`},{email:`admin@biiskit.com`,pw:`password`,role:`admin`,color:`amber`},{email:`user@biiskit.com`,pw:`password`,role:`user`,color:`blue`}].map(e=>(0,o.jsxs)(`tr`,{className:`border-b border-gray-50 dark:border-white/5 last:border-0`,children:[(0,o.jsx)(`td`,{className:`py-3 pr-6 font-mono text-[#3D4E4B] dark:text-white font-bold`,children:e.email}),(0,o.jsx)(`td`,{className:`py-3 pr-6 font-mono text-gray-400`,children:e.pw}),(0,o.jsx)(`td`,{className:`py-3`,children:(0,o.jsx)(c,{color:e.color,children:e.role})})]},e.email))})]})})]}),(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`h3`,{className:`text-xs font-black text-[#3D4E4B] dark:text-white uppercase tracking-widest mb-3`,children:`Alur Login Web`}),(0,o.jsx)(`div`,{className:`flex flex-wrap gap-2 items-center text-xs font-bold text-gray-500`,children:[`Form Login`,`→`,`Auth Check`,`→`,`2FA Challenge?`,`→`,`Email Verified?`,`→`,`Dashboard`].map((e,t)=>(0,o.jsx)(`span`,{className:e===`→`?`text-gray-300`:`px-3 py-1.5 bg-gray-50 dark:bg-white/5 rounded-lg text-[#3D4E4B] dark:text-white`,children:e},t))}),(0,o.jsxs)(`p`,{className:`text-xs text-gray-400 font-medium mt-2`,children:[`2FA Challenge hanya muncul jika user telah mengaktifkan Two-Factor Auth di `,(0,o.jsx)(`code`,{className:`bg-gray-100 dark:bg-white/10 px-1 py-0.5 rounded font-mono`,children:`/settings#2fa`}),`.`]})]}),(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`h3`,{className:`text-xs font-black text-[#3D4E4B] dark:text-white uppercase tracking-widest mb-2`,children:`Login via API`}),(0,o.jsx)(l,{lang:`json`,children:`POST /api/v1/login +Content-Type: application/json + +{ + "email": "admin@biiskit.com", + "password": "password" +} + +// Response +{ + "token": "1|abc123...", + "user": { "id": 1, "email": "admin@biiskit.com", ... } +}`})]})]})]}),(0,o.jsxs)(`section`,{children:[(0,o.jsx)(u,{id:`roles`,title:`Roles & Permission`,badge:`Spatie`,badgeColor:`green`}),(0,o.jsxs)(`div`,{className:`bg-white dark:bg-[#1A2120] rounded-2xl border border-gray-100 dark:border-white/10 shadow-sm p-8 space-y-6`,children:[(0,o.jsxs)(`p`,{className:`text-sm text-gray-500 dark:text-gray-400 font-medium leading-relaxed`,children:[`Menggunakan `,(0,o.jsx)(`strong`,{className:`text-[#3D4E4B] dark:text-white`,children:`spatie/laravel-permission`}),`. Role `,(0,o.jsx)(c,{color:`red`,children:`super-admin`}),` mendapat akses penuh via `,(0,o.jsx)(`code`,{className:`text-[11px] bg-gray-100 dark:bg-white/10 px-1.5 py-0.5 rounded font-mono`,children:`Gate::before`}),` bypass — tidak perlu assign permission satu per satu.`]}),(0,o.jsx)(`div`,{className:`overflow-x-auto`,children:(0,o.jsxs)(`table`,{className:`w-full text-xs`,children:[(0,o.jsx)(`thead`,{children:(0,o.jsxs)(`tr`,{className:`border-b border-gray-100 dark:border-white/10`,children:[(0,o.jsx)(`th`,{className:`text-left font-black text-gray-400 uppercase tracking-widest py-2 pr-6`,children:`Permission`}),(0,o.jsx)(`th`,{className:`text-center font-black text-gray-400 uppercase tracking-widest py-2 px-4`,children:`user`}),(0,o.jsx)(`th`,{className:`text-center font-black text-gray-400 uppercase tracking-widest py-2 px-4`,children:`admin`}),(0,o.jsx)(`th`,{className:`text-center font-black text-gray-400 uppercase tracking-widest py-2 px-4`,children:`super-admin`})]})}),(0,o.jsx)(`tbody`,{children:[{perm:`user.view`,u:!0,a:!0,s:!0},{perm:`user.create`,u:!1,a:!0,s:!0},{perm:`user.edit`,u:!1,a:!0,s:!0},{perm:`user.delete`,u:!1,a:!0,s:!0},{perm:`role.view`,u:!1,a:!0,s:!0},{perm:`role.manage`,u:!1,a:!1,s:!0},{perm:`settings.manage`,u:!1,a:!1,s:!0},{perm:`reports.view`,u:!1,a:!0,s:!0}].map(e=>(0,o.jsxs)(`tr`,{className:`border-b border-gray-50 dark:border-white/5 last:border-0`,children:[(0,o.jsx)(`td`,{className:`py-3 pr-6 font-mono font-bold text-[#3D4E4B] dark:text-white`,children:e.perm}),[e.u,e.a,e.s].map((e,t)=>(0,o.jsx)(`td`,{className:`py-3 text-center px-4`,children:e?(0,o.jsx)(`span`,{className:`text-emerald-500 font-black text-sm`,children:`✓`}):(0,o.jsx)(`span`,{className:`text-gray-200 font-black text-sm`,children:`✗`})},t))]},e.perm))})]})}),(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`h3`,{className:`text-xs font-black text-[#3D4E4B] dark:text-white uppercase tracking-widest mb-2`,children:`Pengecekan Permission di Controller`}),(0,o.jsx)(l,{lang:`php`,children:`// Via Policy (model instance) +$this->authorize('update', $user); + +// Via Gate string (tanpa model) +$this->authorize('user.delete'); + +// Via Blade / React (shared props) +// auth.permissions = ['user.view', 'user.create', ...]`})]})]})]}),(0,o.jsxs)(`section`,{children:[(0,o.jsx)(u,{id:`features`,title:`Fitur Lengkap`}),(0,o.jsx)(`div`,{className:`bg-white dark:bg-[#1A2120] rounded-2xl border border-gray-100 dark:border-white/10 shadow-sm p-8 space-y-6`,children:[{title:`Manajemen Pengguna`,icon:`👥`,items:[`CRUD lengkap (tambah, edit, hapus, restore)`,`Soft delete dengan arsip & purge permanen`,`Bulk archive / restore / force-delete`,`Filter by status, role, pencarian nama/email`,`Sorting multi-kolom + pagination`,`Export ke Excel (.xlsx)`,`Import user massal via Excel/CSV`,`Assign multi-role per user`]},{title:`Roles & Permission Manager`,icon:`🛡️`,items:[`Kelola role dari UI (tambah / hapus role)`,`Assign/revoke permission per role via toggle`,`Super-admin bypass via Gate::before`,`3 role default: super-admin, admin, user`]},{title:`Notifikasi`,icon:`🔔`,items:[`Kirim notifikasi (email / in-app)`,`Target: all users, role tertentu, atau user spesifik`,`Log pengiriman dengan status (sent/failed)`,`Badge counter di topbar (unread last 7 hari)`,`Pagination history notifikasi`]},{title:`Activity Logs`,icon:`📋`,items:[`Log otomatis via spatie/laravel-activitylog`,`Filter by user, event, tanggal`,`Bulk delete logs`,`Tampilan subject & properties berubah`]},{title:`Dashboard`,icon:`📊`,items:[`Statistik total users, admin, active, inactive`,`Chart pendaftaran user 30 hari terakhir (Chart.js)`,`Tabel aktivitas terbaru`,`Quick actions (tambah user, lihat logs)`]},{title:`Account Settings`,icon:`👤`,items:[`Tab Profile: nama, email, telepon, bio, avatar upload`,`Tab Security & Password: ganti password`,`Tab Two-Factor Auth: aktifkan/nonaktifkan TOTP 2FA`,`Tab Danger Zone: hapus akun permanen`,`Tab aktif persisten saat reload (via URL hash)`]},{title:`UI/UX`,icon:`🎨`,items:[`Dark mode toggle (persisted di localStorage)`,`Sidebar responsif + burger menu mobile`,`Breadcrumb dinamis di topbar`,`Flash messages (success / error)`,`Animasi masuk halaman (anim-down, anim-up, anim-left)`,`Tab state persisten via URL hash (#tab-name)`,`Custom scrollbar`,`Error pages: 403, 404, 500`]}].map(e=>(0,o.jsxs)(`div`,{className:`p-5 bg-gray-50 dark:bg-white/5 rounded-xl`,children:[(0,o.jsxs)(`div`,{className:`flex items-center gap-3 mb-3`,children:[(0,o.jsx)(`span`,{className:`text-xl`,children:e.icon}),(0,o.jsx)(`div`,{className:`text-sm font-black text-[#3D4E4B] dark:text-white`,children:e.title})]}),(0,o.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-1.5`,children:e.items.map(e=>(0,o.jsxs)(`div`,{className:`flex items-start gap-2 text-xs font-medium text-gray-500 dark:text-gray-400`,children:[(0,o.jsx)(`span`,{className:`text-emerald-500 font-black mt-0.5 shrink-0`,children:`✓`}),e]},e))})]},e.title))})]}),(0,o.jsxs)(`section`,{children:[(0,o.jsx)(u,{id:`api`,title:`REST API`,badge:`v1`,badgeColor:`blue`}),(0,o.jsxs)(`div`,{className:`bg-white dark:bg-[#1A2120] rounded-2xl border border-gray-100 dark:border-white/10 shadow-sm p-8 space-y-6`,children:[(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`h3`,{className:`text-xs font-black text-[#3D4E4B] dark:text-white uppercase tracking-widest mb-2`,children:`Base URL`}),(0,o.jsx)(l,{lang:`http`,children:`http://your-domain.com/api/v1`})]}),(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`h3`,{className:`text-xs font-black text-[#3D4E4B] dark:text-white uppercase tracking-widest mb-2`,children:`Authentication Header`}),(0,o.jsx)(l,{lang:`http`,children:`Authorization: Bearer {your-sanctum-token}`})]}),(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`h3`,{className:`text-xs font-black text-[#3D4E4B] dark:text-white uppercase tracking-widest mb-4`,children:`Endpoints`}),(0,o.jsxs)(`div`,{className:`border border-gray-100 dark:border-white/10 rounded-xl overflow-hidden`,children:[(0,o.jsx)(`div`,{className:`px-4 py-2.5 bg-gray-50 dark:bg-white/5 border-b border-gray-100 dark:border-white/10`,children:(0,o.jsx)(`span`,{className:`text-[10px] font-black text-gray-400 uppercase tracking-widest`,children:`Auth`})}),(0,o.jsxs)(`div`,{className:`px-4`,children:[(0,o.jsx)(d,{method:`POST`,path:`/api/v1/login`,desc:`Dapatkan Sanctum token`,auth:!1}),(0,o.jsx)(d,{method:`GET`,path:`/api/v1/me`,desc:`Data user aktif`}),(0,o.jsx)(d,{method:`POST`,path:`/api/v1/logout`,desc:`Revoke token`})]}),(0,o.jsx)(`div`,{className:`px-4 py-2.5 bg-gray-50 dark:bg-white/5 border-y border-gray-100 dark:border-white/10`,children:(0,o.jsx)(`span`,{className:`text-[10px] font-black text-gray-400 uppercase tracking-widest`,children:`Users`})}),(0,o.jsxs)(`div`,{className:`px-4`,children:[(0,o.jsx)(d,{method:`GET`,path:`/api/v1/users`,desc:`List semua user`}),(0,o.jsx)(d,{method:`POST`,path:`/api/v1/users`,desc:`Buat user baru`}),(0,o.jsx)(d,{method:`GET`,path:`/api/v1/users/{id}`,desc:`Detail user`}),(0,o.jsx)(d,{method:`PATCH`,path:`/api/v1/users/{id}`,desc:`Update user`}),(0,o.jsx)(d,{method:`DELETE`,path:`/api/v1/users/{id}`,desc:`Hapus user`})]}),(0,o.jsx)(`div`,{className:`px-4 py-2.5 bg-gray-50 dark:bg-white/5 border-y border-gray-100 dark:border-white/10`,children:(0,o.jsx)(`span`,{className:`text-[10px] font-black text-gray-400 uppercase tracking-widest`,children:`App Config`})}),(0,o.jsx)(`div`,{className:`px-4`,children:(0,o.jsx)(d,{method:`GET`,path:`/api/v1/app-config`,desc:`Konfigurasi aplikasi publik`,auth:!1})})]})]})]})]}),(0,o.jsxs)(`section`,{children:[(0,o.jsx)(u,{id:`2fa`,title:`Two-Factor Authentication`,badge:`TOTP`,badgeColor:`amber`}),(0,o.jsxs)(`div`,{className:`bg-white dark:bg-[#1A2120] rounded-2xl border border-gray-100 dark:border-white/10 shadow-sm p-8 space-y-4`,children:[(0,o.jsxs)(`p`,{className:`text-sm text-gray-500 dark:text-gray-400 font-medium leading-relaxed`,children:[`2FA menggunakan protokol `,(0,o.jsx)(`strong`,{className:`text-[#3D4E4B] dark:text-white`,children:`TOTP (Time-based One-Time Password)`}),` yang kompatibel dengan Google Authenticator, Authy, dan 1Password.`]}),(0,o.jsx)(`div`,{className:`space-y-3`,children:[{step:`1`,title:`Buka tab Two-Factor Auth`,desc:`Masuk ke Account Settings (/settings) → tab "Two-Factor Auth"`},{step:`2`,title:`Scan QR Code`,desc:`Gunakan aplikasi authenticator (Google Authenticator / Authy) untuk scan QR`},{step:`3`,title:`Masukkan kode verifikasi`,desc:`Ketik 6 digit dari aplikasi untuk mengaktifkan 2FA`},{step:`4`,title:`Simpan recovery codes`,desc:`8 kode cadangan tersedia — simpan di tempat aman jika kehilangan akses ke authenticator`},{step:`5`,title:`Login berikutnya`,desc:`Setelah diaktifkan, setiap login akan redirect ke halaman 2FA Challenge sebelum masuk dashboard`}].map(e=>(0,o.jsxs)(`div`,{className:`flex items-start gap-4 p-4 bg-gray-50 dark:bg-white/5 rounded-xl`,children:[(0,o.jsx)(`div`,{className:`w-7 h-7 rounded-full bg-[#3D4E4B] text-white text-xs font-black flex items-center justify-center shrink-0`,children:e.step}),(0,o.jsxs)(`div`,{children:[(0,o.jsx)(`div`,{className:`text-sm font-bold text-[#3D4E4B] dark:text-white`,children:e.title}),(0,o.jsx)(`div`,{className:`text-xs text-gray-400 font-medium mt-0.5`,children:e.desc})]})]},e.step))}),(0,o.jsx)(`div`,{className:`p-4 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-700/40 rounded-xl`,children:(0,o.jsx)(`p`,{className:`text-xs font-bold text-blue-700 dark:text-blue-400`,children:`2FA bersifat opsional per user. Setelah diaktifkan, setiap login akan meminta kode 6 digit dari authenticator.`})})]})]}),(0,o.jsxs)(`section`,{children:[(0,o.jsx)(u,{id:`settings`,title:`System Settings`,badge:`Super Admin`,badgeColor:`red`}),(0,o.jsxs)(`div`,{className:`bg-white dark:bg-[#1A2120] rounded-2xl border border-gray-100 dark:border-white/10 shadow-sm p-8 space-y-4`,children:[(0,o.jsxs)(`p`,{className:`text-sm text-gray-500 dark:text-gray-400 font-medium`,children:[`Hanya bisa diakses oleh pengguna dengan role `,(0,o.jsx)(c,{color:`red`,children:`super-admin`}),`. Tersedia di `,(0,o.jsx)(`code`,{className:`text-xs bg-gray-100 dark:bg-white/10 px-2 py-0.5 rounded font-mono`,children:`/system-settings`}),`.`]}),(0,o.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4`,children:[{tab:`General & Branding`,items:[`Nama aplikasi`,`Logo upload`,`Teks logo fallback`,`Registrasi publik on/off`,`Verifikasi email on/off`]},{tab:`Security & OAuth`,items:[`Password minimum panjang`,`Wajib huruf besar/kecil/angka/simbol`,`Google OAuth (Client ID & Secret)`,`GitHub OAuth (Client ID & Secret)`]},{tab:`Email / SMTP`,items:[`Host & port SMTP`,`Enkripsi (TLS/SSL)`,`Username & password SMTP`,`From name & address`,`Test kirim email dari UI`]},{tab:`Mobile App Control`,items:[`Versi terbaru & minimum Android`,`URL Play Store`,`Mode maintenance mobile app`,`Pesan maintenance kustom`]}].map(e=>(0,o.jsxs)(`div`,{className:`p-5 bg-gray-50 dark:bg-white/5 rounded-xl`,children:[(0,o.jsx)(`div`,{className:`text-xs font-black text-[#D4A017] uppercase tracking-widest mb-3`,children:e.tab}),e.items.map(e=>(0,o.jsxs)(`div`,{className:`flex items-center gap-2 text-xs font-semibold text-gray-500 dark:text-gray-400 mb-1.5`,children:[(0,o.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-600 shrink-0`}),e]},e))]},e.tab))})]})]}),(0,o.jsxs)(`section`,{children:[(0,o.jsx)(u,{id:`structure`,title:`Struktur Folder`}),(0,o.jsx)(`div`,{className:`bg-white dark:bg-[#1A2120] rounded-2xl border border-gray-100 dark:border-white/10 shadow-sm p-8 space-y-4`,children:(0,o.jsx)(l,{lang:`text`,children:`biiskit/ +├── app/ +│ ├── Http/ +│ │ ├── Controllers/ # Web + API controllers +│ │ │ └── Api/V1/ # REST API v1 controllers +│ │ ├── Middleware/ +│ │ │ └── HandleInertiaRequests.php # Shared props (auth, settings) +│ │ └── Requests/ # Form request validation +│ ├── Models/ +│ │ ├── User.php # SoftDeletes + HasRoles + HasPermissions +│ │ ├── Setting.php # System settings key-value store +│ │ └── NotificationLog.php # Notifikasi log +│ └── Policies/ +│ └── UserPolicy.php # Gate policies untuk user CRUD +│ +├── database/ +│ ├── migrations/ # PostgreSQL migrations +│ └── seeders/ +│ └── DatabaseSeeder.php # Roles, permissions, demo users +│ +├── resources/js/ +│ ├── Layouts/ +│ │ ├── AuthenticatedLayout.tsx # Wrapper utama + mobile sidebar +│ │ └── components/ +│ │ ├── Sidebar.tsx # Nav dengan permission check +│ │ └── Topbar.tsx # Breadcrumb + notif bell + dark mode +│ ├── Pages/ +│ │ ├── Auth/ # Login, Register, Password reset +│ │ ├── Dashboard/ # Dashboard dengan chart +│ │ ├── Users/ # Index, Show (CRUD) +│ │ ├── Roles/ # Roles & permission manager +│ │ ├── Notifications/ # Kirim & history notifikasi +│ │ ├── ActivityLogs/ # Log aktivitas +│ │ ├── Settings/ # Account settings (profile, password, 2FA, danger zone) +│ │ ├── TwoFactor/ # 2FA challenge page (login flow, no auth) +│ │ ├── SystemSettings/ # Sistem config (super-admin) +│ │ ├── Docs/ # Halaman dokumentasi ini +│ │ └── Errors/ # 403, 404, 500 pages +│ └── Components/ +│ ├── DataTable.tsx # Reusable sortable table +│ └── FlashMessage.tsx # Success/error flash +│ +├── routes/ +│ ├── web.php # Web routes (Inertia) +│ └── api.php # API routes (Sanctum) +│ +└── tests/ + ├── Feature/ # Feature tests (Pest) + └── Unit/ # Unit tests`})})]})]})]})]})}export{f as default}; \ No newline at end of file diff --git a/public/build/assets/Index-Cm49_1vz.js b/public/build/assets/Index-Cm49_1vz.js new file mode 100644 index 0000000..a121621 --- /dev/null +++ b/public/build/assets/Index-Cm49_1vz.js @@ -0,0 +1 @@ +import{c as e,d as t,i as n,n as r,t as i}from"./app-BJ7g6sa8.js";import{t as a}from"./AuthenticatedLayout-CrB9BCoI.js";import{n as o,t as s}from"./lodash-ZrZcSXd_.js";import{t as c}from"./Portal-DJbp1s68.js";var l=t(e(),1),u=t(s(),1),d=i();function f({activity:e,onClose:t}){let[n,r]=(0,l.useState)(!1),i=JSON.stringify(e.properties,null,4);return(0,d.jsx)(c,{children:(0,d.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-[#3D4E4B]/60 backdrop-blur-md anim-fade`,children:(0,d.jsxs)(`div`,{className:`bg-white w-full max-w-2xl rounded-2xl shadow-2xl overflow-hidden anim-zoom border border-gray-100 flex flex-col max-h-[90vh]`,children:[(0,d.jsxs)(`div`,{className:`p-8 border-b border-gray-50 shrink-0`,children:[(0,d.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,d.jsx)(`h2`,{className:`text-xl font-bold text-[#3D4E4B] tracking-tight`,children:`Activity Details`}),(0,d.jsx)(`button`,{onClick:t,className:`p-2 hover:bg-gray-50 rounded-xl transition-colors`,children:(0,d.jsx)(`svg`,{className:`w-5 h-5 text-gray-400`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,d.jsx)(`path`,{d:`M6 18L18 6M6 6l12 12`})})})]}),(0,d.jsx)(`p`,{className:`text-sm text-gray-400 font-medium`,children:e.description})]}),(0,d.jsxs)(`div`,{className:`p-8 overflow-y-auto custom-scrollbar space-y-8`,children:[(0,d.jsxs)(`div`,{className:`grid grid-cols-2 gap-8`,children:[(0,d.jsxs)(`div`,{className:`space-y-1`,children:[(0,d.jsx)(`label`,{className:`text-[10px] font-bold text-gray-400 uppercase tracking-widest`,children:`Performed By`}),(0,d.jsx)(`p`,{className:`text-sm font-bold text-[#3D4E4B]`,children:e.causer?`${e.causer.first_name} ${e.causer.last_name}`:`System`})]}),(0,d.jsxs)(`div`,{className:`space-y-1 text-right`,children:[(0,d.jsx)(`label`,{className:`text-[10px] font-bold text-gray-400 uppercase tracking-widest`,children:`Date & Time`}),(0,d.jsx)(`p`,{className:`text-sm font-bold text-[#3D4E4B]`,children:new Date(e.created_at).toLocaleString()})]}),(0,d.jsxs)(`div`,{className:`space-y-1`,children:[(0,d.jsx)(`label`,{className:`text-[10px] font-bold text-gray-400 uppercase tracking-widest`,children:`Log Name`}),(0,d.jsx)(`p`,{className:`text-sm font-bold text-[#3D4E4B]`,children:e.log_name})]}),(0,d.jsxs)(`div`,{className:`space-y-1 text-right`,children:[(0,d.jsx)(`label`,{className:`text-[10px] font-bold text-gray-400 uppercase tracking-widest`,children:`Subject`}),(0,d.jsxs)(`p`,{className:`text-sm font-bold text-[#3D4E4B]`,children:[e.subject_type.split(`\\`).pop(),` #`,e.subject_id]})]})]}),(0,d.jsxs)(`div`,{className:`space-y-4`,children:[(0,d.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,d.jsx)(`label`,{className:`text-[10px] font-bold text-gray-400 uppercase tracking-widest`,children:`Data Changes / Properties`}),(0,d.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,d.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(i),r(!0),setTimeout(()=>r(!1),2e3)},className:`text-[10px] font-bold px-2 py-0.5 rounded-lg border transition-all uppercase tracking-tight flex items-center gap-1 ${n?`bg-green-500/10 text-green-500 border-green-500/20`:`bg-[#D4A017]/5 text-[#D4A017] border-[#D4A017]/10 hover:bg-[#D4A017]/10`}`,children:n?(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(`svg`,{className:`w-3 h-3`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:3,children:(0,d.jsx)(`path`,{d:`M5 13l4 4L19 7`})}),`Copied`]}):(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(`svg`,{className:`w-3 h-3`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,d.jsx)(`path`,{d:`M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2`})}),`Copy JSON`]})}),(0,d.jsx)(`span`,{className:`text-[10px] font-bold text-gray-400 bg-gray-50 px-2 py-0.5 rounded-lg border border-gray-100 uppercase tracking-tight`,children:`JSON Format`})]})]}),(0,d.jsx)(`div`,{className:`bg-[#1E1E1E] p-6 overflow-hidden shadow-inner border border-white/5 relative group`,children:(0,d.jsx)(`pre`,{className:`text-[11px] font-mono text-gray-300 whitespace-pre-wrap break-all leading-relaxed custom-scrollbar max-h-[400px] overflow-y-auto`,children:i})})]})]}),(0,d.jsx)(`div`,{className:`p-8 border-t border-gray-50 bg-gray-50/30 shrink-0 flex justify-end`,children:(0,d.jsx)(`button`,{onClick:t,className:`h-11 px-8 bg-white border border-gray-200 rounded-xl text-sm font-bold text-[#3D4E4B] hover:bg-gray-50 transition-all shadow-sm`,children:`Close`})})]})})})}function p({activities:e,filters:t,availableLogNames:i,availableEvents:s}){let[p,m]=(0,l.useState)(!1),[h,g]=(0,l.useState)(null),[_,v]=(0,l.useState)([]),[y,b]=(0,l.useState)({search:t.search||``,log_name:t.log_name||``,event:t.event||``,per_page:t.per_page||15}),x=(0,l.useCallback)(u.default.debounce(e=>{m(!0),n.get(route(`activity-logs.index`),e,{preserveState:!0,preserveScroll:!0,replace:!0,only:[`activities`,`filters`],onFinish:()=>m(!1)})},400),[]),S=(e,t)=>{let n={...y,[e]:t};b(n);let r={...n,page:1};v([]),x(r)};return(0,d.jsxs)(a,{children:[(0,d.jsx)(r,{title:`Activity Logs`}),(0,d.jsxs)(`div`,{className:`flex items-center justify-between mb-8 anim-down`,children:[(0,d.jsxs)(`div`,{children:[(0,d.jsx)(`h1`,{className:`text-xl font-bold text-[#3D4E4B] tracking-tight leading-none`,children:`Activity Logs`}),(0,d.jsx)(`p`,{className:`text-sm font-semibold text-gray-400 tracking-tight mt-2`,children:`Audit trail of system events and user actions`})]}),(0,d.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,d.jsxs)(`div`,{className:`relative w-[240px]`,children:[(0,d.jsx)(`svg`,{className:`absolute left-3.5 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400 pointer-events-none`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,d.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z`})}),(0,d.jsx)(`input`,{type:`text`,placeholder:`Search logs…`,value:y.search,onChange:e=>S(`search`,e.target.value),className:`w-full h-11 pl-10 pr-4 rounded-2xl border border-gray-100 bg-white text-sm font-semibold text-gray-700 placeholder-gray-400 focus:outline-none focus:border-[#D4A017] focus:ring-4 focus:ring-[#D4A017]/5 transition-all shadow-sm`})]}),(0,d.jsxs)(`select`,{value:y.log_name,onChange:e=>S(`log_name`,e.target.value),className:`h-11 px-4 rounded-2xl border border-gray-100 bg-white text-sm font-semibold text-gray-700 focus:outline-none focus:border-[#D4A017] focus:ring-4 focus:ring-[#D4A017]/5 transition-all shadow-sm cursor-pointer min-w-[140px]`,children:[(0,d.jsx)(`option`,{value:``,children:`All Logs`}),i.map(e=>(0,d.jsx)(`option`,{value:e,children:e},e))]}),(0,d.jsxs)(`select`,{value:y.event,onChange:e=>S(`event`,e.target.value),className:`h-11 px-4 rounded-2xl border border-gray-100 bg-white text-sm font-semibold text-gray-700 focus:outline-none focus:border-[#D4A017] focus:ring-4 focus:ring-[#D4A017]/5 transition-all shadow-sm cursor-pointer min-w-[140px]`,children:[(0,d.jsx)(`option`,{value:``,children:`All Events`}),s.map(e=>(0,d.jsx)(`option`,{value:e,children:e},e))]})]})]}),(0,d.jsx)(`div`,{className:`anim-up`,children:(0,d.jsx)(o,{data:e.data,columns:[{header:`Activity`,accessorKey:`description`,cell:e=>(0,d.jsxs)(`div`,{className:`flex flex-col`,children:[(0,d.jsx)(`span`,{className:`text-sm font-bold text-[#3D4E4B] tracking-tight`,children:e.description}),(0,d.jsx)(`span`,{className:`text-[10px] text-gray-400 font-bold uppercase tracking-widest mt-0.5`,children:e.log_name})]})},{header:`Causer`,accessorKey:`causer`,cell:e=>(0,d.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,d.jsx)(`div`,{className:`w-8 h-8 rounded-lg bg-gray-100 flex items-center justify-center text-[10px] font-bold text-gray-500`,children:e.causer?`${e.causer.first_name[0]}${e.causer.last_name[0]}`:`SYS`}),(0,d.jsxs)(`div`,{className:`flex flex-col`,children:[(0,d.jsx)(`span`,{className:`text-xs font-bold text-[#3D4E4B]`,children:e.causer?`${e.causer.first_name} ${e.causer.last_name}`:`System`}),(0,d.jsx)(`span`,{className:`text-[10px] text-gray-400 font-semibold`,children:e.causer?.email||`automated@system`})]})]})},{header:`Properties`,accessorKey:`properties`,cell:e=>(0,d.jsx)(`div`,{className:`max-w-[300px] truncate`,children:(0,d.jsx)(`code`,{className:`text-[10px] bg-gray-50 px-1.5 py-0.5 rounded text-gray-500 font-semibold`,children:JSON.stringify(e.properties)})})},{header:`Date & Time`,accessorKey:`created_at`,cell:e=>(0,d.jsx)(`span`,{className:`text-xs font-semibold text-gray-400 tracking-tight`,children:new Date(e.created_at).toLocaleString(`en-US`,{day:`2-digit`,month:`short`,year:`numeric`,hour:`2-digit`,minute:`2-digit`})})},{header:`Action`,accessorKey:`actions`,cell:e=>(0,d.jsx)(`div`,{className:`flex justify-end pr-4`,children:(0,d.jsx)(`button`,{onClick:()=>g(e),className:`p-2 rounded-xl text-gray-400 hover:text-[#D4A017] hover:bg-[#D4A017]/5 transition-all opacity-0 group-hover:opacity-100 translate-x-2 group-hover:translate-x-0`,title:`View Details`,children:(0,d.jsxs)(`svg`,{className:`w-5 h-5`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:[(0,d.jsx)(`path`,{d:`M15 12a3 3 0 11-6 0 3 3 0 016 0z`}),(0,d.jsx)(`path`,{d:`M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z`})]})})})}],meta:e.meta,links:e.links,filters:y,isLoading:p,selectedIds:_,onSelectionChange:v})}),h&&(0,d.jsx)(f,{activity:h,onClose:()=>g(null)}),(0,d.jsx)(c,{children:(0,d.jsx)(`div`,{className:`fixed bottom-8 left-1/2 -translate-x-1/2 z-40 transition-all duration-500 ${_.length>0?`translate-y-0 opacity-100`:`translate-y-20 opacity-0 pointer-events-none`}`,children:(0,d.jsxs)(`div`,{className:`bg-[#3D4E4B] rounded-2xl shadow-2xl px-6 py-4 flex items-center gap-6 border border-white/10 backdrop-blur-xl`,children:[(0,d.jsxs)(`div`,{className:`flex items-center gap-3 pr-6 border-r border-white/10`,children:[(0,d.jsx)(`span`,{className:`w-8 h-8 rounded-lg bg-white/10 flex items-center justify-center text-white text-xs font-bold`,children:_.length}),(0,d.jsx)(`span`,{className:`text-white text-sm font-bold tracking-tight`,children:`Logs selected`})]}),(0,d.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,d.jsxs)(`button`,{onClick:()=>{let e=_.length;swal.confirm(`Purge Logs?`,`Are you sure you want to permanently delete ${e} activity logs?`,`Purge`).then(t=>{t.isConfirmed&&n.post(route(`activity-logs.bulk-delete`),{ids:_},{preserveScroll:!0,onSuccess:()=>{v([]),swal.success(`Purged`,`${e} logs deleted successfully.`)}})})},className:`h-10 px-5 rounded-xl bg-red-500 text-white text-xs font-bold hover:bg-red-600 transition-all flex items-center gap-2`,children:[(0,d.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,d.jsx)(`path`,{d:`M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16`})}),`Bulk Purge`]}),(0,d.jsx)(`button`,{onClick:()=>v([]),className:`h-10 px-4 text-white/40 text-xs font-bold hover:text-white transition-colors`,children:`Cancel`})]})]})})})]})}export{p as default}; \ No newline at end of file diff --git a/public/build/assets/Index-DLpY0zj1.js b/public/build/assets/Index-DLpY0zj1.js new file mode 100644 index 0000000..7f8568b --- /dev/null +++ b/public/build/assets/Index-DLpY0zj1.js @@ -0,0 +1,3 @@ +import{a as e,c as t,i as n,n as r,t as i}from"./app-BJ7g6sa8.js";import{t as a}from"./AuthenticatedLayout-CrB9BCoI.js";import{t as o}from"./swal-DZXjpqDE.js";t();var s=i();function c({logs:t,users:i}){let{data:c,setData:l,post:u,processing:d,reset:f,errors:p}=e({title:``,body:``,image_url:``,deep_link:``,target_type:`all`,target_user_id:``});return(0,s.jsxs)(a,{children:[(0,s.jsx)(r,{title:`Push Notifications`}),(0,s.jsx)(`div`,{className:`flex items-center justify-between mb-8 anim-down`,children:(0,s.jsxs)(`div`,{children:[(0,s.jsx)(`h1`,{className:`text-xl font-bold text-[#3D4E4B] tracking-tight leading-none`,children:`Notification Center`}),(0,s.jsx)(`p`,{className:`text-sm font-semibold text-gray-400 tracking-tight mt-2`,children:`Broadcast messages and alerts to Android devices`})]})}),(0,s.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-12 gap-8`,children:[(0,s.jsx)(`div`,{className:`lg:col-span-5`,children:(0,s.jsxs)(`div`,{className:`bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden anim-up`,children:[(0,s.jsxs)(`div`,{className:`px-6 py-4 border-b border-gray-50 bg-gray-50/30`,children:[(0,s.jsx)(`h2`,{className:`text-sm font-bold text-[#3D4E4B] tracking-tight`,children:`Compose Broadcast`}),(0,s.jsx)(`p`,{className:`text-[10px] text-gray-400 font-bold uppercase tracking-widest mt-1`,children:`New FCM Message`})]}),(0,s.jsx)(`div`,{className:`p-8`,children:(0,s.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),u(route(`notifications.store`),{onSuccess:()=>{f(),o.success(`Dispatched`,`Notification has been sent to devices.`)}})},className:`space-y-6`,children:[(0,s.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,s.jsx)(`label`,{className:`text-xs font-bold text-gray-500 ml-1`,children:`Message Title`}),(0,s.jsx)(`input`,{value:c.title,onChange:e=>l(`title`,e.target.value),placeholder:`e.g. Flash Sale Alert!`,className:`input-field ${p.title?`is-error`:``}`}),p.title&&(0,s.jsx)(`p`,{className:`text-[10px] text-red-500 font-bold ml-1`,children:p.title})]}),(0,s.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,s.jsx)(`label`,{className:`text-xs font-bold text-gray-500 ml-1`,children:`Message Body`}),(0,s.jsx)(`textarea`,{value:c.body,onChange:e=>l(`body`,e.target.value),rows:3,placeholder:`Write your notification message here...`,className:`input-field py-3 resize-none ${p.body?`is-error`:``}`}),p.body&&(0,s.jsx)(`p`,{className:`text-[10px] text-red-500 font-bold ml-1`,children:p.body})]}),(0,s.jsxs)(`div`,{className:`grid grid-cols-2 gap-4`,children:[(0,s.jsxs)(`div`,{className:`space-y-1.5 text-xs font-bold text-gray-500 ml-1`,children:[(0,s.jsx)(`label`,{children:`Target Audience`}),(0,s.jsxs)(`select`,{value:c.target_type,onChange:e=>l(`target_type`,e.target.value),className:`input-field mt-1.5 h-10`,children:[(0,s.jsx)(`option`,{value:`all`,children:`All Users`}),(0,s.jsx)(`option`,{value:`individual`,children:`Specific User`})]})]}),c.target_type===`individual`&&(0,s.jsxs)(`div`,{className:`space-y-1.5 text-xs font-bold text-gray-500 ml-1`,children:[(0,s.jsx)(`label`,{children:`Select User`}),(0,s.jsxs)(`select`,{value:c.target_user_id,onChange:e=>l(`target_user_id`,e.target.value),className:`input-field mt-1.5 h-10`,children:[(0,s.jsx)(`option`,{value:``,children:`Choose User...`}),i.map(e=>(0,s.jsxs)(`option`,{value:e.id,children:[e.first_name,` `,e.last_name]},e.id))]})]})]}),(0,s.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,s.jsx)(`label`,{className:`text-xs font-bold text-gray-500 ml-1`,children:`Deep Link (Optional)`}),(0,s.jsx)(`input`,{value:c.deep_link,onChange:e=>l(`deep_link`,e.target.value),placeholder:`app://screen/profile`,className:`input-field`})]}),(0,s.jsx)(`div`,{className:`pt-4 border-t border-gray-50`,children:(0,s.jsx)(`button`,{type:`submit`,disabled:d,className:`w-full h-11 bg-[#3D4E4B] text-white text-xs font-black uppercase tracking-widest rounded-xl hover:bg-[#2D3A38] transition-all shadow-lg shadow-[#3D4E4B]/20 disabled:opacity-60`,children:d?`Sending...`:`Send Notification`})})]})})]})}),(0,s.jsx)(`div`,{className:`lg:col-span-7`,children:(0,s.jsxs)(`div`,{className:`bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden anim-up`,style:{animationDelay:`0.1s`},children:[(0,s.jsx)(`div`,{className:`px-6 py-4 border-b border-gray-50`,children:(0,s.jsx)(`h2`,{className:`text-sm font-bold text-[#3D4E4B] tracking-tight`,children:`Recent Broadcasts`})}),(0,s.jsx)(`div`,{className:`overflow-x-auto`,children:(0,s.jsxs)(`table`,{className:`w-full text-left border-collapse`,children:[(0,s.jsx)(`thead`,{className:`bg-gray-50/50`,children:(0,s.jsxs)(`tr`,{children:[(0,s.jsx)(`th`,{className:`px-6 py-3 text-[10px] font-black text-gray-400 uppercase tracking-widest`,children:`Message`}),(0,s.jsx)(`th`,{className:`px-6 py-3 text-[10px] font-black text-gray-400 uppercase tracking-widest`,children:`Target`}),(0,s.jsx)(`th`,{className:`px-6 py-3 text-[10px] font-black text-gray-400 uppercase tracking-widest`,children:`Status`}),(0,s.jsx)(`th`,{className:`px-6 py-3 text-[10px] font-black text-gray-400 uppercase tracking-widest`,children:`Sent At`})]})}),(0,s.jsxs)(`tbody`,{className:`divide-y divide-gray-50`,children:[t.data.map(e=>(0,s.jsxs)(`tr`,{className:`hover:bg-gray-50/30 transition-colors group`,children:[(0,s.jsxs)(`td`,{className:`px-6 py-4`,children:[(0,s.jsx)(`div`,{className:`text-sm font-bold text-[#3D4E4B] tracking-tight`,children:e.title}),(0,s.jsx)(`div`,{className:`text-[10px] text-gray-400 font-medium truncate max-w-[200px] mt-0.5`,children:e.body})]}),(0,s.jsx)(`td`,{className:`px-6 py-4`,children:(0,s.jsx)(`span`,{className:`text-[10px] font-black uppercase tracking-widest ${e.target_type===`all`?`text-[#D4A017]`:`text-blue-600`}`,children:e.target_type===`all`?`All Devices`:e.target_user?.first_name||`Individual`})}),(0,s.jsx)(`td`,{className:`px-6 py-4`,children:(0,s.jsx)(`span`,{className:`px-2 py-0.5 rounded-md text-[9px] font-black uppercase tracking-widest border ${e.status===`sent`?`bg-emerald-50 text-emerald-600 border-emerald-100`:`bg-red-50 text-red-500 border-red-100`}`,children:e.status})}),(0,s.jsx)(`td`,{className:`px-6 py-4 text-[10px] font-bold text-gray-400`,children:new Date(e.created_at).toLocaleDateString(`en-GB`,{day:`2-digit`,month:`short`,year:`numeric`})})]},e.id)),t.data.length===0&&(0,s.jsx)(`tr`,{children:(0,s.jsx)(`td`,{colSpan:4,className:`px-6 py-16 text-center`,children:(0,s.jsxs)(`div`,{className:`flex flex-col items-center gap-3`,children:[(0,s.jsx)(`div`,{className:`w-12 h-12 rounded-2xl bg-gray-50 border border-gray-100 flex items-center justify-center`,children:(0,s.jsx)(`svg`,{className:`w-5 h-5 text-gray-300`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2,children:(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9`})})}),(0,s.jsx)(`p`,{className:`text-xs font-bold text-gray-300`,children:`No broadcasts sent yet`})]})})})]})]})}),t.meta&&t.meta.last_page>1&&(0,s.jsxs)(`div`,{className:`px-6 py-4 border-t border-gray-50 flex items-center justify-between`,children:[(0,s.jsxs)(`p`,{className:`text-[10px] font-bold text-gray-400 uppercase tracking-widest`,children:[t.meta.total,` total — page `,t.meta.current_page,` of `,t.meta.last_page]}),(0,s.jsx)(`div`,{className:`flex items-center gap-1`,children:t.links.map((e,t)=>(0,s.jsx)(`button`,{disabled:!e.url||e.active,onClick:()=>e.url&&n.get(e.url,{},{preserveScroll:!0}),className:`h-8 min-w-[2rem] px-2 rounded-lg text-xs font-bold transition-all border + ${e.active?`bg-[#3D4E4B] text-white border-[#3D4E4B]`:`bg-white text-gray-400 border-gray-100 hover:border-gray-200 hover:text-[#3D4E4B]`} + ${e.url?`cursor-pointer`:`opacity-30 cursor-not-allowed`}`,dangerouslySetInnerHTML:{__html:e.label}},t))})]})]})})]})]})}export{c as default}; \ No newline at end of file diff --git a/public/build/assets/Index-cmCbZg8n.js b/public/build/assets/Index-cmCbZg8n.js new file mode 100644 index 0000000..df9e024 --- /dev/null +++ b/public/build/assets/Index-cmCbZg8n.js @@ -0,0 +1 @@ +import{c as e,d as t,i as n,n as r,o as i,t as a}from"./app-BJ7g6sa8.js";import{t as o}from"./AuthenticatedLayout-CrB9BCoI.js";import{n as s,t as c}from"./lodash-ZrZcSXd_.js";import{t as l}from"./Portal-DJbp1s68.js";import{t as u}from"./swal-DZXjpqDE.js";import{t as d}from"./Can-DIOq7dyw.js";var f=t(e(),1),p=t(c(),1),m=a();function h({user:e,availableRoles:t,onClose:r}){let i=e?.id?(e.roles||[]).map(e=>e.name||e):[],[a,o]=(0,f.useState)({first_name:e?.first_name||``,last_name:e?.last_name||``,email:e?.email||``,password:``,status:e?.status||`active`,roles:i}),[s,c]=(0,f.useState)({}),[d,p]=(0,f.useState)(!1),h=()=>{let t={};return a.first_name.trim()||(t.first_name=`Required`),a.last_name.trim()||(t.last_name=`Required`),a.email.trim()?/\S+@\S+\.\S+/.test(a.email)||(t.email=`Invalid`):t.email=`Required`,!e?.id&&!a.password&&(t.password=`Required`),c(t),Object.keys(t).length===0},g=e=>{o(t=>({...t,roles:t.roles.includes(e)?t.roles.filter(t=>t!==e):[...t.roles,e]}))};return(0,m.jsx)(l,{children:(0,m.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-[#3D4E4B]/60 backdrop-blur-md anim-fade`,children:(0,m.jsx)(`div`,{className:`bg-white w-full max-w-lg rounded-2xl shadow-2xl overflow-hidden anim-zoom border border-gray-100`,children:(0,m.jsxs)(`div`,{className:`p-8`,children:[(0,m.jsxs)(`div`,{className:`flex items-center justify-between mb-6`,children:[(0,m.jsxs)(`div`,{children:[(0,m.jsx)(`h2`,{className:`text-xl font-bold text-[#3D4E4B] tracking-tight`,children:e?.id?`Edit user`:`New user`}),(0,m.jsx)(`p`,{className:`text-sm text-gray-400 font-medium mt-1`,children:`Fill in the user details below.`})]}),(0,m.jsx)(`button`,{onClick:r,className:`p-2 hover:bg-gray-50 rounded-xl transition-colors`,children:(0,m.jsx)(`svg`,{className:`w-5 h-5 text-gray-400`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,m.jsx)(`path`,{d:`M6 18L18 6M6 6l12 12`})})})]}),(0,m.jsxs)(`form`,{onSubmit:t=>{if(t.preventDefault(),!h())return;p(!0);let i={...a};e?.id?n.patch(`/users/${e.id}`,i,{preserveScroll:!0,onSuccess:()=>{r(),u.success(`Updated`,`User updated successfully.`)},onError:e=>{c(e),p(!1)}}):n.post(`/users`,i,{preserveScroll:!0,onSuccess:()=>{r(),u.success(`Created`,`New user created successfully.`)},onError:e=>{c(e),p(!1)}})},className:`space-y-6`,children:[(0,m.jsxs)(`div`,{className:`grid grid-cols-2 gap-4`,children:[(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(`label`,{className:`text-xs font-semibold text-gray-500 tracking-tight px-1`,children:`First Name`}),(0,m.jsx)(`input`,{type:`text`,value:a.first_name,onChange:e=>o({...a,first_name:e.target.value}),className:`input-field${s.first_name?` is-error`:``}`,placeholder:`John`,required:!0}),s.first_name&&(0,m.jsx)(`p`,{className:`text-[10px] text-red-500 font-bold ml-1`,children:s.first_name})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(`label`,{className:`text-xs font-semibold text-gray-500 tracking-tight px-1`,children:`Last Name`}),(0,m.jsx)(`input`,{type:`text`,value:a.last_name,onChange:e=>o({...a,last_name:e.target.value}),className:`input-field${s.last_name?` is-error`:``}`,placeholder:`Doe`,required:!0}),s.last_name&&(0,m.jsx)(`p`,{className:`text-[10px] text-red-500 font-bold ml-1`,children:s.last_name})]})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(`label`,{className:`text-xs font-semibold text-gray-500 tracking-tight px-1`,children:`Email Address`}),(0,m.jsx)(`input`,{type:`email`,value:a.email,onChange:e=>o({...a,email:e.target.value}),className:`input-field${s.email?` is-error`:``}`,placeholder:`john.doe@example.com`,required:!0}),s.email&&(0,m.jsx)(`p`,{className:`text-[10px] text-red-500 font-bold ml-1`,children:s.email})]}),!e?.id&&(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(`label`,{className:`text-xs font-semibold text-gray-500 tracking-tight px-1`,children:`Initial Password`}),(0,m.jsx)(`input`,{type:`password`,value:a.password,onChange:e=>o({...a,password:e.target.value}),className:`input-field`,placeholder:`••••••••`,required:!0})]}),(0,m.jsxs)(`div`,{className:`space-y-3`,children:[(0,m.jsx)(`label`,{className:`text-xs font-semibold text-gray-500 tracking-tight px-1`,children:`Assigned Roles`}),(0,m.jsx)(`div`,{className:`flex flex-wrap gap-2 p-1`,children:t.map(e=>(0,m.jsx)(`button`,{type:`button`,onClick:()=>g(e),className:`px-4 py-2 rounded-xl text-xs font-bold tracking-tight transition-all border ${a.roles.includes(e)?`bg-[#3D4E4B] text-white border-[#3D4E4B] shadow-md shadow-[#3D4E4B]/20`:`bg-white text-gray-400 border-gray-100 hover:border-gray-200`}`,children:e},e))})]}),(0,m.jsxs)(`div`,{className:`pt-4 flex gap-3`,children:[(0,m.jsx)(`button`,{type:`button`,onClick:r,className:`flex-1 h-9 bg-white border border-gray-200 rounded-xl text-sm font-bold text-gray-400 hover:bg-gray-50 transition-all`,children:`Cancel`}),(0,m.jsx)(`button`,{type:`submit`,disabled:d,className:`flex-1 h-9 bg-[#3D4E4B] text-white rounded-xl text-sm font-bold hover:bg-[#2D3A38] transition-all shadow-lg shadow-[#3D4E4B]/20 flex items-center justify-center gap-2 disabled:opacity-60`,children:d?(0,m.jsx)(`div`,{className:`w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin`}):e?.id?`Save changes`:`Create user`})]})]})]})})})})}function g({users:e,availableRoles:t,filters:a}){let{permissions:c}=i().props.auth,[g,_]=(0,f.useState)(!1),[v,y]=(0,f.useState)(null),[b,x]=(0,f.useState)(!1),[S,C]=(0,f.useState)([]),[w,T]=(0,f.useState)({search:a.search||``,status:a.status||``,role:a.role||``,trashed:a.trashed||``,per_page:a.per_page||15,sort_field:a.sort_field||`created_at`,sort_direction:a.sort_direction||`desc`});f.useEffect(()=>{T({search:a.search||``,status:a.status||``,role:a.role||``,sort_field:a.sort_field||`created_at`,sort_direction:a.sort_direction||`desc`,per_page:a.per_page||15,trashed:a.trashed||``})},[a]);let E=(0,f.useCallback)(p.default.debounce(e=>{x(!0),n.get(`/users`,e,{preserveState:!0,preserveScroll:!0,replace:!0,only:[`users`,`filters`],onFinish:()=>x(!1)})},400),[]),D=(e,t)=>{let n={...w,[e]:t};T(n);let r={...n,page:1};C([]),E(r)},O=e=>{let t={archive:{url:route(`users.bulk-archive`),text:`Archive`},restore:{url:route(`users.bulk-restore`),text:`Restore`},delete:{url:route(`users.bulk-force-delete`),text:`Delete`}}[e];u.confirm(`${t.text} Selected?`,`Are you sure you want to ${e} ${S.length} users?`,t.text).then(r=>{r.isConfirmed&&n.post(t.url,{ids:S},{preserveScroll:!0,onSuccess:()=>{C([]),u.success(`Success`,`${S.length} users ${e}d successfully.`)}})})},k=[{header:`User`,accessorKey:`first_name`,sortable:!0,cell:e=>(0,m.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,m.jsx)(`div`,{className:`w-10 h-10 rounded-xl flex items-center justify-center text-white text-sm font-bold overflow-hidden shrink-0 ${e.deleted_at?`bg-gray-400`:`bg-[#3D4E4B]`}`,children:e.avatar_url?(0,m.jsx)(`img`,{src:e.avatar_url,className:`w-full h-full object-cover`}):`${e.first_name?.charAt(0)}${e.last_name?.charAt(0)}`}),(0,m.jsxs)(`div`,{children:[(0,m.jsxs)(`div`,{className:`text-sm font-bold tracking-tight ${e.deleted_at?`text-gray-400 line-through`:`text-[#3D4E4B]`}`,children:[e.first_name,` `,e.last_name]}),(0,m.jsx)(`div`,{className:`text-xs text-gray-400 font-semibold mt-0.5`,children:e.email})]})]})},{header:`Roles`,accessorKey:`roles`,cell:e=>(0,m.jsx)(`div`,{className:`flex gap-1.5`,children:e.roles?.length?e.roles.map(t=>(0,m.jsx)(`span`,{className:`px-2 py-0.5 text-sm font-bold tracking-tight bg-white border border-gray-100 rounded-md ${e.deleted_at?`text-gray-300`:`text-gray-500`}`,children:t.name||t},t.name||t)):(0,m.jsx)(`span`,{className:`text-sm font-semibold text-gray-300 italic tracking-tight`,children:`Unassigned`})})},{header:`Status`,accessorKey:`status`,sortable:!0,cell:e=>(0,m.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-bold tracking-tight border border-gray-100 ${e.deleted_at?`text-gray-300 bg-gray-50/50`:e.status===`active`?`text-green-600 bg-white border-green-100`:`text-gray-400 bg-white`}`,children:[(0,m.jsx)(`span`,{className:`w-1 h-1 rounded-full ${e.deleted_at?`bg-gray-300`:e.status===`active`?`bg-green-500`:`bg-gray-300`}`}),e.deleted_at?`Archived`:e.status]})},{header:w.trashed===`only`?`Archived at`:`Joined`,accessorKey:w.trashed===`only`?`deleted_at`:`created_at`,sortable:!0,cell:e=>(0,m.jsx)(`span`,{className:`text-sm font-semibold text-gray-400 tracking-tight`,children:new Date(e[e.deleted_at?`deleted_at`:`created_at`]).toLocaleDateString(`en-US`,{day:`2-digit`,month:`short`,year:`numeric`})})}],A=w.trashed===`only`;return(0,m.jsxs)(o,{children:[(0,m.jsx)(r,{title:`Users`}),(0,m.jsxs)(`div`,{className:`flex items-center justify-between mb-8 anim-down`,children:[(0,m.jsxs)(`div`,{children:[(0,m.jsx)(`h1`,{className:`text-xl font-bold text-[#3D4E4B] tracking-tight leading-none`,children:`User Management`}),(0,m.jsx)(`p`,{className:`text-sm font-semibold text-gray-400 tracking-tight mt-2`,children:`Maintain and configure the global user registry`})]}),(0,m.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,m.jsxs)(`div`,{className:`relative w-[240px]`,children:[(0,m.jsx)(`svg`,{className:`absolute left-3.5 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400 pointer-events-none`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,m.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z`})}),(0,m.jsx)(`input`,{type:`text`,placeholder:`Search users…`,value:w.search,onChange:e=>D(`search`,e.target.value),className:`w-full h-11 pl-10 pr-4 rounded-2xl border border-gray-100 bg-white text-sm font-semibold text-gray-700 placeholder-gray-400 focus:outline-none focus:border-[#D4A017] focus:ring-4 focus:ring-[#D4A017]/5 transition-all shadow-sm`})]}),!A&&(0,m.jsxs)(m.Fragment,{children:[(0,m.jsxs)(`select`,{value:w.status,onChange:e=>D(`status`,e.target.value),className:`h-11 px-4 rounded-2xl border border-gray-100 bg-white text-sm font-semibold text-gray-700 focus:outline-none focus:border-[#D4A017] focus:ring-4 focus:ring-[#D4A017]/5 transition-all shadow-sm cursor-pointer min-w-[140px]`,children:[(0,m.jsx)(`option`,{value:``,children:`All Status`}),(0,m.jsx)(`option`,{value:`active`,children:`Active`}),(0,m.jsx)(`option`,{value:`inactive`,children:`Inactive`})]}),(0,m.jsxs)(`select`,{value:w.role,onChange:e=>D(`role`,e.target.value),className:`h-11 px-4 rounded-2xl border border-gray-100 bg-white text-sm font-semibold text-gray-700 focus:outline-none focus:border-[#D4A017] focus:ring-4 focus:ring-[#D4A017]/5 transition-all shadow-sm cursor-pointer min-w-[140px]`,children:[(0,m.jsx)(`option`,{value:``,children:`All Roles`}),t.map(e=>(0,m.jsx)(`option`,{value:e,children:e},e))]})]}),!A&&(0,m.jsx)(`div`,{className:`flex items-center gap-2 border-l border-gray-100 pl-3`,children:(0,m.jsxs)(`a`,{href:route(`users.export`),className:`flex items-center gap-2 h-11 px-4 rounded-2xl bg-white border border-gray-100 text-[#3D4E4B] text-sm font-bold hover:bg-gray-50 transition-all shadow-sm`,children:[(0,m.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,m.jsx)(`path`,{d:`M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4`})}),`Export`]})}),!A&&(0,m.jsx)(d,{ability:`user.create`,children:(0,m.jsx)(`button`,{onClick:()=>{y(null),_(!0)},className:`flex items-center gap-2 h-11 px-6 rounded-2xl bg-[#D4A017] text-white text-sm font-bold hover:bg-[#B88B14] transition-all shadow-lg shadow-[#D4A017]/20 hover:-translate-y-0.5 active:translate-y-0 ml-1`,children:`New user`})})]})]}),(0,m.jsx)(`div`,{className:`flex items-center justify-between mb-5 anim-down`,style:{animationDelay:`0.05s`},children:(0,m.jsxs)(`div`,{className:`flex items-center gap-1 border-b border-gray-100 w-full`,children:[(0,m.jsxs)(`button`,{type:`button`,onClick:()=>D(`trashed`,``),className:`relative pb-3 px-1 mr-4 text-sm font-bold tracking-tight transition-colors ${A?`text-gray-400 hover:text-[#3D4E4B]`:`text-[#3D4E4B]`}`,children:[`Active users`,!A&&(0,m.jsx)(`span`,{className:`absolute bottom-0 left-0 w-full h-0.5 bg-[#D4A017] rounded-t-full`})]}),(0,m.jsxs)(`button`,{type:`button`,onClick:()=>D(`trashed`,`only`),className:`relative pb-3 px-1 text-sm font-bold tracking-tight transition-colors ${A?`text-[#3D4E4B]`:`text-gray-400 hover:text-[#3D4E4B]`}`,children:[`Archived`,A&&(0,m.jsx)(`span`,{className:`absolute bottom-0 left-0 w-full h-0.5 bg-red-400 rounded-t-full`})]}),A&&(0,m.jsxs)(`span`,{className:`ml-auto mb-2 flex items-center gap-1.5 text-xs font-semibold text-amber-600 bg-amber-50 border border-amber-100 px-2.5 py-1 rounded-lg`,children:[(0,m.jsx)(`svg`,{className:`w-3 h-3`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,m.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 9v2m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z`})}),`Archived users cannot log in`]})]})}),(0,m.jsx)(`div`,{className:`anim-up relative`,style:{animationDelay:`0.08s`},children:(0,m.jsx)(s,{data:e.data,columns:k,meta:e.meta,links:e.links,filters:w,onSort:(e,t)=>{D(`sort_field`,e),D(`sort_direction`,t)},isLoading:b,selectedIds:S,onSelectionChange:C,canEdit:!A&&c.includes(`user.edit`),emptyAction:!A&&c.includes(`user.create`)?(0,m.jsx)(`button`,{onClick:()=>{y(null),_(!0)},className:`h-9 px-5 rounded-xl bg-[#D4A017] text-white text-xs font-bold hover:bg-[#B88B14] transition-all shadow-md shadow-[#D4A017]/20`,children:`Add first user`}):void 0,onEdit:e=>{y(e),_(!0)},onDelete:A?void 0:e=>{u.confirm(`Archive user?`,`Move ${e.first_name} ${e.last_name} to the archived list?`,`Archive`).then(t=>{t.isConfirmed&&n.delete(`/users/${e.id}`,{preserveScroll:!0,onSuccess:()=>u.success(`Archived`,`User archived successfully.`)})})},onRestore:A?e=>{u.confirm(`Restore user?`,`Restore ${e.first_name} ${e.last_name} to active status?`,`Restore`).then(t=>{t.isConfirmed&&n.post(`/users/${e.id}/restore`,{},{preserveScroll:!0,onSuccess:()=>u.success(`Restored`,`User restored successfully.`)})})}:void 0,onPermanentDelete:A?e=>{u.confirmDelete(`${e.first_name} ${e.last_name}`).then(t=>{t.isConfirmed&&n.delete(`/users/${e.id}/force-delete`,{preserveScroll:!0,onSuccess:()=>u.success(`Deleted`,`User permanently deleted.`)})})}:void 0})}),g&&(0,m.jsx)(h,{user:v,availableRoles:t,onClose:()=>{_(!1),y(null)}}),(0,m.jsx)(l,{children:(0,m.jsx)(`div`,{className:`fixed bottom-8 left-1/2 -translate-x-1/2 z-40 transition-all duration-500 ${S.length>0?`translate-y-0 opacity-100`:`translate-y-20 opacity-0 pointer-events-none`}`,children:(0,m.jsxs)(`div`,{className:`bg-[#3D4E4B] rounded-2xl shadow-2xl px-6 py-4 flex items-center gap-6 border border-white/10 backdrop-blur-xl`,children:[(0,m.jsxs)(`div`,{className:`flex items-center gap-3 pr-6 border-r border-white/10`,children:[(0,m.jsx)(`span`,{className:`w-8 h-8 rounded-lg bg-white/10 flex items-center justify-center text-white text-xs font-bold`,children:S.length}),(0,m.jsx)(`span`,{className:`text-white text-sm font-bold tracking-tight`,children:`Items selected`})]}),(0,m.jsxs)(`div`,{className:`flex items-center gap-2`,children:[A?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsxs)(`button`,{onClick:()=>O(`restore`),className:`h-10 px-5 rounded-xl bg-green-500 text-white text-xs font-bold hover:bg-green-600 transition-all flex items-center gap-2`,children:[(0,m.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,m.jsx)(`path`,{d:`M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15`})}),`Bulk Restore`]}),(0,m.jsxs)(`button`,{onClick:()=>O(`delete`),className:`h-10 px-5 rounded-xl bg-red-500 text-white text-xs font-bold hover:bg-red-600 transition-all flex items-center gap-2`,children:[(0,m.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,m.jsx)(`path`,{d:`M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16`})}),`Bulk Delete`]})]}):(0,m.jsxs)(`button`,{onClick:()=>O(`archive`),className:`h-10 px-5 rounded-xl bg-white/10 text-white text-xs font-bold hover:bg-white/20 transition-all flex items-center gap-2`,children:[(0,m.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,m.jsx)(`path`,{d:`M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16`})}),`Bulk Archive`]}),(0,m.jsx)(`button`,{onClick:()=>C([]),className:`h-10 px-4 text-white/40 text-xs font-bold hover:text-white transition-colors`,children:`Cancel`})]})]})})})]})}export{g as default}; \ No newline at end of file diff --git a/public/build/assets/Index-z4H1ItiM.js b/public/build/assets/Index-z4H1ItiM.js new file mode 100644 index 0000000..55d10a6 --- /dev/null +++ b/public/build/assets/Index-z4H1ItiM.js @@ -0,0 +1 @@ +import{a as e,c as t,d as n,i as r,n as i,o as a,t as o}from"./app-BJ7g6sa8.js";import{t as s}from"./AuthenticatedLayout-CrB9BCoI.js";import{n as c,t as l}from"./swal-DZXjpqDE.js";import{n as u,r as d,t as f}from"./filepond-plugin-file-validate-type-CBUe71W_.js";var p=n(t(),1),m=n(c(),1),h=d(),g=n(u(),1),_=n(f(),1),v=o();(0,h.registerPlugin)(g.default,_.default);function y({title:e,description:t,children:n,delay:r=`0s`,variant:i=`default`}){let a=i===`danger`;return(0,v.jsxs)(`div`,{className:`bg-white rounded-2xl border ${a?`border-red-200 shadow-none`:`border-gray-100 shadow-sm`} overflow-hidden h-full flex flex-col anim-up`,style:{animationDelay:r},children:[(0,v.jsxs)(`div`,{className:`px-6 py-4 border-b ${a?`border-red-100 bg-red-50`:`border-gray-50 bg-gray-50/30`}`,children:[(0,v.jsx)(`h2`,{className:`text-sm font-bold tracking-tight ${a?`text-red-600`:`text-[#3D4E4B]`}`,children:e}),(0,v.jsx)(`p`,{className:`text-xs font-semibold tracking-tight mt-1 ${a?`text-red-400`:`text-gray-400`}`,children:t})]}),(0,v.jsx)(`div`,{className:`p-8 flex-1`,children:n})]})}function b({label:e,id:t,type:n=`text`,value:r,onChange:i,error:a,placeholder:o,required:s=!1}){return(0,v.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,v.jsxs)(`label`,{htmlFor:t,className:`block text-xs font-semibold text-gray-500 tracking-tight ml-1`,children:[e,` `,s&&(0,v.jsx)(`span`,{className:`text-red-500`,children:`*`})]}),(0,v.jsx)(`input`,{id:t,type:n,value:r,onChange:i,placeholder:o,className:`input-field${a?` is-error`:``}`}),a&&(0,v.jsx)(`p`,{className:`text-xs text-red-500 font-semibold ml-1 mt-1`,children:a})]})}var x=[`profile`,`security`,`2fa`,`danger`];function S(){let e=window.location.hash.replace(`#`,``);return x.includes(e)?e:`profile`}function C({twoFactor:t}){let{user:n}=a().props.auth,[o,c]=(0,p.useState)(S);(0,p.useEffect)(()=>{let e=()=>c(S());return window.addEventListener(`hashchange`,e),()=>window.removeEventListener(`hashchange`,e)},[]);let u=e=>{window.location.hash=e,c(e)},{data:d,setData:f,post:g,processing:_,errors:x}=e({first_name:n.first_name||``,last_name:n.last_name||``,email:n.email||``,phone:n.phone||``,bio:n.bio||``,avatar_file:null,_method:`PATCH`}),[C,w]=(0,p.useState)([]),T=e=>{e.preventDefault(),g(route(`profile.update`),{preserveScroll:!0,onSuccess:()=>l.success(`Saved`,`Profile updated successfully.`)})},{data:E,setData:D,put:O,processing:k,errors:A,reset:j}=e({current_password:``,password:``,password_confirmation:``}),M=e=>{e.preventDefault(),O(route(`password.update`),{preserveScroll:!0,onSuccess:()=>{j(),l.success(`Saved`,`Password updated successfully.`)}})},N=async()=>{if((await l.confirm(`Delete account?`,`This action is irreversible.`,`Delete Permanently`)).isConfirmed){let{value:e}=await m.default.fire({title:`Confirm Password`,input:`password`,inputPlaceholder:`Enter your current password`,showCancelButton:!0,confirmButtonText:`Delete`,confirmButtonColor:`#dc2626`});e&&r.delete(route(`profile.destroy`),{data:{password:e},preserveScroll:!0,onSuccess:()=>l.success(`Deleted`,`Account removed.`),onError:e=>l.error(`Error`,e.password||`Incorrect password.`)})}},P=`${n.first_name?.charAt(0)||``}${n.last_name?.charAt(0)||``}`.toUpperCase(),[F,I]=(0,p.useState)(!1),[L,R]=(0,p.useState)(!1),z=e({code:``});return(0,v.jsxs)(s,{children:[(0,v.jsx)(i,{title:`Account Settings`}),(0,v.jsx)(`div`,{className:`flex items-center justify-between mb-8 anim-down`,children:(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`h1`,{className:`text-xl font-bold text-[#3D4E4B] tracking-tight leading-none`,children:`Account Settings`}),(0,v.jsx)(`p`,{className:`text-sm font-semibold text-gray-400 tracking-tight mt-2`,children:`Manage your personal credentials and security preferences`})]})}),(0,v.jsxs)(`div`,{className:`flex items-center gap-1 border-b border-gray-100 w-full mb-8 anim-down`,style:{animationDelay:`0.05s`},children:[(0,v.jsxs)(`button`,{type:`button`,onClick:()=>u(`profile`),className:`relative pb-3 px-1 mr-8 text-sm font-bold tracking-tight transition-colors ${o===`profile`?`text-[#3D4E4B]`:`text-gray-400 hover:text-[#3D4E4B]`}`,children:[`Profile Information`,o===`profile`&&(0,v.jsx)(`span`,{className:`absolute bottom-0 left-0 w-full h-0.5 bg-[#D4A017] rounded-t-full`})]}),(0,v.jsxs)(`button`,{type:`button`,onClick:()=>u(`security`),className:`relative pb-3 px-1 mr-8 text-sm font-bold tracking-tight transition-colors ${o===`security`?`text-[#3D4E4B]`:`text-gray-400 hover:text-[#3D4E4B]`}`,children:[`Security & Password`,o===`security`&&(0,v.jsx)(`span`,{className:`absolute bottom-0 left-0 w-full h-0.5 bg-[#D4A017] rounded-t-full`})]}),(0,v.jsxs)(`button`,{type:`button`,onClick:()=>u(`2fa`),className:`relative pb-3 px-1 mr-8 text-sm font-bold tracking-tight transition-colors ${o===`2fa`?`text-[#3D4E4B]`:`text-gray-400 hover:text-[#3D4E4B]`}`,children:[`Two-Factor Auth`,o===`2fa`&&(0,v.jsx)(`span`,{className:`absolute bottom-0 left-0 w-full h-0.5 bg-[#D4A017] rounded-t-full`})]}),(0,v.jsxs)(`button`,{type:`button`,onClick:()=>u(`danger`),className:`relative pb-3 px-1 text-sm font-bold tracking-tight transition-colors ${o===`danger`?`text-red-600`:`text-gray-400 hover:text-red-600`}`,children:[`Danger Zone`,o===`danger`&&(0,v.jsx)(`span`,{className:`absolute bottom-0 left-0 w-full h-0.5 bg-red-500 rounded-t-full`})]})]}),(0,v.jsxs)(`div`,{className:`space-y-8 pb-20`,children:[o===`profile`&&(0,v.jsx)(`div`,{className:`space-y-8 anim-fade`,children:(0,v.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-3 gap-8`,children:[(0,v.jsx)(`div`,{className:`lg:col-span-2`,children:(0,v.jsx)(y,{title:`Identity`,description:`Manage your public name and contact email`,delay:`0.1s`,children:(0,v.jsxs)(`form`,{onSubmit:T,className:`space-y-8`,children:[(0,v.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-6`,children:[(0,v.jsx)(b,{label:`First Name`,id:`first_name`,value:d.first_name,onChange:e=>f(`first_name`,e.target.value),error:x.first_name,required:!0,placeholder:`e.g. John`}),(0,v.jsx)(b,{label:`Last Name`,id:`last_name`,value:d.last_name,onChange:e=>f(`last_name`,e.target.value),error:x.last_name,required:!0,placeholder:`e.g. Doe`})]}),(0,v.jsx)(b,{label:`Email Address`,id:`email`,type:`email`,value:d.email,onChange:e=>f(`email`,e.target.value),error:x.email,required:!0,placeholder:`e.g. john.doe@example.com`}),(0,v.jsx)(b,{label:`Phone Number`,id:`phone`,value:d.phone,onChange:e=>f(`phone`,e.target.value),error:x.phone,placeholder:`e.g. +62 812 3456 7890`}),(0,v.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,v.jsx)(`label`,{htmlFor:`bio`,className:`block text-xs font-semibold text-gray-500 tracking-tight ml-1`,children:`Bio`}),(0,v.jsx)(`textarea`,{id:`bio`,value:d.bio,onChange:e=>f(`bio`,e.target.value),rows:3,placeholder:`A short description about yourself...`,className:`input-field py-3 resize-none${x.bio?` is-error`:``}`}),x.bio&&(0,v.jsx)(`p`,{className:`text-xs text-red-500 font-semibold ml-1 mt-1`,children:x.bio})]}),(0,v.jsx)(`div`,{className:`flex justify-end pt-4 border-t border-gray-50`,children:(0,v.jsx)(`button`,{type:`submit`,disabled:_,className:`h-10 px-8 bg-[#3D4E4B] text-white text-sm font-bold tracking-tight rounded-xl hover:bg-[#2D3A38] transition-all shadow-lg shadow-[#3D4E4B]/20 disabled:opacity-60`,children:_?`Saving...`:`Save Profile`})})]})})}),(0,v.jsx)(`div`,{className:`lg:col-span-1`,children:(0,v.jsx)(y,{title:`Profile Photo`,description:`Update your avatar`,delay:`0.15s`,children:(0,v.jsxs)(`div`,{className:`flex flex-col items-center gap-6`,children:[(0,v.jsx)(`div`,{className:`w-24 h-24 rounded-2xl bg-[#3D4E4B] flex items-center justify-center text-white text-2xl font-bold shadow-lg shadow-[#3D4E4B]/10 overflow-hidden border-2 border-white`,children:n.avatar_url?(0,v.jsx)(`img`,{src:n.avatar_url,className:`w-full h-full object-cover`}):P}),(0,v.jsx)(`div`,{className:`w-full`,children:(0,v.jsx)(h.FilePond,{files:C,onupdatefiles:e=>{w(e),f(`avatar_file`,e[0]?.file||null)},allowMultiple:!1,maxFiles:1,labelIdle:`Drop Photo here`})})]})})})]})}),o===`security`&&(0,v.jsx)(`div`,{className:`max-w-4xl anim-fade`,children:(0,v.jsx)(y,{title:`Password`,description:`Update your secure access key`,delay:`0.1s`,children:(0,v.jsxs)(`form`,{onSubmit:M,className:`space-y-8`,children:[(0,v.jsx)(`div`,{className:`max-w-md`,children:(0,v.jsx)(b,{label:`Current Password`,id:`current_password`,type:`password`,value:E.current_password,onChange:e=>D(`current_password`,e.target.value),error:A.current_password,required:!0,placeholder:`••••••••`})}),(0,v.jsx)(`div`,{className:`h-px bg-gray-50 -mx-8`}),(0,v.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-8`,children:[(0,v.jsx)(b,{label:`New Password`,id:`password`,type:`password`,value:E.password,onChange:e=>D(`password`,e.target.value),error:A.password,required:!0,placeholder:`Enter new password`}),(0,v.jsx)(b,{label:`Confirm New Password`,id:`password_confirmation`,type:`password`,value:E.password_confirmation,onChange:e=>D(`password_confirmation`,e.target.value),error:A.password_confirmation,required:!0,placeholder:`Repeat new password`})]}),(0,v.jsx)(`div`,{className:`flex justify-end pt-4 border-t border-gray-50`,children:(0,v.jsx)(`button`,{type:`submit`,disabled:k,className:`h-10 px-8 bg-[#3D4E4B] text-white text-sm font-bold tracking-tight rounded-xl hover:bg-[#2D3A38] transition-all shadow-lg shadow-[#3D4E4B]/20 disabled:opacity-60`,children:k?`Updating...`:`Update Password`})})]})})}),o===`2fa`&&(0,v.jsxs)(`div`,{className:`max-w-3xl space-y-6 anim-fade`,children:[(0,v.jsxs)(`div`,{className:`p-5 bg-amber-50 border border-amber-200 rounded-2xl flex items-start gap-3`,children:[(0,v.jsx)(`svg`,{className:`w-5 h-5 text-amber-500 mt-0.5 shrink-0`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,v.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 9v2m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z`})}),(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`p`,{className:`text-xs font-bold text-amber-800 mb-1`,children:`Two-Factor Authentication (2FA)`}),(0,v.jsx)(`p`,{className:`text-[11px] text-amber-700 font-medium leading-relaxed`,children:`2FA menambah lapisan keamanan ekstra dengan meminta kode OTP dari aplikasi authenticator setiap kali login.`})]})]}),t.enabled?(0,v.jsxs)(`div`,{className:`space-y-4`,children:[(0,v.jsxs)(`div`,{className:`bg-white rounded-2xl border border-emerald-100 shadow-sm p-6 flex items-center gap-4`,children:[(0,v.jsx)(`div`,{className:`w-12 h-12 rounded-xl bg-emerald-50 flex items-center justify-center shrink-0`,children:(0,v.jsx)(`svg`,{className:`w-6 h-6 text-emerald-600`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,v.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z`})})}),(0,v.jsxs)(`div`,{className:`flex-1`,children:[(0,v.jsx)(`div`,{className:`text-sm font-bold text-[#3D4E4B]`,children:`Two-Factor Authentication Aktif`}),(0,v.jsx)(`div`,{className:`text-xs text-gray-400 font-medium mt-0.5`,children:`Akun Anda dilindungi dengan TOTP authentication.`})]}),(0,v.jsx)(`button`,{onClick:async()=>{let{value:e}=await m.default.fire({title:`Disable 2FA`,text:`Enter your password to confirm.`,input:`password`,inputPlaceholder:`Your current password`,showCancelButton:!0,confirmButtonText:`Disable`,confirmButtonColor:`#dc2626`});e&&r.post(route(`two-factor.disable`),{password:e},{preserveScroll:!0,onSuccess:()=>l.success(`Disabled`,`2FA has been disabled.`)})},type:`button`,className:`h-9 px-5 text-xs font-bold text-red-500 border border-red-200 rounded-xl hover:bg-red-50 transition-all`,children:`Disable 2FA`})]}),(0,v.jsx)(y,{title:`Recovery Codes`,description:`Simpan kode ini dengan aman — gunakan jika kehilangan akses ke authenticator`,children:(0,v.jsxs)(`div`,{className:`space-y-4`,children:[(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,v.jsx)(`button`,{onClick:()=>R(!L),type:`button`,className:`h-8 px-4 text-xs font-bold text-[#3D4E4B] border border-gray-200 rounded-lg hover:bg-gray-50 transition-all`,children:L?`Hide`:`Show Codes`}),(0,v.jsx)(`button`,{onClick:async()=>{(await l.confirm(`Regenerate Codes?`,`Old recovery codes will be invalidated.`,`Regenerate`)).isConfirmed&&r.post(route(`two-factor.recovery-codes`),{},{preserveScroll:!0,onSuccess:()=>{R(!0),l.success(`Regenerated`,`New recovery codes generated.`)}})},type:`button`,className:`h-8 px-4 text-xs font-bold text-[#D4A017] border border-amber-200 rounded-lg hover:bg-amber-50 transition-all`,children:`Regenerate`})]}),L&&t.recovery_codes.length>0&&(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`div`,{className:`grid grid-cols-2 gap-2`,children:t.recovery_codes.map((e,t)=>(0,v.jsx)(`code`,{className:`px-4 py-2.5 bg-gray-50 border border-gray-100 rounded-xl text-xs font-mono text-[#3D4E4B] tracking-wider text-center`,children:e},t))}),(0,v.jsx)(`p`,{className:`text-[11px] text-amber-600 font-semibold mt-3`,children:`⚠ Setiap kode hanya bisa digunakan sekali.`})]})]})})]}):(0,v.jsx)(y,{title:`Setup Authenticator App`,description:`Scan QR code dengan Google Authenticator, Authy, atau TOTP app lainnya`,children:(0,v.jsxs)(`div`,{className:`flex flex-col md:flex-row gap-10 items-center md:items-start`,children:[(0,v.jsx)(`div`,{className:`shrink-0`,children:(0,v.jsx)(`div`,{className:`p-4 bg-white border-2 border-gray-100 rounded-2xl inline-block shadow-sm`,children:t.qr_code&&(0,v.jsx)(`img`,{src:t.qr_code,alt:`2FA QR Code`,className:`w-44 h-44`})})}),(0,v.jsxs)(`div`,{className:`flex-1 space-y-6`,children:[(0,v.jsx)(`div`,{className:`space-y-3`,children:[`Install aplikasi authenticator (Google Authenticator, Authy, 1Password)`,`Scan QR code atau masukkan manual key di bawah`,`Masukkan kode 6 digit dari aplikasi untuk mengaktifkan`].map((e,t)=>(0,v.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,v.jsx)(`div`,{className:`w-6 h-6 rounded-full bg-[#3D4E4B] text-white text-[10px] font-black flex items-center justify-center shrink-0 mt-0.5`,children:t+1}),(0,v.jsx)(`p`,{className:`text-xs font-medium text-gray-500 leading-relaxed pt-0.5`,children:e})]},t))}),(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`label`,{className:`block text-xs font-semibold text-gray-400 mb-1.5`,children:`Manual Key`}),(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,v.jsx)(`code`,{className:`flex-1 text-xs font-mono bg-gray-50 border border-gray-100 rounded-xl px-4 py-3 text-[#3D4E4B] tracking-wider`,children:t.secret}),(0,v.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(t.secret||``),I(!0),setTimeout(()=>I(!1),2e3)},type:`button`,className:`shrink-0 h-11 px-4 border border-gray-200 rounded-xl text-xs font-bold text-gray-500 hover:bg-gray-50 transition-all`,children:F?`✓ Copied`:`Copy`})]})]}),(0,v.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),z.post(route(`two-factor.enable`),{preserveScroll:!0,onSuccess:()=>{z.reset(),l.success(`Enabled`,`2FA is now active on your account.`)}})},className:`space-y-3`,children:[(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`label`,{className:`block text-xs font-semibold text-gray-400 mb-1.5`,children:`Verification Code *`}),(0,v.jsx)(`input`,{type:`text`,inputMode:`numeric`,maxLength:6,value:z.data.code,onChange:e=>z.setData(`code`,e.target.value),className:`input-field w-full text-center tracking-[0.5em] font-bold text-lg`,placeholder:`000000`}),z.errors.code&&(0,v.jsx)(`p`,{className:`text-xs text-red-500 font-semibold mt-1`,children:z.errors.code})]}),(0,v.jsx)(`button`,{type:`submit`,disabled:z.processing||z.data.code.length<6,className:`w-full h-11 bg-[#3D4E4B] text-white text-xs font-bold rounded-xl hover:bg-[#2D3A38] transition-all disabled:opacity-60`,children:z.processing?`Verifying...`:`Enable Two-Factor Authentication`})]})]})]})})]}),o===`danger`&&(0,v.jsx)(`div`,{className:`max-w-4xl anim-fade`,children:(0,v.jsx)(y,{title:`Account Lifecycle`,description:`Critical and irreversible account actions`,delay:`0.1s`,children:(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-10 p-6 rounded-2xl bg-red-50 border border-red-100`,children:[(0,v.jsxs)(`div`,{className:`flex items-center gap-6`,children:[(0,v.jsx)(`div`,{className:`w-14 h-14 rounded-2xl bg-white border border-red-100 flex items-center justify-center text-red-600 shrink-0`,children:(0,v.jsx)(`svg`,{className:`w-7 h-7`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,v.jsx)(`path`,{d:`M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16`})})}),(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`p`,{className:`text-base font-bold text-red-900 leading-none`,children:`Delete Account Permanently`}),(0,v.jsx)(`p`,{className:`text-xs text-red-700/60 font-semibold mt-2 leading-relaxed`,children:`Proceeding will scrub your identity, logs, and settings from our database. This action is irreversible.`})]})]}),(0,v.jsx)(`button`,{onClick:N,className:`h-11 px-8 bg-red-600 text-white text-xs font-bold uppercase tracking-widest rounded-xl hover:bg-red-700 transition-all shrink-0`,children:`Delete Account`})]})})})]})]})}export{C as default}; \ No newline at end of file diff --git a/public/build/assets/Login-DUDEFmAx.js b/public/build/assets/Login-DUDEFmAx.js new file mode 100644 index 0000000..4db019e --- /dev/null +++ b/public/build/assets/Login-DUDEFmAx.js @@ -0,0 +1 @@ +import{a as e,c as t,n,o as r,r as i,t as a}from"./app-BJ7g6sa8.js";import{t as o}from"./GuestLayout-CN-YY0cs.js";t();var s=a();function c({status:t,canResetPassword:a}){let{system_settings:c}=r().props,l=c?.oauth_google_enabled===`1`||c?.oauth_google_enabled===!0,u=c?.oauth_github_enabled===`1`||c?.oauth_github_enabled===!0,{data:d,setData:f,post:p,processing:m,errors:h,reset:g}=e({email:``,password:``,remember:!1});return(0,s.jsxs)(o,{children:[(0,s.jsx)(n,{title:`Sign in`}),(0,s.jsxs)(`div`,{className:`mb-8 anim-down`,children:[(0,s.jsx)(`h1`,{className:`text-2xl font-bold text-[#1A2421] tracking-tight`,children:`Sign in`}),(0,s.jsx)(`p`,{className:`mt-1.5 text-sm text-gray-400 font-medium`,children:`Enter your credentials to access the dashboard.`})]}),t&&(0,s.jsx)(`div`,{className:`mb-6 px-4 py-3 rounded-xl bg-emerald-50 border border-emerald-100 text-sm font-semibold text-emerald-700 anim-fade`,children:t}),(l||u)&&(0,s.jsxs)(`div`,{className:`mb-6 anim-up`,style:{animationDelay:`0.08s`},children:[(0,s.jsxs)(`div`,{className:`grid gap-3 ${l&&u?`grid-cols-2`:`grid-cols-1`}`,children:[l&&(0,s.jsxs)(`a`,{href:`/auth/google/redirect`,className:`flex items-center justify-center gap-2.5 px-4 py-2.5 rounded-xl border border-gray-200 bg-white hover:bg-gray-50 hover:border-gray-300 transition-colors duration-200 text-sm font-semibold text-gray-700`,children:[(0,s.jsxs)(`svg`,{className:`w-4 h-4 shrink-0`,viewBox:`0 0 24 24`,children:[(0,s.jsx)(`path`,{fill:`#EA4335`,d:`M12 5c1.61 0 3.09.59 4.23 1.57l3.12-3.12C17.35 1.67 14.85 1 12 1 7.73 1 4.14 3.48 2.46 7.1l3.71 2.87C7.04 7.09 9.34 5 12 5z`}),(0,s.jsx)(`path`,{fill:`#4285F4`,d:`M23.49 12.27c0-.79-.07-1.54-.19-2.27H12v4.51h6.47c-.29 1.48-1.14 2.73-2.4 3.58l3.7 2.87c2.16-2 3.72-4.94 3.72-8.69z`}),(0,s.jsx)(`path`,{fill:`#FBBC05`,d:`M6.17 14.77l-3.71 2.87C4.14 21.27 7.73 23 12 23c2.97 0 5.48-1 7.37-2.69l-3.7-2.87c-1.03.69-2.35 1.11-3.67 1.11-2.66 0-4.96-2.09-5.83-4.78z`}),(0,s.jsx)(`path`,{fill:`#34A853`,d:`M12 19.45c1.32 0 2.64-.42 3.67-1.11l3.7 2.87C17.48 22 14.97 23 12 23 7.73 23 4.14 21.27 2.47 17.64l3.71-2.87c.86 2.69 3.16 4.68 5.82 4.68z`})]}),`Google`]}),u&&(0,s.jsxs)(`a`,{href:`/auth/github/redirect`,className:`flex items-center justify-center gap-2.5 px-4 py-2.5 rounded-xl border border-gray-200 bg-white hover:bg-gray-50 hover:border-gray-300 transition-colors duration-200 text-sm font-semibold text-gray-700`,children:[(0,s.jsx)(`svg`,{className:`w-4 h-4 shrink-0`,fill:`currentColor`,viewBox:`0 0 24 24`,children:(0,s.jsx)(`path`,{d:`M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12`})}),`GitHub`]})]}),(0,s.jsxs)(`div`,{className:`relative my-6`,children:[(0,s.jsx)(`div`,{className:`absolute inset-0 flex items-center`,children:(0,s.jsx)(`div`,{className:`w-full border-t border-gray-100`})}),(0,s.jsx)(`div`,{className:`relative flex justify-center`,children:(0,s.jsx)(`span`,{className:`px-3 bg-white text-xs font-semibold text-gray-300 uppercase tracking-widest`,children:`or`})})]})]}),(0,s.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),p(route(`login`),{onFinish:()=>g(`password`)})},className:`anim-up`,style:{animationDelay:`0.14s`},children:[(0,s.jsxs)(`div`,{className:`space-y-4`,children:[(0,s.jsxs)(`div`,{children:[(0,s.jsx)(`label`,{htmlFor:`email`,className:`block text-sm font-semibold text-gray-600 mb-1.5`,children:`Email address`}),(0,s.jsx)(`input`,{id:`email`,type:`email`,autoComplete:`email`,autoFocus:!0,value:d.email,onChange:e=>f(`email`,e.target.value),placeholder:`you@company.com`,className:`auth-input${h.email?` !border-red-300 !bg-red-50/50`:``}`}),h.email&&(0,s.jsx)(`p`,{className:`mt-1.5 text-xs font-semibold text-red-500`,children:h.email})]}),(0,s.jsxs)(`div`,{children:[(0,s.jsxs)(`div`,{className:`flex items-center justify-between mb-1.5`,children:[(0,s.jsx)(`label`,{htmlFor:`password`,className:`text-sm font-semibold text-gray-600`,children:`Password`}),a&&(0,s.jsx)(i,{href:route(`password.request`),className:`text-xs font-semibold text-[#D4A017] hover:text-[#B88B14] transition-colors duration-200`,children:`Forgot password?`})]}),(0,s.jsx)(`input`,{id:`password`,type:`password`,autoComplete:`current-password`,value:d.password,onChange:e=>f(`password`,e.target.value),placeholder:`••••••••`,className:`auth-input${h.password?` !border-red-300 !bg-red-50/50`:``}`}),h.password&&(0,s.jsx)(`p`,{className:`mt-1.5 text-xs font-semibold text-red-500`,children:h.password})]})]}),(0,s.jsxs)(`label`,{className:`mt-4 flex items-center gap-2.5 cursor-pointer select-none group w-fit`,children:[(0,s.jsx)(`input`,{type:`checkbox`,checked:d.remember,onChange:e=>f(`remember`,e.target.checked),className:`sr-only`}),(0,s.jsx)(`div`,{className:`w-4 h-4 rounded-[5px] border flex items-center justify-center transition-colors duration-200 shrink-0 ${d.remember?`bg-[#3D4E4B] border-[#3D4E4B]`:`bg-white border-gray-300`}`,children:d.remember&&(0,s.jsx)(`svg`,{className:`w-2.5 h-2.5 text-white`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:3.5,children:(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M5 13l4 4L19 7`})})}),(0,s.jsx)(`span`,{className:`text-sm font-medium text-gray-500 group-hover:text-gray-700 transition-colors duration-200`,children:`Keep me signed in`})]}),(0,s.jsx)(`button`,{type:`submit`,disabled:m,className:`mt-6 w-full h-11 rounded-xl bg-[#3D4E4B] hover:bg-[#2D3A38] text-white text-sm font-bold tracking-tight transition-colors duration-200 flex items-center justify-center gap-2 disabled:opacity-60 disabled:cursor-not-allowed`,children:m?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(`svg`,{className:`w-4 h-4 animate-spin text-white/60`,fill:`none`,viewBox:`0 0 24 24`,children:[(0,s.jsx)(`circle`,{className:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,strokeWidth:`4`}),(0,s.jsx)(`path`,{className:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z`})]}),`Signing in…`]}):`Sign in`})]}),(0,s.jsxs)(`p`,{className:`mt-7 text-center text-sm text-gray-400 font-medium anim-fade`,style:{animationDelay:`0.22s`},children:[`Don't have an account?`,` `,(0,s.jsx)(i,{href:route(`register`),className:`text-[#3D4E4B] font-semibold hover:text-[#D4A017] transition-colors duration-200`,children:`Create one`})]})]})}export{c as default}; \ No newline at end of file diff --git a/public/build/assets/Portal-DJbp1s68.js b/public/build/assets/Portal-DJbp1s68.js new file mode 100644 index 0000000..03f3b6b --- /dev/null +++ b/public/build/assets/Portal-DJbp1s68.js @@ -0,0 +1 @@ +import{d as e,s as t}from"./app-BJ7g6sa8.js";var n=e(t(),1);function r({children:e}){return(0,n.createPortal)(e,document.body)}export{r as t}; \ No newline at end of file diff --git a/public/build/assets/PrimaryButton-KeVcwQeg.js b/public/build/assets/PrimaryButton-KeVcwQeg.js new file mode 100644 index 0000000..7b70a3e --- /dev/null +++ b/public/build/assets/PrimaryButton-KeVcwQeg.js @@ -0,0 +1 @@ +import{t as e}from"./app-BJ7g6sa8.js";var t=e();function n({className:e=``,disabled:n,children:r,...i}){return(0,t.jsx)(`button`,{...i,className:`inline-flex items-center rounded-md border border-transparent bg-gray-800 px-4 py-2 text-xs font-bold tracking-tight text-white transition duration-150 ease-in-out hover:bg-gray-700 focus:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 active:bg-gray-900 ${n&&`opacity-25`} `+e,disabled:n,children:r})}export{n as t}; \ No newline at end of file diff --git a/public/build/assets/Register-BscYc22x.js b/public/build/assets/Register-BscYc22x.js new file mode 100644 index 0000000..885b7f1 --- /dev/null +++ b/public/build/assets/Register-BscYc22x.js @@ -0,0 +1 @@ +import{a as e,c as t,n,o as r,r as i,t as a}from"./app-BJ7g6sa8.js";import{t as o}from"./GuestLayout-CN-YY0cs.js";t();var s=a();function c(){let{system_settings:t}=r().props,a=t?.allow_registration===`1`||t?.allow_registration===!0,c=t?.oauth_google_enabled===`1`||t?.oauth_google_enabled===!0,l=t?.oauth_github_enabled===`1`||t?.oauth_github_enabled===!0,{data:u,setData:d,post:f,processing:p,errors:m,reset:h}=e({first_name:``,last_name:``,email:``,password:``,password_confirmation:``});return a?(0,s.jsxs)(o,{children:[(0,s.jsx)(n,{title:`Create account`}),(0,s.jsxs)(`div`,{className:`mb-8 anim-down`,children:[(0,s.jsx)(`h1`,{className:`text-2xl font-bold text-[#1A2421] tracking-tight`,children:`Create account`}),(0,s.jsx)(`p`,{className:`mt-1.5 text-sm text-gray-400 font-medium`,children:`Fill in your details to get started.`})]}),(c||l)&&(0,s.jsxs)(`div`,{className:`mb-6 anim-up`,style:{animationDelay:`0.08s`},children:[(0,s.jsxs)(`div`,{className:`grid gap-3 ${c&&l?`grid-cols-2`:`grid-cols-1`}`,children:[c&&(0,s.jsxs)(`a`,{href:`/auth/google/redirect`,className:`flex items-center justify-center gap-2.5 px-4 py-2.5 rounded-xl border border-gray-200 bg-white hover:bg-gray-50 hover:border-gray-300 transition-colors duration-200 text-sm font-semibold text-gray-700`,children:[(0,s.jsxs)(`svg`,{className:`w-4 h-4 shrink-0`,viewBox:`0 0 24 24`,children:[(0,s.jsx)(`path`,{fill:`#EA4335`,d:`M12 5c1.61 0 3.09.59 4.23 1.57l3.12-3.12C17.35 1.67 14.85 1 12 1 7.73 1 4.14 3.48 2.46 7.1l3.71 2.87C7.04 7.09 9.34 5 12 5z`}),(0,s.jsx)(`path`,{fill:`#4285F4`,d:`M23.49 12.27c0-.79-.07-1.54-.19-2.27H12v4.51h6.47c-.29 1.48-1.14 2.73-2.4 3.58l3.7 2.87c2.16-2 3.72-4.94 3.72-8.69z`}),(0,s.jsx)(`path`,{fill:`#FBBC05`,d:`M6.17 14.77l-3.71 2.87C4.14 21.27 7.73 23 12 23c2.97 0 5.48-1 7.37-2.69l-3.7-2.87c-1.03.69-2.35 1.11-3.67 1.11-2.66 0-4.96-2.09-5.83-4.78z`}),(0,s.jsx)(`path`,{fill:`#34A853`,d:`M12 19.45c1.32 0 2.64-.42 3.67-1.11l3.7 2.87C17.48 22 14.97 23 12 23 7.73 23 4.14 21.27 2.47 17.64l3.71-2.87c.86 2.69 3.16 4.68 5.82 4.68z`})]}),`Google`]}),l&&(0,s.jsxs)(`a`,{href:`/auth/github/redirect`,className:`flex items-center justify-center gap-2.5 px-4 py-2.5 rounded-xl border border-gray-200 bg-white hover:bg-gray-50 hover:border-gray-300 transition-colors duration-200 text-sm font-semibold text-gray-700`,children:[(0,s.jsx)(`svg`,{className:`w-4 h-4 shrink-0`,fill:`currentColor`,viewBox:`0 0 24 24`,children:(0,s.jsx)(`path`,{d:`M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12`})}),`GitHub`]})]}),(0,s.jsxs)(`div`,{className:`relative my-6`,children:[(0,s.jsx)(`div`,{className:`absolute inset-0 flex items-center`,children:(0,s.jsx)(`div`,{className:`w-full border-t border-gray-100`})}),(0,s.jsx)(`div`,{className:`relative flex justify-center`,children:(0,s.jsx)(`span`,{className:`px-3 bg-white text-xs font-semibold text-gray-300 uppercase tracking-widest`,children:`or`})})]})]}),(0,s.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),f(route(`register`),{onFinish:()=>h(`password`,`password_confirmation`)})},className:`anim-up`,style:{animationDelay:`0.14s`},children:[(0,s.jsxs)(`div`,{className:`space-y-4`,children:[(0,s.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,s.jsxs)(`div`,{children:[(0,s.jsx)(`label`,{htmlFor:`first_name`,className:`block text-sm font-semibold text-gray-600 mb-1.5`,children:`First name`}),(0,s.jsx)(`input`,{id:`first_name`,type:`text`,autoComplete:`given-name`,autoFocus:!0,value:u.first_name,onChange:e=>d(`first_name`,e.target.value),placeholder:`Alex`,className:`auth-input${m.first_name?` !border-red-300 !bg-red-50/50`:``}`}),m.first_name&&(0,s.jsx)(`p`,{className:`mt-1.5 text-xs font-semibold text-red-500`,children:m.first_name})]}),(0,s.jsxs)(`div`,{children:[(0,s.jsx)(`label`,{htmlFor:`last_name`,className:`block text-sm font-semibold text-gray-600 mb-1.5`,children:`Last name`}),(0,s.jsx)(`input`,{id:`last_name`,type:`text`,autoComplete:`family-name`,value:u.last_name,onChange:e=>d(`last_name`,e.target.value),placeholder:`Johnson`,className:`auth-input${m.last_name?` !border-red-300 !bg-red-50/50`:``}`}),m.last_name&&(0,s.jsx)(`p`,{className:`mt-1.5 text-xs font-semibold text-red-500`,children:m.last_name})]})]}),(0,s.jsxs)(`div`,{children:[(0,s.jsx)(`label`,{htmlFor:`email`,className:`block text-sm font-semibold text-gray-600 mb-1.5`,children:`Email address`}),(0,s.jsx)(`input`,{id:`email`,type:`email`,autoComplete:`email`,value:u.email,onChange:e=>d(`email`,e.target.value),placeholder:`you@company.com`,className:`auth-input${m.email?` !border-red-300 !bg-red-50/50`:``}`}),m.email&&(0,s.jsx)(`p`,{className:`mt-1.5 text-xs font-semibold text-red-500`,children:m.email})]}),(0,s.jsxs)(`div`,{children:[(0,s.jsx)(`label`,{htmlFor:`password`,className:`block text-sm font-semibold text-gray-600 mb-1.5`,children:`Password`}),(0,s.jsx)(`input`,{id:`password`,type:`password`,autoComplete:`new-password`,value:u.password,onChange:e=>d(`password`,e.target.value),placeholder:`Min. 8 characters`,className:`auth-input${m.password?` !border-red-300 !bg-red-50/50`:``}`}),m.password&&(0,s.jsx)(`p`,{className:`mt-1.5 text-xs font-semibold text-red-500`,children:m.password})]}),(0,s.jsxs)(`div`,{children:[(0,s.jsx)(`label`,{htmlFor:`password_confirmation`,className:`block text-sm font-semibold text-gray-600 mb-1.5`,children:`Confirm password`}),(0,s.jsx)(`input`,{id:`password_confirmation`,type:`password`,autoComplete:`new-password`,value:u.password_confirmation,onChange:e=>d(`password_confirmation`,e.target.value),placeholder:`••••••••`,className:`auth-input${m.password_confirmation?` !border-red-300 !bg-red-50/50`:``}`}),m.password_confirmation&&(0,s.jsx)(`p`,{className:`mt-1.5 text-xs font-semibold text-red-500`,children:m.password_confirmation})]})]}),(0,s.jsx)(`button`,{type:`submit`,disabled:p,className:`mt-6 w-full h-11 rounded-xl bg-[#3D4E4B] hover:bg-[#2D3A38] text-white text-sm font-bold tracking-tight transition-colors duration-200 flex items-center justify-center gap-2 disabled:opacity-60 disabled:cursor-not-allowed`,children:p?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(`svg`,{className:`w-4 h-4 animate-spin text-white/60`,fill:`none`,viewBox:`0 0 24 24`,children:[(0,s.jsx)(`circle`,{className:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,strokeWidth:`4`}),(0,s.jsx)(`path`,{className:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z`})]}),`Creating account…`]}):`Create account`})]}),(0,s.jsxs)(`p`,{className:`mt-7 text-center text-sm text-gray-400 font-medium anim-fade`,style:{animationDelay:`0.22s`},children:[`Already have an account?`,` `,(0,s.jsx)(i,{href:route(`login`),className:`text-[#3D4E4B] font-semibold hover:text-[#D4A017] transition-colors duration-200`,children:`Sign in`})]})]}):(0,s.jsxs)(o,{children:[(0,s.jsx)(n,{title:`Registration Closed`}),(0,s.jsxs)(`div`,{className:`anim-fade`,children:[(0,s.jsx)(`div`,{className:`w-12 h-12 bg-amber-50 border border-amber-100 rounded-2xl flex items-center justify-center mb-6`,children:(0,s.jsx)(`svg`,{className:`w-5 h-5 text-amber-600`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2,children:(0,s.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z`})})}),(0,s.jsx)(`h1`,{className:`text-2xl font-bold text-[#1A2421] tracking-tight`,children:`Registration closed`}),(0,s.jsx)(`p`,{className:`mt-2 text-sm text-gray-400 font-medium`,children:`New account registration is currently disabled by the administrator.`}),(0,s.jsx)(`div`,{className:`mt-8 pt-6 border-t border-gray-100`,children:(0,s.jsx)(i,{href:route(`login`),className:`text-sm font-semibold text-[#3D4E4B] hover:text-[#D4A017] transition-colors duration-200`,children:`← Back to sign in`})})]})]})}export{c as default}; \ No newline at end of file diff --git a/public/build/assets/ResetPassword-BTTfjVJh.js b/public/build/assets/ResetPassword-BTTfjVJh.js new file mode 100644 index 0000000..5768732 --- /dev/null +++ b/public/build/assets/ResetPassword-BTTfjVJh.js @@ -0,0 +1 @@ +import{a as e,c as t,n,t as r}from"./app-BJ7g6sa8.js";import{t as i}from"./GuestLayout-CN-YY0cs.js";t();var a=r();function o({token:t,email:r}){let{data:o,setData:s,post:c,processing:l,errors:u,reset:d}=e({token:t,email:r,password:``,password_confirmation:``});return(0,a.jsxs)(i,{children:[(0,a.jsx)(n,{title:`Reset password`}),(0,a.jsxs)(`div`,{className:`mb-8 anim-down`,children:[(0,a.jsx)(`h1`,{className:`text-2xl font-bold text-[#1A2421] tracking-tight`,children:`Set new password`}),(0,a.jsxs)(`p`,{className:`mt-1.5 text-sm text-gray-400 font-medium`,children:[`Choose a strong password for `,(0,a.jsx)(`span`,{className:`text-[#3D4E4B] font-semibold`,children:r}),`.`]})]}),(0,a.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),c(route(`password.store`),{onFinish:()=>d(`password`,`password_confirmation`)})},className:`space-y-4 anim-up`,style:{animationDelay:`0.1s`},children:[(0,a.jsx)(`input`,{type:`hidden`,value:o.email}),(0,a.jsx)(`input`,{type:`hidden`,value:o.token}),(0,a.jsxs)(`div`,{children:[(0,a.jsx)(`label`,{htmlFor:`password`,className:`block text-sm font-semibold text-gray-600 mb-1.5`,children:`New password`}),(0,a.jsx)(`input`,{id:`password`,type:`password`,autoComplete:`new-password`,autoFocus:!0,value:o.password,onChange:e=>s(`password`,e.target.value),placeholder:`Min. 8 characters`,className:`auth-input${u.password?` !border-red-300 !bg-red-50/50`:``}`}),u.password&&(0,a.jsx)(`p`,{className:`mt-1.5 text-xs font-semibold text-red-500`,children:u.password})]}),(0,a.jsxs)(`div`,{children:[(0,a.jsx)(`label`,{htmlFor:`password_confirmation`,className:`block text-sm font-semibold text-gray-600 mb-1.5`,children:`Confirm new password`}),(0,a.jsx)(`input`,{id:`password_confirmation`,type:`password`,autoComplete:`new-password`,value:o.password_confirmation,onChange:e=>s(`password_confirmation`,e.target.value),placeholder:`••••••••`,className:`auth-input${u.password_confirmation?` !border-red-300 !bg-red-50/50`:``}`}),u.password_confirmation&&(0,a.jsx)(`p`,{className:`mt-1.5 text-xs font-semibold text-red-500`,children:u.password_confirmation})]}),(0,a.jsx)(`button`,{type:`submit`,disabled:l,className:`mt-2 w-full h-11 rounded-xl bg-[#3D4E4B] hover:bg-[#2D3A38] text-white text-sm font-bold tracking-tight transition-colors duration-200 flex items-center justify-center gap-2 disabled:opacity-60 disabled:cursor-not-allowed`,children:l?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(`svg`,{className:`w-4 h-4 animate-spin text-white/60`,fill:`none`,viewBox:`0 0 24 24`,children:[(0,a.jsx)(`circle`,{className:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,strokeWidth:`4`}),(0,a.jsx)(`path`,{className:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z`})]}),`Saving…`]}):`Reset password`})]})]})}export{o as default}; \ No newline at end of file diff --git a/public/build/assets/Setup-ZspLG92f.js b/public/build/assets/Setup-ZspLG92f.js new file mode 100644 index 0000000..df34133 --- /dev/null +++ b/public/build/assets/Setup-ZspLG92f.js @@ -0,0 +1 @@ +import{a as e,c as t,d as n,i as r,n as i,t as a}from"./app-BJ7g6sa8.js";import{t as o}from"./AuthenticatedLayout-CrB9BCoI.js";import{n as s,t as c}from"./swal-DZXjpqDE.js";var l=n(t(),1),u=n(s(),1),d=a();function f({enabled:t,qr_code:n,secret:a,recovery_codes:s}){let[f,p]=(0,l.useState)(!1),[m,h]=(0,l.useState)(!1),{data:g,setData:_,post:v,processing:y,errors:b,reset:x}=e({code:``});return e({password:``}),(0,d.jsxs)(o,{children:[(0,d.jsx)(i,{title:`Two-Factor Authentication`}),(0,d.jsxs)(`div`,{className:`flex items-center justify-between mb-8 anim-down`,children:[(0,d.jsxs)(`div`,{children:[(0,d.jsx)(`h1`,{className:`text-xl font-bold text-[#3D4E4B] dark:text-white tracking-tight leading-none`,children:`Two-Factor Authentication`}),(0,d.jsx)(`p`,{className:`text-sm font-semibold text-gray-400 tracking-tight mt-2`,children:`Protect your account with an additional verification step`})]}),(0,d.jsxs)(`div`,{className:`flex items-center gap-2 px-4 py-2 rounded-xl text-xs font-bold ${t?`bg-emerald-50 text-emerald-700 border border-emerald-200`:`bg-amber-50 text-amber-700 border border-amber-200`}`,children:[(0,d.jsx)(`span`,{className:`w-2 h-2 rounded-full ${t?`bg-emerald-500`:`bg-amber-400`}`}),t?`2FA Active`:`2FA Not Enabled`]})]}),(0,d.jsxs)(`div`,{className:`max-w-3xl space-y-6`,children:[(0,d.jsxs)(`div`,{className:`p-5 bg-amber-50 border border-amber-200 rounded-2xl flex items-start gap-3 anim-down`,children:[(0,d.jsx)(`svg`,{className:`w-5 h-5 text-amber-500 mt-0.5 shrink-0`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,d.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 9v2m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z`})}),(0,d.jsxs)(`div`,{children:[(0,d.jsx)(`p`,{className:`text-xs font-bold text-amber-800 mb-1`,children:`What is Two-Factor Authentication?`}),(0,d.jsx)(`p`,{className:`text-[11px] text-amber-700 font-medium leading-relaxed`,children:`2FA adds an extra layer of security by requiring a one-time code from your authenticator app in addition to your password when signing in.`})]})]}),t?(0,d.jsxs)(`div`,{className:`space-y-4`,children:[(0,d.jsxs)(`div`,{className:`bg-white rounded-2xl border border-emerald-100 shadow-sm p-6 flex items-center gap-4 anim-up`,children:[(0,d.jsx)(`div`,{className:`w-12 h-12 rounded-xl bg-emerald-50 flex items-center justify-center shrink-0`,children:(0,d.jsx)(`svg`,{className:`w-6 h-6 text-emerald-600`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2.5,children:(0,d.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z`})})}),(0,d.jsxs)(`div`,{className:`flex-1`,children:[(0,d.jsx)(`div`,{className:`text-sm font-bold text-[#3D4E4B]`,children:`Two-Factor Authentication is Active`}),(0,d.jsx)(`div`,{className:`text-xs text-gray-400 font-medium mt-0.5`,children:`Your account is secured with TOTP authentication.`})]}),(0,d.jsx)(`button`,{onClick:async()=>{let{value:e}=await u.default.fire({title:`Disable 2FA`,text:`Enter your password to confirm disabling Two-Factor Authentication.`,input:`password`,inputPlaceholder:`Your current password`,showCancelButton:!0,confirmButtonText:`Disable`,confirmButtonColor:`#dc2626`});e&&r.post(route(`two-factor.disable`),{password:e},{preserveScroll:!0,onSuccess:()=>c.success(`Disabled`,`2FA has been disabled.`)})},className:`h-9 px-5 text-xs font-bold text-red-500 border border-red-200 rounded-xl hover:bg-red-50 transition-all`,children:`Disable 2FA`})]}),(0,d.jsxs)(`div`,{className:`bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden anim-up`,style:{animationDelay:`0.05s`},children:[(0,d.jsxs)(`div`,{className:`px-6 py-4 border-b border-gray-50 bg-gray-50/30 flex items-center justify-between`,children:[(0,d.jsxs)(`div`,{children:[(0,d.jsx)(`h2`,{className:`text-sm font-bold text-[#3D4E4B]`,children:`Recovery Codes`}),(0,d.jsx)(`p`,{className:`text-xs text-gray-400 font-semibold mt-1`,children:`Store these codes safely — use them if you lose access to your authenticator`})]}),(0,d.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,d.jsx)(`button`,{onClick:()=>h(!m),className:`h-8 px-4 text-xs font-bold text-[#3D4E4B] border border-gray-200 rounded-lg hover:bg-gray-50 transition-all`,children:m?`Hide`:`Show`}),(0,d.jsx)(`button`,{onClick:async()=>{(await c.confirm(`Regenerate Codes?`,`Old recovery codes will be invalidated immediately.`,`Regenerate`)).isConfirmed&&r.post(route(`two-factor.recovery-codes`),{},{preserveScroll:!0,onSuccess:()=>{h(!0),c.success(`Regenerated`,`New recovery codes have been generated.`)}})},className:`h-8 px-4 text-xs font-bold text-[#D4A017] border border-amber-200 rounded-lg hover:bg-amber-50 transition-all`,children:`Regenerate`})]})]}),m&&s.length>0&&(0,d.jsxs)(`div`,{className:`p-6`,children:[(0,d.jsx)(`div`,{className:`grid grid-cols-2 gap-2`,children:s.map((e,t)=>(0,d.jsx)(`code`,{className:`px-4 py-2.5 bg-gray-50 border border-gray-100 rounded-xl text-xs font-mono text-[#3D4E4B] tracking-wider text-center`,children:e},t))}),(0,d.jsx)(`p`,{className:`text-[11px] text-amber-600 font-semibold mt-4`,children:`⚠ Each code can only be used once. Regenerate if compromised.`})]})]})]}):(0,d.jsxs)(`div`,{className:`bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden anim-up`,children:[(0,d.jsxs)(`div`,{className:`px-6 py-4 border-b border-gray-50 bg-gray-50/30`,children:[(0,d.jsx)(`h2`,{className:`text-sm font-bold text-[#3D4E4B]`,children:`Setup Authenticator App`}),(0,d.jsx)(`p`,{className:`text-xs text-gray-400 font-semibold mt-1`,children:`Scan the QR code with Google Authenticator, Authy, or any TOTP app`})]}),(0,d.jsx)(`div`,{className:`p-8`,children:(0,d.jsxs)(`div`,{className:`flex flex-col md:flex-row gap-10 items-center md:items-start`,children:[(0,d.jsx)(`div`,{className:`shrink-0`,children:(0,d.jsx)(`div`,{className:`p-4 bg-white border-2 border-gray-100 rounded-2xl inline-block shadow-sm`,children:(0,d.jsx)(`img`,{src:n,alt:`2FA QR Code`,className:`w-48 h-48`})})}),(0,d.jsxs)(`div`,{className:`flex-1 space-y-6`,children:[(0,d.jsx)(`div`,{className:`space-y-4`,children:[`Install an authenticator app (Google Authenticator, Authy, 1Password)`,`Scan the QR code or enter the manual key below`,`Enter the 6-digit code from your app to verify and activate`].map((e,t)=>(0,d.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,d.jsx)(`div`,{className:`w-6 h-6 rounded-full bg-[#3D4E4B] text-white text-[10px] font-black flex items-center justify-center shrink-0 mt-0.5`,children:t+1}),(0,d.jsx)(`p`,{className:`text-xs font-medium text-gray-500 leading-relaxed pt-0.5`,children:e})]},t))}),(0,d.jsxs)(`div`,{children:[(0,d.jsx)(`label`,{className:`block text-xs font-semibold text-gray-400 mb-1.5`,children:`Manual Key`}),(0,d.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,d.jsx)(`code`,{className:`flex-1 text-xs font-mono bg-gray-50 border border-gray-100 rounded-xl px-4 py-3 text-[#3D4E4B] tracking-wider`,children:a}),(0,d.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(a),p(!0),setTimeout(()=>p(!1),2e3)},className:`shrink-0 h-11 px-4 border border-gray-200 rounded-xl text-xs font-bold text-gray-500 hover:bg-gray-50 transition-all`,children:f?`✓ Copied`:`Copy`})]})]}),(0,d.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),v(route(`two-factor.enable`),{preserveScroll:!0,onSuccess:()=>{x(),c.success(`Enabled`,`2FA is now active on your account.`)}})},className:`space-y-3`,children:[(0,d.jsxs)(`div`,{children:[(0,d.jsx)(`label`,{className:`block text-xs font-semibold text-gray-400 mb-1.5`,children:`Verification Code *`}),(0,d.jsx)(`input`,{type:`text`,inputMode:`numeric`,maxLength:6,value:g.code,onChange:e=>_(`code`,e.target.value),className:`input-field w-full text-center tracking-[0.5em] font-bold text-lg`,placeholder:`000000`}),b.code&&(0,d.jsx)(`p`,{className:`text-xs text-red-500 font-semibold mt-1`,children:b.code})]}),(0,d.jsx)(`button`,{type:`submit`,disabled:y||g.code.length<6,className:`w-full h-11 bg-[#3D4E4B] text-white text-xs font-bold rounded-xl hover:bg-[#2D3A38] transition-all disabled:opacity-60`,children:y?`Verifying...`:`Enable Two-Factor Authentication`})]})]})]})})]})]})]})}export{f as default}; \ No newline at end of file diff --git a/public/build/assets/Show-lMRyP8VR.js b/public/build/assets/Show-lMRyP8VR.js new file mode 100644 index 0000000..63ad844 --- /dev/null +++ b/public/build/assets/Show-lMRyP8VR.js @@ -0,0 +1 @@ +import{c as e,n as t,r as n,t as r}from"./app-BJ7g6sa8.js";import{t as i}from"./AuthenticatedLayout-CrB9BCoI.js";e();var a=r();function o({label:e,children:t}){return(0,a.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-start gap-1 sm:gap-0 py-3.5 border-b border-gray-50 last:border-0`,children:[(0,a.jsx)(`dt`,{className:`text-xs font-semibold text-gray-500 sm:w-44 shrink-0 mt-0.5`,children:e}),(0,a.jsx)(`dd`,{className:`text-sm font-semibold text-[#3D4E4B] tracking-tight`,children:t})]})}function s({viewUser:e}){let r=`${e.first_name?.charAt(0)||``}${e.last_name?.charAt(0)||``}`.toUpperCase();return(0,a.jsxs)(i,{children:[(0,a.jsx)(t,{title:`${e.first_name} ${e.last_name} — Users`}),(0,a.jsxs)(`div`,{className:`flex items-center gap-2 text-sm mb-6 anim-fade`,children:[(0,a.jsx)(n,{href:`/users`,className:`text-gray-400 hover:text-[#3D4E4B] transition-colors font-semibold`,children:`Users`}),(0,a.jsx)(`svg`,{className:`w-3.5 h-3.5 text-gray-300`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2,children:(0,a.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M9 5l7 7-7 7`})}),(0,a.jsxs)(`span`,{className:`text-[#3D4E4B] font-bold`,children:[e.first_name,` `,e.last_name]})]}),(0,a.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-3 gap-6`,children:[(0,a.jsxs)(`div`,{className:`lg:col-span-1 space-y-4 anim-up`,children:[(0,a.jsx)(`div`,{className:`bg-white rounded-2xl border border-gray-100 shadow-sm p-6`,children:(0,a.jsxs)(`div`,{className:`flex flex-col items-center text-center`,children:[(0,a.jsx)(`div`,{className:`w-20 h-20 rounded-2xl bg-[#3D4E4B] flex items-center justify-center text-white text-2xl font-bold overflow-hidden mb-4`,children:e.avatar_url?(0,a.jsx)(`img`,{src:e.avatar_url,className:`w-full h-full object-cover`,alt:``}):r}),(0,a.jsxs)(`h2`,{className:`text-base font-bold text-[#3D4E4B] tracking-tight`,children:[e.first_name,` `,e.last_name]}),(0,a.jsx)(`p`,{className:`text-xs text-gray-400 font-medium mt-0.5`,children:e.email}),(0,a.jsx)(`div`,{className:`flex flex-wrap justify-center gap-1.5 mt-3`,children:e.roles?.map(e=>(0,a.jsx)(`span`,{className:`px-2.5 py-1 text-xs font-bold bg-white text-gray-500 border border-gray-100 rounded-md`,children:e.name||e},e.name||e))}),(0,a.jsx)(`div`,{className:`mt-4`,children:(0,a.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-bold border ${e.status===`active`?`text-green-600 bg-white border-green-100`:`text-gray-400 bg-white border-gray-100`}`,children:[(0,a.jsx)(`span`,{className:`w-1 h-1 rounded-full ${e.status===`active`?`bg-green-500`:`bg-gray-300`}`}),e.status===`active`?`Active`:`Inactive`]})})]})}),(0,a.jsx)(`div`,{className:`bg-white rounded-2xl border border-gray-100 shadow-sm p-4 space-y-1`,children:(0,a.jsxs)(n,{href:`/users`,className:`flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-semibold text-gray-500 hover:bg-gray-50 hover:text-[#3D4E4B] transition-colors w-full`,children:[(0,a.jsx)(`svg`,{className:`w-4 h-4 text-gray-400`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2,children:(0,a.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M10 19l-7-7m0 0l7-7m-7 7h18`})}),`Back to Users`]})})]}),(0,a.jsxs)(`div`,{className:`lg:col-span-2 space-y-4 anim-up`,style:{animationDelay:`0.08s`},children:[(0,a.jsxs)(`div`,{className:`bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden`,children:[(0,a.jsx)(`div`,{className:`px-6 py-4 border-b border-gray-50 bg-gray-50/30`,children:(0,a.jsx)(`h3`,{className:`text-sm font-bold text-[#3D4E4B] tracking-tight`,children:`Personal Information`})}),(0,a.jsx)(`div`,{className:`px-6`,children:(0,a.jsxs)(`dl`,{children:[(0,a.jsx)(o,{label:`First name`,children:e.first_name}),(0,a.jsx)(o,{label:`Last name`,children:e.last_name}),(0,a.jsx)(o,{label:`Email`,children:e.email}),(0,a.jsx)(o,{label:`User ID`,children:(0,a.jsxs)(`span`,{className:`font-mono text-gray-400 text-xs`,children:[`#`,e.id]})})]})})]}),(0,a.jsxs)(`div`,{className:`bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden`,children:[(0,a.jsx)(`div`,{className:`px-6 py-4 border-b border-gray-50 bg-gray-50/30`,children:(0,a.jsx)(`h3`,{className:`text-sm font-bold text-[#3D4E4B] tracking-tight`,children:`Roles & Permissions`})}),(0,a.jsxs)(`div`,{className:`p-6 space-y-5`,children:[(0,a.jsxs)(`div`,{children:[(0,a.jsx)(`p`,{className:`text-xs font-semibold text-gray-400 tracking-tight mb-2`,children:`Assigned Roles`}),(0,a.jsx)(`div`,{className:`flex flex-wrap gap-1.5`,children:e.roles?.length?e.roles.map(e=>(0,a.jsx)(`span`,{className:`px-3 py-1.5 text-xs font-bold bg-[#3D4E4B] text-white rounded-lg`,children:e.name||e},e.name||e)):(0,a.jsx)(`span`,{className:`text-sm text-gray-400 font-semibold`,children:`No roles assigned`})})]}),(0,a.jsxs)(`div`,{children:[(0,a.jsx)(`p`,{className:`text-xs font-semibold text-gray-400 tracking-tight mb-2`,children:`Granted Permissions`}),(0,a.jsx)(`div`,{className:`grid grid-cols-2 sm:grid-cols-3 gap-1.5`,children:e.permissions?.length?e.permissions.map(e=>(0,a.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-gray-600 font-semibold bg-gray-50 border border-gray-100 px-2.5 py-1.5 rounded-lg`,children:[(0,a.jsx)(`div`,{className:`w-1.5 h-1.5 rounded-full bg-[#21A59F] shrink-0`}),e.name||e]},e.name||e)):(0,a.jsx)(`span`,{className:`text-sm text-gray-400 font-semibold col-span-full`,children:`Inherited from roles`})})]})]})]}),(0,a.jsxs)(`div`,{className:`bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden`,children:[(0,a.jsx)(`div`,{className:`px-6 py-4 border-b border-gray-50 bg-gray-50/30`,children:(0,a.jsx)(`h3`,{className:`text-sm font-bold text-[#3D4E4B] tracking-tight`,children:`Activity Timeline`})}),(0,a.jsxs)(`div`,{className:`p-6 space-y-4`,children:[(0,a.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,a.jsx)(`div`,{className:`w-8 h-8 rounded-xl bg-[#E3EBE8] flex items-center justify-center shrink-0`,children:(0,a.jsx)(`svg`,{className:`w-4 h-4 text-[#3D4E4B]`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2,children:(0,a.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 4v16m8-8H4`})})}),(0,a.jsxs)(`div`,{children:[(0,a.jsx)(`p`,{className:`text-sm font-bold text-[#3D4E4B] tracking-tight`,children:`Account Created`}),(0,a.jsx)(`p`,{className:`text-xs text-gray-400 font-medium mt-0.5`,children:new Date(e.created_at).toLocaleDateString(`en-US`,{weekday:`long`,year:`numeric`,month:`long`,day:`numeric`})})]})]}),(0,a.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,a.jsx)(`div`,{className:`w-8 h-8 rounded-xl bg-[#E3EBE8] flex items-center justify-center shrink-0`,children:(0,a.jsx)(`svg`,{className:`w-4 h-4 text-[#3D4E4B]`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2,children:(0,a.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15`})})}),(0,a.jsxs)(`div`,{children:[(0,a.jsx)(`p`,{className:`text-sm font-bold text-[#3D4E4B] tracking-tight`,children:`Last Updated`}),(0,a.jsx)(`p`,{className:`text-xs text-gray-400 font-medium mt-0.5`,children:new Date(e.updated_at).toLocaleDateString(`en-US`,{weekday:`long`,year:`numeric`,month:`long`,day:`numeric`})})]})]})]})]})]})]})]})}export{s as default}; \ No newline at end of file diff --git a/public/build/assets/TextInput-DV7QeRn3.js b/public/build/assets/TextInput-DV7QeRn3.js new file mode 100644 index 0000000..2e15270 --- /dev/null +++ b/public/build/assets/TextInput-DV7QeRn3.js @@ -0,0 +1,5 @@ +import{c as e,d as t,t as n}from"./app-BJ7g6sa8.js";var r=n();function i({message:e,className:t=``,...n}){return e?(0,r.jsx)(`p`,{...n,className:`text-sm text-red-600 `+t,children:e}):null}function a({value:e,className:t=``,children:n,...i}){return(0,r.jsx)(`label`,{...i,className:`block text-sm font-medium text-gray-700 `+t,children:e||n})}var o=t(e(),1),s=Object.defineProperty,c=(e,t,n)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,l=(e,t,n)=>(c(e,typeof t==`symbol`?t:t+``,n),n),u=new class{constructor(){l(this,`current`,this.detect()),l(this,`handoffState`,`pending`),l(this,`currentId`,0)}set(e){this.current!==e&&(this.handoffState=`pending`,this.currentId=0,this.current=e)}reset(){this.set(this.detect())}nextId(){return++this.currentId}get isServer(){return this.current===`server`}get isClient(){return this.current===`client`}detect(){return typeof window>`u`||typeof document>`u`?`server`:`client`}handoff(){this.handoffState===`pending`&&(this.handoffState=`complete`)}get isHandoffComplete(){return this.handoffState===`complete`}};function d(e){typeof queueMicrotask==`function`?queueMicrotask(e):Promise.resolve().then(e).catch(e=>setTimeout(()=>{throw e}))}function f(){let e=[],t={addEventListener(e,n,r,i){return e.addEventListener(n,r,i),t.add(()=>e.removeEventListener(n,r,i))},requestAnimationFrame(...e){let n=requestAnimationFrame(...e);return t.add(()=>cancelAnimationFrame(n))},nextFrame(...e){return t.requestAnimationFrame(()=>t.requestAnimationFrame(...e))},setTimeout(...e){let n=setTimeout(...e);return t.add(()=>clearTimeout(n))},microTask(...e){let n={current:!0};return d(()=>{n.current&&e[0]()}),t.add(()=>{n.current=!1})},style(e,t,n){let r=e.style.getPropertyValue(t);return Object.assign(e.style,{[t]:n}),this.add(()=>{Object.assign(e.style,{[t]:r})})},group(e){let t=f();return e(t),this.add(()=>t.dispose())},add(t){return e.includes(t)||e.push(t),()=>{let n=e.indexOf(t);if(n>=0)for(let t of e.splice(n,1))t()}},dispose(){for(let t of e.splice(0))t()}};return t}function p(){let[e]=(0,o.useState)(f);return(0,o.useEffect)(()=>()=>e.dispose(),[e]),e}var m=(e,t)=>{u.isServer?(0,o.useEffect)(e,t):(0,o.useLayoutEffect)(e,t)};function h(e){let t=(0,o.useRef)(e);return m(()=>{t.current=e},[e]),t}var g=function(e){let t=h(e);return o.useCallback((...e)=>t.current(...e),[t])};function _(...e){return Array.from(new Set(e.flatMap(e=>typeof e==`string`?e.split(` `):[]))).filter(Boolean).join(` `)}function v(e,t,...n){if(e in t){let r=t[e];return typeof r==`function`?r(...n):r}let r=Error(`Tried to handle "${e}" but there is no handler defined. Only defined handlers are: ${Object.keys(t).map(e=>`"${e}"`).join(`, `)}.`);throw Error.captureStackTrace&&Error.captureStackTrace(r,v),r}var y=(e=>(e[e.None=0]=`None`,e[e.RenderStrategy=1]=`RenderStrategy`,e[e.Static=2]=`Static`,e))(y||{}),b=(e=>(e[e.Unmount=0]=`Unmount`,e[e.Hidden=1]=`Hidden`,e))(b||{});function x(){let e=ee();return(0,o.useCallback)(t=>S({mergeRefs:e,...t}),[e])}function S({ourProps:e,theirProps:t,slot:n,defaultTag:r,features:i,visible:a=!0,name:o,mergeRefs:s}){s??=w;let c=T(t,e);if(a)return C(c,n,r,o,s);let l=i??0;if(l&2){let{static:e=!1,...t}=c;if(e)return C(t,n,r,o,s)}if(l&1){let{unmount:e=!0,...t}=c;return v(+!e,{0(){return null},1(){return C({...t,hidden:!0,style:{display:`none`}},n,r,o,s)}})}return C(c,n,r,o,s)}function C(e,t={},n,r,i){let{as:a=n,children:s,refName:c=`ref`,...l}=O(e,[`unmount`,`static`]),u=e.ref===void 0?{}:{[c]:e.ref},d=typeof s==`function`?s(t):s;d=A(d),`className`in l&&l.className&&typeof l.className==`function`&&(l.className=l.className(t)),l[`aria-labelledby`]&&l[`aria-labelledby`]===l.id&&(l[`aria-labelledby`]=void 0);let f={};if(t){let e=!1,n=[];for(let[r,i]of Object.entries(t))typeof i==`boolean`&&(e=!0),i===!0&&n.push(r.replace(/([A-Z])/g,e=>`-${e.toLowerCase()}`));if(e){f[`data-headlessui-state`]=n.join(` `);for(let e of n)f[`data-${e}`]=``}}if(j(a)&&(Object.keys(D(l)).length>0||Object.keys(D(f)).length>0))if(!(0,o.isValidElement)(d)||Array.isArray(d)&&d.length>1||M(d)){if(Object.keys(D(l)).length>0)throw Error([`Passing props on "Fragment"!`,``,`The current component <${r} /> is rendering a "Fragment".`,`However we need to passthrough the following props:`,Object.keys(D(l)).concat(Object.keys(D(f))).map(e=>` - ${e}`).join(` +`),``,`You can apply a few solutions:`,['Add an `as="..."` prop, to ensure that we render an actual element instead of a "Fragment".',`Render a single element as the child so that we can forward the props onto that element.`].map(e=>` - ${e}`).join(` +`)].join(` +`))}else{let e=d.props?.className,t=typeof e==`function`?(...t)=>_(e(...t),l.className):_(e,l.className),n=t?{className:t}:{},r=T(d.props,D(O(l,[`ref`])));for(let e in f)e in r&&delete f[e];return(0,o.cloneElement)(d,Object.assign({},r,f,u,{ref:i(k(d),u.ref)},n))}return(0,o.createElement)(a,Object.assign({},O(l,[`ref`]),!j(a)&&u,!j(a)&&f),d)}function ee(){let e=(0,o.useRef)([]),t=(0,o.useCallback)(t=>{for(let n of e.current)n!=null&&(typeof n==`function`?n(t):n.current=t)},[]);return(...n)=>{if(!n.every(e=>e==null))return e.current=n,t}}function w(...e){return e.every(e=>e==null)?void 0:t=>{for(let n of e)n!=null&&(typeof n==`function`?n(t):n.current=t)}}function T(...e){if(e.length===0)return{};if(e.length===1)return e[0];let t={},n={};for(let r of e)for(let e in r)e.startsWith(`on`)&&typeof r[e]==`function`?(n[e]??(n[e]=[]),n[e].push(r[e])):t[e]=r[e];if(t.disabled||t[`aria-disabled`])for(let e in n)/^(on(?:Click|Pointer|Mouse|Key)(?:Down|Up|Press)?)$/.test(e)&&(n[e]=[e=>(e?.preventDefault)?.call(e)]);for(let e in n)Object.assign(t,{[e](t,...r){let i=n[e];for(let e of i){if((t instanceof Event||t?.nativeEvent instanceof Event)&&t.defaultPrevented)return;e(t,...r)}}});return t}function E(e){return Object.assign((0,o.forwardRef)(e),{displayName:e.displayName??e.name})}function D(e){let t=Object.assign({},e);for(let e in t)t[e]===void 0&&delete t[e];return t}function O(e,t=[]){let n=Object.assign({},e);for(let e of t)e in n&&delete n[e];return n}function k(e){return`18.3.1`.split(`.`)[0]>=`19`?e.props.ref:e.ref}function A(e){if(e!=null&&e.$$typeof===Symbol.for(`react.lazy`)){let t=e._payload;if(t!=null&&t.status===`fulfilled`)return A(t.value)}return e}function j(e){return e===o.Fragment||e===Symbol.for(`react.fragment`)}function M(e){return j(e.type)}var N=Symbol();function P(e,t=!0){return Object.assign(e,{[N]:t})}function F(...e){let t=(0,o.useRef)(e);(0,o.useEffect)(()=>{t.current=e},[e]);let n=g(e=>{for(let n of t.current)n!=null&&(typeof n==`function`?n(e):n.current=e)});return e.every(e=>e==null||e?.[N])?void 0:n}function I(e=0){let[t,n]=(0,o.useState)(e);return{flags:t,setFlag:(0,o.useCallback)(e=>n(e),[]),addFlag:(0,o.useCallback)(e=>n(t=>t|e),[]),hasFlag:(0,o.useCallback)(e=>(t&e)===e,[t]),removeFlag:(0,o.useCallback)(e=>n(t=>t&~e),[]),toggleFlag:(0,o.useCallback)(e=>n(t=>t^e),[])}}typeof process<`u`&&typeof globalThis<`u`&&typeof Element<`u`&&(process==null?void 0:{})?.NODE_ENV===`test`&&(Element==null?void 0:Element.prototype)?.getAnimations===void 0&&(Element.prototype.getAnimations=function(){return console.warn(["Headless UI has polyfilled `Element.prototype.getAnimations` for your tests.","Please install a proper polyfill e.g. `jsdom-testing-mocks`, to silence these warnings.",``,`Example usage:`,"```js",`import { mockAnimationsApi } from 'jsdom-testing-mocks'`,`mockAnimationsApi()`,"```"].join(` +`)),[]});var L=(e=>(e[e.None=0]=`None`,e[e.Closed=1]=`Closed`,e[e.Enter=2]=`Enter`,e[e.Leave=4]=`Leave`,e))(L||{});function te(e){let t={};for(let n in e)e[n]===!0&&(t[`data-${n}`]=``);return t}function ne(e,t,n,r){let[i,a]=(0,o.useState)(n),{hasFlag:s,addFlag:c,removeFlag:l}=I(e&&i?3:0),u=(0,o.useRef)(!1),d=(0,o.useRef)(!1);return m(()=>{var i;if(e){if(n&&a(!0),!t){n&&c(3);return}return(i=r?.start)==null||i.call(r,n),R(t,{inFlight:u,prepare(){d.current?d.current=!1:d.current=u.current,u.current=!0,!d.current&&(n?(c(3),l(4)):(c(4),l(2)))},run(){d.current?n?(l(3),c(4)):(l(4),c(3)):n?l(1):c(1)},done(){var e;d.current&&V(t)||(u.current=!1,l(7),n||a(!1),(e=r?.end)==null||e.call(r,n))}})}},[e,n,t,p()]),e?[i,{closed:s(1),enter:s(2),leave:s(4),transition:s(2)||s(4)}]:[n,{closed:void 0,enter:void 0,leave:void 0,transition:void 0}]}function R(e,{prepare:t,run:n,done:r,inFlight:i}){let a=f();return B(e,{prepare:t,inFlight:i}),a.nextFrame(()=>{n(),a.requestAnimationFrame(()=>{a.add(z(e,r))})}),a.dispose}function z(e,t){let n=f();if(!e)return n.dispose;let r=!1;n.add(()=>{r=!0});let i=e.getAnimations?.call(e).filter(e=>e instanceof CSSTransition)??[];return i.length===0?(t(),n.dispose):(Promise.allSettled(i.map(e=>e.finished)).then(()=>{r||t()}),n.dispose)}function B(e,{inFlight:t,prepare:n}){if(t!=null&&t.current){n();return}let r=e.style.transition;e.style.transition=`none`,n(),e.offsetHeight,e.style.transition=r}function V(e){return(e.getAnimations?.call(e)??[]).some(e=>e instanceof CSSTransition&&e.playState!==`finished`)}var H=(0,o.createContext)(null);H.displayName=`OpenClosedContext`;var U=(e=>(e[e.Open=1]=`Open`,e[e.Closed=2]=`Closed`,e[e.Closing=4]=`Closing`,e[e.Opening=8]=`Opening`,e))(U||{});function W(){return(0,o.useContext)(H)}function re({value:e,children:t}){return o.createElement(H.Provider,{value:e},t)}function G({children:e}){return o.createElement(H.Provider,{value:null},e)}function K(){let e=typeof document>`u`;return`useSyncExternalStore`in o?(e=>e.useSyncExternalStore)(o)(()=>()=>{},()=>!1,()=>!e):!1}function q(){let e=K(),[t,n]=o.useState(u.isHandoffComplete);return t&&u.isHandoffComplete===!1&&n(!1),o.useEffect(()=>{t!==!0&&n(!0)},[t]),o.useEffect(()=>u.handoff(),[]),e?!1:t}function J(){let e=(0,o.useRef)(!1);return m(()=>(e.current=!0,()=>{e.current=!1}),[]),e}function Y(e){return!!(e.enter||e.enterFrom||e.enterTo||e.leave||e.leaveFrom||e.leaveTo)||!j(e.as??ce)||o.Children.count(e.children)===1}var X=(0,o.createContext)(null);X.displayName=`TransitionContext`;var ie=(e=>(e.Visible=`visible`,e.Hidden=`hidden`,e))(ie||{});function ae(){let e=(0,o.useContext)(X);if(e===null)throw Error(`A is used but it is missing a parent or .`);return e}function oe(){let e=(0,o.useContext)(Z);if(e===null)throw Error(`A is used but it is missing a parent or .`);return e}var Z=(0,o.createContext)(null);Z.displayName=`NestingContext`;function Q(e){return`children`in e?Q(e.children):e.current.filter(({el:e})=>e.current!==null).filter(({state:e})=>e===`visible`).length>0}function se(e,t){let n=h(e),r=(0,o.useRef)([]),i=J(),a=p(),s=g((e,t=b.Hidden)=>{let o=r.current.findIndex(({el:t})=>t===e);o!==-1&&(v(t,{[b.Unmount](){r.current.splice(o,1)},[b.Hidden](){r.current[o].state=`hidden`}}),a.microTask(()=>{var e;!Q(r)&&i.current&&((e=n.current)==null||e.call(n))}))}),c=g(e=>{let t=r.current.find(({el:t})=>t===e);return t?t.state!==`visible`&&(t.state=`visible`):r.current.push({el:e,state:`visible`}),()=>s(e,b.Unmount)}),l=(0,o.useRef)([]),u=(0,o.useRef)(Promise.resolve()),d=(0,o.useRef)({enter:[],leave:[]}),f=g((e,n,r)=>{l.current.splice(0),t&&(t.chains.current[n]=t.chains.current[n].filter(([t])=>t!==e)),t?.chains.current[n].push([e,new Promise(e=>{l.current.push(e)})]),t?.chains.current[n].push([e,new Promise(e=>{Promise.all(d.current[n].map(([e,t])=>t)).then(()=>e())})]),n===`enter`?u.current=u.current.then(()=>t?.wait.current).then(()=>r(n)):r(n)}),m=g((e,t,n)=>{Promise.all(d.current[t].splice(0).map(([e,t])=>t)).then(()=>{var e;(e=l.current.shift())==null||e()}).then(()=>n(t))});return(0,o.useMemo)(()=>({children:r,register:c,unregister:s,onStart:f,onStop:m,wait:u,chains:d}),[c,s,r,f,m,d,u])}var ce=o.Fragment,le=y.RenderStrategy;function ue(e,t){var n;let{transition:r=!0,beforeEnter:i,afterEnter:a,beforeLeave:s,afterLeave:c,enter:l,enterFrom:u,enterTo:d,entered:f,leave:p,leaveFrom:h,leaveTo:y,...S}=e,[C,ee]=(0,o.useState)(null),w=(0,o.useRef)(null),T=Y(e),E=F(...T?[w,t,ee]:t===null?[]:[t]),O=(n=S.unmount)==null||n?b.Unmount:b.Hidden,{show:k,appear:A,initial:j}=ae(),[M,N]=(0,o.useState)(k?`visible`:`hidden`),P=oe(),{register:I,unregister:L}=P;m(()=>I(w),[I,w]),m(()=>{if(O===b.Hidden&&w.current){if(k&&M!==`visible`){N(`visible`);return}return v(M,{hidden:()=>L(w),visible:()=>I(w)})}},[M,w,I,L,k,O]);let R=q();m(()=>{if(T&&R&&M===`visible`&&w.current===null)throw Error("Did you forget to passthrough the `ref` to the actual DOM node?")},[w,M,R,T]);let z=j&&!A,B=A&&k&&j,V=(0,o.useRef)(!1),H=se(()=>{V.current||(N(`hidden`),L(w))},P),W=g(e=>{V.current=!0;let t=e?`enter`:`leave`;H.onStart(w,t,e=>{e===`enter`?i?.():e===`leave`&&s?.()})}),G=g(e=>{let t=e?`enter`:`leave`;V.current=!1,H.onStop(w,t,e=>{e===`enter`?a?.():e===`leave`&&c?.()}),t===`leave`&&!Q(H)&&(N(`hidden`),L(w))});(0,o.useEffect)(()=>{T&&r||(W(k),G(k))},[k,T,r]);let[,K]=ne(!(!r||!T||!R||z),C,k,{start:W,end:G}),J=D({ref:E,className:_(S.className,B&&l,B&&u,K.enter&&l,K.enter&&K.closed&&u,K.enter&&!K.closed&&d,K.leave&&p,K.leave&&!K.closed&&h,K.leave&&K.closed&&y,!K.transition&&k&&f)?.trim()||void 0,...te(K)}),X=0;M===`visible`&&(X|=U.Open),M===`hidden`&&(X|=U.Closed),k&&M===`hidden`&&(X|=U.Opening),!k&&M===`visible`&&(X|=U.Closing);let ie=x();return o.createElement(Z.Provider,{value:H},o.createElement(re,{value:X},ie({ourProps:J,theirProps:S,defaultTag:ce,features:le,visible:M===`visible`,name:`Transition.Child`})))}function de(e,t){let{show:n,appear:r=!1,unmount:i=!0,...a}=e,s=(0,o.useRef)(null),c=F(...Y(e)?[s,t]:t===null?[]:[t]);q();let l=W();if(n===void 0&&l!==null&&(n=(l&U.Open)===U.Open),n===void 0)throw Error("A is used but it is missing a `show={true | false}` prop.");let[u,d]=(0,o.useState)(n?`visible`:`hidden`),f=se(()=>{n||d(`hidden`)}),[p,h]=(0,o.useState)(!0),_=(0,o.useRef)([n]);m(()=>{p!==!1&&_.current[_.current.length-1]!==n&&(_.current.push(n),h(!1))},[_,n]);let v=(0,o.useMemo)(()=>({show:n,appear:r,initial:p}),[n,r,p]);m(()=>{n?d(`visible`):!Q(f)&&s.current!==null&&d(`hidden`)},[n,f]);let y={unmount:i},b=g(()=>{var t;p&&h(!1),(t=e.beforeEnter)==null||t.call(e)}),S=g(()=>{var t;p&&h(!1),(t=e.beforeLeave)==null||t.call(e)}),C=x();return o.createElement(Z.Provider,{value:f},o.createElement(X.Provider,{value:v},C({ourProps:{...y,as:o.Fragment,children:o.createElement(pe,{ref:c,...y,...a,beforeEnter:b,beforeLeave:S})},theirProps:{},defaultTag:o.Fragment,features:le,visible:u===`visible`,name:`Transition`})))}function fe(e,t){let n=(0,o.useContext)(X)!==null,r=W()!==null;return o.createElement(o.Fragment,null,!n&&r?o.createElement($,{ref:t,...e}):o.createElement(pe,{ref:t,...e}))}var $=E(de),pe=E(ue),me=E(fe),he=Object.assign($,{Child:me,Root:$}),ge=(0,o.forwardRef)(function({type:e=`text`,className:t=``,isFocused:n=!1,...i},a){let s=(0,o.useRef)(null);return(0,o.useImperativeHandle)(a,()=>({focus:()=>s.current?.focus()})),(0,o.useEffect)(()=>{n&&s.current?.focus()},[n]),(0,r.jsx)(`input`,{...i,type:e,className:`rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 `+t,ref:s})});export{i as C,a as S,m as _,q as a,d as b,W as c,y as d,x as f,h as g,g as h,J as i,P as l,v as m,he as n,U as o,E as p,me as r,G as s,ge as t,F as u,p as v,u as x,f as y}; \ No newline at end of file diff --git a/public/build/assets/UpdatePasswordForm-DXZy5eGn.js b/public/build/assets/UpdatePasswordForm-DXZy5eGn.js new file mode 100644 index 0000000..987d3a6 --- /dev/null +++ b/public/build/assets/UpdatePasswordForm-DXZy5eGn.js @@ -0,0 +1 @@ +import{a as e,c as t,d as n,t as r}from"./app-BJ7g6sa8.js";import{C as i,S as a,n as o,t as s}from"./TextInput-DV7QeRn3.js";import{t as c}from"./PrimaryButton-KeVcwQeg.js";var l=n(t(),1),u=r();function d({className:t=``}){let n=(0,l.useRef)(),r=(0,l.useRef)(),{data:d,setData:f,errors:p,put:m,reset:h,processing:g,recentlySuccessful:_}=e({current_password:``,password:``,password_confirmation:``});return(0,u.jsxs)(`section`,{className:t,children:[(0,u.jsxs)(`header`,{children:[(0,u.jsx)(`h2`,{className:`text-lg font-medium text-gray-900`,children:`Update Password`}),(0,u.jsx)(`p`,{className:`mt-1 text-sm text-gray-600`,children:`Ensure your account is using a long, random password to stay secure.`})]}),(0,u.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),m(route(`password.update`),{preserveScroll:!0,onSuccess:()=>h(),onError:e=>{e.password&&(h(`password`,`password_confirmation`),n.current.focus()),e.current_password&&(h(`current_password`),r.current.focus())}})},className:`mt-6 space-y-6`,children:[(0,u.jsxs)(`div`,{children:[(0,u.jsx)(a,{htmlFor:`current_password`,value:`Current Password`}),(0,u.jsx)(s,{id:`current_password`,ref:r,value:d.current_password,onChange:e=>f(`current_password`,e.target.value),type:`password`,className:`mt-1 block w-full`,autoComplete:`current-password`}),(0,u.jsx)(i,{message:p.current_password,className:`mt-2`})]}),(0,u.jsxs)(`div`,{children:[(0,u.jsx)(a,{htmlFor:`password`,value:`New Password`}),(0,u.jsx)(s,{id:`password`,ref:n,value:d.password,onChange:e=>f(`password`,e.target.value),type:`password`,className:`mt-1 block w-full`,autoComplete:`new-password`}),(0,u.jsx)(i,{message:p.password,className:`mt-2`})]}),(0,u.jsxs)(`div`,{children:[(0,u.jsx)(a,{htmlFor:`password_confirmation`,value:`Confirm Password`}),(0,u.jsx)(s,{id:`password_confirmation`,value:d.password_confirmation,onChange:e=>f(`password_confirmation`,e.target.value),type:`password`,className:`mt-1 block w-full`,autoComplete:`new-password`}),(0,u.jsx)(i,{message:p.password_confirmation,className:`mt-2`})]}),(0,u.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,u.jsx)(c,{disabled:g,children:`Save`}),(0,u.jsx)(o,{show:_,enter:`transition ease-in-out`,enterFrom:`opacity-0`,leave:`transition ease-in-out`,leaveTo:`opacity-0`,children:(0,u.jsx)(`p`,{className:`text-sm text-gray-600`,children:`Saved.`})})]})]})]})}export{d as default}; \ No newline at end of file diff --git a/public/build/assets/UpdateProfileInformationForm-CZPCM5rZ.js b/public/build/assets/UpdateProfileInformationForm-CZPCM5rZ.js new file mode 100644 index 0000000..d26ae4c --- /dev/null +++ b/public/build/assets/UpdateProfileInformationForm-CZPCM5rZ.js @@ -0,0 +1 @@ +import{a as e,o as t,r as n,t as r}from"./app-BJ7g6sa8.js";import{C as i,S as a,n as o,t as s}from"./TextInput-DV7QeRn3.js";import{t as c}from"./PrimaryButton-KeVcwQeg.js";var l=r();function u({mustVerifyEmail:r,status:u,className:d=``}){let f=t().props.auth.user,{data:p,setData:m,patch:h,errors:g,processing:_,recentlySuccessful:v}=e({name:f.name,email:f.email});return(0,l.jsxs)(`section`,{className:d,children:[(0,l.jsxs)(`header`,{children:[(0,l.jsx)(`h2`,{className:`text-lg font-medium text-gray-900`,children:`Profile Information`}),(0,l.jsx)(`p`,{className:`mt-1 text-sm text-gray-600`,children:`Update your account's profile information and email address.`})]}),(0,l.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),h(route(`profile.update`))},className:`mt-6 space-y-6`,children:[(0,l.jsxs)(`div`,{children:[(0,l.jsx)(a,{htmlFor:`name`,value:`Name`}),(0,l.jsx)(s,{id:`name`,className:`mt-1 block w-full`,value:p.name,onChange:e=>m(`name`,e.target.value),required:!0,isFocused:!0,autoComplete:`name`}),(0,l.jsx)(i,{className:`mt-2`,message:g.name})]}),(0,l.jsxs)(`div`,{children:[(0,l.jsx)(a,{htmlFor:`email`,value:`Email`}),(0,l.jsx)(s,{id:`email`,type:`email`,className:`mt-1 block w-full`,value:p.email,onChange:e=>m(`email`,e.target.value),required:!0,autoComplete:`username`}),(0,l.jsx)(i,{className:`mt-2`,message:g.email})]}),r&&f.email_verified_at===null&&(0,l.jsxs)(`div`,{children:[(0,l.jsxs)(`p`,{className:`mt-2 text-sm text-gray-800`,children:[`Your email address is unverified.`,(0,l.jsx)(n,{href:route(`verification.send`),method:`post`,as:`button`,className:`rounded-md text-sm text-gray-600 underline hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2`,children:`Click here to re-send the verification email.`})]}),u===`verification-link-sent`&&(0,l.jsx)(`div`,{className:`mt-2 text-sm font-medium text-green-600`,children:`A new verification link has been sent to your email address.`})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,l.jsx)(c,{disabled:_,children:`Save`}),(0,l.jsx)(o,{show:v,enter:`transition ease-in-out`,enterFrom:`opacity-0`,leave:`transition ease-in-out`,leaveTo:`opacity-0`,children:(0,l.jsx)(`p`,{className:`text-sm text-gray-600`,children:`Saved.`})})]})]})]})}export{u as default}; \ No newline at end of file diff --git a/public/build/assets/VerifyEmail-rqxgUqlx.js b/public/build/assets/VerifyEmail-rqxgUqlx.js new file mode 100644 index 0000000..9efe072 --- /dev/null +++ b/public/build/assets/VerifyEmail-rqxgUqlx.js @@ -0,0 +1 @@ +import{a as e,c as t,n,r,t as i}from"./app-BJ7g6sa8.js";import{t as a}from"./GuestLayout-CN-YY0cs.js";t();var o=i();function s({status:t}){let{post:i,processing:s}=e({});return(0,o.jsxs)(a,{children:[(0,o.jsx)(n,{title:`Verify email`}),(0,o.jsxs)(`div`,{className:`mb-8 anim-down`,children:[(0,o.jsx)(`div`,{className:`w-12 h-12 bg-[#3D4E4B]/5 rounded-2xl flex items-center justify-center mb-6`,children:(0,o.jsx)(`svg`,{className:`w-5 h-5 text-[#3D4E4B]`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2,children:(0,o.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z`})})}),(0,o.jsx)(`h1`,{className:`text-2xl font-bold text-[#1A2421] tracking-tight`,children:`Check your email`}),(0,o.jsx)(`p`,{className:`mt-1.5 text-sm text-gray-400 font-medium leading-relaxed`,children:`We sent a verification link to your email address. Click the link to activate your account.`})]}),t===`verification-link-sent`&&(0,o.jsx)(`div`,{className:`mb-6 px-4 py-3 rounded-xl bg-emerald-50 border border-emerald-100 text-sm font-semibold text-emerald-700 anim-fade`,children:`A new verification link has been sent to your email.`}),(0,o.jsx)(`form`,{onSubmit:e=>{e.preventDefault(),i(route(`verification.send`))},className:`anim-up`,style:{animationDelay:`0.1s`},children:(0,o.jsx)(`button`,{type:`submit`,disabled:s,className:`w-full h-11 rounded-xl bg-[#3D4E4B] hover:bg-[#2D3A38] text-white text-sm font-bold tracking-tight transition-colors duration-200 flex items-center justify-center gap-2 disabled:opacity-60 disabled:cursor-not-allowed`,children:s?(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(`svg`,{className:`w-4 h-4 animate-spin text-white/60`,fill:`none`,viewBox:`0 0 24 24`,children:[(0,o.jsx)(`circle`,{className:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,strokeWidth:`4`}),(0,o.jsx)(`path`,{className:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z`})]}),`Sending…`]}):`Resend verification email`})}),(0,o.jsx)(`div`,{className:`mt-5 text-center anim-fade`,style:{animationDelay:`0.18s`},children:(0,o.jsx)(r,{href:route(`logout`),method:`post`,as:`button`,className:`text-sm font-semibold text-gray-400 hover:text-[#3D4E4B] transition-colors duration-200`,children:`Sign out`})})]})}export{s as default}; \ No newline at end of file diff --git a/public/build/assets/Welcome-CDP6Hme4.js b/public/build/assets/Welcome-CDP6Hme4.js new file mode 100644 index 0000000..24833d0 --- /dev/null +++ b/public/build/assets/Welcome-CDP6Hme4.js @@ -0,0 +1 @@ +import{c as e,n as t,o as n,r,t as i}from"./app-BJ7g6sa8.js";e();var a=i();function o({auth:e}){let{system_settings:i}=n().props,o=i?.app_name||`biiproject kit v2`,s=i?.app_logo,c=i?.app_logo_text||`BK`;return(0,a.jsxs)(`div`,{className:`min-h-screen bg-[#E3EBE8] text-[#3D4E4B] selection:bg-[#D4A017] selection:text-white font-sans`,children:[(0,a.jsx)(t,{title:`${o} — Premium Enterprise Identity`}),(0,a.jsx)(`nav`,{className:`fixed w-full z-50 px-6 py-6 anim-down`,children:(0,a.jsxs)(`div`,{className:`max-w-7xl mx-auto flex items-center justify-between bg-white/80 backdrop-blur-md rounded-[2rem] px-8 py-4 border border-white/20 shadow-sm`,children:[(0,a.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,a.jsx)(`div`,{className:`w-10 h-10 rounded-xl flex items-center justify-center text-xl font-bold overflow-hidden border border-gray-100 ${s?`bg-white`:`bg-[#3D4E4B] text-[#D4A017]`}`,children:s?(0,a.jsx)(`img`,{src:s,className:`w-full h-full object-contain`}):c}),(0,a.jsx)(`span`,{className:`text-sm font-bold tracking-tight`,children:o})]}),(0,a.jsxs)(`div`,{className:`flex items-center gap-8`,children:[(0,a.jsx)(`div`,{className:`hidden md:flex items-center gap-6`,children:[`Solutions`,`Ecosystem`,`Xxx`,`Governance`,`Intelligence`].map(e=>(0,a.jsx)(r,{href:e===`Xxx`?route(`xxx`):`#`,className:`text-sm font-bold tracking-tight hover:text-[#D4A017] transition-colors`,children:e},e))}),(0,a.jsx)(`div`,{className:`h-6 w-[1px] bg-gray-100 mx-2`}),e.user?(0,a.jsx)(r,{href:route(`dashboard`),className:`px-6 py-2.5 bg-[#3D4E4B] text-white text-sm font-bold tracking-tight rounded-xl hover:bg-[#2D3A38] transition-all`,children:`Command Center`}):(0,a.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,a.jsx)(r,{href:route(`login`),className:`text-sm font-bold tracking-tight hover:text-[#D4A017] transition-colors`,children:`Access`}),(0,a.jsx)(r,{href:route(`register`),className:`px-6 py-2.5 bg-[#D4A017] text-white text-sm font-bold tracking-tight rounded-xl hover:bg-[#B88B14] transition-all`,children:`Initialize Identity`})]})]})]})}),(0,a.jsx)(`section`,{className:`relative pt-40 pb-20 px-6 overflow-hidden`,children:(0,a.jsxs)(`div`,{className:`max-w-7xl mx-auto grid grid-cols-1 lg:grid-cols-2 gap-20 items-center`,children:[(0,a.jsxs)(`div`,{className:`relative z-10 anim-left`,children:[(0,a.jsxs)(`div`,{className:`inline-flex items-center gap-2 px-4 py-2 bg-white rounded-full border border-gray-100 mb-8`,children:[(0,a.jsx)(`span`,{className:`flex h-2 w-2 rounded-full bg-[#D4A017]`}),(0,a.jsx)(`span`,{className:`text-xs font-bold tracking-tight text-[#D4A017]`,children:`Enterprise V4.0 Live`})]}),(0,a.jsxs)(`h1`,{className:`text-6xl lg:text-8xl font-bold text-[#3D4E4B] tracking-tighter leading-[0.9] mb-8`,children:[`Precision `,(0,a.jsx)(`br`,{}),(0,a.jsx)(`span`,{className:`text-transparent`,style:{WebkitTextStroke:`1px #3D4E4B`},children:`Identity`}),` `,(0,a.jsx)(`br`,{}),`Architecture.`]}),(0,a.jsx)(`p`,{className:`text-lg text-gray-500 font-medium max-w-md leading-relaxed mb-10`,children:`The ultimate governance framework for airline-grade digital ecosystems. Secure, modular, and uncompromisingly professional.`}),(0,a.jsxs)(`div`,{className:`flex flex-wrap items-center gap-8`,children:[(0,a.jsxs)(r,{href:e.user?route(`dashboard`):route(`register`),className:`px-10 py-5 bg-[#3D4E4B] text-white text-sm font-bold tracking-tight rounded-2xl hover:bg-[#2D3A38] transition-all shadow-2xl shadow-[#3D4E4B]/20 hover:shadow-[#D4A017]/10 flex items-center gap-3 group border border-[#3D4E4B]`,children:[e.user?`Access Command`:`Initialize Session`,(0,a.jsx)(`svg`,{className:`w-4 h-4 transition-transform group-hover:translate-x-1`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:3,children:(0,a.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M13 7l5 5m0 0l-5 5m5-5H6`})})]}),(0,a.jsxs)(`div`,{className:`flex items-center`,children:[(0,a.jsx)(`div`,{className:`flex -space-x-3`,children:[1,2,3].map(e=>(0,a.jsx)(`div`,{className:`w-10 h-10 rounded-full border-4 border-[#E3EBE8] bg-[#3D4E4B] flex items-center justify-center text-sm font-bold text-white ring-1 ring-white/10`,children:String.fromCharCode(64+e)},e))}),(0,a.jsxs)(`div`,{className:`pl-6 flex flex-col justify-center`,children:[(0,a.jsx)(`span`,{className:`text-sm font-bold tracking-tight text-[#3D4E4B]`,children:`2,400+ Entities`}),(0,a.jsx)(`span`,{className:`text-sm font-semibold tracking-tight text-gray-400 mt-0.5`,children:`Authenticated Weekly`})]})]})]})]}),(0,a.jsx)(`div`,{className:`relative anim-right`,children:(0,a.jsxs)(`div`,{className:`aspect-square bg-white rounded-[3rem] border border-gray-100 shadow-2xl relative overflow-hidden p-8 group`,children:[(0,a.jsx)(`div`,{className:`absolute inset-0 bg-[#3D4E4B] opacity-0 group-hover:opacity-[0.02] transition-opacity`}),(0,a.jsxs)(`div`,{className:`w-full h-full border-2 border-dashed border-gray-100 rounded-[2rem] flex flex-col items-center justify-center relative`,children:[(0,a.jsx)(`div`,{className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-40 h-40 bg-[#D4A017]/10 rounded-full blur-[80px]`}),(0,a.jsx)(`div`,{className:`text-[120px] font-bold text-[#3D4E4B] opacity-5 select-none tracking-tight`,children:`SYSTEM`}),(0,a.jsxs)(`div`,{className:`absolute inset-x-8 bottom-8 h-32 bg-gray-50 rounded-2xl border border-gray-100 p-6 flex items-end justify-between`,children:[(0,a.jsxs)(`div`,{className:`space-y-2`,children:[(0,a.jsx)(`div`,{className:`w-24 h-2 bg-gray-200 rounded-full`}),(0,a.jsx)(`div`,{className:`w-16 h-2 bg-gray-200 rounded-full opacity-50`})]}),(0,a.jsx)(`div`,{className:`w-12 h-12 bg-[#3D4E4B] rounded-xl`})]})]})]})})]})}),(0,a.jsx)(`section`,{className:`py-20 px-6 bg-white border-y border-gray-100`,children:(0,a.jsxs)(`div`,{className:`max-w-7xl mx-auto`,children:[(0,a.jsxs)(`div`,{className:`text-center mb-20 anim-up`,children:[(0,a.jsx)(`h2`,{className:`text-sm font-bold tracking-tight text-[#D4A017] mb-4`,children:`Core Ecosystem`}),(0,a.jsx)(`h3`,{className:`text-4xl font-bold text-[#3D4E4B] tracking-tight`,children:`Governance Intelligence.`})]}),(0,a.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-3 gap-8`,children:[{t:`Secure Matrix`,d:`Advanced role-based access control with granular permission governance.`,c:`#3D4E4B`},{t:`Live Telemetry`,d:`Real-time activity monitoring and audit logging for complete transparency.`,c:`#D4A017`},{t:`Global Identity`,d:`Multi-provider authentication and identity verification systems.`,c:`#21A59F`}].map((e,t)=>(0,a.jsxs)(`div`,{className:`p-10 rounded-[2.5rem] bg-[#E3EBE8]/30 border border-gray-100 hover:bg-white hover:shadow-xl hover:-translate-y-2 transition-all duration-500 group anim-up`,style:{animationDelay:`${t*.1}s`},children:[(0,a.jsx)(`div`,{className:`w-12 h-12 rounded-2xl flex items-center justify-center text-white mb-8 group-hover:scale-110 transition-transform`,style:{backgroundColor:e.c},children:(0,a.jsx)(`svg`,{className:`w-6 h-6`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:3,children:(0,a.jsx)(`path`,{d:`M13 10V3L4 14h7v7l9-11h-7z`})})}),(0,a.jsx)(`h4`,{className:`text-sm font-bold tracking-tight text-[#3D4E4B] mb-4`,children:e.t}),(0,a.jsx)(`p`,{className:`text-sm font-medium text-gray-400 leading-relaxed tracking-tight`,children:e.d})]},t))})]})}),(0,a.jsx)(`footer`,{className:`py-12 px-6 border-t border-gray-100`,children:(0,a.jsxs)(`div`,{className:`max-w-7xl mx-auto flex flex-col md:flex-row items-center justify-between gap-8`,children:[(0,a.jsxs)(`div`,{className:`flex items-center gap-3 anim-left`,children:[(0,a.jsx)(`div`,{className:`w-8 h-8 rounded-lg flex items-center justify-center text-sm font-bold border border-gray-100 ${s?`bg-white`:`bg-[#3D4E4B] text-[#D4A017]`}`,children:s?(0,a.jsx)(`img`,{src:s,className:`w-full h-full object-contain`}):c}),(0,a.jsxs)(`span`,{className:`text-sm font-bold tracking-tight`,children:[o,` © 2024`]})]}),(0,a.jsxs)(`div`,{className:`flex items-center gap-8 text-xs font-bold tracking-tight text-gray-400 anim-right`,children:[(0,a.jsx)(`a`,{href:`#`,className:`hover:text-[#3D4E4B]`,children:`Term of Service`}),(0,a.jsx)(`a`,{href:`#`,className:`hover:text-[#3D4E4B]`,children:`Privacy Protocol`}),(0,a.jsx)(`a`,{href:`#`,className:`hover:text-[#3D4E4B]`,children:`Compliance`})]})]})})]})}export{o as default}; \ No newline at end of file diff --git a/public/build/assets/Xxx-CagXuP8t.js b/public/build/assets/Xxx-CagXuP8t.js new file mode 100644 index 0000000..f6c94c7 --- /dev/null +++ b/public/build/assets/Xxx-CagXuP8t.js @@ -0,0 +1 @@ +import{c as e,n as t,t as n}from"./app-BJ7g6sa8.js";e();var r=n();function i({auth:e}){return(0,r.jsxs)(`div`,{className:`min-h-screen bg-[#E3EBE8] text-[#3D4E4B] font-sans`,children:[(0,r.jsx)(t,{title:`Xxx`}),(0,r.jsxs)(`div`,{className:`max-w-7xl mx-auto px-6 py-12`,children:[(0,r.jsx)(`h1`,{className:`text-3xl font-bold mb-8`,children:`Xxx Page`}),(0,r.jsx)(`div`,{className:`bg-white rounded-lg shadow-sm p-6`,children:(0,r.jsx)(`p`,{children:`This is the new xxx page content.`})})]})]})}export{i as default}; \ No newline at end of file diff --git a/public/build/assets/app-BJ7g6sa8.js b/public/build/assets/app-BJ7g6sa8.js new file mode 100644 index 0000000..428d7a6 --- /dev/null +++ b/public/build/assets/app-BJ7g6sa8.js @@ -0,0 +1,95 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/Index-Cm49_1vz.js","assets/lodash-ZrZcSXd_.js","assets/Portal-DJbp1s68.js","assets/AuthenticatedLayout-CrB9BCoI.js","assets/ConfirmPassword-Ducw29r7.js","assets/GuestLayout-CN-YY0cs.js","assets/ForgotPassword-BmQrO4Bp.js","assets/Login-DUDEFmAx.js","assets/Register-BscYc22x.js","assets/ResetPassword-BTTfjVJh.js","assets/VerifyEmail-rqxgUqlx.js","assets/Dashboard-DZOwY3RZ.js","assets/Index-CgghpLIe.js","assets/Index-DLpY0zj1.js","assets/swal-DZXjpqDE.js","assets/swal-DtpL8WXZ.css","assets/Edit-BCh5fCTK.js","assets/filepond-plugin-file-validate-type-CBUe71W_.js","assets/filepond-plugin-file-validate-type-CEtEkCs1.css","assets/DeleteUserForm-DLkG3tvo.js","assets/TextInput-DV7QeRn3.js","assets/UpdatePasswordForm-DXZy5eGn.js","assets/PrimaryButton-KeVcwQeg.js","assets/UpdateProfileInformationForm-CZPCM5rZ.js","assets/Index-Bnf5l0xj.js","assets/Can-DIOq7dyw.js","assets/Index-z4H1ItiM.js","assets/Index-A9YntmU6.js","assets/Setup-ZspLG92f.js","assets/Index-cmCbZg8n.js","assets/Show-lMRyP8VR.js"])))=>i.map(i=>d[i]); +var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},c=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},l=(n,r,a)=>(a=n==null?{}:e(i(n)),c(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));function u(e,t){return function(){return e.apply(t,arguments)}}var{toString:d}=Object.prototype,{getPrototypeOf:f}=Object,{iterator:p,toStringTag:m}=Symbol,h=(e=>t=>{let n=d.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),g=e=>(e=e.toLowerCase(),t=>h(t)===e),_=e=>t=>typeof t===e,{isArray:v}=Array,y=_(`undefined`);function b(e){return e!==null&&!y(e)&&e.constructor!==null&&!y(e.constructor)&&w(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}var x=g(`ArrayBuffer`);function S(e){let t;return t=typeof ArrayBuffer<`u`&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&x(e.buffer),t}var C=_(`string`),w=_(`function`),T=_(`number`),E=e=>typeof e==`object`&&!!e,D=e=>e===!0||e===!1,O=e=>{if(h(e)!==`object`)return!1;let t=f(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(m in e)&&!(p in e)},k=e=>{if(!E(e)||b(e))return!1;try{return Object.keys(e).length===0&&Object.getPrototypeOf(e)===Object.prototype}catch{return!1}},A=g(`Date`),j=g(`File`),M=e=>!!(e&&e.uri!==void 0),N=e=>e&&e.getParts!==void 0,P=g(`Blob`),F=g(`FileList`),I=e=>E(e)&&w(e.pipe);function L(){return typeof globalThis<`u`?globalThis:typeof self<`u`?self:typeof window<`u`?window:typeof global<`u`?global:{}}var ee=L(),te=ee.FormData===void 0?void 0:ee.FormData,ne=e=>{if(!e)return!1;if(te&&e instanceof te)return!0;let t=f(e);if(!t||t===Object.prototype||!w(e.append))return!1;let n=h(e);return n===`formdata`||n===`object`&&w(e.toString)&&e.toString()===`[object FormData]`},R=g(`URLSearchParams`),[re,ie,ae,z]=[`ReadableStream`,`Request`,`Response`,`Headers`].map(g),oe=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,``);function se(e,t,{allOwnKeys:n=!1}={}){if(e==null)return;let r,i;if(typeof e!=`object`&&(e=[e]),v(e))for(r=0,i=e.length;r0;)if(i=n[r],t===i.toLowerCase())return i;return null}var le=typeof globalThis<`u`?globalThis:typeof self<`u`?self:typeof window<`u`?window:global,ue=e=>!y(e)&&e!==le;function de(...e){let{caseless:t,skipUndefined:n}=ue(this)&&this||{},r={},i=(e,i)=>{if(i===`__proto__`||i===`constructor`||i===`prototype`)return;let a=t&&ce(r,i)||i,o=Ce(r,a)?r[a]:void 0;O(o)&&O(e)?r[a]=de(o,e):O(e)?r[a]=de({},e):v(e)?r[a]=e.slice():(!n||!y(e))&&(r[a]=e)};for(let t=0,n=e.length;t(se(t,(t,r)=>{n&&w(t)?Object.defineProperty(e,r,{__proto__:null,value:u(t,n),writable:!0,enumerable:!0,configurable:!0}):Object.defineProperty(e,r,{__proto__:null,value:t,writable:!0,enumerable:!0,configurable:!0})},{allOwnKeys:r}),e),pe=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),me=(e,t,n,r)=>{e.prototype=Object.create(t.prototype,r),Object.defineProperty(e.prototype,`constructor`,{__proto__:null,value:e,writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(e,`super`,{__proto__:null,value:t.prototype}),n&&Object.assign(e.prototype,n)},he=(e,t,n,r)=>{let i,a,o,s={};if(t||={},e==null)return t;do{for(i=Object.getOwnPropertyNames(e),a=i.length;a-- >0;)o=i[a],(!r||r(o,e,t))&&!s[o]&&(t[o]=e[o],s[o]=!0);e=n!==!1&&f(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},ge=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;let r=e.indexOf(t,n);return r!==-1&&r===n},_e=e=>{if(!e)return null;if(v(e))return e;let t=e.length;if(!T(t))return null;let n=Array(t);for(;t-- >0;)n[t]=e[t];return n},ve=(e=>t=>e&&t instanceof e)(typeof Uint8Array<`u`&&f(Uint8Array)),ye=(e,t)=>{let n=(e&&e[p]).call(e),r;for(;(r=n.next())&&!r.done;){let n=r.value;t.call(e,n[0],n[1])}},be=(e,t)=>{let n,r=[];for(;(n=e.exec(t))!==null;)r.push(n);return r},xe=g(`HTMLFormElement`),Se=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(e,t,n){return t.toUpperCase()+n}),Ce=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),we=g(`RegExp`),Te=(e,t)=>{let n=Object.getOwnPropertyDescriptors(e),r={};se(n,(n,i)=>{let a;(a=t(n,i,e))!==!1&&(r[i]=a||n)}),Object.defineProperties(e,r)},Ee=e=>{Te(e,(t,n)=>{if(w(e)&&[`arguments`,`caller`,`callee`].includes(n))return!1;let r=e[n];if(w(r)){if(t.enumerable=!1,`writable`in t){t.writable=!1;return}t.set||=()=>{throw Error(`Can not rewrite read-only method '`+n+`'`)}}})},De=(e,t)=>{let n={},r=e=>{e.forEach(e=>{n[e]=!0})};return v(e)?r(e):r(String(e).split(t)),n},Oe=()=>{},ke=(e,t)=>e!=null&&Number.isFinite(e=+e)?e:t;function Ae(e){return!!(e&&w(e.append)&&e[m]===`FormData`&&e[p])}var je=e=>{let t=Array(10),n=(e,r)=>{if(E(e)){if(t.indexOf(e)>=0)return;if(b(e))return e;if(!(`toJSON`in e)){t[r]=e;let i=v(e)?[]:{};return se(e,(e,t)=>{let a=n(e,r+1);!y(a)&&(i[t]=a)}),t[r]=void 0,i}}return e};return n(e,0)},Me=g(`AsyncFunction`),Ne=e=>e&&(E(e)||w(e))&&w(e.then)&&w(e.catch),Pe=((e,t)=>e?setImmediate:t?((e,t)=>(le.addEventListener(`message`,({source:n,data:r})=>{n===le&&r===e&&t.length&&t.shift()()},!1),n=>{t.push(n),le.postMessage(e,`*`)}))(`axios@${Math.random()}`,[]):e=>setTimeout(e))(typeof setImmediate==`function`,w(le.postMessage)),B={isArray:v,isArrayBuffer:x,isBuffer:b,isFormData:ne,isArrayBufferView:S,isString:C,isNumber:T,isBoolean:D,isObject:E,isPlainObject:O,isEmptyObject:k,isReadableStream:re,isRequest:ie,isResponse:ae,isHeaders:z,isUndefined:y,isDate:A,isFile:j,isReactNativeBlob:M,isReactNative:N,isBlob:P,isRegExp:we,isFunction:w,isStream:I,isURLSearchParams:R,isTypedArray:ve,isFileList:F,forEach:se,merge:de,extend:fe,trim:oe,stripBOM:pe,inherits:me,toFlatObject:he,kindOf:h,kindOfTest:g,endsWith:ge,toArray:_e,forEachEntry:ye,matchAll:be,isHTMLForm:xe,hasOwnProperty:Ce,hasOwnProp:Ce,reduceDescriptors:Te,freezeMethods:Ee,toObjectSet:De,toCamelCase:Se,noop:Oe,toFiniteNumber:ke,findKey:ce,global:le,isContextDefined:ue,isSpecCompliantForm:Ae,toJSONObject:je,isAsyncFn:Me,isThenable:Ne,setImmediate:Pe,asap:typeof queueMicrotask<`u`?queueMicrotask.bind(le):typeof process<`u`&&process.nextTick||Pe,isIterable:e=>e!=null&&w(e[p])},Fe=B.toObjectSet([`age`,`authorization`,`content-length`,`content-type`,`etag`,`expires`,`from`,`host`,`if-modified-since`,`if-unmodified-since`,`last-modified`,`location`,`max-forwards`,`proxy-authorization`,`referer`,`retry-after`,`user-agent`]),Ie=e=>{let t={},n,r,i;return e&&e.split(` +`).forEach(function(e){i=e.indexOf(`:`),n=e.substring(0,i).trim().toLowerCase(),r=e.substring(i+1).trim(),!(!n||t[n]&&Fe[n])&&(n===`set-cookie`?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+`, `+r:r)}),t},Le=Symbol(`internals`),Re=/[^\x09\x20-\x7E\x80-\xFF]/g;function ze(e){let t=0,n=e.length;for(;tt;){let t=e.charCodeAt(n-1);if(t!==9&&t!==32)break;--n}return t===0&&n===e.length?e:e.slice(t,n)}function Be(e){return e&&String(e).trim().toLowerCase()}function Ve(e){return ze(e.replace(Re,``))}function He(e){return e===!1||e==null?e:B.isArray(e)?e.map(He):Ve(String(e))}function Ue(e){let t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g,r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}var We=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function Ge(e,t,n,r,i){if(B.isFunction(r))return r.call(this,t,n);if(i&&(t=n),B.isString(t)){if(B.isString(r))return t.indexOf(r)!==-1;if(B.isRegExp(r))return r.test(t)}}function Ke(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(e,t,n)=>t.toUpperCase()+n)}function qe(e,t){let n=B.toCamelCase(` `+t);[`get`,`set`,`has`].forEach(r=>{Object.defineProperty(e,r+n,{__proto__:null,value:function(e,n,i){return this[r].call(this,t,e,n,i)},configurable:!0})})}var Je=class{constructor(e){e&&this.set(e)}set(e,t,n){let r=this;function i(e,t,n){let i=Be(t);if(!i)throw Error(`header name must be a non-empty string`);let a=B.findKey(r,i);(!a||r[a]===void 0||n===!0||n===void 0&&r[a]!==!1)&&(r[a||t]=He(e))}let a=(e,t)=>B.forEach(e,(e,n)=>i(e,n,t));if(B.isPlainObject(e)||e instanceof this.constructor)a(e,t);else if(B.isString(e)&&(e=e.trim())&&!We(e))a(Ie(e),t);else if(B.isObject(e)&&B.isIterable(e)){let n={},r,i;for(let t of e){if(!B.isArray(t))throw TypeError(`Object iterator must return a key-value pair`);n[i=t[0]]=(r=n[i])?B.isArray(r)?[...r,t[1]]:[r,t[1]]:t[1]}a(n,t)}else e!=null&&i(t,e,n);return this}get(e,t){if(e=Be(e),e){let n=B.findKey(this,e);if(n){let e=this[n];if(!t)return e;if(t===!0)return Ue(e);if(B.isFunction(t))return t.call(this,e,n);if(B.isRegExp(t))return t.exec(e);throw TypeError(`parser must be boolean|regexp|function`)}}}has(e,t){if(e=Be(e),e){let n=B.findKey(this,e);return!!(n&&this[n]!==void 0&&(!t||Ge(this,this[n],n,t)))}return!1}delete(e,t){let n=this,r=!1;function i(e){if(e=Be(e),e){let i=B.findKey(n,e);i&&(!t||Ge(n,n[i],i,t))&&(delete n[i],r=!0)}}return B.isArray(e)?e.forEach(i):i(e),r}clear(e){let t=Object.keys(this),n=t.length,r=!1;for(;n--;){let i=t[n];(!e||Ge(this,this[i],i,e,!0))&&(delete this[i],r=!0)}return r}normalize(e){let t=this,n={};return B.forEach(this,(r,i)=>{let a=B.findKey(n,i);if(a){t[a]=He(r),delete t[i];return}let o=e?Ke(i):String(i).trim();o!==i&&delete t[i],t[o]=He(r),n[o]=!0}),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){let t=Object.create(null);return B.forEach(this,(n,r)=>{n!=null&&n!==!1&&(t[r]=e&&B.isArray(n)?n.join(`, `):n)}),t}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([e,t])=>e+`: `+t).join(` +`)}getSetCookie(){return this.get(`set-cookie`)||[]}get[Symbol.toStringTag](){return`AxiosHeaders`}static from(e){return e instanceof this?e:new this(e)}static concat(e,...t){let n=new this(e);return t.forEach(e=>n.set(e)),n}static accessor(e){let t=(this[Le]=this[Le]={accessors:{}}).accessors,n=this.prototype;function r(e){let r=Be(e);t[r]||(qe(n,e),t[r]=!0)}return B.isArray(e)?e.forEach(r):r(e),this}};Je.accessor([`Content-Type`,`Content-Length`,`Accept`,`Accept-Encoding`,`User-Agent`,`Authorization`]),B.reduceDescriptors(Je.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(e){this[n]=e}}}),B.freezeMethods(Je);var Ye=`[REDACTED ****]`;function Xe(e){if(B.hasOwnProp(e,`toJSON`))return!0;let t=Object.getPrototypeOf(e);for(;t&&t!==Object.prototype;){if(B.hasOwnProp(t,`toJSON`))return!0;t=Object.getPrototypeOf(t)}return!1}function Ze(e,t){let n=new Set(t.map(e=>String(e).toLowerCase())),r=[],i=e=>{if(typeof e!=`object`||!e||B.isBuffer(e))return e;if(r.indexOf(e)!==-1)return;e instanceof Je&&(e=e.toJSON()),r.push(e);let t;if(B.isArray(e))t=[],e.forEach((e,n)=>{let r=i(e);B.isUndefined(r)||(t[n]=r)});else{if(!B.isPlainObject(e)&&Xe(e))return r.pop(),e;t=Object.create(null);for(let[r,a]of Object.entries(e)){let e=n.has(r.toLowerCase())?Ye:i(a);B.isUndefined(e)||(t[r]=e)}}return r.pop(),t};return i(e)}var V=class e extends Error{static from(t,n,r,i,a,o){let s=new e(t.message,n||t.code,r,i,a);return s.cause=t,s.name=t.name,t.status!=null&&s.status==null&&(s.status=t.status),o&&Object.assign(s,o),s}constructor(e,t,n,r,i){super(e),Object.defineProperty(this,`message`,{__proto__:null,value:e,enumerable:!0,writable:!0,configurable:!0}),this.name=`AxiosError`,this.isAxiosError=!0,t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),i&&(this.response=i,this.status=i.status)}toJSON(){let e=this.config,t=e&&B.hasOwnProp(e,`redact`)?e.redact:void 0,n=B.isArray(t)&&t.length>0?Ze(e,t):B.toJSONObject(e);return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:n,code:this.code,status:this.status}}};V.ERR_BAD_OPTION_VALUE=`ERR_BAD_OPTION_VALUE`,V.ERR_BAD_OPTION=`ERR_BAD_OPTION`,V.ECONNABORTED=`ECONNABORTED`,V.ETIMEDOUT=`ETIMEDOUT`,V.ECONNREFUSED=`ECONNREFUSED`,V.ERR_NETWORK=`ERR_NETWORK`,V.ERR_FR_TOO_MANY_REDIRECTS=`ERR_FR_TOO_MANY_REDIRECTS`,V.ERR_DEPRECATED=`ERR_DEPRECATED`,V.ERR_BAD_RESPONSE=`ERR_BAD_RESPONSE`,V.ERR_BAD_REQUEST=`ERR_BAD_REQUEST`,V.ERR_CANCELED=`ERR_CANCELED`,V.ERR_NOT_SUPPORT=`ERR_NOT_SUPPORT`,V.ERR_INVALID_URL=`ERR_INVALID_URL`,V.ERR_FORM_DATA_DEPTH_EXCEEDED=`ERR_FORM_DATA_DEPTH_EXCEEDED`;function Qe(e){return B.isPlainObject(e)||B.isArray(e)}function $e(e){return B.endsWith(e,`[]`)?e.slice(0,-2):e}function et(e,t,n){return e?e.concat(t).map(function(e,t){return e=$e(e),!n&&t?`[`+e+`]`:e}).join(n?`.`:``):t}function tt(e){return B.isArray(e)&&!e.some(Qe)}var nt=B.toFlatObject(B,{},null,function(e){return/^is[A-Z]/.test(e)});function rt(e,t,n){if(!B.isObject(e))throw TypeError(`target must be an object`);t||=new FormData,n=B.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(e,t){return!B.isUndefined(t[e])});let r=n.metaTokens,i=n.visitor||d,a=n.dots,o=n.indexes,s=n.Blob||typeof Blob<`u`&&Blob,c=n.maxDepth===void 0?100:n.maxDepth,l=s&&B.isSpecCompliantForm(t);if(!B.isFunction(i))throw TypeError(`visitor must be a function`);function u(e){if(e===null)return``;if(B.isDate(e))return e.toISOString();if(B.isBoolean(e))return e.toString();if(!l&&B.isBlob(e))throw new V(`Blob is not supported. Use a Buffer instead.`);return B.isArrayBuffer(e)||B.isTypedArray(e)?l&&typeof Blob==`function`?new Blob([e]):Buffer.from(e):e}function d(e,n,i){let s=e;if(B.isReactNative(t)&&B.isReactNativeBlob(e))return t.append(et(i,n,a),u(e)),!1;if(e&&!i&&typeof e==`object`){if(B.endsWith(n,`{}`))n=r?n:n.slice(0,-2),e=JSON.stringify(e);else if(B.isArray(e)&&tt(e)||(B.isFileList(e)||B.endsWith(n,`[]`))&&(s=B.toArray(e)))return n=$e(n),s.forEach(function(e,r){!(B.isUndefined(e)||e===null)&&t.append(o===!0?et([n],r,a):o===null?n:n+`[]`,u(e))}),!1}return Qe(e)?!0:(t.append(et(i,n,a),u(e)),!1)}let f=[],p=Object.assign(nt,{defaultVisitor:d,convertValue:u,isVisitable:Qe});function m(e,n,r=0){if(!B.isUndefined(e)){if(r>c)throw new V(`Object is too deeply nested (`+r+` levels). Max depth: `+c,V.ERR_FORM_DATA_DEPTH_EXCEEDED);if(f.indexOf(e)!==-1)throw Error(`Circular reference detected in `+n.join(`.`));f.push(e),B.forEach(e,function(e,a){(!(B.isUndefined(e)||e===null)&&i.call(t,e,B.isString(a)?a.trim():a,n,p))===!0&&m(e,n?n.concat(a):[a],r+1)}),f.pop()}}if(!B.isObject(e))throw TypeError(`data must be an object`);return m(e),t}function it(e){let t={"!":`%21`,"'":`%27`,"(":`%28`,")":`%29`,"~":`%7E`,"%20":`+`};return encodeURIComponent(e).replace(/[!'()~]|%20/g,function(e){return t[e]})}function at(e,t){this._pairs=[],e&&rt(e,this,t)}var ot=at.prototype;ot.append=function(e,t){this._pairs.push([e,t])},ot.toString=function(e){let t=e?function(t){return e.call(this,t,it)}:it;return this._pairs.map(function(e){return t(e[0])+`=`+t(e[1])},``).join(`&`)};function st(e){return encodeURIComponent(e).replace(/%3A/gi,`:`).replace(/%24/g,`$`).replace(/%2C/gi,`,`).replace(/%20/g,`+`)}function ct(e,t,n){if(!t)return e;let r=n&&n.encode||st,i=B.isFunction(n)?{serialize:n}:n,a=i&&i.serialize,o;if(o=a?a(t,i):B.isURLSearchParams(t)?t.toString():new at(t,i).toString(r),o){let t=e.indexOf(`#`);t!==-1&&(e=e.slice(0,t)),e+=(e.indexOf(`?`)===-1?`?`:`&`)+o}return e}var lt=class{constructor(){this.handlers=[]}use(e,t,n){return this.handlers.push({fulfilled:e,rejected:t,synchronous:n?n.synchronous:!1,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&=[]}forEach(e){B.forEach(this.handlers,function(t){t!==null&&e(t)})}},ut={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1,legacyInterceptorReqResOrdering:!0},dt={isBrowser:!0,classes:{URLSearchParams:typeof URLSearchParams<`u`?URLSearchParams:at,FormData:typeof FormData<`u`?FormData:null,Blob:typeof Blob<`u`?Blob:null},protocols:[`http`,`https`,`file`,`blob`,`url`,`data`]},ft=s({hasBrowserEnv:()=>pt,hasStandardBrowserEnv:()=>ht,hasStandardBrowserWebWorkerEnv:()=>gt,navigator:()=>mt,origin:()=>_t}),pt=typeof window<`u`&&typeof document<`u`,mt=typeof navigator==`object`&&navigator||void 0,ht=pt&&(!mt||[`ReactNative`,`NativeScript`,`NS`].indexOf(mt.product)<0),gt=typeof WorkerGlobalScope<`u`&&self instanceof WorkerGlobalScope&&typeof self.importScripts==`function`,_t=pt&&window.location.href||`http://localhost`,vt={...ft,...dt};function yt(e,t){return rt(e,new vt.classes.URLSearchParams,{visitor:function(e,t,n,r){return vt.isNode&&B.isBuffer(e)?(this.append(t,e.toString(`base64`)),!1):r.defaultVisitor.apply(this,arguments)},...t})}function bt(e){return B.matchAll(/\w+|\[(\w*)]/g,e).map(e=>e[0]===`[]`?``:e[1]||e[0])}function xt(e){let t={},n=Object.keys(e),r,i=n.length,a;for(r=0;r=e.length;return a=!a&&B.isArray(r)?r.length:a,s?(B.hasOwnProp(r,a)?r[a]=B.isArray(r[a])?r[a].concat(n):[r[a],n]:r[a]=n,!o):((!r[a]||!B.isObject(r[a]))&&(r[a]=[]),t(e,n,r[a],i)&&B.isArray(r[a])&&(r[a]=xt(r[a])),!o)}if(B.isFormData(e)&&B.isFunction(e.entries)){let n={};return B.forEachEntry(e,(e,r)=>{t(bt(e),r,n,0)}),n}return null}var Ct=(e,t)=>e!=null&&B.hasOwnProp(e,t)?e[t]:void 0;function wt(e,t,n){if(B.isString(e))try{return(t||JSON.parse)(e),B.trim(e)}catch(e){if(e.name!==`SyntaxError`)throw e}return(n||JSON.stringify)(e)}var Tt={transitional:ut,adapter:[`xhr`,`http`,`fetch`],transformRequest:[function(e,t){let n=t.getContentType()||``,r=n.indexOf(`application/json`)>-1,i=B.isObject(e);if(i&&B.isHTMLForm(e)&&(e=new FormData(e)),B.isFormData(e))return r?JSON.stringify(St(e)):e;if(B.isArrayBuffer(e)||B.isBuffer(e)||B.isStream(e)||B.isFile(e)||B.isBlob(e)||B.isReadableStream(e))return e;if(B.isArrayBufferView(e))return e.buffer;if(B.isURLSearchParams(e))return t.setContentType(`application/x-www-form-urlencoded;charset=utf-8`,!1),e.toString();let a;if(i){let t=Ct(this,`formSerializer`);if(n.indexOf(`application/x-www-form-urlencoded`)>-1)return yt(e,t).toString();if((a=B.isFileList(e))||n.indexOf(`multipart/form-data`)>-1){let n=Ct(this,`env`),r=n&&n.FormData;return rt(a?{"files[]":e}:e,r&&new r,t)}}return i||r?(t.setContentType(`application/json`,!1),wt(e)):e}],transformResponse:[function(e){let t=Ct(this,`transitional`)||Tt.transitional,n=t&&t.forcedJSONParsing,r=Ct(this,`responseType`),i=r===`json`;if(B.isResponse(e)||B.isReadableStream(e))return e;if(e&&B.isString(e)&&(n&&!r||i)){let n=!(t&&t.silentJSONParsing)&&i;try{return JSON.parse(e,Ct(this,`parseReviver`))}catch(e){if(n)throw e.name===`SyntaxError`?V.from(e,V.ERR_BAD_RESPONSE,this,null,Ct(this,`response`)):e}}return e}],timeout:0,xsrfCookieName:`XSRF-TOKEN`,xsrfHeaderName:`X-XSRF-TOKEN`,maxContentLength:-1,maxBodyLength:-1,env:{FormData:vt.classes.FormData,Blob:vt.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:`application/json, text/plain, */*`,"Content-Type":void 0}}};B.forEach([`delete`,`get`,`head`,`post`,`put`,`patch`,`query`],e=>{Tt.headers[e]={}});function Et(e,t){let n=this||Tt,r=t||n,i=Je.from(r.headers),a=r.data;return B.forEach(e,function(e){a=e.call(n,a,i.normalize(),t?t.status:void 0)}),i.normalize(),a}function Dt(e){return!!(e&&e.__CANCEL__)}var Ot=class extends V{constructor(e,t,n){super(e??`canceled`,V.ERR_CANCELED,t,n),this.name=`CanceledError`,this.__CANCEL__=!0}};function kt(e,t,n){let r=n.config.validateStatus;!n.status||!r||r(n.status)?e(n):t(new V(`Request failed with status code `+n.status,n.status>=400&&n.status<500?V.ERR_BAD_REQUEST:V.ERR_BAD_RESPONSE,n.config,n.request,n))}function At(e){let t=/^([-+\w]{1,25}):(?:\/\/)?/.exec(e);return t&&t[1]||``}function jt(e,t){e||=10;let n=Array(e),r=Array(e),i=0,a=0,o;return t=t===void 0?1e3:t,function(s){let c=Date.now(),l=r[a];o||=c,n[i]=s,r[i]=c;let u=a,d=0;for(;u!==i;)d+=n[u++],u%=e;if(i=(i+1)%e,i===a&&(a=(a+1)%e),c-o{n=r,i=null,a&&=(clearTimeout(a),null),e(...t)};return[(...e)=>{let t=Date.now(),s=t-n;s>=r?o(e,t):(i=e,a||=setTimeout(()=>{a=null,o(i)},r-s))},()=>i&&o(i)]}var Nt=(e,t,n=3)=>{let r=0,i=jt(50,250);return Mt(n=>{let a=n.loaded,o=n.lengthComputable?n.total:void 0,s=o==null?a:Math.min(a,o),c=Math.max(0,s-r),l=i(c);r=Math.max(r,s),e({loaded:s,total:o,progress:o?s/o:void 0,bytes:c,rate:l||void 0,estimated:l&&o?(o-s)/l:void 0,event:n,lengthComputable:o!=null,[t?`download`:`upload`]:!0})},n)},Pt=(e,t)=>{let n=e!=null;return[r=>t[0]({lengthComputable:n,total:e,loaded:r}),t[1]]},Ft=e=>(...t)=>B.asap(()=>e(...t)),It=vt.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,vt.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(vt.origin),vt.navigator&&/(msie|trident)/i.test(vt.navigator.userAgent)):()=>!0,Lt=vt.hasStandardBrowserEnv?{write(e,t,n,r,i,a,o){if(typeof document>`u`)return;let s=[`${e}=${encodeURIComponent(t)}`];B.isNumber(n)&&s.push(`expires=${new Date(n).toUTCString()}`),B.isString(r)&&s.push(`path=${r}`),B.isString(i)&&s.push(`domain=${i}`),a===!0&&s.push(`secure`),B.isString(o)&&s.push(`SameSite=${o}`),document.cookie=s.join(`; `)},read(e){if(typeof document>`u`)return null;let t=document.cookie.split(`;`);for(let n=0;ne instanceof Je?{...e}:e;function Vt(e,t){t||={};let n=Object.create(null);Object.defineProperty(n,`hasOwnProperty`,{__proto__:null,value:Object.prototype.hasOwnProperty,enumerable:!1,writable:!0,configurable:!0});function r(e,t,n,r){return B.isPlainObject(e)&&B.isPlainObject(t)?B.merge.call({caseless:r},e,t):B.isPlainObject(t)?B.merge({},t):B.isArray(t)?t.slice():t}function i(e,t,n,i){if(!B.isUndefined(t))return r(e,t,n,i);if(!B.isUndefined(e))return r(void 0,e,n,i)}function a(e,t){if(!B.isUndefined(t))return r(void 0,t)}function o(e,t){if(!B.isUndefined(t))return r(void 0,t);if(!B.isUndefined(e))return r(void 0,e)}function s(n,i,a){if(B.hasOwnProp(t,a))return r(n,i);if(B.hasOwnProp(e,a))return r(void 0,n)}let c={url:a,method:a,data:a,baseURL:o,transformRequest:o,transformResponse:o,paramsSerializer:o,timeout:o,timeoutMessage:o,withCredentials:o,withXSRFToken:o,adapter:o,responseType:o,xsrfCookieName:o,xsrfHeaderName:o,onUploadProgress:o,onDownloadProgress:o,decompress:o,maxContentLength:o,maxBodyLength:o,beforeRedirect:o,transport:o,httpAgent:o,httpsAgent:o,cancelToken:o,socketPath:o,allowedSocketPaths:o,responseEncoding:o,validateStatus:s,headers:(e,t,n)=>i(Bt(e),Bt(t),n,!0)};return B.forEach(Object.keys({...e,...t}),function(r){if(r===`__proto__`||r===`constructor`||r===`prototype`)return;let a=B.hasOwnProp(c,r)?c[r]:i,o=a(B.hasOwnProp(e,r)?e[r]:void 0,B.hasOwnProp(t,r)?t[r]:void 0,r);B.isUndefined(o)&&a!==s||(n[r]=o)}),n}var Ht=[`content-type`,`content-length`];function Ut(e,t,n){if(n!==`content-only`){e.set(t);return}Object.entries(t).forEach(([t,n])=>{Ht.includes(t.toLowerCase())&&e.set(t,n)})}var Wt=e=>encodeURIComponent(e).replace(/%([0-9A-F]{2})/gi,(e,t)=>String.fromCharCode(parseInt(t,16))),Gt=e=>{let t=Vt({},e),n=e=>B.hasOwnProp(t,e)?t[e]:void 0,r=n(`data`),i=n(`withXSRFToken`),a=n(`xsrfHeaderName`),o=n(`xsrfCookieName`),s=n(`headers`),c=n(`auth`),l=n(`baseURL`),u=n(`allowAbsoluteUrls`),d=n(`url`);if(t.headers=s=Je.from(s),t.url=ct(zt(l,d,u),e.params,e.paramsSerializer),c&&s.set(`Authorization`,`Basic `+btoa((c.username||``)+`:`+(c.password?Wt(c.password):``))),B.isFormData(r)&&(vt.hasStandardBrowserEnv||vt.hasStandardBrowserWebWorkerEnv?s.setContentType(void 0):B.isFunction(r.getHeaders)&&Ut(s,r.getHeaders(),n(`formDataHeaderPolicy`))),vt.hasStandardBrowserEnv&&(B.isFunction(i)&&(i=i(t)),i===!0||i==null&&It(t.url))){let e=a&&o&&Lt.read(o);e&&s.set(a,e)}return t},Kt=typeof XMLHttpRequest<`u`&&function(e){return new Promise(function(t,n){let r=Gt(e),i=r.data,a=Je.from(r.headers).normalize(),{responseType:o,onUploadProgress:s,onDownloadProgress:c}=r,l,u,d,f,p;function m(){f&&f(),p&&p(),r.cancelToken&&r.cancelToken.unsubscribe(l),r.signal&&r.signal.removeEventListener(`abort`,l)}let h=new XMLHttpRequest;h.open(r.method.toUpperCase(),r.url,!0),h.timeout=r.timeout;function g(){if(!h)return;let r=Je.from(`getAllResponseHeaders`in h&&h.getAllResponseHeaders());kt(function(e){t(e),m()},function(e){n(e),m()},{data:!o||o===`text`||o===`json`?h.responseText:h.response,status:h.status,statusText:h.statusText,headers:r,config:e,request:h}),h=null}`onloadend`in h?h.onloadend=g:h.onreadystatechange=function(){!h||h.readyState!==4||h.status===0&&!(h.responseURL&&h.responseURL.startsWith(`file:`))||setTimeout(g)},h.onabort=function(){h&&=(n(new V(`Request aborted`,V.ECONNABORTED,e,h)),m(),null)},h.onerror=function(t){let r=new V(t&&t.message?t.message:`Network Error`,V.ERR_NETWORK,e,h);r.event=t||null,n(r),m(),h=null},h.ontimeout=function(){let t=r.timeout?`timeout of `+r.timeout+`ms exceeded`:`timeout exceeded`,i=r.transitional||ut;r.timeoutErrorMessage&&(t=r.timeoutErrorMessage),n(new V(t,i.clarifyTimeoutError?V.ETIMEDOUT:V.ECONNABORTED,e,h)),m(),h=null},i===void 0&&a.setContentType(null),`setRequestHeader`in h&&B.forEach(a.toJSON(),function(e,t){h.setRequestHeader(t,e)}),B.isUndefined(r.withCredentials)||(h.withCredentials=!!r.withCredentials),o&&o!==`json`&&(h.responseType=r.responseType),c&&([d,p]=Nt(c,!0),h.addEventListener(`progress`,d)),s&&h.upload&&([u,f]=Nt(s),h.upload.addEventListener(`progress`,u),h.upload.addEventListener(`loadend`,f)),(r.cancelToken||r.signal)&&(l=t=>{h&&=(n(!t||t.type?new Ot(null,e,h):t),h.abort(),m(),null)},r.cancelToken&&r.cancelToken.subscribe(l),r.signal&&(r.signal.aborted?l():r.signal.addEventListener(`abort`,l)));let _=At(r.url);if(_&&!vt.protocols.includes(_)){n(new V(`Unsupported protocol `+_+`:`,V.ERR_BAD_REQUEST,e));return}h.send(i||null)})},qt=(e,t)=>{let{length:n}=e=e?e.filter(Boolean):[];if(t||n){let n=new AbortController,r,i=function(e){if(!r){r=!0,o();let t=e instanceof Error?e:this.reason;n.abort(t instanceof V?t:new Ot(t instanceof Error?t.message:t))}},a=t&&setTimeout(()=>{a=null,i(new V(`timeout of ${t}ms exceeded`,V.ETIMEDOUT))},t),o=()=>{e&&=(a&&clearTimeout(a),a=null,e.forEach(e=>{e.unsubscribe?e.unsubscribe(i):e.removeEventListener(`abort`,i)}),null)};e.forEach(e=>e.addEventListener(`abort`,i));let{signal:s}=n;return s.unsubscribe=()=>B.asap(o),s}},Jt=function*(e,t){let n=e.byteLength;if(!t||n{let i=Yt(e,t),a=0,o,s=e=>{o||(o=!0,r&&r(e))};return new ReadableStream({async pull(e){try{let{done:t,value:r}=await i.next();if(t){s(),e.close();return}let o=r.byteLength;n&&n(a+=o),e.enqueue(new Uint8Array(r))}catch(e){throw s(e),e}},cancel(e){return s(e),i.return()}},{highWaterMark:2})};function Qt(e){if(!e||typeof e!=`string`||!e.startsWith(`data:`))return 0;let t=e.indexOf(`,`);if(t<0)return 0;let n=e.slice(5,t),r=e.slice(t+1);if(/;base64/i.test(n)){let e=r.length,t=r.length;for(let n=0;n=48&&t<=57||t>=65&&t<=70||t>=97&&t<=102)&&(i>=48&&i<=57||i>=65&&i<=70||i>=97&&i<=102)&&(e-=2,n+=2)}let n=0,i=t-1,a=e=>e>=2&&r.charCodeAt(e-2)===37&&r.charCodeAt(e-1)===51&&(r.charCodeAt(e)===68||r.charCodeAt(e)===100);i>=0&&(r.charCodeAt(i)===61?(n++,i--):a(i)&&(n++,i-=3)),n===1&&i>=0&&(r.charCodeAt(i)===61||a(i))&&n++;let o=Math.floor(e/4)*3-(n||0);return o>0?o:0}if(typeof Buffer<`u`&&typeof Buffer.byteLength==`function`)return Buffer.byteLength(r,`utf8`);let i=0;for(let e=0,t=r.length;e=55296&&n<=56319&&e+1=56320&&t<=57343?(i+=4,e++):i+=3}else i+=3}return i}var $t=`1.16.0`,en=64*1024,{isFunction:tn}=B,nn=(e,...t)=>{try{return!!e(...t)}catch{return!1}},rn=e=>{let t=B.global??globalThis,{ReadableStream:n,TextEncoder:r}=t;e=B.merge.call({skipUndefined:!0},{Request:t.Request,Response:t.Response},e);let{fetch:i,Request:a,Response:o}=e,s=i?tn(i):typeof fetch==`function`,c=tn(a),l=tn(o);if(!s)return!1;let u=s&&tn(n),d=s&&(typeof r==`function`?(e=>t=>e.encode(t))(new r):async e=>new Uint8Array(await new a(e).arrayBuffer())),f=c&&u&&nn(()=>{let e=!1,t=new a(vt.origin,{body:new n,method:`POST`,get duplex(){return e=!0,`half`}}),r=t.headers.has(`Content-Type`);return t.body!=null&&t.body.cancel(),e&&!r}),p=l&&u&&nn(()=>B.isReadableStream(new o(``).body)),m={stream:p&&(e=>e.body)};s&&[`text`,`arrayBuffer`,`blob`,`formData`,`stream`].forEach(e=>{!m[e]&&(m[e]=(t,n)=>{let r=t&&t[e];if(r)return r.call(t);throw new V(`Response type '${e}' is not supported`,V.ERR_NOT_SUPPORT,n)})});let h=async e=>{if(e==null)return 0;if(B.isBlob(e))return e.size;if(B.isSpecCompliantForm(e))return(await new a(vt.origin,{method:`POST`,body:e}).arrayBuffer()).byteLength;if(B.isArrayBufferView(e)||B.isArrayBuffer(e))return e.byteLength;if(B.isURLSearchParams(e)&&(e+=``),B.isString(e))return(await d(e)).byteLength},g=async(e,t)=>B.toFiniteNumber(e.getContentLength())??h(t);return async e=>{let{url:t,method:n,data:s,signal:l,cancelToken:u,timeout:d,onDownloadProgress:h,onUploadProgress:_,responseType:v,headers:y,withCredentials:b=`same-origin`,fetchOptions:x,maxContentLength:S,maxBodyLength:C}=Gt(e),w=B.isNumber(S)&&S>-1,T=B.isNumber(C)&&C>-1,E=i||fetch;v=v?(v+``).toLowerCase():`text`;let D=qt([l,u&&u.toAbortSignal()],d),O=null,k=D&&D.unsubscribe&&(()=>{D.unsubscribe()}),A;try{if(w&&typeof t==`string`&&t.startsWith(`data:`)&&Qt(t)>S)throw new V(`maxContentLength size of `+S+` exceeded`,V.ERR_BAD_RESPONSE,e,O);if(T&&n!==`get`&&n!==`head`){let t=await g(y,s);if(typeof t==`number`&&isFinite(t)&&t>C)throw new V(`Request body larger than maxBodyLength limit`,V.ERR_BAD_REQUEST,e,O)}if(_&&f&&n!==`get`&&n!==`head`&&(A=await g(y,s))!==0){let e=new a(t,{method:`POST`,body:s,duplex:`half`}),n;if(B.isFormData(s)&&(n=e.headers.get(`content-type`))&&y.setContentType(n),e.body){let[t,n]=Pt(A,Nt(Ft(_)));s=Zt(e.body,en,t,n)}}B.isString(b)||(b=b?`include`:`omit`);let i=c&&`credentials`in a.prototype;if(B.isFormData(s)){let e=y.getContentType();e&&/^multipart\/form-data/i.test(e)&&!/boundary=/i.test(e)&&y.delete(`content-type`)}y.set(`User-Agent`,`axios/`+$t,!1);let l={...x,signal:D,method:n.toUpperCase(),headers:y.normalize().toJSON(),body:s,duplex:`half`,credentials:i?b:void 0};O=c&&new a(t,l);let u=await(c?E(O,x):E(t,l));if(w){let t=B.toFiniteNumber(u.headers.get(`content-length`));if(t!=null&&t>S)throw new V(`maxContentLength size of `+S+` exceeded`,V.ERR_BAD_RESPONSE,e,O)}let d=p&&(v===`stream`||v===`response`);if(p&&u.body&&(h||w||d&&k)){let t={};[`status`,`statusText`,`headers`].forEach(e=>{t[e]=u[e]});let n=B.toFiniteNumber(u.headers.get(`content-length`)),[r,i]=h&&Pt(n,Nt(Ft(h),!0))||[],a=0;u=new o(Zt(u.body,en,t=>{if(w&&(a=t,a>S))throw new V(`maxContentLength size of `+S+` exceeded`,V.ERR_BAD_RESPONSE,e,O);r&&r(t)},()=>{i&&i(),k&&k()}),t)}v||=`text`;let j=await m[B.findKey(m,v)||`text`](u,e);if(w&&!p&&!d){let t;if(j!=null&&(typeof j.byteLength==`number`?t=j.byteLength:typeof j.size==`number`?t=j.size:typeof j==`string`&&(t=typeof r==`function`?new r().encode(j).byteLength:j.length)),typeof t==`number`&&t>S)throw new V(`maxContentLength size of `+S+` exceeded`,V.ERR_BAD_RESPONSE,e,O)}return!d&&k&&k(),await new Promise((t,n)=>{kt(t,n,{data:j,headers:Je.from(u.headers),status:u.status,statusText:u.statusText,config:e,request:O})})}catch(t){if(k&&k(),D&&D.aborted&&D.reason instanceof V){let n=D.reason;throw n.config=e,O&&(n.request=O),t!==n&&(n.cause=t),n}throw t&&t.name===`TypeError`&&/Load failed|fetch/i.test(t.message)?Object.assign(new V(`Network Error`,V.ERR_NETWORK,e,O,t&&t.response),{cause:t.cause||t}):V.from(t,t&&t.code,e,O,t&&t.response)}}},an=new Map,on=e=>{let t=e&&e.env||{},{fetch:n,Request:r,Response:i}=t,a=[r,i,n],o=a.length,s,c,l=an;for(;o--;)s=a[o],c=l.get(s),c===void 0&&l.set(s,c=o?new Map:rn(t)),l=c;return c};on();var sn={http:null,xhr:Kt,fetch:{get:on}};B.forEach(sn,(e,t)=>{if(e){try{Object.defineProperty(e,`name`,{__proto__:null,value:t})}catch{}Object.defineProperty(e,`adapterName`,{__proto__:null,value:t})}});var cn=e=>`- ${e}`,ln=e=>B.isFunction(e)||e===null||e===!1;function un(e,t){e=B.isArray(e)?e:[e];let{length:n}=e,r,i,a={};for(let o=0;o`adapter ${e} `+(t===!1?`is not supported by the environment`:`is not available in the build`));throw new V(`There is no suitable adapter to dispatch the request `+(n?e.length>1?`since : +`+e.map(cn).join(` +`):` `+cn(e[0]):`as no adapter specified`),`ERR_NOT_SUPPORT`)}return i}var dn={getAdapter:un,adapters:sn};function fn(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new Ot(null,e)}function pn(e){return fn(e),e.headers=Je.from(e.headers),e.data=Et.call(e,e.transformRequest),[`post`,`put`,`patch`].indexOf(e.method)!==-1&&e.headers.setContentType(`application/x-www-form-urlencoded`,!1),dn.getAdapter(e.adapter||Tt.adapter,e)(e).then(function(t){fn(e),e.response=t;try{t.data=Et.call(e,e.transformResponse,t)}finally{delete e.response}return t.headers=Je.from(t.headers),t},function(t){if(!Dt(t)&&(fn(e),t&&t.response)){e.response=t.response;try{t.response.data=Et.call(e,e.transformResponse,t.response)}finally{delete e.response}t.response.headers=Je.from(t.response.headers)}return Promise.reject(t)})}var mn={};[`object`,`boolean`,`number`,`function`,`string`,`symbol`].forEach((e,t)=>{mn[e]=function(n){return typeof n===e||`a`+(t<1?`n `:` `)+e}});var hn={};mn.transitional=function(e,t,n){function r(e,t){return`[Axios v`+$t+`] Transitional option '`+e+`'`+t+(n?`. `+n:``)}return(n,i,a)=>{if(e===!1)throw new V(r(i,` has been removed`+(t?` in `+t:``)),V.ERR_DEPRECATED);return t&&!hn[i]&&(hn[i]=!0,console.warn(r(i,` has been deprecated since v`+t+` and will be removed in the near future`))),e?e(n,i,a):!0}},mn.spelling=function(e){return(t,n)=>(console.warn(`${n} is likely a misspelling of ${e}`),!0)};function gn(e,t,n){if(typeof e!=`object`)throw new V(`options must be an object`,V.ERR_BAD_OPTION_VALUE);let r=Object.keys(e),i=r.length;for(;i-- >0;){let a=r[i],o=Object.prototype.hasOwnProperty.call(t,a)?t[a]:void 0;if(o){let t=e[a],n=t===void 0||o(t,a,e);if(n!==!0)throw new V(`option `+a+` must be `+n,V.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new V(`Unknown option `+a,V.ERR_BAD_OPTION)}}var _n={assertOptions:gn,validators:mn},vn=_n.validators,yn=class{constructor(e){this.defaults=e||{},this.interceptors={request:new lt,response:new lt}}async request(e,t){try{return await this._request(e,t)}catch(e){if(e instanceof Error){let t={};Error.captureStackTrace?Error.captureStackTrace(t):t=Error();let n=(()=>{if(!t.stack)return``;let e=t.stack.indexOf(` +`);return e===-1?``:t.stack.slice(e+1)})();try{if(!e.stack)e.stack=n;else if(n){let t=n.indexOf(` +`),r=t===-1?-1:n.indexOf(` +`,t+1),i=r===-1?``:n.slice(r+1);String(e.stack).endsWith(i)||(e.stack+=` +`+n)}}catch{}}throw e}}_request(e,t){typeof e==`string`?(t||={},t.url=e):t=e||{},t=Vt(this.defaults,t);let{transitional:n,paramsSerializer:r,headers:i}=t;n!==void 0&&_n.assertOptions(n,{silentJSONParsing:vn.transitional(vn.boolean),forcedJSONParsing:vn.transitional(vn.boolean),clarifyTimeoutError:vn.transitional(vn.boolean),legacyInterceptorReqResOrdering:vn.transitional(vn.boolean)},!1),r!=null&&(B.isFunction(r)?t.paramsSerializer={serialize:r}:_n.assertOptions(r,{encode:vn.function,serialize:vn.function},!0)),t.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls===void 0?t.allowAbsoluteUrls=!0:t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls),_n.assertOptions(t,{baseUrl:vn.spelling(`baseURL`),withXsrfToken:vn.spelling(`withXSRFToken`)},!0),t.method=(t.method||this.defaults.method||`get`).toLowerCase();let a=i&&B.merge(i.common,i[t.method]);i&&B.forEach([`delete`,`get`,`head`,`post`,`put`,`patch`,`query`,`common`],e=>{delete i[e]}),t.headers=Je.concat(a,i);let o=[],s=!0;this.interceptors.request.forEach(function(e){if(typeof e.runWhen==`function`&&e.runWhen(t)===!1)return;s&&=e.synchronous;let n=t.transitional||ut;n&&n.legacyInterceptorReqResOrdering?o.unshift(e.fulfilled,e.rejected):o.push(e.fulfilled,e.rejected)});let c=[];this.interceptors.response.forEach(function(e){c.push(e.fulfilled,e.rejected)});let l,u=0,d;if(!s){let e=[pn.bind(this),void 0];for(e.unshift(...o),e.push(...c),d=e.length,l=Promise.resolve(t);u{if(!n._listeners)return;let t=n._listeners.length;for(;t-- >0;)n._listeners[t](e);n._listeners=null}),this.promise.then=e=>{let t,r=new Promise(e=>{n.subscribe(e),t=e}).then(e);return r.cancel=function(){n.unsubscribe(t)},r},e(function(e,r,i){n.reason||(n.reason=new Ot(e,r,i),t(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;let t=this._listeners.indexOf(e);t!==-1&&this._listeners.splice(t,1)}toAbortSignal(){let e=new AbortController,t=t=>{e.abort(t)};return this.subscribe(t),e.signal.unsubscribe=()=>this.unsubscribe(t),e.signal}static source(){let t;return{token:new e(function(e){t=e}),cancel:t}}};function xn(e){return function(t){return e.apply(null,t)}}function Sn(e){return B.isObject(e)&&e.isAxiosError===!0}var Cn={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(Cn).forEach(([e,t])=>{Cn[t]=e});function wn(e){let t=new yn(e),n=u(yn.prototype.request,t);return B.extend(n,yn.prototype,t,{allOwnKeys:!0}),B.extend(n,t,null,{allOwnKeys:!0}),n.create=function(t){return wn(Vt(e,t))},n}var U=wn(Tt);U.Axios=yn,U.CanceledError=Ot,U.CancelToken=bn,U.isCancel=Dt,U.VERSION=$t,U.toFormData=rt,U.AxiosError=V,U.Cancel=U.CanceledError,U.all=function(e){return Promise.all(e)},U.spread=xn,U.isAxiosError=Sn,U.mergeConfig=Vt,U.AxiosHeaders=Je,U.formToJSON=e=>St(B.isHTMLForm(e)?new FormData(e):e),U.getAdapter=dn.getAdapter,U.HttpStatusCode=Cn,U.default=U;var{Axios:Tn,AxiosError:En,CanceledError:Dn,isCancel:On,CancelToken:kn,VERSION:An,all:jn,Cancel:Mn,isAxiosError:Nn,spread:Pn,toFormData:Fn,AxiosHeaders:In,HttpStatusCode:Ln,formToJSON:Rn,getAdapter:zn,mergeConfig:Bn,create:Vn}=U;window.axios=U,window.axios.defaults.headers.common[`X-Requested-With`]=`XMLHttpRequest`;var Hn=typeof global==`object`&&global&&global.Object===Object&&global,Un=typeof self==`object`&&self&&self.Object===Object&&self,Wn=Hn||Un||Function(`return this`)(),Gn=Wn.Symbol,Kn=Object.prototype,qn=Kn.hasOwnProperty,Jn=Kn.toString,Yn=Gn?Gn.toStringTag:void 0;function Xn(e){var t=qn.call(e,Yn),n=e[Yn];try{e[Yn]=void 0;var r=!0}catch{}var i=Jn.call(e);return r&&(t?e[Yn]=n:delete e[Yn]),i}var Zn=Object.prototype.toString;function Qn(e){return Zn.call(e)}var $n=`[object Null]`,er=`[object Undefined]`,tr=Gn?Gn.toStringTag:void 0;function nr(e){return e==null?e===void 0?er:$n:tr&&tr in Object(e)?Xn(e):Qn(e)}function rr(e){return typeof e==`object`&&!!e}var ir=`[object Symbol]`;function ar(e){return typeof e==`symbol`||rr(e)&&nr(e)==ir}function or(e,t){for(var n=-1,r=e==null?0:e.length,i=Array(r);++n0){if(++t>=Yr)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}function $r(e){return function(){return e}}var ei=function(){try{var e=Ur(Object,`defineProperty`);return e({},``,{}),e}catch{}}(),ti=Qr(ei?function(e,t){return ei(e,`toString`,{configurable:!0,enumerable:!1,value:$r(t),writable:!0})}:Cr);function ni(e,t){for(var n=-1,r=e==null?0:e.length;++n-1&&e%1==0&&e-1&&e%1==0&&e<=pi}function hi(e){return e!=null&&mi(e.length)&&!Or(e)}function gi(e,t,n){if(!gr(n))return!1;var r=typeof t;return(r==`number`?hi(n)&&ii(t,n.length):r==`string`&&t in n)?oi(n[t],e):!1}function _i(e){return fi(function(t,n){var r=-1,i=n.length,a=i>1?n[i-1]:void 0,o=i>2?n[2]:void 0;for(a=e.length>3&&typeof a==`function`?(i--,a):void 0,o&&gi(n[0],n[1],o)&&(a=i<3?void 0:a,i=1),t=Object(t);++r-1}function za(e,t){var n=this.__data__,r=Pa(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}function Ba(e){var t=-1,n=e==null?0:e.length;for(this.clear();++ts))return!1;var l=a.get(e),u=a.get(t);if(l&&u)return l==t&&u==e;var d=-1,f=!0,p=n&Mc?new Oc:void 0;for(a.set(e,t),a.set(t,e);++d=t||n<0||d&&r>=a}function _(){var e=ul();if(g(e))return v(e);s=setTimeout(_,h(e))}function v(e){return s=void 0,f&&r?p(e):(r=i=void 0,o)}function y(){s!==void 0&&clearTimeout(s),l=0,r=c=i=s=void 0}function b(){return s===void 0?o:v(ul())}function x(){var e=ul(),n=g(e);if(r=arguments,i=this,c=e,n){if(s===void 0)return m(c);if(d)return clearTimeout(s),s=setTimeout(_,t),p(c)}return s===void 0&&(s=setTimeout(_,t)),o}return x.cancel=y,x.flush=b,x}function hl(e,t,n){(n!==void 0&&!oi(e[t],n)||n===void 0&&!(t in e))&&ai(e,t,n)}function gl(e){return rr(e)&&hi(e)}function _l(e,t){if(!(t===`constructor`&&typeof e[t]==`function`)&&t!=`__proto__`)return e[t]}function vl(e){return li(e,va(e))}function yl(e,t,n,r,i,a,o){var s=_l(e,n),c=_l(t,n),l=o.get(c);if(l){hl(e,n,l);return}var u=a?a(s,c,n+``,e,t,o):void 0,d=u===void 0;if(d){var f=sr(c),p=!f&&ji(c),m=!f&&!p&&sa(c);u=c,f||p||m?sr(s)?u=s:gl(s)?u=Jr(s):p?(d=!1,u=No(c,!0)):m?(d=!1,u=_s(c,!0)):u=[]:vo(c)||Ei(c)?(u=s,Ei(s)?u=vl(s):(!gr(s)||Or(s))&&(u=Rs(c))):d=!1}d&&(o.set(c,u),i(u,c,r,a,o),o.delete(c)),hl(e,n,u)}function bl(e,t,n,r,i){e!==t&&ll(t,function(a,o){if(i||=new Eo,gr(a))yl(e,t,o,n,bl,r,i);else{var s=r?r(_l(e,o),a,o+``,e,t,i):void 0;s===void 0&&(s=a),hl(e,o,s)}},va)}var xl=yo({"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`}),Sl=/[&<>"']/g,Cl=RegExp(Sl.source);function wl(e){return e=ro(e),e&&Cl.test(e)?e.replace(Sl,xl):e}var Tl=Object.prototype.hasOwnProperty;function El(e,t){return e!=null&&Tl.call(e,t)}function Dl(e,t){return e!=null&&sl(e,t,El)}function Ol(e,t){return ol(e,t)}var kl=_i(function(e,t,n){bl(e,t,n)});function Al(e,t,n,r){if(!gr(e))return e;t=io(t,e);for(var i=-1,a=t.length,o=a-1,s=e;s!=null&&++i{t.exports=TypeError})),Nl=o(((e,t)=>{t.exports={}})),Pl=o(((e,t)=>{var n=typeof Map==`function`&&Map.prototype,r=Object.getOwnPropertyDescriptor&&n?Object.getOwnPropertyDescriptor(Map.prototype,`size`):null,i=n&&r&&typeof r.get==`function`?r.get:null,a=n&&Map.prototype.forEach,o=typeof Set==`function`&&Set.prototype,s=Object.getOwnPropertyDescriptor&&o?Object.getOwnPropertyDescriptor(Set.prototype,`size`):null,c=o&&s&&typeof s.get==`function`?s.get:null,l=o&&Set.prototype.forEach,u=typeof WeakMap==`function`&&WeakMap.prototype?WeakMap.prototype.has:null,d=typeof WeakSet==`function`&&WeakSet.prototype?WeakSet.prototype.has:null,f=typeof WeakRef==`function`&&WeakRef.prototype?WeakRef.prototype.deref:null,p=Boolean.prototype.valueOf,m=Object.prototype.toString,h=Function.prototype.toString,g=String.prototype.match,_=String.prototype.slice,v=String.prototype.replace,y=String.prototype.toUpperCase,b=String.prototype.toLowerCase,x=RegExp.prototype.test,S=Array.prototype.concat,C=Array.prototype.join,w=Array.prototype.slice,T=Math.floor,E=typeof BigInt==`function`?BigInt.prototype.valueOf:null,D=Object.getOwnPropertySymbols,O=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?Symbol.prototype.toString:null,k=typeof Symbol==`function`&&typeof Symbol.iterator==`object`,A=typeof Symbol==`function`&&Symbol.toStringTag?Symbol.toStringTag:null,j=Object.prototype.propertyIsEnumerable,M=(typeof Reflect==`function`?Reflect.getPrototypeOf:Object.getPrototypeOf)||([].__proto__===Array.prototype?function(e){return e.__proto__}:null);function N(e,t){if(e===1/0||e===-1/0||e!==e||e&&e>-1e3&&e<1e3||x.call(/e/,t))return t;var n=/[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;if(typeof e==`number`){var r=e<0?-T(-e):T(e);if(r!==e){var i=String(r),a=_.call(t,i.length+1);return v.call(i,n,`$&_`)+`.`+v.call(v.call(a,/([0-9]{3})/g,`$&_`),/_$/,``)}}return v.call(t,n,`$&_`)}var P=Nl(),F=P.custom,I=le(F)?F:null,L={__proto__:null,double:`"`,single:`'`},ee={__proto__:null,double:/(["\\])/g,single:/(['\\])/g};t.exports=function e(t,n,r,o){var s=n||{};if(fe(s,`quoteStyle`)&&!fe(L,s.quoteStyle))throw TypeError(`option "quoteStyle" must be "single" or "double"`);if(fe(s,`maxStringLength`)&&(typeof s.maxStringLength==`number`?s.maxStringLength<0&&s.maxStringLength!==1/0:s.maxStringLength!==null))throw TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');var u=fe(s,`customInspect`)?s.customInspect:!0;if(typeof u!=`boolean`&&u!==`symbol`)throw TypeError("option \"customInspect\", if provided, must be `true`, `false`, or `'symbol'`");if(fe(s,`indent`)&&s.indent!==null&&s.indent!==` `&&!(parseInt(s.indent,10)===s.indent&&s.indent>0))throw TypeError('option "indent" must be "\\t", an integer > 0, or `null`');if(fe(s,`numericSeparator`)&&typeof s.numericSeparator!=`boolean`)throw TypeError('option "numericSeparator", if provided, must be `true` or `false`');var d=s.numericSeparator;if(t===void 0)return`undefined`;if(t===null)return`null`;if(typeof t==`boolean`)return t?`true`:`false`;if(typeof t==`string`)return Se(t,s);if(typeof t==`number`){if(t===0)return 1/0/t>0?`0`:`-0`;var f=String(t);return d?N(t,f):f}if(typeof t==`bigint`){var m=String(t)+`n`;return d?N(t,m):m}var h=s.depth===void 0?5:s.depth;if(r===void 0&&(r=0),r>=h&&h>0&&typeof t==`object`)return re(t)?`[Array]`:`[Object]`;var g=Oe(s,r);if(o===void 0)o=[];else if(he(o,t)>=0)return`[Circular]`;function y(t,n,i){if(n&&(o=w.call(o),o.push(n)),i){var a={depth:s.depth};return fe(s,`quoteStyle`)&&(a.quoteStyle=s.quoteStyle),e(t,a,r+1,o)}return e(t,s,r+1,o)}if(typeof t==`function`&&!ae(t)){var x=me(t),T=Ae(t,y);return`[Function`+(x?`: `+x:` (anonymous)`)+`]`+(T.length>0?` { `+C.call(T,`, `)+` }`:``)}if(le(t)){var D=k?v.call(String(t),/^(Symbol\(.*\))_[^)]*$/,`$1`):O.call(t);return typeof t==`object`&&!k?we(D):D}if(xe(t)){for(var F=`<`+b.call(String(t.nodeName)),ee=t.attributes||[],R=0;R`,t.childNodes&&t.childNodes.length&&(F+=`...`),F+=``,F}if(re(t)){if(t.length===0)return`[]`;var de=Ae(t,y);return g&&!De(de)?`[`+ke(de,g)+`]`:`[ `+C.call(de,`, `)+` ]`}if(z(t)){var Ce=Ae(t,y);return!(`cause`in Error.prototype)&&`cause`in t&&!j.call(t,`cause`)?`{ [`+String(t)+`] `+C.call(S.call(`[cause]: `+y(t.cause),Ce),`, `)+` }`:Ce.length===0?`[`+String(t)+`]`:`{ [`+String(t)+`] `+C.call(Ce,`, `)+` }`}if(typeof t==`object`&&u){if(I&&typeof t[I]==`function`&&P)return P(t,{depth:h-r});if(u!==`symbol`&&typeof t.inspect==`function`)return t.inspect()}if(ge(t)){var je=[];return a&&a.call(t,function(e,n){je.push(y(n,t,!0)+` => `+y(e,t))}),Ee(`Map`,i.call(t),je,g)}if(ye(t)){var Me=[];return l&&l.call(t,function(e){Me.push(y(e,t))}),Ee(`Set`,c.call(t),Me,g)}if(_e(t))return Te(`WeakMap`);if(be(t))return Te(`WeakSet`);if(ve(t))return Te(`WeakRef`);if(se(t))return we(y(Number(t)));if(ue(t))return we(y(E.call(t)));if(ce(t))return we(p.call(t));if(oe(t))return we(y(String(t)));if(typeof window<`u`&&t===window)return`{ [object Window] }`;if(typeof globalThis<`u`&&t===globalThis||typeof global<`u`&&t===global)return`{ [object globalThis] }`;if(!ie(t)&&!ae(t)){var Ne=Ae(t,y),Pe=M?M(t)===Object.prototype:t instanceof Object||t.constructor===Object,B=t instanceof Object?``:`null prototype`,Fe=!Pe&&A&&Object(t)===t&&A in t?_.call(pe(t),8,-1):B?`Object`:``,Ie=(Pe||typeof t.constructor!=`function`?``:t.constructor.name?t.constructor.name+` `:``)+(Fe||B?`[`+C.call(S.call([],Fe||[],B||[]),`: `)+`] `:``);return Ne.length===0?Ie+`{}`:g?Ie+`{`+ke(Ne,g)+`}`:Ie+`{ `+C.call(Ne,`, `)+` }`}return String(t)};function te(e,t,n){var r=L[n.quoteStyle||t];return r+e+r}function ne(e){return v.call(String(e),/"/g,`"`)}function R(e){return!A||!(typeof e==`object`&&(A in e||e[A]!==void 0))}function re(e){return pe(e)===`[object Array]`&&R(e)}function ie(e){return pe(e)===`[object Date]`&&R(e)}function ae(e){return pe(e)===`[object RegExp]`&&R(e)}function z(e){return pe(e)===`[object Error]`&&R(e)}function oe(e){return pe(e)===`[object String]`&&R(e)}function se(e){return pe(e)===`[object Number]`&&R(e)}function ce(e){return pe(e)===`[object Boolean]`&&R(e)}function le(e){if(k)return e&&typeof e==`object`&&e instanceof Symbol;if(typeof e==`symbol`)return!0;if(!e||typeof e!=`object`||!O)return!1;try{return O.call(e),!0}catch{}return!1}function ue(e){if(!e||typeof e!=`object`||!E)return!1;try{return E.call(e),!0}catch{}return!1}var de=Object.prototype.hasOwnProperty||function(e){return e in this};function fe(e,t){return de.call(e,t)}function pe(e){return m.call(e)}function me(e){if(e.name)return e.name;var t=g.call(h.call(e),/^function\s*([\w$]+)/);return t?t[1]:null}function he(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0,r=e.length;nt.maxStringLength){var n=e.length-t.maxStringLength,r=`... `+n+` more character`+(n>1?`s`:``);return Se(_.call(e,0,t.maxStringLength),t)+r}var i=ee[t.quoteStyle||`single`];return i.lastIndex=0,te(v.call(v.call(e,i,`\\$1`),/[\x00-\x1f]/g,Ce),`single`,t)}function Ce(e){var t=e.charCodeAt(0),n={8:`b`,9:`t`,10:`n`,12:`f`,13:`r`}[t];return n?`\\`+n:`\\x`+(t<16?`0`:``)+y.call(t.toString(16))}function we(e){return`Object(`+e+`)`}function Te(e){return e+` { ? }`}function Ee(e,t,n,r){var i=r?ke(n,r):C.call(n,`, `);return e+` (`+t+`) {`+i+`}`}function De(e){for(var t=0;t=0)return!1;return!0}function Oe(e,t){var n;if(e.indent===` `)n=` `;else if(typeof e.indent==`number`&&e.indent>0)n=C.call(Array(e.indent+1),` `);else return null;return{base:n,prev:C.call(Array(t+1),n)}}function ke(e,t){if(e.length===0)return``;var n=` +`+t.prev+t.base;return n+C.call(e,`,`+n)+` +`+t.prev}function Ae(e,t){var n=re(e),r=[];if(n){r.length=e.length;for(var i=0;i{var n=Pl(),r=Ml(),i=function(e,t,n){for(var r=e,i;(i=r.next)!=null;r=i)if(i.key===t)return r.next=i.next,n||(i.next=e.next,e.next=i),i},a=function(e,t){if(e){var n=i(e,t);return n&&n.value}},o=function(e,t,n){var r=i(e,t);r?r.value=n:e.next={key:t,next:e.next,value:n}},s=function(e,t){return e?!!i(e,t):!1},c=function(e,t){if(e)return i(e,t,!0)};t.exports=function(){var e,t={assert:function(e){if(!t.has(e))throw new r(`Side channel does not contain `+n(e))},delete:function(t){var n=c(e,t);return n&&e&&!e.next&&(e=void 0),!!n},get:function(t){return a(e,t)},has:function(t){return s(e,t)},set:function(t,n){e||={next:void 0},o(e,t,n)}};return t}})),Il=o(((e,t)=>{t.exports=Object})),Ll=o(((e,t)=>{t.exports=Error})),Rl=o(((e,t)=>{t.exports=EvalError})),zl=o(((e,t)=>{t.exports=RangeError})),Bl=o(((e,t)=>{t.exports=ReferenceError})),Vl=o(((e,t)=>{t.exports=SyntaxError})),Hl=o(((e,t)=>{t.exports=URIError})),Ul=o(((e,t)=>{t.exports=Math.abs})),Wl=o(((e,t)=>{t.exports=Math.floor})),Gl=o(((e,t)=>{t.exports=Math.max})),Kl=o(((e,t)=>{t.exports=Math.min})),ql=o(((e,t)=>{t.exports=Math.pow})),Jl=o(((e,t)=>{t.exports=Math.round})),Yl=o(((e,t)=>{t.exports=Number.isNaN||function(e){return e!==e}})),Xl=o(((e,t)=>{var n=Yl();t.exports=function(e){return n(e)||e===0?e:e<0?-1:1}})),Zl=o(((e,t)=>{t.exports=Object.getOwnPropertyDescriptor})),Ql=o(((e,t)=>{var n=Zl();if(n)try{n([],`length`)}catch{n=null}t.exports=n})),$l=o(((e,t)=>{var n=Object.defineProperty||!1;if(n)try{n({},`a`,{value:1})}catch{n=!1}t.exports=n})),eu=o(((e,t)=>{t.exports=function(){if(typeof Symbol!=`function`||typeof Object.getOwnPropertySymbols!=`function`)return!1;if(typeof Symbol.iterator==`symbol`)return!0;var e={},t=Symbol(`test`),n=Object(t);if(typeof t==`string`||Object.prototype.toString.call(t)!==`[object Symbol]`||Object.prototype.toString.call(n)!==`[object Symbol]`)return!1;var r=42;for(var i in e[t]=r,e)return!1;if(typeof Object.keys==`function`&&Object.keys(e).length!==0||typeof Object.getOwnPropertyNames==`function`&&Object.getOwnPropertyNames(e).length!==0)return!1;var a=Object.getOwnPropertySymbols(e);if(a.length!==1||a[0]!==t||!Object.prototype.propertyIsEnumerable.call(e,t))return!1;if(typeof Object.getOwnPropertyDescriptor==`function`){var o=Object.getOwnPropertyDescriptor(e,t);if(o.value!==r||o.enumerable!==!0)return!1}return!0}})),tu=o(((e,t)=>{var n=typeof Symbol<`u`&&Symbol,r=eu();t.exports=function(){return typeof n!=`function`||typeof Symbol!=`function`||typeof n(`foo`)!=`symbol`||typeof Symbol(`bar`)!=`symbol`?!1:r()}})),nu=o(((e,t)=>{t.exports=typeof Reflect<`u`&&Reflect.getPrototypeOf||null})),ru=o(((e,t)=>{t.exports=Il().getPrototypeOf||null})),iu=o(((e,t)=>{var n=`Function.prototype.bind called on incompatible `,r=Object.prototype.toString,i=Math.max,a=`[object Function]`,o=function(e,t){for(var n=[],r=0;r{var n=iu();t.exports=Function.prototype.bind||n})),ou=o(((e,t)=>{t.exports=Function.prototype.call})),su=o(((e,t)=>{t.exports=Function.prototype.apply})),cu=o(((e,t)=>{t.exports=typeof Reflect<`u`&&Reflect&&Reflect.apply})),lu=o(((e,t)=>{var n=au(),r=su(),i=ou();t.exports=cu()||n.call(i,r)})),uu=o(((e,t)=>{var n=au(),r=Ml(),i=ou(),a=lu();t.exports=function(e){if(e.length<1||typeof e[0]!=`function`)throw new r(`a function is required`);return a(n,i,e)}})),du=o(((e,t)=>{var n=uu(),r=Ql(),i;try{i=[].__proto__===Array.prototype}catch(e){if(!e||typeof e!=`object`||!(`code`in e)||e.code!==`ERR_PROTO_ACCESS`)throw e}var a=!!i&&r&&r(Object.prototype,`__proto__`),o=Object,s=o.getPrototypeOf;t.exports=a&&typeof a.get==`function`?n([a.get]):typeof s==`function`?function(e){return s(e==null?e:o(e))}:!1})),fu=o(((e,t)=>{var n=nu(),r=ru(),i=du();t.exports=n?function(e){return n(e)}:r?function(e){if(!e||typeof e!=`object`&&typeof e!=`function`)throw TypeError(`getProto: not an object`);return r(e)}:i?function(e){return i(e)}:null})),pu=o(((e,t)=>{var n=Function.prototype.call,r=Object.prototype.hasOwnProperty;t.exports=au().call(n,r)})),mu=o(((e,t)=>{var n,r=Il(),i=Ll(),a=Rl(),o=zl(),s=Bl(),c=Vl(),l=Ml(),u=Hl(),d=Ul(),f=Wl(),p=Gl(),m=Kl(),h=ql(),g=Jl(),_=Xl(),v=Function,y=function(e){try{return v(`"use strict"; return (`+e+`).constructor;`)()}catch{}},b=Ql(),x=$l(),S=function(){throw new l},C=b?function(){try{return arguments.callee,S}catch{try{return b(arguments,`callee`).get}catch{return S}}}():S,w=tu()(),T=fu(),E=ru(),D=nu(),O=su(),k=ou(),A={},j=typeof Uint8Array>`u`||!T?n:T(Uint8Array),M={__proto__:null,"%AggregateError%":typeof AggregateError>`u`?n:AggregateError,"%Array%":Array,"%ArrayBuffer%":typeof ArrayBuffer>`u`?n:ArrayBuffer,"%ArrayIteratorPrototype%":w&&T?T([][Symbol.iterator]()):n,"%AsyncFromSyncIteratorPrototype%":n,"%AsyncFunction%":A,"%AsyncGenerator%":A,"%AsyncGeneratorFunction%":A,"%AsyncIteratorPrototype%":A,"%Atomics%":typeof Atomics>`u`?n:Atomics,"%BigInt%":typeof BigInt>`u`?n:BigInt,"%BigInt64Array%":typeof BigInt64Array>`u`?n:BigInt64Array,"%BigUint64Array%":typeof BigUint64Array>`u`?n:BigUint64Array,"%Boolean%":Boolean,"%DataView%":typeof DataView>`u`?n:DataView,"%Date%":Date,"%decodeURI%":decodeURI,"%decodeURIComponent%":decodeURIComponent,"%encodeURI%":encodeURI,"%encodeURIComponent%":encodeURIComponent,"%Error%":i,"%eval%":eval,"%EvalError%":a,"%Float16Array%":typeof Float16Array>`u`?n:Float16Array,"%Float32Array%":typeof Float32Array>`u`?n:Float32Array,"%Float64Array%":typeof Float64Array>`u`?n:Float64Array,"%FinalizationRegistry%":typeof FinalizationRegistry>`u`?n:FinalizationRegistry,"%Function%":v,"%GeneratorFunction%":A,"%Int8Array%":typeof Int8Array>`u`?n:Int8Array,"%Int16Array%":typeof Int16Array>`u`?n:Int16Array,"%Int32Array%":typeof Int32Array>`u`?n:Int32Array,"%isFinite%":isFinite,"%isNaN%":isNaN,"%IteratorPrototype%":w&&T?T(T([][Symbol.iterator]())):n,"%JSON%":typeof JSON==`object`?JSON:n,"%Map%":typeof Map>`u`?n:Map,"%MapIteratorPrototype%":typeof Map>`u`||!w||!T?n:T(new Map()[Symbol.iterator]()),"%Math%":Math,"%Number%":Number,"%Object%":r,"%Object.getOwnPropertyDescriptor%":b,"%parseFloat%":parseFloat,"%parseInt%":parseInt,"%Promise%":typeof Promise>`u`?n:Promise,"%Proxy%":typeof Proxy>`u`?n:Proxy,"%RangeError%":o,"%ReferenceError%":s,"%Reflect%":typeof Reflect>`u`?n:Reflect,"%RegExp%":RegExp,"%Set%":typeof Set>`u`?n:Set,"%SetIteratorPrototype%":typeof Set>`u`||!w||!T?n:T(new Set()[Symbol.iterator]()),"%SharedArrayBuffer%":typeof SharedArrayBuffer>`u`?n:SharedArrayBuffer,"%String%":String,"%StringIteratorPrototype%":w&&T?T(``[Symbol.iterator]()):n,"%Symbol%":w?Symbol:n,"%SyntaxError%":c,"%ThrowTypeError%":C,"%TypedArray%":j,"%TypeError%":l,"%Uint8Array%":typeof Uint8Array>`u`?n:Uint8Array,"%Uint8ClampedArray%":typeof Uint8ClampedArray>`u`?n:Uint8ClampedArray,"%Uint16Array%":typeof Uint16Array>`u`?n:Uint16Array,"%Uint32Array%":typeof Uint32Array>`u`?n:Uint32Array,"%URIError%":u,"%WeakMap%":typeof WeakMap>`u`?n:WeakMap,"%WeakRef%":typeof WeakRef>`u`?n:WeakRef,"%WeakSet%":typeof WeakSet>`u`?n:WeakSet,"%Function.prototype.call%":k,"%Function.prototype.apply%":O,"%Object.defineProperty%":x,"%Object.getPrototypeOf%":E,"%Math.abs%":d,"%Math.floor%":f,"%Math.max%":p,"%Math.min%":m,"%Math.pow%":h,"%Math.round%":g,"%Math.sign%":_,"%Reflect.getPrototypeOf%":D};if(T)try{null.error}catch(e){M[`%Error.prototype%`]=T(T(e))}var N=function e(t){var n;if(t===`%AsyncFunction%`)n=y(`async function () {}`);else if(t===`%GeneratorFunction%`)n=y(`function* () {}`);else if(t===`%AsyncGeneratorFunction%`)n=y(`async function* () {}`);else if(t===`%AsyncGenerator%`){var r=e(`%AsyncGeneratorFunction%`);r&&(n=r.prototype)}else if(t===`%AsyncIteratorPrototype%`){var i=e(`%AsyncGenerator%`);i&&T&&(n=T(i.prototype))}return M[t]=n,n},P={__proto__:null,"%ArrayBufferPrototype%":[`ArrayBuffer`,`prototype`],"%ArrayPrototype%":[`Array`,`prototype`],"%ArrayProto_entries%":[`Array`,`prototype`,`entries`],"%ArrayProto_forEach%":[`Array`,`prototype`,`forEach`],"%ArrayProto_keys%":[`Array`,`prototype`,`keys`],"%ArrayProto_values%":[`Array`,`prototype`,`values`],"%AsyncFunctionPrototype%":[`AsyncFunction`,`prototype`],"%AsyncGenerator%":[`AsyncGeneratorFunction`,`prototype`],"%AsyncGeneratorPrototype%":[`AsyncGeneratorFunction`,`prototype`,`prototype`],"%BooleanPrototype%":[`Boolean`,`prototype`],"%DataViewPrototype%":[`DataView`,`prototype`],"%DatePrototype%":[`Date`,`prototype`],"%ErrorPrototype%":[`Error`,`prototype`],"%EvalErrorPrototype%":[`EvalError`,`prototype`],"%Float32ArrayPrototype%":[`Float32Array`,`prototype`],"%Float64ArrayPrototype%":[`Float64Array`,`prototype`],"%FunctionPrototype%":[`Function`,`prototype`],"%Generator%":[`GeneratorFunction`,`prototype`],"%GeneratorPrototype%":[`GeneratorFunction`,`prototype`,`prototype`],"%Int8ArrayPrototype%":[`Int8Array`,`prototype`],"%Int16ArrayPrototype%":[`Int16Array`,`prototype`],"%Int32ArrayPrototype%":[`Int32Array`,`prototype`],"%JSONParse%":[`JSON`,`parse`],"%JSONStringify%":[`JSON`,`stringify`],"%MapPrototype%":[`Map`,`prototype`],"%NumberPrototype%":[`Number`,`prototype`],"%ObjectPrototype%":[`Object`,`prototype`],"%ObjProto_toString%":[`Object`,`prototype`,`toString`],"%ObjProto_valueOf%":[`Object`,`prototype`,`valueOf`],"%PromisePrototype%":[`Promise`,`prototype`],"%PromiseProto_then%":[`Promise`,`prototype`,`then`],"%Promise_all%":[`Promise`,`all`],"%Promise_reject%":[`Promise`,`reject`],"%Promise_resolve%":[`Promise`,`resolve`],"%RangeErrorPrototype%":[`RangeError`,`prototype`],"%ReferenceErrorPrototype%":[`ReferenceError`,`prototype`],"%RegExpPrototype%":[`RegExp`,`prototype`],"%SetPrototype%":[`Set`,`prototype`],"%SharedArrayBufferPrototype%":[`SharedArrayBuffer`,`prototype`],"%StringPrototype%":[`String`,`prototype`],"%SymbolPrototype%":[`Symbol`,`prototype`],"%SyntaxErrorPrototype%":[`SyntaxError`,`prototype`],"%TypedArrayPrototype%":[`TypedArray`,`prototype`],"%TypeErrorPrototype%":[`TypeError`,`prototype`],"%Uint8ArrayPrototype%":[`Uint8Array`,`prototype`],"%Uint8ClampedArrayPrototype%":[`Uint8ClampedArray`,`prototype`],"%Uint16ArrayPrototype%":[`Uint16Array`,`prototype`],"%Uint32ArrayPrototype%":[`Uint32Array`,`prototype`],"%URIErrorPrototype%":[`URIError`,`prototype`],"%WeakMapPrototype%":[`WeakMap`,`prototype`],"%WeakSetPrototype%":[`WeakSet`,`prototype`]},F=au(),I=pu(),L=F.call(k,Array.prototype.concat),ee=F.call(O,Array.prototype.splice),te=F.call(k,String.prototype.replace),ne=F.call(k,String.prototype.slice),R=F.call(k,RegExp.prototype.exec),re=/[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g,ie=/\\(\\)?/g,ae=function(e){var t=ne(e,0,1),n=ne(e,-1);if(t===`%`&&n!==`%`)throw new c("invalid intrinsic syntax, expected closing `%`");if(n===`%`&&t!==`%`)throw new c("invalid intrinsic syntax, expected opening `%`");var r=[];return te(e,re,function(e,t,n,i){r[r.length]=n?te(i,ie,`$1`):t||e}),r},z=function(e,t){var n=e,r;if(I(P,n)&&(r=P[n],n=`%`+r[0]+`%`),I(M,n)){var i=M[n];if(i===A&&(i=N(n)),i===void 0&&!t)throw new l(`intrinsic `+e+` exists, but is not available. Please file an issue!`);return{alias:r,name:n,value:i}}throw new c(`intrinsic `+e+` does not exist!`)};t.exports=function(e,t){if(typeof e!=`string`||e.length===0)throw new l(`intrinsic name must be a non-empty string`);if(arguments.length>1&&typeof t!=`boolean`)throw new l(`"allowMissing" argument must be a boolean`);if(R(/^%?[^%]*%?$/,e)===null)throw new c("`%` may not be present anywhere but at the beginning and end of the intrinsic name");var n=ae(e),r=n.length>0?n[0]:``,i=z(`%`+r+`%`,t),a=i.name,o=i.value,s=!1,u=i.alias;u&&(r=u[0],ee(n,L([0,1],u)));for(var d=1,f=!0;d=n.length){var g=b(o,p);f=!!g,o=f&&`get`in g&&!(`originalValue`in g.get)?g.get:o[p]}else f=I(o,p),o=o[p];f&&!s&&(M[a]=o)}}return o}})),hu=o(((e,t)=>{var n=mu(),r=uu(),i=r([n(`%String.prototype.indexOf%`)]);t.exports=function(e,t){var a=n(e,!!t);return typeof a==`function`&&i(e,`.prototype.`)>-1?r([a]):a}})),gu=o(((e,t)=>{var n=mu(),r=hu(),i=Pl(),a=Ml(),o=n(`%Map%`,!0),s=r(`Map.prototype.get`,!0),c=r(`Map.prototype.set`,!0),l=r(`Map.prototype.has`,!0),u=r(`Map.prototype.delete`,!0),d=r(`Map.prototype.size`,!0);t.exports=!!o&&function(){var e,t={assert:function(e){if(!t.has(e))throw new a(`Side channel does not contain `+i(e))},delete:function(t){if(e){var n=u(e,t);return d(e)===0&&(e=void 0),n}return!1},get:function(t){if(e)return s(e,t)},has:function(t){return e?l(e,t):!1},set:function(t,n){e||=new o,c(e,t,n)}};return t}})),_u=o(((e,t)=>{var n=mu(),r=hu(),i=Pl(),a=gu(),o=Ml(),s=n(`%WeakMap%`,!0),c=r(`WeakMap.prototype.get`,!0),l=r(`WeakMap.prototype.set`,!0),u=r(`WeakMap.prototype.has`,!0),d=r(`WeakMap.prototype.delete`,!0);t.exports=s?function(){var e,t,n={assert:function(e){if(!n.has(e))throw new o(`Side channel does not contain `+i(e))},delete:function(n){if(s&&n&&(typeof n==`object`||typeof n==`function`)){if(e)return d(e,n)}else if(a&&t)return t.delete(n);return!1},get:function(n){return s&&n&&(typeof n==`object`||typeof n==`function`)&&e?c(e,n):t&&t.get(n)},has:function(n){return s&&n&&(typeof n==`object`||typeof n==`function`)&&e?u(e,n):!!t&&t.has(n)},set:function(n,r){s&&n&&(typeof n==`object`||typeof n==`function`)?(e||=new s,l(e,n,r)):a&&(t||=a(),t.set(n,r))}};return n}:a})),vu=o(((e,t)=>{var n=Ml(),r=Pl(),i=Fl(),a=gu(),o=_u()||a||i;t.exports=function(){var e,t={assert:function(e){if(!t.has(e))throw new n(`Side channel does not contain `+r(e))},delete:function(t){return!!e&&e.delete(t)},get:function(t){return e&&e.get(t)},has:function(t){return!!e&&e.has(t)},set:function(t,n){e||=o(),e.set(t,n)}};return t}})),yu=o(((e,t)=>{var n=String.prototype.replace,r=/%20/g,i={RFC1738:`RFC1738`,RFC3986:`RFC3986`};t.exports={default:i.RFC3986,formatters:{RFC1738:function(e){return n.call(e,r,`+`)},RFC3986:function(e){return String(e)}},RFC1738:i.RFC1738,RFC3986:i.RFC3986}})),bu=o(((e,t)=>{var n=yu(),r=vu(),i=Object.prototype.hasOwnProperty,a=Array.isArray,o=r(),s=function(e,t){return o.set(e,t),e},c=function(e){return o.has(e)},l=function(e){return o.get(e)},u=function(e,t){o.set(e,t)},d=function(){for(var e=[],t=0;t<256;++t)e[e.length]=`%`+((t<16?`0`:``)+t.toString(16)).toUpperCase();return e}(),f=function(e){for(;e.length>1;){var t=e.pop(),n=t.obj[t.prop];if(a(n)){for(var r=[],i=0;ir.arrayLimit)return s(p(t.concat(n),r),o);t[o]=n}else if(t&&typeof t==`object`)if(c(t)){var d=l(t)+1;t[d]=n,u(t,d)}else if(r&&r.strictMerge)return[t,n];else (r&&(r.plainObjects||r.allowPrototypes)||!i.call(Object.prototype,n))&&(t[n]=!0);else return[t,n];return t}if(!t||typeof t!=`object`){if(c(n)){for(var f=Object.keys(n),m=r&&r.plainObjects?{__proto__:null,0:t}:{0:t},h=0;hr.arrayLimit?s(p(_,r),_.length-1):_}var v=t;return a(t)&&!a(n)&&(v=p(t,r)),a(t)&&a(n)?(n.forEach(function(n,a){if(i.call(t,a)){var o=t[a];o&&typeof o==`object`&&n&&typeof n==`object`?t[a]=e(o,n,r):t[t.length]=n}else t[a]=n}),t):Object.keys(n).reduce(function(t,a){var o=n[a];if(i.call(t,a)?t[a]=e(t[a],o,r):t[a]=o,c(n)&&!c(t)&&s(t,l(n)),c(t)){var d=parseInt(a,10);String(d)===a&&d>=0&&d>l(t)&&u(t,d)}return t},v)},h=function(e,t){return Object.keys(t).reduce(function(e,n){return e[n]=t[n],e},e)},g=function(e,t,n){var r=e.replace(/\+/g,` `);if(n===`iso-8859-1`)return r.replace(/%[0-9a-f]{2}/gi,unescape);try{return decodeURIComponent(r)}catch{return r}},_=1024;t.exports={arrayToObject:p,assign:h,combine:function(e,t,n,r){if(c(e)){var i=l(e)+1;return e[i]=t,u(e,i),e}var a=[].concat(e,t);return a.length>n?s(p(a,{plainObjects:r}),a.length-1):a},compact:function(e){for(var t=[{obj:{o:e},prop:`o`}],n=[],r=0;r=_?o.slice(c,c+_):o,u=[],f=0;f=48&&p<=57||p>=65&&p<=90||p>=97&&p<=122||a===n.RFC1738&&(p===40||p===41)){u[u.length]=l.charAt(f);continue}if(p<128){u[u.length]=d[p];continue}if(p<2048){u[u.length]=d[192|p>>6]+d[128|p&63];continue}if(p<55296||p>=57344){u[u.length]=d[224|p>>12]+d[128|p>>6&63]+d[128|p&63];continue}f+=1,p=65536+((p&1023)<<10|l.charCodeAt(f)&1023),u[u.length]=d[240|p>>18]+d[128|p>>12&63]+d[128|p>>6&63]+d[128|p&63]}s+=u.join(``)}return s},isBuffer:function(e){return!e||typeof e!=`object`?!1:!!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e))},isOverflow:c,isRegExp:function(e){return Object.prototype.toString.call(e)===`[object RegExp]`},markOverflow:s,maybeMap:function(e,t){if(a(e)){for(var n=[],r=0;r{var n=vu(),r=bu(),i=yu(),a=Object.prototype.hasOwnProperty,o={brackets:function(e){return e+`[]`},comma:`comma`,indices:function(e,t){return e+`[`+t+`]`},repeat:function(e){return e}},s=Array.isArray,c=Array.prototype.push,l=function(e,t){c.apply(e,s(t)?t:[t])},u=Date.prototype.toISOString,d=i.default,f={addQueryPrefix:!1,allowDots:!1,allowEmptyArrays:!1,arrayFormat:`indices`,charset:`utf-8`,charsetSentinel:!1,commaRoundTrip:!1,delimiter:`&`,encode:!0,encodeDotInKeys:!1,encoder:r.encode,encodeValuesOnly:!1,filter:void 0,format:d,formatter:i.formatters[d],indices:!1,serializeDate:function(e){return u.call(e)},skipNulls:!1,strictNullHandling:!1},p=function(e){return typeof e==`string`||typeof e==`number`||typeof e==`boolean`||typeof e==`symbol`||typeof e==`bigint`},m={},h=function e(t,i,a,o,c,u,d,h,g,_,v,y,b,x,S,C,w,T){for(var E=t,D=T,O=0,k=!1;(D=D.get(m))!==void 0&&!k;){var A=D.get(t);if(O+=1,A!==void 0){if(A===O)throw RangeError(`Cyclic object value`);k=!0}D.get(m)===void 0&&(O=0)}if(typeof _==`function`?E=_(i,E):E instanceof Date?E=b(E):a===`comma`&&s(E)&&(E=r.maybeMap(E,function(e){return e instanceof Date?b(e):e})),E===null){if(u)return g&&!C?g(i,f.encoder,w,`key`,x):i;E=``}if(p(E)||r.isBuffer(E))return g?[S(C?i:g(i,f.encoder,w,`key`,x))+`=`+S(g(E,f.encoder,w,`value`,x))]:[S(i)+`=`+S(String(E))];var j=[];if(E===void 0)return j;var M;if(a===`comma`&&s(E))C&&g&&(E=r.maybeMap(E,g)),M=[{value:E.length>0?E.join(`,`)||null:void 0}];else if(s(_))M=_;else{var N=Object.keys(E);M=v?N.sort(v):N}var P=h?String(i).replace(/\./g,`%2E`):String(i),F=o&&s(E)&&E.length===1?P+`[]`:P;if(c&&s(E)&&E.length===0)return F+`[]`;for(var I=0;I0?b+y:``}})),Su=o(((e,t)=>{var n=bu(),r=Object.prototype.hasOwnProperty,i=Array.isArray,a={allowDots:!1,allowEmptyArrays:!1,allowPrototypes:!1,allowSparse:!1,arrayLimit:20,charset:`utf-8`,charsetSentinel:!1,comma:!1,decodeDotInKeys:!1,decoder:n.decode,delimiter:`&`,depth:5,duplicates:`combine`,ignoreQueryPrefix:!1,interpretNumericEntities:!1,parameterLimit:1e3,parseArrays:!0,plainObjects:!1,strictDepth:!1,strictMerge:!0,strictNullHandling:!1,throwOnLimitExceeded:!1},o=function(e){return e.replace(/&#(\d+);/g,function(e,t){return String.fromCharCode(parseInt(t,10))})},s=function(e,t,n){if(e&&typeof e==`string`&&t.comma&&e.indexOf(`,`)>-1)return e.split(`,`);if(t.throwOnLimitExceeded&&n>=t.arrayLimit)throw RangeError(`Array limit exceeded. Only `+t.arrayLimit+` element`+(t.arrayLimit===1?``:`s`)+` allowed in an array.`);return e},c=`utf8=%26%2310003%3B`,l=`utf8=%E2%9C%93`,u=function(e,t){var u={__proto__:null},d=t.ignoreQueryPrefix?e.replace(/^\?/,``):e;d=d.replace(/%5B/gi,`[`).replace(/%5D/gi,`]`);var f=t.parameterLimit===1/0?void 0:t.parameterLimit,p=d.split(t.delimiter,t.throwOnLimitExceeded&&f!==void 0?f+1:f);if(t.throwOnLimitExceeded&&f!==void 0&&p.length>f)throw RangeError(`Parameter limit exceeded. Only `+f+` parameter`+(f===1?``:`s`)+` allowed.`);var m=-1,h,g=t.charset;if(t.charsetSentinel)for(h=0;h-1&&(x=i(x)?[x]:x),t.comma&&i(x)&&x.length>t.arrayLimit){if(t.throwOnLimitExceeded)throw RangeError(`Array limit exceeded. Only `+t.arrayLimit+` element`+(t.arrayLimit===1?``:`s`)+` allowed in an array.`);x=n.combine([],x,t.arrayLimit,t.plainObjects)}if(b!==null){var S=r.call(u,b);S&&(t.duplicates===`combine`||_.indexOf(`[]=`)>-1)?u[b]=n.combine(u[b],x,t.arrayLimit,t.plainObjects):(!S||t.duplicates===`last`)&&(u[b]=x)}}return u},d=function(e,t,r,i){var a=0;if(e.length>0&&e[e.length-1]===`[]`){var o=e.slice(0,-1).join(``);a=Array.isArray(t)&&t[o]?t[o].length:0}for(var c=i?t:s(t,r,a),l=e.length-1;l>=0;--l){var u,d=e[l];if(d===`[]`&&r.parseArrays)u=n.isOverflow(c)?c:r.allowEmptyArrays&&(c===``||r.strictNullHandling&&c===null)?[]:n.combine([],c,r.arrayLimit,r.plainObjects);else{u=r.plainObjects?{__proto__:null}:{};var f=d.charAt(0)===`[`&&d.charAt(d.length-1)===`]`?d.slice(1,-1):d,p=r.decodeDotInKeys?f.replace(/%2E/g,`.`):f,m=parseInt(p,10),h=!isNaN(m)&&d!==p&&String(m)===p&&m>=0&&r.parseArrays;if(!r.parseArrays&&p===``)u={0:c};else if(h&&m{var n=xu(),r=Su();t.exports={formats:yu(),parse:r,stringify:n}}))(),1),wu=new class{constructor(e){this.config={},this.defaults=e}extend(e){return e&&(this.defaults={...this.defaults,...e}),this}replace(e){this.config=e}get(e){return Dl(this.config,e)?co(this.config,e):co(this.defaults,e)}set(e,t){typeof e==`string`?jl(this.config,e,t):Object.entries(e).forEach(([e,t])=>{jl(this.config,e,t)})}}({form:{recentlySuccessfulDuration:2e3,forceIndicesArrayFormatInFormData:!0,withAllErrors:!1},future:{preserveEqualProps:!1,useDataInertiaHeadAttribute:!1,useDialogForErrorModal:!1,useScriptElementForInitialPage:!1},prefetch:{cacheFor:3e4,hoverDelay:75}});function Tu(e,t){let n;return function(...r){clearTimeout(n),n=setTimeout(()=>e.apply(this,r),t)}}function Eu(e,t){return document.dispatchEvent(new CustomEvent(`inertia:${e}`,t))}var Du=e=>Eu(`before`,{cancelable:!0,detail:{visit:e}}),Ou=e=>Eu(`error`,{detail:{errors:e}}),ku=e=>Eu(`exception`,{cancelable:!0,detail:{exception:e}}),Au=e=>Eu(`finish`,{detail:{visit:e}}),ju=e=>Eu(`invalid`,{cancelable:!0,detail:{response:e}}),Mu=e=>Eu(`beforeUpdate`,{detail:{page:e}}),Nu=e=>Eu(`navigate`,{detail:{page:e}}),Pu=e=>Eu(`progress`,{detail:{progress:e}}),Fu=e=>Eu(`start`,{detail:{visit:e}}),Iu=e=>Eu(`success`,{detail:{page:e}}),Lu=(e,t)=>Eu(`prefetched`,{detail:{fetchedAt:Date.now(),response:e.data,visit:t}}),Ru=e=>Eu(`prefetching`,{detail:{visit:e}}),zu=e=>Eu(`flash`,{detail:{flash:e}}),Bu=class{static set(e,t){typeof window<`u`&&window.sessionStorage.setItem(e,JSON.stringify(t))}static get(e){if(typeof window<`u`)return JSON.parse(window.sessionStorage.getItem(e)||`null`)}static merge(e,t){let n=this.get(e);n===null?this.set(e,t):this.set(e,{...n,...t})}static remove(e){typeof window<`u`&&window.sessionStorage.removeItem(e)}static removeNested(e,t){let n=this.get(e);n!==null&&(delete n[t],this.set(e,n))}static exists(e){try{return this.get(e)!==null}catch{return!1}}static clear(){typeof window<`u`&&window.sessionStorage.clear()}};Bu.locationVisitKey=`inertiaLocationVisit`;var Vu=async e=>{if(typeof window>`u`)throw Error(`Unable to encrypt history`);let t=Ku(),n=await Yu(await Xu());if(!n)throw Error(`Unable to encrypt history`);return await Wu(t,n,e)},Hu={key:`historyKey`,iv:`historyIv`},Uu=async e=>{let t=Ku(),n=await Xu();if(!n)throw Error(`Unable to decrypt history`);return await Gu(t,n,e)},Wu=async(e,t,n)=>{if(typeof window>`u`)throw Error(`Unable to encrypt history`);if(window.crypto.subtle===void 0)return console.warn(`Encryption is not supported in this environment. SSL is required.`),Promise.resolve(n);let r=new TextEncoder,i=JSON.stringify(n),a=new Uint8Array(i.length*3),o=r.encodeInto(i,a);return window.crypto.subtle.encrypt({name:`AES-GCM`,iv:e},t,a.subarray(0,o.written))},Gu=async(e,t,n)=>{if(window.crypto.subtle===void 0)return console.warn(`Decryption is not supported in this environment. SSL is required.`),Promise.resolve(n);let r=await window.crypto.subtle.decrypt({name:`AES-GCM`,iv:e},t,n);return JSON.parse(new TextDecoder().decode(r))},Ku=()=>{let e=Bu.get(Hu.iv);if(e)return new Uint8Array(e);let t=window.crypto.getRandomValues(new Uint8Array(12));return Bu.set(Hu.iv,Array.from(t)),t},qu=async()=>window.crypto.subtle===void 0?(console.warn(`Encryption is not supported in this environment. SSL is required.`),Promise.resolve(null)):window.crypto.subtle.generateKey({name:`AES-GCM`,length:256},!0,[`encrypt`,`decrypt`]),Ju=async e=>{if(window.crypto.subtle===void 0)return console.warn(`Encryption is not supported in this environment. SSL is required.`),Promise.resolve();let t=await window.crypto.subtle.exportKey(`raw`,e);Bu.set(Hu.key,Array.from(new Uint8Array(t)))},Yu=async e=>{if(e)return e;let t=await qu();return t?(await Ju(t),t):null},Xu=async()=>{let e=Bu.get(Hu.key);return e?await window.crypto.subtle.importKey(`raw`,new Uint8Array(e),{name:`AES-GCM`,length:256},!0,[`encrypt`,`decrypt`]):null},Zu=(e,t,n)=>{if(e===t)return!0;for(let r in e)if(!n.includes(r)&&e[r]!==t[r]&&!Qu(e[r],t[r]))return!1;for(let r in t)if(!n.includes(r)&&!(r in e))return!1;return!0},Qu=(e,t)=>{switch(typeof e){case`object`:return Zu(e,t,[]);case`function`:return e.toString()===t.toString();default:return e===t}},$u={ms:1,s:1e3,m:1e3*60,h:1e3*60*60,d:1e3*60*60*24},ed=e=>{if(typeof e==`number`)return e;for(let[t,n]of Object.entries($u))if(e.endsWith(t))return parseFloat(e)*n;return parseInt(e)},td=new class{constructor(){this.cached=[],this.inFlightRequests=[],this.removalTimers=[],this.currentUseId=null}add(e,t,{cacheFor:n,cacheTags:r}){if(this.findInFlight(e))return Promise.resolve();let i=this.findCached(e);if(!e.fresh&&i&&i.staleTimestamp>Date.now())return Promise.resolve();let[a,o]=this.extractStaleValues(n),s=new Promise((n,r)=>{t({...e,onCancel:()=>{this.remove(e),e.onCancel(),r()},onError:t=>{this.remove(e),e.onError(t),r()},onPrefetching(t){e.onPrefetching(t)},onPrefetched(t,n){e.onPrefetched(t,n)},onPrefetchResponse(e){n(e)},onPrefetchError(t){td.removeFromInFlight(e),r(t)}})}).then(t=>{this.remove(e);let n=t.getPageResponse();Z.mergeOncePropsIntoResponse(n),this.cached.push({params:{...e},staleTimestamp:Date.now()+a,expiresAt:Date.now()+o,response:s,singleUse:o===0,timestamp:Date.now(),inFlight:!1,tags:Array.isArray(r)?r:[r]});let i=this.getShortestOncePropTtl(n);return this.scheduleForRemoval(e,i?Math.min(o,i):o),this.removeFromInFlight(e),t.handlePrefetch(),t});return this.inFlightRequests.push({params:{...e},response:s,staleTimestamp:null,inFlight:!0}),s}removeAll(){this.cached=[],this.removalTimers.forEach(e=>{clearTimeout(e.timer)}),this.removalTimers=[]}removeByTags(e){this.cached=this.cached.filter(t=>!t.tags.some(t=>e.includes(t)))}remove(e){this.cached=this.cached.filter(t=>!this.paramsAreEqual(t.params,e)),this.clearTimer(e)}removeFromInFlight(e){this.inFlightRequests=this.inFlightRequests.filter(t=>!this.paramsAreEqual(t.params,e))}extractStaleValues(e){let[t,n]=this.cacheForToStaleAndExpires(e);return[ed(t),ed(n)]}cacheForToStaleAndExpires(e){if(!Array.isArray(e))return[e,e];switch(e.length){case 0:return[0,0];case 1:return[e[0],e[0]];default:return[e[0],e[1]]}}clearTimer(e){let t=this.removalTimers.find(t=>this.paramsAreEqual(t.params,e));t&&(clearTimeout(t.timer),this.removalTimers=this.removalTimers.filter(e=>e!==t))}scheduleForRemoval(e,t){if(!(typeof window>`u`)&&(this.clearTimer(e),t>0)){let n=window.setTimeout(()=>this.remove(e),t);this.removalTimers.push({params:e,timer:n})}}get(e){return this.findCached(e)||this.findInFlight(e)}use(e,t){let n=`${t.url.pathname}-${Date.now()}-${Math.random().toString(36).substring(7)}`;return this.currentUseId=n,e.response.then(e=>{if(this.currentUseId===n)return e.mergeParams({...t,onPrefetched:()=>{}}),this.removeSingleUseItems(t),e.handle()})}removeSingleUseItems(e){this.cached=this.cached.filter(t=>this.paramsAreEqual(t.params,e)?!t.singleUse:!0)}findCached(e){return this.cached.find(t=>this.paramsAreEqual(t.params,e))||null}findInFlight(e){return this.inFlightRequests.find(t=>this.paramsAreEqual(t.params,e))||null}withoutPurposePrefetchHeader(e){let t=wc(e);return t.headers.Purpose===`prefetch`&&delete t.headers.Purpose,t}paramsAreEqual(e,t){return Zu(this.withoutPurposePrefetchHeader(e),this.withoutPurposePrefetchHeader(t),[`showProgress`,`replace`,`prefetch`,`preserveScroll`,`preserveState`,`onBefore`,`onBeforeUpdate`,`onStart`,`onProgress`,`onFinish`,`onCancel`,`onSuccess`,`onError`,`onFlash`,`onPrefetched`,`onCancelToken`,`onPrefetching`,`async`,`viewTransition`])}updateCachedOncePropsFromCurrentPage(){this.cached.forEach(e=>{e.response.then(t=>{let n=t.getPageResponse();Z.mergeOncePropsIntoResponse(n,{force:!0});for(let[e,t]of Object.entries(n.deferredProps??{})){let r=t.filter(e=>n.props[e]===void 0);r.length>0?n.deferredProps[e]=r:delete n.deferredProps[e]}let r=this.getShortestOncePropTtl(n);if(r===null)return;let i=e.expiresAt-Date.now(),a=Math.min(i,r);a>0?this.scheduleForRemoval(e.params,a):this.remove(e.params)})})}getShortestOncePropTtl(e){let t=Object.values(e.onceProps??{}).map(e=>e.expiresAt).filter(e=>!!e);return t.length===0?null:Math.min(...t)-Date.now()}},nd=e=>{if(e.offsetParent===null)return!1;let t=e.getBoundingClientRect(),n=t.top=0,r=t.left=0;return n&&r},rd=e=>{let t=e=>{let t=window.getComputedStyle(e);return[`scroll`,`overlay`].includes(t.overflowY)?!0:t.overflowY===`auto`?[`visible`,`clip`].includes(t.overflowX)?!0:r(t.maxHeight,e.style.height)||i(e,`height`):!1},n=e=>{let t=window.getComputedStyle(e);return[`scroll`,`overlay`].includes(t.overflowX)?!0:t.overflowX===`auto`?[`visible`,`clip`].includes(t.overflowY)?!0:r(t.maxWidth,e.style.width)||i(e,`width`):!1},r=(e,t)=>!!(e&&e!==`none`&&e!==`0px`||t&&t!==`auto`&&t!==`0`),i=(e,t)=>{let n=e.parentElement;if(!n)return!1;let r=window.getComputedStyle(n);if([`flex`,`inline-flex`].includes(r.display)){let e=[`column`,`column-reverse`].includes(r.flexDirection);return t===`height`?e:!e}return[`grid`,`inline-grid`].includes(r.display)},a=e?.parentElement;for(;a;){let e=t(a)||n(a);if(window.getComputedStyle(a).display!==`contents`&&e)return a;a=a.parentElement}return null},id=(e,t)=>{if(!t)return e.filter(e=>nd(e));let n=e.indexOf(t),r=[],i=[];for(let t=n;t>=0;t--){let n=e[t];if(nd(n))r.push(n);else break}for(let t=n+1;t{window.requestAnimationFrame(()=>{t>1?ad(e,t-1):e()})},od=(e,t=!1)=>{if(typeof window>`u`)return null;if(!t){let t=document.getElementById(e);if(t?.dataset.page)return JSON.parse(t.dataset.page)}let n=document.querySelector(`script[data-page="${e}"][type="application/json"]`);return n?.textContent?JSON.parse(n.textContent):null},sd=typeof window>`u`,cd=!sd&&/Firefox/i.test(window.navigator.userAgent),ld=class{static save(){Q.saveScrollPositions(this.getScrollRegions())}static getScrollRegions(){return Array.from(this.regions()).map(e=>({top:e.scrollTop,left:e.scrollLeft}))}static regions(){return document.querySelectorAll(`[scroll-region]`)}static scrollToTop(){if(cd&&getComputedStyle(document.documentElement).scrollBehavior===`smooth`)return ad(()=>window.scrollTo(0,0),2);window.scrollTo(0,0)}static reset(){!sd&&window.location.hash||this.scrollToTop(),this.regions().forEach(e=>{typeof e.scrollTo==`function`?e.scrollTo(0,0):(e.scrollTop=0,e.scrollLeft=0)}),this.save(),this.scrollToAnchor()}static scrollToAnchor(){let e=sd?null:window.location.hash;e&&setTimeout(()=>{let t=document.getElementById(e.slice(1));t?t.scrollIntoView():this.scrollToTop()})}static restore(e){sd||window.requestAnimationFrame(()=>{this.restoreDocument(),this.restoreScrollRegions(e)})}static restoreScrollRegions(e){sd||this.regions().forEach((t,n)=>{let r=e[n];r&&(typeof t.scrollTo==`function`?t.scrollTo(r.left,r.top):(t.scrollTop=r.top,t.scrollLeft=r.left))})}static restoreDocument(){let e=Q.getDocumentScrollPosition();window.scrollTo(e.left,e.top)}static onScroll(e){let t=e.target;typeof t.hasAttribute==`function`&&t.hasAttribute(`scroll-region`)&&this.save()}static onWindowScroll(){Q.saveDocumentScrollPosition({top:window.scrollY,left:window.scrollX})}},ud=e=>typeof File<`u`&&e instanceof File||e instanceof Blob||typeof FileList<`u`&&e instanceof FileList&&e.length>0;function dd(e){return ud(e)||e instanceof FormData&&Array.from(e.values()).some(e=>dd(e))||typeof e==`object`&&!!e&&Object.values(e).some(e=>dd(e))}var fd=e=>e instanceof FormData;function pd(e,t=new FormData,n=null,r=`brackets`){e||={};for(let i in e)Object.prototype.hasOwnProperty.call(e,i)&&hd(t,md(n,i,`indices`),e[i],r);return t}function md(e,t,n){return e?n===`brackets`?`${e}[]`:`${e}[${t}]`:t}function hd(e,t,n,r){if(Array.isArray(n))return Array.from(n.keys()).forEach(i=>hd(e,md(t,i.toString(),r),n[i],r));if(n instanceof Date)return e.append(t,n.toISOString());if(n instanceof File)return e.append(t,n,n.name);if(n instanceof Blob)return e.append(t,n);if(typeof n==`boolean`)return e.append(t,n?`1`:`0`);if(typeof n==`string`)return e.append(t,n);if(typeof n==`number`)return e.append(t,`${n}`);if(n==null)return e.append(t,``);pd(n,e,t,r)}function gd(e){return new URL(e.toString(),typeof window>`u`?void 0:window.location.toString())}var _d=(e,t,n,r,i)=>{let a=typeof e==`string`?gd(e):e;if((dd(t)||r)&&!fd(t)&&(wu.get(`form.forceIndicesArrayFormatInFormData`)&&(i=`indices`),t=pd(t,new FormData,null,i)),fd(t))return[a,t];let[o,s]=vd(n,a,t,i);return[gd(o),s]};function vd(e,t,n,r=`brackets`){let i=e===`get`&&!fd(n)&&Object.keys(n).length>0,a=wd(t.toString()),o=a||t.toString().startsWith(`/`)||t.toString()===``,s=!o&&!t.toString().startsWith(`#`)&&!t.toString().startsWith(`?`),c=/^[.]{1,2}([/]|$)/.test(t.toString()),l=t.toString().includes(`?`)||i,u=t.toString().includes(`#`),d=new URL(t.toString(),typeof window>`u`?`http://localhost`:window.location.toString());if(i){let e=/\[\d+\]/.test(decodeURIComponent(d.search));d.search=Cu.stringify({...Cu.parse(d.search,{ignoreQueryPrefix:!0,allowSparse:!0}),...n},{encodeValuesOnly:!0,arrayFormat:e?`indices`:r})}return[[a?`${d.protocol}//${d.host}`:``,o?d.pathname:``,s?d.pathname.substring(+!c):``,l?d.search:``,u?d.hash:``].join(``),i?{}:n]}function yd(e){return e=new URL(e.href),e.hash=``,e}var bd=(e,t)=>{e.hash&&!t.hash&&yd(e).href===t.href&&(t.hash=e.hash)},xd=(e,t)=>yd(e).href===yd(t).href,Sd=(e,t)=>e.origin===t.origin&&e.pathname===t.pathname;function Cd(e){return typeof e==`object`&&!!e&&e!==void 0&&`url`in e&&`method`in e}function wd(e){return/^([a-z][a-z0-9+.-]*:)?\/\/[^/]/i.test(e)}function Td(e,t){let n=typeof e==`string`?gd(e):e;return t?`${n.protocol}//${n.host}${n.pathname}${n.search}${n.hash}`:`${n.pathname}${n.search}${n.hash}`}var Z=new class{constructor(){this.componentId={},this.listeners=[],this.isFirstPageLoad=!0,this.cleared=!1,this.pendingDeferredProps=null,this.historyQuotaExceeded=!1}init({initialPage:e,swapComponent:t,resolveComponent:n,onFlash:r}){return this.page={...e,flash:e.flash??{}},this.swapComponent=t,this.resolveComponent=n,this.onFlashCallback=r,jd.on(`historyQuotaExceeded`,()=>{this.historyQuotaExceeded=!0}),this}set(e,{replace:t=!1,preserveScroll:n=!1,preserveState:r=!1,viewTransition:i=!1}={}){Object.keys(e.deferredProps||{}).length&&(this.pendingDeferredProps={deferredProps:e.deferredProps,component:e.component,url:e.url},e.initialDeferredProps===void 0&&(e.initialDeferredProps=e.deferredProps)),this.componentId={};let a=this.componentId;return e.clearHistory&&Q.clear(),this.resolve(e.component).then(o=>{if(a!==this.componentId)return;e.rememberedState??={};let s=typeof window>`u`,c=s?new URL(e.url):window.location,l=!s&&n?ld.getScrollRegions():[];t||=xd(gd(e.url),c);let u={...e,flash:{}};return new Promise(e=>t?Q.replaceState(u,e):Q.pushState(u,e)).then(()=>{let a=!this.isTheSame(e);if(!a&&Object.keys(e.props.errors||{}).length>0&&(i=!1),this.page=e,this.cleared=!1,this.hasOnceProps()&&td.updateCachedOncePropsFromCurrentPage(),a&&this.fireEventsFor(`newComponent`),this.isFirstPageLoad&&this.fireEventsFor(`firstLoad`),this.isFirstPageLoad=!1,this.historyQuotaExceeded){this.historyQuotaExceeded=!1;return}return this.swap({component:o,page:e,preserveState:r,viewTransition:i}).then(()=>{n?window.requestAnimationFrame(()=>ld.restoreScrollRegions(l)):ld.reset(),this.pendingDeferredProps&&this.pendingDeferredProps.component===e.component&&this.pendingDeferredProps.url===e.url&&jd.fireInternalEvent(`loadDeferredProps`,this.pendingDeferredProps.deferredProps),this.pendingDeferredProps=null,t||Nu(e)})})})}setQuietly(e,{preserveState:t=!1}={}){return this.resolve(e.component).then(n=>(this.page=e,this.cleared=!1,Q.setCurrent(e),this.swap({component:n,page:e,preserveState:t,viewTransition:!1})))}clear(){this.cleared=!0}isCleared(){return this.cleared}get(){return this.page}getWithoutFlashData(){return{...this.page,flash:{}}}hasOnceProps(){return Object.keys(this.page.onceProps??{}).length>0}merge(e){this.page={...this.page,...e}}setFlash(e){this.page={...this.page,flash:e},this.onFlashCallback?.(e)}setUrlHash(e){this.page.url.includes(e)||(this.page.url+=e)}remember(e){this.page.rememberedState=e}swap({component:e,page:t,preserveState:n,viewTransition:r}){let i=()=>this.swapComponent({component:e,page:t,preserveState:n});if(!r||!document?.startViewTransition||document.visibilityState===`hidden`)return i();let a=typeof r==`boolean`?()=>null:r;return new Promise(e=>{a(document.startViewTransition(()=>i().then(e)))})}resolve(e){return Promise.resolve(this.resolveComponent(e))}isTheSame(e){return this.page.component===e.component}on(e,t){return this.listeners.push({event:e,callback:t}),()=>{this.listeners=this.listeners.filter(n=>n.event!==e&&n.callback!==t)}}fireEventsFor(e){this.listeners.filter(t=>t.event===e).forEach(e=>e.callback())}mergeOncePropsIntoResponse(e,{force:t=!1}={}){Object.entries(e.onceProps??{}).forEach(([n,r])=>{let i=this.page.onceProps?.[n];i!==void 0&&(t||e.props[r.prop]===void 0)&&(e.props[r.prop]=this.page.props[i.prop],e.onceProps[n].expiresAt=i.expiresAt)})}},Ed=class{constructor(){this.items=[],this.processingPromise=null}add(e){return this.items.push(e),this.process()}process(){return this.processingPromise??=this.processNext().finally(()=>{this.processingPromise=null}),this.processingPromise}processNext(){let e=this.items.shift();return e?Promise.resolve(e()).then(()=>this.processNext()):Promise.resolve()}},Dd=typeof window>`u`,Od=new Ed,kd=!Dd&&/CriOS/.test(window.navigator.userAgent),Ad=class{constructor(){this.rememberedState=`rememberedState`,this.scrollRegions=`scrollRegions`,this.preserveUrl=!1,this.current={},this.initialState=null}remember(e,t){this.replaceState({...Z.getWithoutFlashData(),rememberedState:{...Z.get()?.rememberedState??{},[t]:e}})}restore(e){if(!Dd)return this.current[this.rememberedState]?.[e]===void 0?this.initialState?.[this.rememberedState]?.[e]:this.current[this.rememberedState]?.[e]}pushState(e,t=null){if(!Dd){if(this.preserveUrl){t&&t();return}this.current=e,Od.add(()=>this.getPageData(e).then(n=>{let r=()=>this.doPushState({page:n},e.url).then(()=>t?.());return kd?new Promise(e=>{setTimeout(()=>r().then(e))}):r()}))}}clonePageProps(e){try{return structuredClone(e.props),e}catch{return{...e,props:wc(e.props)}}}getPageData(e){let t=this.clonePageProps(e);return new Promise(n=>e.encryptHistory?Vu(t).then(n):n(t))}processQueue(){return Od.process()}decrypt(e=null){if(Dd)return Promise.resolve(e??Z.get());let t=e??window.history.state?.page;return this.decryptPageData(t).then(e=>{if(!e)throw Error(`Unable to decrypt history`);return this.initialState===null?this.initialState=e??void 0:this.current=e??{},e})}decryptPageData(e){return e instanceof ArrayBuffer?Uu(e):Promise.resolve(e)}saveScrollPositions(e){Od.add(()=>Promise.resolve().then(()=>{if(window.history.state?.page&&!Ol(this.getScrollRegions(),e))return this.doReplaceState({page:window.history.state.page,scrollRegions:e})}))}saveDocumentScrollPosition(e){Od.add(()=>Promise.resolve().then(()=>{if(window.history.state?.page&&!Ol(this.getDocumentScrollPosition(),e))return this.doReplaceState({page:window.history.state.page,documentScrollPosition:e})}))}getScrollRegions(){return window.history.state?.scrollRegions||[]}getDocumentScrollPosition(){return window.history.state?.documentScrollPosition||{top:0,left:0}}replaceState(e,t=null){if(Ol(this.current,e)){t&&t();return}let{flash:n,...r}=e;if(Z.merge(r),!Dd){if(this.preserveUrl){t&&t();return}this.current=e,Od.add(()=>this.getPageData(e).then(n=>{let r=()=>this.doReplaceState({page:n},e.url).then(()=>t?.());return kd?new Promise(e=>{setTimeout(()=>r().then(e))}):r()}))}}isHistoryThrottleError(e){return e instanceof Error&&e.name===`SecurityError`&&(e.message.includes(`history.pushState`)||e.message.includes(`history.replaceState`))}isQuotaExceededError(e){return e instanceof Error&&e.name===`QuotaExceededError`}withThrottleProtection(e){return Promise.resolve().then(()=>{try{return e()}catch(e){if(!this.isHistoryThrottleError(e))throw e;console.error(e.message)}})}doReplaceState(e,t){return this.withThrottleProtection(()=>{window.history.replaceState({...e,scrollRegions:e.scrollRegions??window.history.state?.scrollRegions,documentScrollPosition:e.documentScrollPosition??window.history.state?.documentScrollPosition},``,t)})}doPushState(e,t){return this.withThrottleProtection(()=>{try{window.history.pushState(e,``,t)}catch(e){if(!this.isQuotaExceededError(e))throw e;jd.fireInternalEvent(`historyQuotaExceeded`,t)}})}getState(e,t){return this.current?.[e]??t}deleteState(e){this.current[e]!==void 0&&(delete this.current[e],this.replaceState(this.current))}clearInitialState(e){this.initialState&&this.initialState[e]!==void 0&&delete this.initialState[e]}browserHasHistoryEntry(){return!Dd&&!!window.history.state?.page}clear(){Bu.remove(Hu.key),Bu.remove(Hu.iv)}setCurrent(e){this.current=e}isValidState(e){return!!e.page}getAllState(){return this.current}};typeof window<`u`&&window.history.scrollRestoration&&(window.history.scrollRestoration=`manual`);var Q=new Ad,jd=new class{constructor(){this.internalListeners=[]}init(){typeof window<`u`&&(window.addEventListener(`popstate`,this.handlePopstateEvent.bind(this)),window.addEventListener(`pageshow`,this.handlePageshowEvent.bind(this)),window.addEventListener(`scroll`,Tu(ld.onWindowScroll.bind(ld),100),!0)),typeof document<`u`&&document.addEventListener(`scroll`,Tu(ld.onScroll.bind(ld),100),!0)}onGlobalEvent(e,t){return this.registerListener(`inertia:${e}`,(e=>{let n=t(e);e.cancelable&&!e.defaultPrevented&&n===!1&&e.preventDefault()}))}on(e,t){return this.internalListeners.push({event:e,listener:t}),()=>{this.internalListeners=this.internalListeners.filter(e=>e.listener!==t)}}onMissingHistoryItem(){Z.clear(),this.fireInternalEvent(`missingHistoryItem`)}fireInternalEvent(e,...t){this.internalListeners.filter(t=>t.event===e).forEach(e=>e.listener(...t))}registerListener(e,t){return document.addEventListener(e,t),()=>document.removeEventListener(e,t)}handlePageshowEvent(e){e.persisted&&Q.decrypt().catch(()=>this.onMissingHistoryItem())}handlePopstateEvent(e){let t=e.state||null;if(t===null){let e=gd(Z.get().url);e.hash=window.location.hash,Q.replaceState({...Z.getWithoutFlashData(),url:e.href}),ld.reset();return}if(!Q.isValidState(t))return this.onMissingHistoryItem();Q.decrypt(t.page).then(e=>{if(Z.get().version!==e.version){this.onMissingHistoryItem();return}Xf.cancelAll({prefetch:!1}),Z.setQuietly(e,{preserveState:!1}).then(()=>{ld.restore(Q.getScrollRegions()),Nu(Z.get());let t={},n=Z.get().props;for(let[r,i]of Object.entries(e.initialDeferredProps??e.deferredProps??{})){let e=i.filter(e=>n[e]===void 0);e.length>0&&(t[r]=e)}Object.keys(t).length>0&&this.fireInternalEvent(`loadDeferredProps`,t)})}).catch(()=>{this.onMissingHistoryItem()})}},Md=new class{constructor(){this.type=this.resolveType()}resolveType(){return typeof window>`u`?`navigate`:window.performance&&window.performance.getEntriesByType&&window.performance.getEntriesByType(`navigation`).length>0?window.performance.getEntriesByType(`navigation`)[0].type:`navigate`}get(){return this.type}isBackForward(){return this.type===`back_forward`}isReload(){return this.type===`reload`}},Nd=class{static handle(){this.clearRememberedStateOnReload(),[this.handleBackForward,this.handleLocation,this.handleDefault].find(e=>e.bind(this)())}static clearRememberedStateOnReload(){Md.isReload()&&(Q.deleteState(Q.rememberedState),Q.clearInitialState(Q.rememberedState))}static handleBackForward(){if(!Md.isBackForward()||!Q.browserHasHistoryEntry())return!1;let e=Q.getScrollRegions();return Q.decrypt().then(t=>{Z.set(t,{preserveScroll:!0,preserveState:!0}).then(()=>{ld.restore(e),Nu(Z.get())})}).catch(()=>{jd.onMissingHistoryItem()}),!0}static handleLocation(){if(!Bu.exists(Bu.locationVisitKey))return!1;let e=Bu.get(Bu.locationVisitKey)||{};return Bu.remove(Bu.locationVisitKey),typeof window<`u`&&Z.setUrlHash(window.location.hash),Q.decrypt(Z.get()).then(()=>{let t=Q.getState(Q.rememberedState,{}),n=Q.getScrollRegions();Z.remember(t),Z.set(Z.get(),{preserveScroll:e.preserveScroll,preserveState:!0}).then(()=>{e.preserveScroll&&ld.restore(n),Nu(Z.get())})}).catch(()=>{jd.onMissingHistoryItem()}),!0}static handleDefault(){typeof window<`u`&&Z.setUrlHash(window.location.hash),Z.set(Z.get(),{preserveScroll:!0,preserveState:!0}).then(()=>{Md.isReload()?ld.restore(Q.getScrollRegions()):ld.scrollToAnchor();let e=Z.get();Nu(e);let t=e.flash;Object.keys(t).length>0&&queueMicrotask(()=>zu(t))})}},Pd=class{constructor(e,t,n){this.id=null,this.throttle=!1,this.keepAlive=!1,this.cbCount=0,this.keepAlive=n.keepAlive??!1,this.cb=t,this.interval=e,(n.autoStart??!0)&&this.start()}stop(){this.id&&clearInterval(this.id)}start(){typeof window>`u`||(this.stop(),this.id=window.setInterval(()=>{(!this.throttle||this.cbCount%10==0)&&this.cb(),this.throttle&&this.cbCount++},this.interval))}isInBackground(e){this.throttle=this.keepAlive?!1:e,this.throttle&&(this.cbCount=0)}},Fd=new class{constructor(){this.polls=[],this.setupVisibilityListener()}add(e,t,n){let r=new Pd(e,t,n);return this.polls.push(r),{stop:()=>r.stop(),start:()=>r.start()}}clear(){this.polls.forEach(e=>e.stop()),this.polls=[]}setupVisibilityListener(){typeof document>`u`||document.addEventListener(`visibilitychange`,()=>{this.polls.forEach(e=>e.isInBackground(document.hidden))},!1)}},Id=class e{constructor(e){if(this.callbacks=[],!e.prefetch)this.params=e;else{let t={onBefore:this.wrapCallback(e,`onBefore`),onBeforeUpdate:this.wrapCallback(e,`onBeforeUpdate`),onStart:this.wrapCallback(e,`onStart`),onProgress:this.wrapCallback(e,`onProgress`),onFinish:this.wrapCallback(e,`onFinish`),onCancel:this.wrapCallback(e,`onCancel`),onSuccess:this.wrapCallback(e,`onSuccess`),onError:this.wrapCallback(e,`onError`),onFlash:this.wrapCallback(e,`onFlash`),onCancelToken:this.wrapCallback(e,`onCancelToken`),onPrefetched:this.wrapCallback(e,`onPrefetched`),onPrefetching:this.wrapCallback(e,`onPrefetching`)};this.params={...e,...t,onPrefetchResponse:e.onPrefetchResponse||(()=>{}),onPrefetchError:e.onPrefetchError||(()=>{})}}}static create(t){return new e(t)}data(){return this.params.method===`get`?null:this.params.data}queryParams(){return this.params.method===`get`?this.params.data:{}}isPartial(){return this.params.only.length>0||this.params.except.length>0||this.params.reset.length>0}isPrefetch(){return this.params.prefetch===!0}isDeferredPropsRequest(){return this.params.deferredProps===!0}onCancelToken(e){this.params.onCancelToken({cancel:e})}markAsFinished(){this.params.completed=!0,this.params.cancelled=!1,this.params.interrupted=!1}markAsCancelled({cancelled:e=!0,interrupted:t=!1}){this.params.onCancel(),this.params.completed=!1,this.params.cancelled=e,this.params.interrupted=t}wasCancelledAtAll(){return this.params.cancelled||this.params.interrupted}onFinish(){this.params.onFinish(this.params)}onStart(){this.params.onStart(this.params)}onPrefetching(){this.params.onPrefetching(this.params)}onPrefetchResponse(e){this.params.onPrefetchResponse&&this.params.onPrefetchResponse(e)}onPrefetchError(e){this.params.onPrefetchError&&this.params.onPrefetchError(e)}all(){return this.params}headers(){let e={...this.params.headers};this.isPartial()&&(e[`X-Inertia-Partial-Component`]=Z.get().component);let t=this.params.only.concat(this.params.reset);return t.length>0&&(e[`X-Inertia-Partial-Data`]=t.join(`,`)),this.params.except.length>0&&(e[`X-Inertia-Partial-Except`]=this.params.except.join(`,`)),this.params.reset.length>0&&(e[`X-Inertia-Reset`]=this.params.reset.join(`,`)),this.params.errorBag&&this.params.errorBag.length>0&&(e[`X-Inertia-Error-Bag`]=this.params.errorBag),e}setPreserveOptions(t){this.params.preserveScroll=e.resolvePreserveOption(this.params.preserveScroll,t),this.params.preserveState=e.resolvePreserveOption(this.params.preserveState,t)}runCallbacks(){this.callbacks.forEach(({name:e,args:t})=>{this.params[e](...t)})}merge(e){this.params={...this.params,...e}}wrapCallback(e,t){return(...n)=>{this.recordCallback(t,n),e[t](...n)}}recordCallback(e,t){this.callbacks.push({name:e,args:t})}static resolvePreserveOption(e,t){return typeof e==`function`?e(t):e===`errors`?Object.keys(t.props.errors||{}).length>0:e}},Ld={modal:null,listener:null,createIframeAndPage(e){typeof e==`object`&&(e=`All Inertia requests must receive a valid Inertia response, however a plain JSON response was received.
${JSON.stringify(e)}`);let t=document.createElement(`html`);t.innerHTML=e,t.querySelectorAll(`a`).forEach(e=>e.setAttribute(`target`,`_top`));let n=document.createElement(`iframe`);return n.style.backgroundColor=`white`,n.style.borderRadius=`5px`,n.style.width=`100%`,n.style.height=`100%`,n.setAttribute(`sandbox`,`allow-scripts`),{iframe:n,page:t}},show(e){let{iframe:t,page:n}=this.createIframeAndPage(e);this.modal=document.createElement(`div`),this.modal.style.position=`fixed`,this.modal.style.width=`100vw`,this.modal.style.height=`100vh`,this.modal.style.padding=`50px`,this.modal.style.boxSizing=`border-box`,this.modal.style.backgroundColor=`rgba(0, 0, 0, .6)`,this.modal.style.zIndex=2e5,this.modal.addEventListener(`click`,()=>this.hide()),this.modal.appendChild(t),document.body.prepend(this.modal),document.body.style.overflow=`hidden`,t.srcdoc=n.outerHTML,this.listener=this.hideOnEscape.bind(this),document.addEventListener(`keydown`,this.listener)},hide(){this.modal.outerHTML=``,this.modal=null,document.body.style.overflow=`visible`,document.removeEventListener(`keydown`,this.listener)},hideOnEscape(e){e.keyCode===27&&this.hide()}},Rd={show(e){let{iframe:t,page:n}=Ld.createIframeAndPage(e);t.style.boxSizing=`border-box`,t.style.display=`block`;let r=document.createElement(`dialog`);r.id=`inertia-error-dialog`,Object.assign(r.style,{width:`calc(100vw - 100px)`,height:`calc(100vh - 100px)`,padding:`0`,margin:`auto`,border:`none`,backgroundColor:`transparent`});let i=document.createElement(`style`);i.textContent=` + dialog#inertia-error-dialog::backdrop { + background-color: rgba(0, 0, 0, 0.6); + } + + dialog#inertia-error-dialog:focus { + outline: none; + } + `,document.head.appendChild(i),r.addEventListener(`click`,e=>{e.target===r&&r.close()}),r.addEventListener(`close`,()=>{i.remove(),r.remove()}),r.appendChild(t),document.body.prepend(r),r.showModal(),r.focus(),t.srcdoc=n.outerHTML}},zd=new Ed,Bd=class e{constructor(e,t,n){this.requestParams=e,this.response=t,this.originatingPage=n,this.wasPrefetched=!1}static create(t,n,r){return new e(t,n,r)}async handlePrefetch(){xd(this.requestParams.all().url,window.location)&&this.handle()}async handle(){return zd.add(()=>this.process())}async process(){if(this.requestParams.all().prefetch)return this.wasPrefetched=!0,this.requestParams.all().prefetch=!1,this.requestParams.all().onPrefetched(this.response,this.requestParams.all()),Lu(this.response,this.requestParams.all()),Promise.resolve();if(this.requestParams.runCallbacks(),!this.isInertiaResponse())return this.handleNonInertiaResponse();await Q.processQueue(),Q.preserveUrl=this.requestParams.all().preserveUrl,await this.setPage();let e=Z.get().props.errors||{};if(Object.keys(e).length>0){let t=this.getScopedErrors(e);return Ou(t),this.requestParams.all().onError(t)}Xf.flushByCacheTags(this.requestParams.all().invalidateCacheTags||[]),this.wasPrefetched||Xf.flush(Z.get().url);let{flash:t}=Z.get();Object.keys(t).length>0&&!this.requestParams.isDeferredPropsRequest()&&(zu(t),this.requestParams.all().onFlash(t)),Iu(Z.get()),await this.requestParams.all().onSuccess(Z.get()),Q.preserveUrl=!1}mergeParams(e){this.requestParams.merge(e)}getPageResponse(){let e=this.getDataFromResponse(this.response.data);return typeof e==`object`?this.response.data={...e,flash:e.flash??{}}:this.response.data=e}async handleNonInertiaResponse(){if(this.isLocationVisit()){let e=gd(this.getHeader(`x-inertia-location`));return bd(this.requestParams.all().url,e),this.locationVisit(e)}let e={...this.response,data:this.getDataFromResponse(this.response.data)};if(ju(e))return wu.get(`future.useDialogForErrorModal`)?Rd.show(e.data):Ld.show(e.data)}isInertiaResponse(){return this.hasHeader(`x-inertia`)}hasStatus(e){return this.response.status===e}getHeader(e){return this.response.headers[e]}hasHeader(e){return this.getHeader(e)!==void 0}isLocationVisit(){return this.hasStatus(409)&&this.hasHeader(`x-inertia-location`)}locationVisit(e){try{if(Bu.set(Bu.locationVisitKey,{preserveScroll:this.requestParams.all().preserveScroll===!0}),typeof window>`u`)return;xd(window.location,e)?window.location.reload():window.location.href=e.href}catch{return!1}}async setPage(){let e=this.getPageResponse();return this.shouldSetPage(e)?(this.mergeProps(e),Z.mergeOncePropsIntoResponse(e),this.preserveEqualProps(e),await this.setRememberedState(e),this.requestParams.setPreserveOptions(e),e.url=Q.preserveUrl?Z.get().url:this.pageUrl(e),this.requestParams.all().onBeforeUpdate(e),Mu(e),Z.set(e,{replace:this.requestParams.all().replace,preserveScroll:this.requestParams.all().preserveScroll,preserveState:this.requestParams.all().preserveState,viewTransition:this.requestParams.all().viewTransition})):Promise.resolve()}getDataFromResponse(e){if(typeof e!=`string`)return e;try{return JSON.parse(e)}catch{return e}}shouldSetPage(e){if(!this.requestParams.all().async||this.originatingPage.component!==e.component)return!0;if(this.originatingPage.component!==Z.get().component)return!1;let t=gd(this.originatingPage.url),n=gd(Z.get().url);return t.origin===n.origin&&t.pathname===n.pathname}pageUrl(e){let t=gd(e.url);return bd(this.requestParams.all().url,t),t.pathname+t.search+t.hash}preserveEqualProps(e){if(e.component!==Z.get().component||wu.get(`future.preserveEqualProps`)!==!0)return;let t=Z.get().props;Object.entries(e.props).forEach(([n,r])=>{Ol(r,t[n])&&(e.props[n]=t[n])})}mergeProps(e){if(!this.requestParams.isPartial()||e.component!==Z.get().component)return;let t=e.mergeProps||[],n=e.prependProps||[],r=e.deepMergeProps||[],i=e.matchPropsOn||[],a=(t,n)=>{let r=co(Z.get().props,t),a=co(e.props,t);if(Array.isArray(a)){let o=this.mergeOrMatchItems(r||[],a,t,i,n);jl(e.props,t,o)}else if(typeof a==`object`&&a){let n={...r||{},...a};jl(e.props,t,n)}};if(t.forEach(e=>a(e,!0)),n.forEach(e=>a(e,!1)),r.forEach(t=>{let n=Z.get().props[t],r=e.props[t],a=(e,t,n)=>Array.isArray(t)?this.mergeOrMatchItems(e,t,n,i):typeof t==`object`&&t?Object.keys(t).reduce((r,i)=>(r[i]=a(e?e[i]:void 0,t[i],`${n}.${i}`),r),{...e}):t;e.props[t]=a(n,r,t)}),e.props={...Z.get().props,...e.props},this.requestParams.isDeferredPropsRequest()){let t=Z.get().props.errors;t&&Object.keys(t).length>0&&(e.props.errors=t)}Z.get().scrollProps&&(e.scrollProps={...Z.get().scrollProps||{},...e.scrollProps||{}}),Z.hasOnceProps()&&(e.onceProps={...Z.get().onceProps||{},...e.onceProps||{}}),this.requestParams.isDeferredPropsRequest()&&(e.flash={...Z.get().flash});let o=Z.get().initialDeferredProps;o&&Object.keys(o).length>0&&(e.initialDeferredProps=o)}mergeOrMatchItems(e,t,n,r,i=!0){let a=Array.isArray(e)?e:[],o=r.find(e=>e.split(`.`).slice(0,-1).join(`.`)===n);if(!o)return i?[...a,...t]:[...t,...a];let s=o.split(`.`).pop()||``,c=new Map;return t.forEach(e=>{this.hasUniqueProperty(e,s)&&c.set(e[s],e)}),i?this.appendWithMatching(a,t,c,s):this.prependWithMatching(a,t,c,s)}appendWithMatching(e,t,n,r){let i=e.map(e=>this.hasUniqueProperty(e,r)&&n.has(e[r])?n.get(e[r]):e),a=t.filter(t=>this.hasUniqueProperty(t,r)?!e.some(e=>this.hasUniqueProperty(e,r)&&e[r]===t[r]):!0);return[...i,...a]}prependWithMatching(e,t,n,r){let i=e.filter(e=>this.hasUniqueProperty(e,r)?!n.has(e[r]):!0);return[...t,...i]}hasUniqueProperty(e,t){return e&&typeof e==`object`&&t in e}async setRememberedState(e){let t=await Q.getState(Q.rememberedState,{});this.requestParams.all().preserveState&&t&&e.component===Z.get().component&&(e.rememberedState=t)}getScopedErrors(e){return this.requestParams.all().errorBag?e[this.requestParams.all().errorBag||``]||{}:e}},Vd=class e{constructor(e,t){this.page=t,this.requestHasFinished=!1,this.requestParams=Id.create(e),this.cancelToken=new AbortController}static create(t,n){return new e(t,n)}isPrefetch(){return this.requestParams.isPrefetch()}async send(){this.requestParams.onCancelToken(()=>this.cancel({cancelled:!0})),Fu(this.requestParams.all()),this.requestParams.onStart(),this.requestParams.all().prefetch&&(this.requestParams.onPrefetching(),Ru(this.requestParams.all()));let e=this.requestParams.all().prefetch;return U({method:this.requestParams.all().method,url:yd(this.requestParams.all().url).href,data:this.requestParams.data(),params:this.requestParams.queryParams(),signal:this.cancelToken.signal,headers:this.getHeaders(),onUploadProgress:this.onProgress.bind(this),responseType:`text`}).then(e=>(this.response=Bd.create(this.requestParams,e,this.page),this.response.handle())).catch(e=>e?.response?(this.response=Bd.create(this.requestParams,e.response,this.page),this.response.handle()):Promise.reject(e)).catch(t=>{if(!U.isCancel(t)&&ku(t))return e&&this.requestParams.onPrefetchError(t),Promise.reject(t)}).finally(()=>{this.finish(),e&&this.response&&this.requestParams.onPrefetchResponse(this.response)})}finish(){this.requestParams.wasCancelledAtAll()||(this.requestParams.markAsFinished(),this.fireFinishEvents())}fireFinishEvents(){this.requestHasFinished||(this.requestHasFinished=!0,Au(this.requestParams.all()),this.requestParams.onFinish())}cancel({cancelled:e=!1,interrupted:t=!1}){this.requestHasFinished||(this.cancelToken.abort(),this.requestParams.markAsCancelled({cancelled:e,interrupted:t}),this.fireFinishEvents())}onProgress(e){this.requestParams.data()instanceof FormData&&(e.percentage=e.progress?Math.round(e.progress*100):0,Pu(e),this.requestParams.all().onProgress(e))}getHeaders(){let e={...this.requestParams.headers(),Accept:`text/html, application/xhtml+xml`,"X-Requested-With":`XMLHttpRequest`,"X-Inertia":!0},t=Z.get();t.version&&(e[`X-Inertia-Version`]=t.version);let n=Object.entries(t.onceProps||{}).filter(([,e])=>t.props[e.prop]===void 0?!1:!e.expiresAt||e.expiresAt>Date.now()).map(([e])=>e);return n.length>0&&(e[`X-Inertia-Except-Once-Props`]=n.join(`,`)),e}},Hd=class{constructor({maxConcurrent:e,interruptible:t}){this.requests=[],this.maxConcurrent=e,this.interruptible=t}send(e){this.requests.push(e),e.send().finally(()=>{this.requests=this.requests.filter(t=>t!==e)})}interruptInFlight(){this.cancel({interrupted:!0},!1)}cancelInFlight({prefetch:e=!0}={}){this.requests.filter(t=>e||!t.isPrefetch()).forEach(e=>e.cancel({cancelled:!0}))}cancel({cancelled:e=!1,interrupted:t=!1}={},n=!1){!n&&!this.shouldCancel()||this.requests.shift()?.cancel({cancelled:e,interrupted:t})}shouldCancel(){return this.interruptible&&this.requests.length>=this.maxConcurrent}},Ud=class{constructor(){this.syncRequestStream=new Hd({maxConcurrent:1,interruptible:!0}),this.asyncRequestStream=new Hd({maxConcurrent:1/0,interruptible:!1}),this.clientVisitQueue=new Ed}init({initialPage:e,resolveComponent:t,swapComponent:n,onFlash:r}){Z.init({initialPage:e,resolveComponent:t,swapComponent:n,onFlash:r}),Nd.handle(),jd.init(),jd.on(`missingHistoryItem`,()=>{typeof window<`u`&&this.visit(window.location.href,{preserveState:!0,preserveScroll:!0,replace:!0})}),jd.on(`loadDeferredProps`,e=>{this.loadDeferredProps(e)}),jd.on(`historyQuotaExceeded`,e=>{window.location.href=e})}get(e,t={},n={}){return this.visit(e,{...n,method:`get`,data:t})}post(e,t={},n={}){return this.visit(e,{preserveState:!0,...n,method:`post`,data:t})}put(e,t={},n={}){return this.visit(e,{preserveState:!0,...n,method:`put`,data:t})}patch(e,t={},n={}){return this.visit(e,{preserveState:!0,...n,method:`patch`,data:t})}delete(e,t={}){return this.visit(e,{preserveState:!0,...t,method:`delete`})}reload(e={}){return this.doReload(e)}doReload(e={}){if(!(typeof window>`u`))return this.visit(window.location.href,{...e,preserveScroll:!0,preserveState:!0,async:!0,headers:{...e.headers||{},"Cache-Control":`no-cache`}})}remember(e,t=`default`){Q.remember(e,t)}restore(e=`default`){return Q.restore(e)}on(e,t){return typeof window>`u`?()=>{}:jd.onGlobalEvent(e,t)}cancel(){this.syncRequestStream.cancelInFlight()}cancelAll({async:e=!0,prefetch:t=!0,sync:n=!0}={}){e&&this.asyncRequestStream.cancelInFlight({prefetch:t}),n&&this.syncRequestStream.cancelInFlight()}poll(e,t={},n={}){return Fd.add(e,()=>this.reload(t),{autoStart:n.autoStart??!0,keepAlive:n.keepAlive??!1})}visit(e,t={}){let n=this.getPendingVisit(e,{...t,showProgress:t.showProgress??!t.async}),r=this.getVisitEvents(t);if(r.onBefore(n)===!1||!Du(n))return;let i=gd(Z.get().url);(n.only.length>0||n.except.length>0||n.reset.length>0?Sd(n.url,i):xd(n.url,i))||this.asyncRequestStream.cancelInFlight({prefetch:!1}),n.async||this.syncRequestStream.interruptInFlight(),!Z.isCleared()&&!n.preserveUrl&&ld.save();let a={...n,...r},o=td.get(a);o?(Lf.reveal(o.inFlight),td.use(o,a)):(Lf.reveal(!0),(n.async?this.asyncRequestStream:this.syncRequestStream).send(Vd.create(a,Z.get())))}getCached(e,t={}){return td.findCached(this.getPrefetchParams(e,t))}flush(e,t={}){td.remove(this.getPrefetchParams(e,t))}flushAll(){td.removeAll()}flushByCacheTags(e){td.removeByTags(Array.isArray(e)?e:[e])}getPrefetching(e,t={}){return td.findInFlight(this.getPrefetchParams(e,t))}prefetch(e,t={},n={}){if((t.method??(Cd(e)?e.method:`get`))!==`get`)throw Error(`Prefetch requests must use the GET method`);let r=this.getPendingVisit(e,{...t,async:!0,showProgress:!1,prefetch:!0,viewTransition:!1});if(r.url.origin+r.url.pathname+r.url.search===window.location.origin+window.location.pathname+window.location.search)return;let i=this.getVisitEvents(t);if(i.onBefore(r)===!1||!Du(r))return;Lf.hide(),this.asyncRequestStream.interruptInFlight();let a={...r,...i};new Promise(e=>{let t=()=>{Z.get()?e():setTimeout(t,50)};t()}).then(()=>{td.add(a,e=>{this.asyncRequestStream.send(Vd.create(e,Z.get()))},{cacheFor:wu.get(`prefetch.cacheFor`),cacheTags:[],...n})})}clearHistory(){Q.clear()}decryptHistory(){return Q.decrypt()}resolveComponent(e){return Z.resolve(e)}replace(e){this.clientVisit(e,{replace:!0})}replaceProp(e,t,n){this.replace({preserveScroll:!0,preserveState:!0,props(n){let r=typeof t==`function`?t(co(n,e),n):t;return jl(wc(n),e,r)},...n||{}})}appendToProp(e,t,n){this.replaceProp(e,(e,n)=>{let r=typeof t==`function`?t(e,n):t;return Array.isArray(e)||(e=e===void 0?[]:[e]),[...e,r]},n)}prependToProp(e,t,n){this.replaceProp(e,(e,n)=>{let r=typeof t==`function`?t(e,n):t;return Array.isArray(e)||(e=e===void 0?[]:[e]),[r,...e]},n)}push(e){this.clientVisit(e)}flash(e,t){let n=Z.get().flash,r;if(typeof e==`function`)r=e(n);else if(typeof e==`string`)r={...n,[e]:t};else if(e&&Object.keys(e).length)r={...n,...e};else return;Z.setFlash(r),Object.keys(r).length&&zu(r)}clientVisit(e,{replace:t=!1}={}){this.clientVisitQueue.add(()=>this.performClientVisit(e,{replace:t}))}performClientVisit(e,{replace:t=!1}={}){let n=Z.get(),r=typeof e.props==`function`?Object.fromEntries(Object.values(n.onceProps??{}).map(e=>[e.prop,n.props[e.prop]])):{},i=typeof e.props==`function`?e.props(n.props,r):e.props??n.props,a=typeof e.flash==`function`?e.flash(n.flash):e.flash,{viewTransition:o,onError:s,onFinish:c,onFlash:l,onSuccess:u,...d}=e,f={...n,...d,flash:a??{},props:i},p=Id.resolvePreserveOption(e.preserveScroll??!1,f),m=Id.resolvePreserveOption(e.preserveState??!1,f);return Z.set(f,{replace:t,preserveScroll:p,preserveState:m,viewTransition:o}).then(()=>{let t=Z.get().flash;Object.keys(t).length>0&&(zu(t),l?.(t));let n=Z.get().props.errors||{};if(Object.keys(n).length===0){u?.(Z.get());return}let r=e.errorBag?n[e.errorBag||``]||{}:n;s?.(r)}).finally(()=>c?.(e))}getPrefetchParams(e,t){return{...this.getPendingVisit(e,{...t,async:!0,showProgress:!1,prefetch:!0,viewTransition:!1}),...this.getVisitEvents(t)}}getPendingVisit(e,t,n={}){if(Cd(e)){let n=e;e=n.url,t.method=t.method??n.method}let r=wu.get(`visitOptions`),i=r&&r(e.toString(),wc(t))||{},a={method:`get`,data:{},replace:!1,preserveScroll:!1,preserveState:!1,only:[],except:[],headers:{},errorBag:``,forceFormData:!1,queryStringArrayFormat:`brackets`,async:!1,showProgress:!0,fresh:!1,reset:[],preserveUrl:!1,prefetch:!1,invalidateCacheTags:[],viewTransition:!1,...t,...i},[o,s]=_d(e,a.data,a.method,a.forceFormData,a.queryStringArrayFormat),c={cancelled:!1,completed:!1,interrupted:!1,...a,...n,url:o,data:s};return c.prefetch&&(c.headers.Purpose=`prefetch`),c}getVisitEvents(e){return{onCancelToken:e.onCancelToken||(()=>{}),onBefore:e.onBefore||(()=>{}),onBeforeUpdate:e.onBeforeUpdate||(()=>{}),onStart:e.onStart||(()=>{}),onProgress:e.onProgress||(()=>{}),onFinish:e.onFinish||(()=>{}),onCancel:e.onCancel||(()=>{}),onSuccess:e.onSuccess||(()=>{}),onError:e.onError||(()=>{}),onFlash:e.onFlash||(()=>{}),onPrefetched:e.onPrefetched||(()=>{}),onPrefetching:e.onPrefetching||(()=>{})}}loadDeferredProps(e){e&&Object.entries(e).forEach(([e,t])=>{this.doReload({only:t,deferredProps:!0})})}},Wd=class{static createWayfinderCallback(...e){return()=>e.length===1?Cd(e[0])?e[0]:e[0]():{method:typeof e[0]==`function`?e[0]():e[0],url:typeof e[1]==`function`?e[1]():e[1]}}static parseUseFormArguments(...e){return e.length===0?{rememberKey:null,data:{},precognitionEndpoint:null}:e.length===1?{rememberKey:null,data:e[0],precognitionEndpoint:null}:e.length===2?typeof e[0]==`string`?{rememberKey:e[0],data:e[1],precognitionEndpoint:null}:{rememberKey:null,data:e[1],precognitionEndpoint:this.createWayfinderCallback(e[0])}:{rememberKey:null,data:e[2],precognitionEndpoint:this.createWayfinderCallback(e[0],e[1])}}static parseSubmitArguments(e,t){return e.length===3||e.length===2&&typeof e[0]==`string`?{method:e[0],url:e[1],options:e[2]??{}}:Cd(e[0])?{...e[0],options:e[1]??{}}:{...t(),options:e[0]??{}}}static mergeHeadersForValidation(e,t,n){let r=e=>(e.headers={...n??{},...e.headers??{}},e);return e&&typeof e==`object`&&!(`target`in e)?e=r(e):t&&typeof t==`object`?t=r(t):typeof e==`string`?t=r(t??{}):e=r(e??{}),[e,t]}};function Gd(e){return e.includes(`.`)?e.replace(/\\\./g,`__ESCAPED_DOT__`).split(/(\[[^\]]*\])/).filter(Boolean).map(e=>e.startsWith(`[`)&&e.endsWith(`]`)?e:e.split(`.`).reduce((e,t,n)=>n===0?t:`${e}[${t}]`)).join(``).replace(/__ESCAPED_DOT__/g,`.`):e}function Kd(e){let t=[],n=/([^\[\]]+)|\[(\d*)\]/g,r;for(;(r=n.exec(e))!==null;)r[1]===void 0?r[2]!==void 0&&t.push(r[2]===``?``:Number(r[2])):t.push(r[1]);return t}function qd(e,t,n){let r=e;for(let e=0;e/^\d+$/.test(e)).map(Number).sort((e,t)=>e-t);return t.length===n.length&&n.length>0&&n[0]===0&&n.every((e,t)=>e===t)}function Yd(e){if(Array.isArray(e))return e.map(Yd);if(typeof e!=`object`||!e||ud(e))return e;if(Jd(e)){let t=[];for(let n=0;n/^\d+$/.test(e)).map(Number).sort((e,t)=>e-t);jl(t,n,e.length>0?[...e.map(e=>i[e]),r]:[r])}else jl(t,n,[r]);continue}qd(t,e.map(String),r)}return Yd(t)}var Zd={preferredAttribute(){return wu.get(`future.useDataInertiaHeadAttribute`)?`data-inertia`:`inertia`},buildDOMElement(e){let t=document.createElement(`template`);t.innerHTML=e;let n=t.content.firstChild;if(!e.startsWith(` + + + + + + + + + + + + + + + + + + + + MENU + navbar-image + + +
+ +
+ + +
+ + + +
+ + + + +
+ + + + +
+ +
+
+
+

Introduction

+ +
This documentation aims to provide all the information you need to work with our API.
+
+<aside>As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile).
+You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).</aside>
+ +

Authenticating requests

+

This API is not authenticated.

+ +

Authentication

+ +

APIs for managing authentication

+ +

Login

+ +

+

+ +

Authenticate a user and return a Sanctum token.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "http://localhost/api/v1/auth/login" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"email\": \"gbailey@example.net\",
+    \"password\": \"architecto\"
+}"
+
+ + +
+
const url = new URL(
+    "http://localhost/api/v1/auth/login"
+);
+
+const headers = {
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "email": "gbailey@example.net",
+    "password": "architecto"
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + + + + +
+

+ Request    + +    + +

+

+ POST + api/v1/auth/login +

+

Headers

+
+ Content-Type   +  +   +   + +
+

Example: application/json

+
+
+ Accept   +  +   +   + +
+

Example: application/json

+
+

Body Parameters

+
+ email   +string  +   +   + +
+

Must be a valid email address. Example: gbailey@example.net

+
+
+ password   +string  +   +   + +
+

Example: architecto

+
+
+ +

Logout

+ +

+

+ +

Revoke the current user's token.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "http://localhost/api/v1/auth/logout" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
const url = new URL(
+    "http://localhost/api/v1/auth/logout"
+);
+
+const headers = {
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+
+fetch(url, {
+    method: "POST",
+    headers,
+}).then(response => response.json());
+ +
+ + + + + +
+

+ Request    + +    + +

+

+ POST + api/v1/auth/logout +

+

Headers

+
+ Content-Type   +  +   +   + +
+

Example: application/json

+
+
+ Accept   +  +   +   + +
+

Example: application/json

+
+
+ +

User Management

+ +

APIs for managing users

+ +

Create User

+ +

+

+ +

Create a new user with roles.

+ + +
Example request:
+ + +
+
curl --request POST \
+    "http://localhost/api/v1/users" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"firstName\": \"b\",
+    \"lastName\": \"n\",
+    \"email\": \"ashly64@example.com\",
+    \"password\": \"pBNvYg\",
+    \"status\": \"inactive\"
+}"
+
+ + +
+
const url = new URL(
+    "http://localhost/api/v1/users"
+);
+
+const headers = {
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "firstName": "b",
+    "lastName": "n",
+    "email": "ashly64@example.com",
+    "password": "pBNvYg",
+    "status": "inactive"
+};
+
+fetch(url, {
+    method: "POST",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + + + + +
+

+ Request    + +    + +

+

+ POST + api/v1/users +

+

Headers

+
+ Content-Type   +  +   +   + +
+

Example: application/json

+
+
+ Accept   +  +   +   + +
+

Example: application/json

+
+

Body Parameters

+
+ firstName   +string  +   +   + +
+

Must not be greater than 100 characters. Example: b

+
+
+ lastName   +string  +   +   + +
+

Must not be greater than 100 characters. Example: n

+
+
+ email   +string  +   +   + +
+

Must be a valid email address. Example: ashly64@example.com

+
+
+ password   +string  +   +   + +
+

Must be at least 8 characters. Example: pBNvYg

+
+
+ status   +string  +optional   +   + +
+

Example: inactive

+Must be one of: +
  • active
  • inactive
  • suspended
+
+
+ roles   +object  +optional   +   + +
+ +
+
+ +

Update User

+ +

+

+ +

Update a user's details.

+ + +
Example request:
+ + +
+
curl --request PUT \
+    "http://localhost/api/v1/users/16" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json" \
+    --data "{
+    \"firstName\": \"b\",
+    \"lastName\": \"n\",
+    \"status\": \"inactive\"
+}"
+
+ + +
+
const url = new URL(
+    "http://localhost/api/v1/users/16"
+);
+
+const headers = {
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+let body = {
+    "firstName": "b",
+    "lastName": "n",
+    "status": "inactive"
+};
+
+fetch(url, {
+    method: "PUT",
+    headers,
+    body: JSON.stringify(body),
+}).then(response => response.json());
+ +
+ + + + + +
+

+ Request    + +    + +

+

+ PUT + api/v1/users/{id} +

+

+ PATCH + api/v1/users/{id} +

+

Headers

+
+ Content-Type   +  +   +   + +
+

Example: application/json

+
+
+ Accept   +  +   +   + +
+

Example: application/json

+
+

URL Parameters

+
+ id   +integer  +   +   + +
+

The ID of the user. Example: 16

+
+

Body Parameters

+
+ firstName   +string  +optional   +   + +
+

Must not be greater than 100 characters. Example: b

+
+
+ lastName   +string  +optional   +   + +
+

Must not be greater than 100 characters. Example: n

+
+
+ email   +string  +optional   +   + +
+ +
+
+ status   +string  +optional   +   + +
+

Example: inactive

+Must be one of: +
  • active
  • inactive
  • suspended
+
+
+ +

Delete User

+ +

+

+ +

Soft delete a user.

+ + +
Example request:
+ + +
+
curl --request DELETE \
+    "http://localhost/api/v1/users/16" \
+    --header "Content-Type: application/json" \
+    --header "Accept: application/json"
+ + +
+
const url = new URL(
+    "http://localhost/api/v1/users/16"
+);
+
+const headers = {
+    "Content-Type": "application/json",
+    "Accept": "application/json",
+};
+
+
+fetch(url, {
+    method: "DELETE",
+    headers,
+}).then(response => response.json());
+ +
+ + + + + +
+

+ Request    + +    + +

+

+ DELETE + api/v1/users/{id} +

+

Headers

+
+ Content-Type   +  +   +   + +
+

Example: application/json

+
+
+ Accept   +  +   +   + +
+

Example: application/json

+
+

URL Parameters

+
+ id   +integer  +   +   + +
+

The ID of the user. Example: 16

+
+
+ + + + +
+
+
+ + +
+
+
+ + diff --git a/resources/views/vendor/mail/html/button.blade.php b/resources/views/vendor/mail/html/button.blade.php new file mode 100644 index 0000000..050e969 --- /dev/null +++ b/resources/views/vendor/mail/html/button.blade.php @@ -0,0 +1,24 @@ +@props([ + 'url', + 'color' => 'primary', + 'align' => 'center', +]) + + + + + diff --git a/resources/views/vendor/mail/html/footer.blade.php b/resources/views/vendor/mail/html/footer.blade.php new file mode 100644 index 0000000..024fef4 --- /dev/null +++ b/resources/views/vendor/mail/html/footer.blade.php @@ -0,0 +1,18 @@ +@php + $settings = \Illuminate\Support\Facades\Cache::get('system_settings', []); + $appName = $settings['app_name'] ?? config('app.name'); +@endphp + + + + + + + + + diff --git a/resources/views/vendor/mail/html/header.blade.php b/resources/views/vendor/mail/html/header.blade.php new file mode 100644 index 0000000..140dd0e --- /dev/null +++ b/resources/views/vendor/mail/html/header.blade.php @@ -0,0 +1,20 @@ +@props(['url']) +@php + $settings = \Illuminate\Support\Facades\Cache::get('system_settings', []); + $appName = $settings['app_name'] ?? config('app.name'); + $appLogo = $settings['app_logo'] ?? null; + $appLogoText = $settings['app_logo_text'] ?? substr($appName, 0, 1); +@endphp + + + +@if ($appLogo) + +
+@endif + + {{ $appName }} + +
+ + diff --git a/resources/views/vendor/mail/html/layout.blade.php b/resources/views/vendor/mail/html/layout.blade.php new file mode 100644 index 0000000..037efe3 --- /dev/null +++ b/resources/views/vendor/mail/html/layout.blade.php @@ -0,0 +1,58 @@ + + + +{{ config('app.name') }} + + + + + +{!! $head ?? '' !!} + + + + + + + + + + diff --git a/resources/views/vendor/mail/html/message.blade.php b/resources/views/vendor/mail/html/message.blade.php new file mode 100644 index 0000000..a16bace --- /dev/null +++ b/resources/views/vendor/mail/html/message.blade.php @@ -0,0 +1,27 @@ + +{{-- Header --}} + + +{{ config('app.name') }} + + + +{{-- Body --}} +{!! $slot !!} + +{{-- Subcopy --}} +@isset($subcopy) + + +{!! $subcopy !!} + + +@endisset + +{{-- Footer --}} + + +© {{ date('Y') }} {{ config('app.name') }}. {{ __('All rights reserved.') }} + + + diff --git a/resources/views/vendor/mail/html/panel.blade.php b/resources/views/vendor/mail/html/panel.blade.php new file mode 100644 index 0000000..2975a60 --- /dev/null +++ b/resources/views/vendor/mail/html/panel.blade.php @@ -0,0 +1,14 @@ + + + + + + diff --git a/resources/views/vendor/mail/html/subcopy.blade.php b/resources/views/vendor/mail/html/subcopy.blade.php new file mode 100644 index 0000000..790ce6c --- /dev/null +++ b/resources/views/vendor/mail/html/subcopy.blade.php @@ -0,0 +1,7 @@ + + + + + diff --git a/resources/views/vendor/mail/html/table.blade.php b/resources/views/vendor/mail/html/table.blade.php new file mode 100644 index 0000000..a5f3348 --- /dev/null +++ b/resources/views/vendor/mail/html/table.blade.php @@ -0,0 +1,3 @@ +
+{{ Illuminate\Mail\Markdown::parse($slot) }} +
diff --git a/resources/views/vendor/mail/html/themes/default.css b/resources/views/vendor/mail/html/themes/default.css new file mode 100644 index 0000000..5f2e856 --- /dev/null +++ b/resources/views/vendor/mail/html/themes/default.css @@ -0,0 +1,161 @@ +/* resources/views/vendor/mail/html/themes/default.css */ +body, +body *:not(html):not(style):not(br):not(tr):not(code) { + box-sizing: border-box; + font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; + position: relative; +} + +body { + -webkit-text-size-adjust: none; + background-color: #E3EBE8; + color: #3D4E4B; + height: 100%; + line-height: 1.6; + margin: 0; + padding: 0; + width: 100% !important; +} + +p, ul, ol, blockquote { + line-height: 1.6; + text-align: start; +} + +a { + color: #D4A017; + text-decoration: none; + font-weight: bold; +} + +h1 { + color: #3D4E4B; + font-size: 22px; + font-weight: 800; + margin-top: 0; + text-align: start; + text-transform: uppercase; + letter-spacing: -0.02em; +} + +h2 { + font-size: 18px; + font-weight: 800; + margin-top: 0; + text-align: start; + color: #3D4E4B; +} + +p { + font-size: 15px; + line-height: 1.6em; + margin-top: 0; + text-align: left; + color: #4A5568; +} + +.wrapper { + background-color: #E3EBE8; + margin: 0; + padding: 0; + width: 100%; +} + +.header { + padding: 40px 0; + text-align: center; +} + +.header a { + color: #3D4E4B; + font-size: 20px; + font-weight: 900; + text-decoration: none; + text-transform: uppercase; + letter-spacing: 0.2em; +} + +.logo { + height: 64px; + margin-bottom: 15px; + max-height: 64px; + border-radius: 16px; +} + +.body { + background-color: #E3EBE8; + border-bottom: 0; + border-top: 0; + margin: 0; + padding: 0; + width: 100%; +} + +.inner-body { + background-color: #ffffff; + border-color: #E3EBE8; + border-radius: 32px; + border-width: 1px; + box-shadow: 0 10px 40px rgba(61, 78, 75, 0.05); + margin: 0 auto; + padding: 0; + width: 570px; +} + +.content-cell { + padding: 48px; +} + +.footer { + margin: 0 auto; + padding: 32px 0; + text-align: center; + width: 570px; +} + +.footer p { + color: #3D4E4B; + opacity: 0.4; + font-size: 11px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.1em; + text-align: center; +} + +.button { + border-radius: 16px; + color: #fff; + display: inline-block; + overflow: hidden; + text-decoration: none; + font-weight: 800; + text-transform: uppercase; + letter-spacing: 0.1em; + font-size: 12px; +} + +.button-primary { + background-color: #3D4E4B; + border-bottom: 12px solid #3D4E4B; + border-left: 32px solid #3D4E4B; + border-right: 32px solid #3D4E4B; + border-top: 12px solid #3D4E4B; +} + +.panel { + border-left: #D4A017 solid 4px; + margin: 24px 0; + background-color: #F7FAFA; + border-radius: 0 12px 12px 0; +} + +.panel-content { + padding: 16px; +} + +.subcopy { + border-top: 1px solid #E3EBE8; + margin-top: 32px; + padding-top: 24px; +} diff --git a/resources/views/vendor/mail/text/button.blade.php b/resources/views/vendor/mail/text/button.blade.php new file mode 100644 index 0000000..97444eb --- /dev/null +++ b/resources/views/vendor/mail/text/button.blade.php @@ -0,0 +1 @@ +{{ $slot }}: {{ $url }} diff --git a/resources/views/vendor/mail/text/footer.blade.php b/resources/views/vendor/mail/text/footer.blade.php new file mode 100644 index 0000000..3338f62 --- /dev/null +++ b/resources/views/vendor/mail/text/footer.blade.php @@ -0,0 +1 @@ +{{ $slot }} diff --git a/resources/views/vendor/mail/text/header.blade.php b/resources/views/vendor/mail/text/header.blade.php new file mode 100644 index 0000000..97444eb --- /dev/null +++ b/resources/views/vendor/mail/text/header.blade.php @@ -0,0 +1 @@ +{{ $slot }}: {{ $url }} diff --git a/resources/views/vendor/mail/text/layout.blade.php b/resources/views/vendor/mail/text/layout.blade.php new file mode 100644 index 0000000..ec58e83 --- /dev/null +++ b/resources/views/vendor/mail/text/layout.blade.php @@ -0,0 +1,9 @@ +{!! strip_tags($header ?? '') !!} + +{!! strip_tags($slot) !!} +@isset($subcopy) + +{!! strip_tags($subcopy) !!} +@endisset + +{!! strip_tags($footer ?? '') !!} diff --git a/resources/views/vendor/mail/text/message.blade.php b/resources/views/vendor/mail/text/message.blade.php new file mode 100644 index 0000000..80bce21 --- /dev/null +++ b/resources/views/vendor/mail/text/message.blade.php @@ -0,0 +1,27 @@ + + {{-- Header --}} + + + {{ config('app.name') }} + + + + {{-- Body --}} + {{ $slot }} + + {{-- Subcopy --}} + @isset($subcopy) + + + {{ $subcopy }} + + + @endisset + + {{-- Footer --}} + + + © {{ date('Y') }} {{ config('app.name') }}. @lang('All rights reserved.') + + + diff --git a/resources/views/vendor/mail/text/panel.blade.php b/resources/views/vendor/mail/text/panel.blade.php new file mode 100644 index 0000000..3338f62 --- /dev/null +++ b/resources/views/vendor/mail/text/panel.blade.php @@ -0,0 +1 @@ +{{ $slot }} diff --git a/resources/views/vendor/mail/text/subcopy.blade.php b/resources/views/vendor/mail/text/subcopy.blade.php new file mode 100644 index 0000000..3338f62 --- /dev/null +++ b/resources/views/vendor/mail/text/subcopy.blade.php @@ -0,0 +1 @@ +{{ $slot }} diff --git a/resources/views/vendor/mail/text/table.blade.php b/resources/views/vendor/mail/text/table.blade.php new file mode 100644 index 0000000..3338f62 --- /dev/null +++ b/resources/views/vendor/mail/text/table.blade.php @@ -0,0 +1 @@ +{{ $slot }} diff --git a/routes/api.php b/routes/api.php new file mode 100644 index 0000000..3ab05a5 --- /dev/null +++ b/routes/api.php @@ -0,0 +1,54 @@ + + Limit::perMinute(10)->by($request->ip())->response(function () { + return response()->json(['message' => 'Too many login attempts. Please try again later.'], 429); + }) +); + +Route::prefix('v1')->group(function () { + + // Public + Route::post('/auth/login', [AuthController::class, 'login']) + ->middleware('throttle:api.login'); + + Route::get('/app/config', AppConfigController::class) + ->name('api.app.config'); + + // Protected + Route::middleware('auth:sanctum')->group(function () { + + Route::get('/auth/me', [AuthController::class, 'me']); + Route::post('/auth/logout', [AuthController::class, 'logout']); + + Route::apiResource('users', UserController::class)->names([ + 'index' => 'api.users.index', + 'store' => 'api.users.store', + 'show' => 'api.users.show', + 'update' => 'api.users.update', + 'destroy' => 'api.users.destroy', + ]); + + Route::get('/roles', function () { + return response()->json([ + 'data' => Role::select('id', 'name', 'guard_name', 'created_at')->get(), + ]); + })->middleware('permission:role.view')->name('api.roles.index'); + + Route::get('/permissions', function () { + return response()->json([ + 'data' => Permission::select('id', 'name', 'guard_name')->get(), + ]); + })->middleware('permission:role.view')->name('api.permissions.index'); + }); +}); diff --git a/routes/auth.php b/routes/auth.php new file mode 100644 index 0000000..3926ecf --- /dev/null +++ b/routes/auth.php @@ -0,0 +1,59 @@ +group(function () { + Route::get('register', [RegisteredUserController::class, 'create']) + ->name('register'); + + Route::post('register', [RegisteredUserController::class, 'store']); + + Route::get('login', [AuthenticatedSessionController::class, 'create']) + ->name('login'); + + Route::post('login', [AuthenticatedSessionController::class, 'store']); + + Route::get('forgot-password', [PasswordResetLinkController::class, 'create']) + ->name('password.request'); + + Route::post('forgot-password', [PasswordResetLinkController::class, 'store']) + ->name('password.email'); + + Route::get('reset-password/{token}', [NewPasswordController::class, 'create']) + ->name('password.reset'); + + Route::post('reset-password', [NewPasswordController::class, 'store']) + ->name('password.store'); +}); + +Route::middleware('auth')->group(function () { + Route::get('verify-email', EmailVerificationPromptController::class) + ->name('verification.notice'); + + Route::get('verify-email/{id}/{hash}', VerifyEmailController::class) + ->middleware(['signed', 'throttle:6,1']) + ->name('verification.verify'); + + Route::post('email/verification-notification', [EmailVerificationNotificationController::class, 'store']) + ->middleware('throttle:6,1') + ->name('verification.send'); + + Route::get('confirm-password', [ConfirmablePasswordController::class, 'show']) + ->name('password.confirm'); + + Route::post('confirm-password', [ConfirmablePasswordController::class, 'store']); + + Route::put('password', [PasswordController::class, 'update'])->name('password.update'); + + Route::post('logout', [AuthenticatedSessionController::class, 'destroy']) + ->name('logout'); +}); diff --git a/routes/console.php b/routes/console.php new file mode 100644 index 0000000..3c9adf1 --- /dev/null +++ b/routes/console.php @@ -0,0 +1,8 @@ +comment(Inspiring::quote()); +})->purpose('Display an inspiring quote'); diff --git a/routes/web.php b/routes/web.php new file mode 100644 index 0000000..b3e7281 --- /dev/null +++ b/routes/web.php @@ -0,0 +1,85 @@ +route('login'); +}); + +// Global Search API +Route::get('/api/search', \App\Http\Controllers\GlobalSearchController::class) + ->middleware(['auth']) + ->name('api.search'); + +// Two-Factor Challenge (guest — user is not yet fully authenticated) +Route::get('/two-factor/challenge', [\App\Http\Controllers\TwoFactorController::class, 'challenge'])->name('two-factor.challenge'); +Route::post('/two-factor/challenge', [\App\Http\Controllers\TwoFactorController::class, 'verify'])->name('two-factor.verify'); + +// Dashboard +Route::get('/dashboard', [\App\Http\Controllers\DashboardController::class, 'index']) + ->middleware(['auth', 'verified']) + ->name('dashboard'); + +Route::middleware(['auth', 'verified'])->group(function () { + + // Profile + Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit'); + Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update'); + Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy'); + + // Settings page + Route::get('/settings', [SettingsController::class, 'index'])->name('settings.index'); + + // System Settings (Super-Admin only) + Route::get('/system-settings', [\App\Http\Controllers\SystemSettingController::class, 'index'])->name('system.settings.index'); + Route::patch('/system-settings', [\App\Http\Controllers\SystemSettingController::class, 'update'])->name('system.settings.update'); + Route::post('/system-settings/test-email', [\App\Http\Controllers\SystemSettingController::class, 'testEmail'])->name('system.settings.test-email'); + + // Users CRUD + Route::get('/users', [UserController::class, 'index'])->name('users.index'); + Route::post('/users', [UserController::class, 'store'])->name('users.store'); + Route::get('/users/{user}', [UserController::class, 'show'])->name('users.show'); + Route::patch('/users/{user}', [UserController::class, 'update'])->name('users.update'); + Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('users.destroy'); + Route::post('/users/{id}/restore', [UserController::class, 'restore'])->name('users.restore'); + Route::delete('/users/{id}/force-delete', [UserController::class, 'forceDelete'])->name('users.force-delete'); + + // Bulk Actions + Route::post('/users/bulk-archive', [UserController::class, 'bulkArchive'])->name('users.bulk-archive'); + Route::post('/users/bulk-restore', [UserController::class, 'bulkRestore'])->name('users.bulk-restore'); + Route::post('/users/bulk-force-delete', [UserController::class, 'bulkForceDelete'])->name('users.bulk-force-delete'); + Route::get('/users-export', [UserController::class, 'export'])->name('users.export'); + Route::post('/users-import', [UserController::class, 'import'])->name('users.import'); + + // Activity Logs + Route::get('/activity-logs', [\App\Http\Controllers\ActivityLogController::class, 'index'])->name('activity-logs.index'); + Route::post('/activity-logs/bulk-delete', [\App\Http\Controllers\ActivityLogController::class, 'bulkDelete'])->name('activity-logs.bulk-delete'); + + // Notifications + Route::get('/notifications', [\App\Http\Controllers\NotificationController::class, 'index'])->name('notifications.index'); + Route::post('/notifications', [\App\Http\Controllers\NotificationController::class, 'store'])->name('notifications.store'); + + // Internal Docs + Route::get('/documentation', fn() => Inertia::render('Docs/Index'))->name('docs.index'); + + // Two-Factor Authentication + Route::get('/two-factor', [\App\Http\Controllers\TwoFactorController::class, 'show'])->name('two-factor.show'); + Route::post('/two-factor/enable', [\App\Http\Controllers\TwoFactorController::class, 'enable'])->name('two-factor.enable'); + Route::post('/two-factor/disable', [\App\Http\Controllers\TwoFactorController::class, 'disable'])->name('two-factor.disable'); + Route::post('/two-factor/recovery-codes', [\App\Http\Controllers\TwoFactorController::class, 'regenerateCodes'])->name('two-factor.recovery-codes'); + + // Roles & Permissions + Route::get('/roles', [\App\Http\Controllers\RoleController::class, 'index'])->name('roles.index'); + Route::post('/roles', [\App\Http\Controllers\RoleController::class, 'store'])->name('roles.store'); + Route::patch('/roles/{role}/permissions', [\App\Http\Controllers\RoleController::class, 'updatePermissions'])->name('roles.permissions.update'); + Route::delete('/roles/{role}', [\App\Http\Controllers\RoleController::class, 'destroy'])->name('roles.destroy'); +}); + +require __DIR__.'/auth.php'; diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..f1d3688 --- /dev/null +++ b/run.sh @@ -0,0 +1,288 @@ +#!/bin/bash + +# --- Color Definitions for Premium Look --- +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +CYAN='\033[0;36m' +MAGENTA='\033[0;35m' +WHITE='\033[1;37m' +BOLD='\033[1m' +NC='\033[0m' # No Color + +echo -e "${CYAN}======================================================${NC}" +echo -e "${GREEN}${BOLD} 🐳 Biiproject Kit — Fully Containerized Setup 🐳 ${NC}" +echo -e "${CYAN}======================================================${NC}" + +# 1. Pre-flight Checks (Docker & Daemon status) +echo -e "${CYAN}[1/8] Checking Docker & system environment...${NC}" +if ! command -v docker &> /dev/null; then + echo -e " ${RED}❌ Error: Docker is not installed on this system.${NC}" + echo -e " ${YELLOW}👉 Please install Docker and Docker Compose before running this script.${NC}" + exit 1 +fi + +if ! docker info &> /dev/null; then + echo -e " ${RED}❌ Error: Docker daemon is not running.${NC}" + echo -e " ${YELLOW}👉 Please start your Docker service/desktop and try again.${NC}" + exit 1 +fi +echo -e " ${GREEN}✔ Docker is installed and running perfectly.${NC}" +echo "" + +# 2. Prevent Port & Container conflicts +echo -e "${CYAN}[2/8] Checking for port conflicts...${NC}" + +# Ensure .env is present to parse ports +if [ ! -f .env ] && [ -f .env.example ]; then + cp .env.example .env +fi + +# Resolve ports dynamically from .env or defaults +PORT_8000=$(grep "^APP_PORT=" .env 2>/dev/null | cut -d'=' -f2- | tr -d '"'\''') +PORT_8000=${PORT_8000:-8000} + +PORT_5432=$(grep -E "^(FORWARD_DB_PORT|DB_PORT)=" .env 2>/dev/null | head -n1 | cut -d'=' -f2- | tr -d '"'\''') +PORT_5432=${PORT_5432:-5432} + +PORT_6379=$(grep -E "^(FORWARD_REDIS_PORT|REDIS_PORT)=" .env 2>/dev/null | head -n1 | cut -d'=' -f2- | tr -d '"'\''') +PORT_6379=${PORT_6379:-6379} + +# Stop local processes using these ports +if command -v lsof &>/dev/null && command -v fuser &>/dev/null; then + for port in "$PORT_8000" "$PORT_5432" "$PORT_6379"; do + if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null ; then + echo -e "${YELLOW}⚠ Port $port is occupied by a local process. Releasing it...${NC}" + fuser -k $port/tcp 2>/dev/null + sleep 1 + fi + done +fi + +# Find the container names from our own docker-compose.yml to avoid stopping ourselves +MY_CONTAINERS=$(grep "container_name:" docker-compose.yml 2>/dev/null | awk '{print $2}' | tr -d '"'\''') + +stop_conflict_on_port() { + local port=$1 + local port_type=$2 + + local conflicting_container=$(docker ps --filter "publish=$port" --format "{{.Names}}" 2>/dev/null) + if [ ! -z "$conflicting_container" ]; then + local is_ours=false + for ours in $MY_CONTAINERS; do + if [ "$conflicting_container" = "$ours" ]; then + is_ours=true + break + fi + done + + if [ "$is_ours" = "false" ]; then + echo -e "${YELLOW}⚠ Port $port ($port_type) is occupied by container '$conflicting_container'. Stopping conflict...${NC}" + docker stop "$conflicting_container" &>/dev/null + fi + fi +} + +stop_conflict_on_port "$PORT_8000" "Web Server" +stop_conflict_on_port "$PORT_5432" "PostgreSQL Database" +stop_conflict_on_port "$PORT_6379" "Redis Cache" +echo -e " ${GREEN}✔ Ports $PORT_8000 (Web), $PORT_5432 (Postgres), and $PORT_6379 (Redis) are clear and ready.${NC}" +echo "" + +# 3. Environment File (.env) check +echo -e "${CYAN}[3/8] Verifying configuration environment (.env)...${NC}" +if [ ! -f .env ]; then + echo -e " ${YELLOW}⚠ .env file not found. Creating from template (.env.example)...${NC}" + cp .env.example .env + ENV_CREATED=true +else + echo -e " ${GREEN}✔ Environment configuration file (.env) is present.${NC}" + ENV_CREATED=false +fi +echo "" + +# 4. Install Composer dependencies (Zero-Dependency Host) +echo -e "${CYAN}[4/8] Checking backend dependencies (Composer)...${NC}" +if [ ! -d vendor ]; then + echo -e " ${YELLOW}⚠ Vendor directory not found. Installing via lightweight PHP container...${NC}" + docker run --rm \ + -u "$(id -u):$(id -g)" \ + -v "$(pwd):/var/www/html" \ + -w /var/www/html \ + laravelsail/php83-composer:latest \ + composer install --ignore-platform-reqs + + if [ $? -ne 0 ]; then + echo -e " ${RED}❌ Error: Failed to install composer dependencies via Docker.${NC}" + exit 1 + fi + echo -e " ${GREEN}✔ Composer dependencies successfully installed.${NC}" +else + echo -e " ${GREEN}✔ Composer dependencies are up to date.${NC}" +fi +echo "" + +# 5. Start Docker Compose stack +echo -e "${CYAN}[5/8] Booting up Docker Compose containers...${NC}" +docker compose up -d + +if [ $? -ne 0 ]; then + echo -e " ${RED}❌ Error: Failed to start Docker containers. Please check docker-compose.yml.${NC}" + exit 1 +fi +echo -e " ${GREEN}✔ Docker Compose services booted successfully.${NC}" +echo "" + +# Resolve DB container dynamically +DB_CONTAINER=$(docker compose ps --format "{{.Name}}" pgsql 2>/dev/null) +if [ -z "$DB_CONTAINER" ]; then + DB_CONTAINER=$(grep -A 10 -E "^ pgsql:" docker-compose.yml 2>/dev/null | grep "container_name:" | head -n1 | awk '{print $2}' | tr -d '"'\''') +fi +if [ -z "$DB_CONTAINER" ]; then + DB_CONTAINER="bii-kit-pgsql" +fi + +# Resolve Redis container dynamically +REDIS_CONTAINER=$(docker compose ps --format "{{.Name}}" redis 2>/dev/null) +if [ -z "$REDIS_CONTAINER" ]; then + REDIS_CONTAINER=$(grep -A 10 -E "^ redis:" docker-compose.yml 2>/dev/null | grep "container_name:" | head -n1 | awk '{print $2}' | tr -d '"'\''') +fi +if [ -z "$REDIS_CONTAINER" ]; then + REDIS_CONTAINER="bii-kit-redis" +fi + +# 6. Wait for Databases to be ready (Self-Healing) +echo -e "${CYAN}[6/8] Waiting for services to be ready & configuring permissions...${NC}" + +echo -ne " ${YELLOW}Checking PostgreSQL database ($DB_CONTAINER)...${NC}" +RETRIES=0 +MAX_RETRIES=40 +while [ $RETRIES -lt $MAX_RETRIES ]; do + STATUS=$(docker inspect --format='{{.State.Health.Status}}' "$DB_CONTAINER" 2>/dev/null) + if [ "$STATUS" = "healthy" ]; then + echo -e "\r ${GREEN}✔ PostgreSQL is healthy and ready to accept connections! ${NC}" + break + elif [ "$STATUS" = "unhealthy" ]; then + echo -e "\r ${RED}⚠ PostgreSQL health check reported unhealthy. Proceeding anyway...${NC}" + break + elif [ -z "$STATUS" ]; then + # Check if container is at least running + RUNNING=$(docker inspect --format='{{.State.Running}}' "$DB_CONTAINER" 2>/dev/null) + if [ "$RUNNING" = "true" ]; then + echo -e "\r ${GREEN}✔ PostgreSQL container is running (no healthcheck status). ${NC}" + break + fi + fi + echo -n "." + sleep 1.5 + RETRIES=$((RETRIES + 1)) +done + +echo -ne " ${YELLOW}Checking Redis cache ($REDIS_CONTAINER)...${NC}" +RETRIES=0 +while [ $RETRIES -lt $MAX_RETRIES ]; do + STATUS=$(docker inspect --format='{{.State.Health.Status}}' "$REDIS_CONTAINER" 2>/dev/null) + if [ "$STATUS" = "healthy" ]; then + echo -e "\r ${GREEN}✔ Redis is healthy and ready to accept connections! ${NC}" + break + elif [ "$STATUS" = "unhealthy" ]; then + echo -e "\r ${RED}⚠ Redis health check reported unhealthy. Proceeding anyway...${NC}" + break + elif [ -z "$STATUS" ]; then + # Check if container is at least running + RUNNING=$(docker inspect --format='{{.State.Running}}' "$REDIS_CONTAINER" 2>/dev/null) + if [ "$RUNNING" = "true" ]; then + echo -e "\r ${GREEN}✔ Redis container is running (no healthcheck status). ${NC}" + break + fi + fi + echo -n "." + sleep 1.5 + RETRIES=$((RETRIES + 1)) +done + +# Extra sleep to ensure Docker internal DNS has fully propagated the container names +sleep 2 + +# Correct any permission issues on build and storage folders before continuing +echo -ne " ${YELLOW}Securing workspace file permissions...${NC}" +docker compose exec -u root laravel.test chown -R sail:sail /var/www/html/storage /var/www/html/bootstrap/cache 2>/dev/null +docker compose exec -u root laravel.test chmod -R 775 /var/www/html/storage /var/www/html/bootstrap/cache 2>/dev/null +if [ -d public/build ]; then + docker compose exec -u root laravel.test chown -R sail:sail /var/www/html/public/build 2>/dev/null + docker compose exec -u root laravel.test chmod -R 775 /var/www/html/public/build 2>/dev/null +fi +echo -e "\r ${GREEN}✔ Workspace file permissions secured. ${NC}" +echo "" + +# 7. Securing Application & Database Initialization +echo -e "${CYAN}[7/8] Securely initializing application database & keys...${NC}" + +# Check for empty key +APP_KEY_VAL=$(grep "^APP_KEY=" .env | cut -d'=' -f2- | tr -d '"'\''') +if [ -z "$APP_KEY_VAL" ] || [ "$APP_KEY_VAL" = "base64:" ] || [ "$APP_KEY_VAL" = "SomeRandomString" ]; then + echo -e " ${YELLOW}⚙ Generating unique application encryption key...${NC}" + docker compose exec -u sail laravel.test php artisan key:generate +fi + +# Check if tables exist to decide fresh migrate & seed or regular migrate +TABLE_EXISTS=$(docker compose exec -u sail laravel.test php artisan tinker --execute="echo Schema::hasTable('users') ? 'yes' : 'no';" 2>/dev/null | tr -d '\r\n') + +if [ "$TABLE_EXISTS" != "yes" ]; then + echo -e " ${YELLOW}⚙ Database is uninitialized. Running migrations & seeding default accounts...${NC}" + docker compose exec -u sail laravel.test php artisan migrate:fresh --seed +else + USER_COUNT=$(docker compose exec -u sail laravel.test php artisan tinker --execute="echo App\Models\User::count();" 2>/dev/null | tr -d '\r\n') + if [[ -z "$USER_COUNT" || "$USER_COUNT" == "0" ]]; then + echo -e " ${YELLOW}⚙ Database has tables but no records. Seeding default accounts...${NC}" + docker compose exec -u sail laravel.test php artisan db:seed + else + echo -e " ${GREEN}✔ Database already initialized with $USER_COUNT users. Running pending migrations...${NC}" + docker compose exec -u sail laravel.test php artisan migrate + fi +fi +echo "" + +# 8. Frontend Assets (NPM dependencies and dev server) +echo -e "${CYAN}[8/8] Preparing frontend assets & live-reload server...${NC}" +if [ ! -d node_modules ]; then + echo -e " ${YELLOW}⚙ Node modules not found. Installing NPM packages inside container...${NC}" + docker compose exec -u sail laravel.test npm install +else + echo -e " ${GREEN}✔ Node dependencies are already present.${NC}" +fi + +# Ensure storage symlink exists +docker compose exec -u sail laravel.test php artisan storage:link &>/dev/null + +# Clean up permissions again in case npm install created any root-owned folders +docker compose exec -u root laravel.test chown -R sail:sail /var/www/html/node_modules /var/www/html/package-lock.json 2>/dev/null + +# Build production assets first to ensure page loads immediately +echo -e " ${YELLOW}⚙ Compiling frontend production assets (Vite)...${NC}" +docker compose exec -u sail laravel.test npm run build + +# Start Vite live-reload server in background +echo -e " ${GREEN}✔ Production assets compiled. Launching Vite live-reload server in background...${NC}" +docker compose exec -d -u sail laravel.test npm run dev +echo "" + +# Retrieve ports for display +PORT_8000=$(grep "^APP_PORT=" .env | cut -d'=' -f2- | tr -d '"'\''') +PORT_8000=${PORT_8000:-8000} + +echo -e "${CYAN}=========================================================${NC}" +echo -e " 🎉 ${GREEN}${BOLD}Biiproject Kit is running fully in Docker!${NC} 🎉" +echo -e "${CYAN}=========================================================${NC}" +echo -e " 🚀 ${WHITE}${BOLD}Web Application:${NC} ${GREEN}http://localhost:${PORT_8000}${NC}" +echo -e " 📋 ${WHITE}${BOLD}Activity Telemetry:${NC} ${GREEN}http://localhost:${PORT_8000}/activity-logs${NC}" +echo -e " 📖 ${WHITE}${BOLD}Documentation Hub:${NC} ${GREEN}http://localhost:${PORT_8000}/documentation${NC}" +echo -e " 🐘 ${WHITE}${BOLD}Database Port (Postgres):${NC} ${YELLOW}5432${NC}" +echo -e " 🍒 ${WHITE}${BOLD}Redis Port (Cache):${NC} ${YELLOW}6379${NC}" +echo -e "${CYAN}=========================================================${NC}" +echo -e " ${YELLOW}${BOLD}Useful Commands:${NC}" +echo -e " 👉 View live logs: ${CYAN}docker compose logs -f${NC}" +echo -e " 👉 Stop the stack: ${CYAN}docker compose down${NC}" +echo -e " 👉 Restart containers: ${CYAN}./run.sh${NC}" +echo -e "${CYAN}=========================================================${NC}" diff --git a/storage/app/.gitignore b/storage/app/.gitignore new file mode 100755 index 0000000..fedb287 --- /dev/null +++ b/storage/app/.gitignore @@ -0,0 +1,4 @@ +* +!private/ +!public/ +!.gitignore diff --git a/storage/app/private/.gitignore b/storage/app/private/.gitignore new file mode 100755 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/app/private/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/app/public/.gitignore b/storage/app/public/.gitignore new file mode 100755 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/app/public/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/.gitignore b/storage/framework/.gitignore new file mode 100755 index 0000000..05c4471 --- /dev/null +++ b/storage/framework/.gitignore @@ -0,0 +1,9 @@ +compiled.php +config.php +down +events.scanned.php +maintenance.php +routes.php +routes.scanned.php +schedule-* +services.json diff --git a/storage/framework/cache/.gitignore b/storage/framework/cache/.gitignore new file mode 100755 index 0000000..01e4a6c --- /dev/null +++ b/storage/framework/cache/.gitignore @@ -0,0 +1,3 @@ +* +!data/ +!.gitignore diff --git a/storage/framework/cache/data/.gitignore b/storage/framework/cache/data/.gitignore new file mode 100755 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/cache/data/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/sessions/.gitignore b/storage/framework/sessions/.gitignore new file mode 100755 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/sessions/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/testing/.gitignore b/storage/framework/testing/.gitignore new file mode 100755 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/testing/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/views/.gitignore b/storage/framework/views/.gitignore new file mode 100755 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/views/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/logs/.gitignore b/storage/logs/.gitignore new file mode 100755 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/logs/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..5b9fbb1 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,26 @@ +import defaultTheme from 'tailwindcss/defaultTheme'; +import forms from '@tailwindcss/forms'; + +/** @type {import('tailwindcss').Config} */ +export default { + content: [ + './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php', + './storage/framework/views/*.php', + './resources/views/**/*.blade.php', + './resources/js/**/*.jsx', + './resources/js/**/*.tsx', + ], + + darkMode: 'class', + + theme: { + extend: { + fontFamily: { + sans: ['Lexend', ...defaultTheme.fontFamily.sans], + display: ['Lexend', ...defaultTheme.fontFamily.sans], + }, + }, + }, + + plugins: [forms], +}; diff --git a/tests/Feature/Auth/AuthenticationTest.php b/tests/Feature/Auth/AuthenticationTest.php new file mode 100644 index 0000000..a272b9d --- /dev/null +++ b/tests/Feature/Auth/AuthenticationTest.php @@ -0,0 +1,41 @@ +get('/login'); + + $response->assertStatus(200); +}); + +test('users can authenticate using the login screen', function () { + $user = User::factory()->create(); + + $response = $this->post('/login', [ + 'email' => $user->email, + 'password' => 'password', + ]); + + $this->assertAuthenticated(); + $response->assertRedirect(route('dashboard', absolute: false)); +}); + +test('users can not authenticate with invalid password', function () { + $user = User::factory()->create(); + + $this->post('/login', [ + 'email' => $user->email, + 'password' => 'wrong-password', + ]); + + $this->assertGuest(); +}); + +test('users can logout', function () { + $user = User::factory()->create(); + + $response = $this->actingAs($user)->post('/logout'); + + $this->assertGuest(); + $response->assertRedirect('/'); +}); diff --git a/tests/Feature/Auth/EmailVerificationTest.php b/tests/Feature/Auth/EmailVerificationTest.php new file mode 100644 index 0000000..f282dff --- /dev/null +++ b/tests/Feature/Auth/EmailVerificationTest.php @@ -0,0 +1,46 @@ +unverified()->create(); + + $response = $this->actingAs($user)->get('/verify-email'); + + $response->assertStatus(200); +}); + +test('email can be verified', function () { + $user = User::factory()->unverified()->create(); + + Event::fake(); + + $verificationUrl = URL::temporarySignedRoute( + 'verification.verify', + now()->addMinutes(60), + ['id' => $user->id, 'hash' => sha1($user->email)] + ); + + $response = $this->actingAs($user)->get($verificationUrl); + + Event::assertDispatched(Verified::class); + expect($user->fresh()->hasVerifiedEmail())->toBeTrue(); + $response->assertRedirect(route('dashboard', absolute: false).'?verified=1'); +}); + +test('email is not verified with invalid hash', function () { + $user = User::factory()->unverified()->create(); + + $verificationUrl = URL::temporarySignedRoute( + 'verification.verify', + now()->addMinutes(60), + ['id' => $user->id, 'hash' => sha1('wrong-email')] + ); + + $this->actingAs($user)->get($verificationUrl); + + expect($user->fresh()->hasVerifiedEmail())->toBeFalse(); +}); diff --git a/tests/Feature/Auth/PasswordConfirmationTest.php b/tests/Feature/Auth/PasswordConfirmationTest.php new file mode 100644 index 0000000..8a42902 --- /dev/null +++ b/tests/Feature/Auth/PasswordConfirmationTest.php @@ -0,0 +1,32 @@ +create(); + + $response = $this->actingAs($user)->get('/confirm-password'); + + $response->assertStatus(200); +}); + +test('password can be confirmed', function () { + $user = User::factory()->create(); + + $response = $this->actingAs($user)->post('/confirm-password', [ + 'password' => 'password', + ]); + + $response->assertRedirect(); + $response->assertSessionHasNoErrors(); +}); + +test('password is not confirmed with invalid password', function () { + $user = User::factory()->create(); + + $response = $this->actingAs($user)->post('/confirm-password', [ + 'password' => 'wrong-password', + ]); + + $response->assertSessionHasErrors(); +}); diff --git a/tests/Feature/Auth/PasswordResetTest.php b/tests/Feature/Auth/PasswordResetTest.php new file mode 100644 index 0000000..0504276 --- /dev/null +++ b/tests/Feature/Auth/PasswordResetTest.php @@ -0,0 +1,60 @@ +get('/forgot-password'); + + $response->assertStatus(200); +}); + +test('reset password link can be requested', function () { + Notification::fake(); + + $user = User::factory()->create(); + + $this->post('/forgot-password', ['email' => $user->email]); + + Notification::assertSentTo($user, ResetPassword::class); +}); + +test('reset password screen can be rendered', function () { + Notification::fake(); + + $user = User::factory()->create(); + + $this->post('/forgot-password', ['email' => $user->email]); + + Notification::assertSentTo($user, ResetPassword::class, function ($notification) { + $response = $this->get('/reset-password/'.$notification->token); + + $response->assertStatus(200); + + return true; + }); +}); + +test('password can be reset with valid token', function () { + Notification::fake(); + + $user = User::factory()->create(); + + $this->post('/forgot-password', ['email' => $user->email]); + + Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($user) { + $response = $this->post('/reset-password', [ + 'token' => $notification->token, + 'email' => $user->email, + 'password' => 'password', + 'password_confirmation' => 'password', + ]); + + $response + ->assertSessionHasNoErrors() + ->assertRedirect(route('login')); + + return true; + }); +}); diff --git a/tests/Feature/Auth/PasswordUpdateTest.php b/tests/Feature/Auth/PasswordUpdateTest.php new file mode 100644 index 0000000..bbf079d --- /dev/null +++ b/tests/Feature/Auth/PasswordUpdateTest.php @@ -0,0 +1,51 @@ +create(); + + $response = $this + ->actingAs($user) + ->from('/profile') + ->put('/password', [ + 'current_password' => 'password', + 'password' => 'new-password', + 'password_confirmation' => 'new-password', + ]); + + $response + ->assertSessionHasNoErrors() + ->assertRedirect('/profile'); + + $this->assertTrue(Hash::check('new-password', $user->refresh()->password)); + } + + public function test_correct_password_must_be_provided_to_update_password(): void + { + $user = User::factory()->create(); + + $response = $this + ->actingAs($user) + ->from('/profile') + ->put('/password', [ + 'current_password' => 'wrong-password', + 'password' => 'new-password', + 'password_confirmation' => 'new-password', + ]); + + $response + ->assertSessionHasErrors('current_password') + ->assertRedirect('/profile'); + } +} diff --git a/tests/Feature/Auth/RegistrationTest.php b/tests/Feature/Auth/RegistrationTest.php new file mode 100644 index 0000000..85e072e --- /dev/null +++ b/tests/Feature/Auth/RegistrationTest.php @@ -0,0 +1,20 @@ +get('/register'); + + $response->assertStatus(200); +}); + +test('new users can register', function () { + $response = $this->post('/register', [ + 'first_name' => 'Test', + 'last_name' => 'User', + 'email' => 'test@example.com', + 'password' => 'password', + 'password_confirmation' => 'password', + ]); + + $this->assertAuthenticated(); + $response->assertRedirect(route('dashboard', absolute: false)); +}); diff --git a/tests/Feature/ExampleTest.php b/tests/Feature/ExampleTest.php new file mode 100644 index 0000000..8571e80 --- /dev/null +++ b/tests/Feature/ExampleTest.php @@ -0,0 +1,7 @@ +get('/'); + + $response->assertRedirect(route('login')); +}); diff --git a/tests/Feature/ProfileTest.php b/tests/Feature/ProfileTest.php new file mode 100644 index 0000000..a795e6b --- /dev/null +++ b/tests/Feature/ProfileTest.php @@ -0,0 +1,102 @@ +create(); + + $response = $this + ->actingAs($user) + ->get('/profile'); + + $response->assertRedirect(route('settings.index')); + } + + public function test_profile_information_can_be_updated(): void + { + $user = User::factory()->create(); + + $response = $this + ->actingAs($user) + ->patch('/profile', [ + 'first_name' => 'Test', + 'last_name' => 'User', + 'email' => 'test@example.com', + ]); + + $response + ->assertSessionHasNoErrors() + ->assertRedirect(route('settings.index')); + + $user->refresh(); + + $this->assertSame('Test', $user->first_name); + $this->assertSame('User', $user->last_name); + $this->assertSame('test@example.com', $user->email); + $this->assertNull($user->email_verified_at); + } + + public function test_email_verification_status_is_unchanged_when_the_email_address_is_unchanged(): void + { + $user = User::factory()->create(); + + $response = $this + ->actingAs($user) + ->patch('/profile', [ + 'first_name' => 'Test', + 'last_name' => 'User', + 'email' => $user->email, + ]); + + $response + ->assertSessionHasNoErrors() + ->assertRedirect(route('settings.index')); + + $this->assertNotNull($user->refresh()->email_verified_at); + } + + public function test_user_can_delete_their_account(): void + { + $user = User::factory()->create(); + + $response = $this + ->actingAs($user) + ->delete('/profile', [ + 'password' => 'password', + ]); + + $response + ->assertSessionHasNoErrors() + ->assertRedirect('/'); + + $this->assertGuest(); + $this->assertSoftDeleted($user); + } + + public function test_correct_password_must_be_provided_to_delete_account(): void + { + $user = User::factory()->create(); + + $response = $this + ->actingAs($user) + ->from('/profile') + ->delete('/profile', [ + 'password' => 'wrong-password', + ]); + + $response + ->assertSessionHasErrors('password') + ->assertRedirect('/profile'); + + $this->assertNotNull($user->fresh()); + } +} diff --git a/tests/Feature/Users/UserPermissionTest.php b/tests/Feature/Users/UserPermissionTest.php new file mode 100644 index 0000000..399df15 --- /dev/null +++ b/tests/Feature/Users/UserPermissionTest.php @@ -0,0 +1,115 @@ + 'user.view', 'guard_name' => 'web']); + Permission::firstOrCreate(['name' => 'user.create', 'guard_name' => 'web']); + Permission::firstOrCreate(['name' => 'user.edit', 'guard_name' => 'web']); + Permission::firstOrCreate(['name' => 'user.delete', 'guard_name' => 'web']); + Permission::firstOrCreate(['name' => 'role.view', 'guard_name' => 'web']); + Permission::firstOrCreate(['name' => 'role.manage', 'guard_name' => 'web']); + Permission::firstOrCreate(['name' => 'settings.manage', 'guard_name' => 'web']); + + $userRole = Role::firstOrCreate(['name' => 'user', 'guard_name' => 'web']); + $userRole->syncPermissions(['user.view']); + + $adminRole = Role::firstOrCreate(['name' => 'admin', 'guard_name' => 'web']); + $adminRole->syncPermissions(['user.view', 'user.create', 'user.edit', 'user.delete', 'role.view', 'role.manage']); + + Role::firstOrCreate(['name' => 'super-admin', 'guard_name' => 'web']); +}); + +it('prevents user role from accessing users list on web', function () { + $user = User::factory()->create(); + $user->assignRole('user'); + + $this->actingAs($user) + ->get('/users') + ->assertStatus(200); +}); + +it('prevents user role from deleting users via API', function () { + $user = User::factory()->create(); + $user->assignRole('user'); + + $target = User::factory()->create(); + + $this->actingAs($user) + ->deleteJson("/api/v1/users/{$target->id}") + ->assertForbidden(); +}); + +it('allows admin to create users via API', function () { + $admin = User::factory()->create(); + $admin->assignRole('admin'); + + $payload = [ + 'firstName' => 'New', + 'lastName' => 'User', + 'email' => 'newuser@example.com', + 'password' => 'password123', + ]; + + $this->actingAs($admin) + ->postJson('/api/v1/users', $payload) + ->assertCreated() + ->assertJsonPath('data.email', 'newuser@example.com'); +}); + +it('allows admin to update users via API', function () { + $admin = User::factory()->create(); + $admin->assignRole('admin'); + + $target = User::factory()->create(); + + $this->actingAs($admin) + ->putJson("/api/v1/users/{$target->id}", ['firstName' => 'Updated']) + ->assertOk() + ->assertJsonPath('data.firstName', 'Updated'); +}); + +it('allows super-admin to delete users via API', function () { + $superAdmin = User::factory()->create(); + $superAdmin->assignRole('super-admin'); + + $target = User::factory()->create(); + + $this->actingAs($superAdmin) + ->deleteJson("/api/v1/users/{$target->id}") + ->assertOk(); + + expect(User::withTrashed()->find($target->id)->deleted_at)->not->toBeNull(); +}); + +it('prevents user from deleting themselves via web', function () { + $user = User::factory()->create(); + $user->assignRole('super-admin'); + + $this->actingAs($user) + ->delete("/users/{$user->id}") + ->assertRedirect(); + + expect(User::find($user->id))->not->toBeNull(); +}); + +it('correctly returns full name', function () { + $user = User::factory()->create([ + 'first_name' => 'John', + 'last_name' => 'Doe', + ]); + + expect($user->getFullName())->toBe('John Doe'); +}); + +it('returns user with roles and permissions on API me endpoint', function () { + $user = User::factory()->create(); + $user->assignRole('admin'); + + $this->actingAs($user) + ->getJson('/api/v1/auth/me') + ->assertOk() + ->assertJsonStructure(['data' => ['id', 'email', 'roles', 'permissions']]); +}); diff --git a/tests/Pest.php b/tests/Pest.php new file mode 100644 index 0000000..6885ad5 --- /dev/null +++ b/tests/Pest.php @@ -0,0 +1,50 @@ +extend(TestCase::class) + ->use(RefreshDatabase::class) + ->in('Feature'); + +/* +|-------------------------------------------------------------------------- +| Expectations +|-------------------------------------------------------------------------- +| +| When you're writing tests, you often need to check that values meet certain conditions. The +| "expect()" function gives you access to a set of "expectations" methods that you can use +| to assert different things. Of course, you may extend the Expectation API at any time. +| +*/ + +expect()->extend('toBeOne', function () { + return $this->toBe(1); +}); + +/* +|-------------------------------------------------------------------------- +| Functions +|-------------------------------------------------------------------------- +| +| While Pest is very powerful out-of-the-box, you may have some testing code specific to your +| project that you don't want to repeat in every file. Here you can also expose helpers as +| global functions to help you to reduce the number of lines of code in your test files. +| +*/ + +function something() +{ + // .. +} diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..fe1ffc2 --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,10 @@ +toBeTrue(); +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..d3c0062 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "allowJs": false, + "skipLibCheck": true, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "moduleResolution": "Node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "paths": { + "@/*": ["./resources/js/*"], + "ziggy-js": ["./vendor/tightenco/ziggy/src/js"] + } + }, + "include": ["resources/js/**/*.ts", "resources/js/**/*.tsx", "resources/js/**/*.d.ts"] +} diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..e275290 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,15 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; +import react from '@vitejs/plugin-react'; +import tailwindcss from '@tailwindcss/vite'; + +export default defineConfig({ + plugins: [ + laravel({ + input: 'resources/js/app.tsx', + refresh: true, + }), + tailwindcss(), + react(), + ], +}); diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..4ccfd44 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from 'vitest/config'; +import react from '@vitejs/plugin-react'; +import path from 'path'; + +export default defineConfig({ + plugins: [react()], + test: { + environment: 'jsdom', + globals: true, + setupFiles: './resources/js/__tests__/setup.ts', + include: ['resources/js/__tests__/**/*.test.tsx'], + }, + resolve: { + alias: { + '@': path.resolve(__dirname, './resources/js'), + }, + }, +});