diff --git a/.env.example b/.env.example
index eb423aaa..a1c38110 100644
--- a/.env.example
+++ b/.env.example
@@ -78,6 +78,8 @@ SESSION_SAME_SITE=strict
LOG_SLACK_WEBHOOK_URL=
+BRRR_WEBHOOK_URL=
+
FLARE_KEY=
IGNITION_OPEN_AI_KEY=
diff --git a/app/Console/Commands/ReprocessMediaImages.php b/app/Console/Commands/ReprocessMediaImages.php
index c5e22d1b..b6c86c47 100644
--- a/app/Console/Commands/ReprocessMediaImages.php
+++ b/app/Console/Commands/ReprocessMediaImages.php
@@ -6,9 +6,9 @@ namespace App\Console\Commands;
use App\Models\Media;
use Illuminate\Console\Command;
+use Illuminate\Image\ImageException;
+use Illuminate\Support\Facades\Image;
use Illuminate\Support\Facades\Storage;
-use Intervention\Image\Exceptions\DecoderException;
-use Intervention\Image\ImageManager;
class ReprocessMediaImages extends Command
{
@@ -16,7 +16,7 @@ class ReprocessMediaImages extends Command
protected $description = 'Regenerate medium and small image variants using correct aspect-ratio scaling';
- public function handle(ImageManager $manager): void
+ public function handle(): void
{
$media = Media::where('type', 'image')
->whereNotNull('image_widths')
@@ -44,10 +44,10 @@ class ReprocessMediaImages extends Command
$this->info("Processing: {$path}");
+ $image = Image::fromStorage($path, 'public');
try {
- $file = Storage::disk('public')->get($path);
- $image = $manager->read($file);
- } catch (DecoderException) {
+ $image->width();
+ } catch (ImageException) {
$this->warn(' Could not decode image, skipping.');
continue;
@@ -57,11 +57,8 @@ class ReprocessMediaImages extends Command
$extension = array_pop($filenameParts);
$basename = trim(implode('.', $filenameParts), '.');
- $medium = $image->scale(width: 1000);
- Storage::disk('public')->put($basename.'-medium.'.$extension, (string) $medium->encode());
-
- $small = $image->scale(width: 500);
- Storage::disk('public')->put($basename.'-small.'.$extension, (string) $small->encode());
+ Storage::disk('public')->put($basename.'-medium.'.$extension, $image->scale(width: 1000)->toBytes());
+ Storage::disk('public')->put($basename.'-small.'.$extension, $image->scale(width: 500)->toBytes());
$this->info(' Done.');
}
diff --git a/app/Exceptions/AuthorshipParserException.php b/app/Exceptions/AuthorshipParserException.php
new file mode 100644
index 00000000..7b3e418f
--- /dev/null
+++ b/app/Exceptions/AuthorshipParserException.php
@@ -0,0 +1,9 @@
+ About::first()?->content,
+ ]);
+ }
+}
diff --git a/app/Http/Controllers/Admin/AboutController.php b/app/Http/Controllers/Admin/AboutController.php
new file mode 100644
index 00000000..cc5be0ad
--- /dev/null
+++ b/app/Http/Controllers/Admin/AboutController.php
@@ -0,0 +1,32 @@
+ $about,
+ ]);
+ }
+
+ public function update(Request $request): RedirectResponse
+ {
+ $about = About::firstOrNew();
+ $about->content = $request->input('content');
+ $about->save();
+
+ return redirect()->route('admin.about.show');
+ }
+}
diff --git a/app/Http/Controllers/Admin/ContactsController.php b/app/Http/Controllers/Admin/ContactsController.php
index 17e4a8a7..211f9fa8 100644
--- a/app/Http/Controllers/Admin/ContactsController.php
+++ b/app/Http/Controllers/Admin/ContactsController.php
@@ -6,11 +6,11 @@ namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Contact;
-use GuzzleHttp\Client;
-use GuzzleHttp\Exception\BadResponseException;
use Illuminate\Filesystem\Filesystem;
+use Illuminate\Http\Client\RequestException;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Arr;
+use Illuminate\Support\Facades\Http;
use Illuminate\View\View;
class ContactsController extends Controller
@@ -113,14 +113,13 @@ class ContactsController extends Controller
$avatar = null;
$contact = Contact::findOrFail($contactId);
if ($contact->homepage !== null && mb_strlen($contact->homepage) !== 0) {
- $client = resolve(Client::class);
try {
- $response = $client->get($contact->homepage);
- } catch (BadResponseException $e) {
+ $response = Http::throw()->get($contact->homepage);
+ } catch (RequestException $e) {
return redirect('/admin/contacts/'.$contactId.'/edit')
->with('error', 'Bad resposne from contact’s homepage');
}
- $mf2 = \Mf2\parse((string) $response->getBody(), $contact->homepage);
+ $mf2 = \Mf2\parse($response->body(), $contact->homepage);
foreach ($mf2['items'] as $microformat) {
if (Arr::get($microformat, 'type.0') === 'h-card') {
$avatarURL = Arr::get($microformat, 'properties.photo.0.value');
@@ -129,8 +128,8 @@ class ContactsController extends Controller
}
if ($avatarURL !== null) {
try {
- $avatar = $client->get($avatarURL);
- } catch (BadResponseException $e) {
+ $avatar = Http::throw()->get($avatarURL);
+ } catch (RequestException $e) {
return redirect('/admin/contacts/'.$contactId.'/edit')
->with('error', 'Unable to download avatar');
}
@@ -141,7 +140,7 @@ class ContactsController extends Controller
if ($filesystem->isDirectory($directory) === false) {
$filesystem->makeDirectory($directory);
}
- $filesystem->put($directory.'/image', $avatar->getBody());
+ $filesystem->put($directory.'/image', $avatar->body());
return view('admin.contacts.getavatarsuccess', [
'homepage' => parse_url($contact->homepage, PHP_URL_HOST),
diff --git a/app/Http/Controllers/Admin/PasskeysController.php b/app/Http/Controllers/Admin/PasskeysController.php
index 8012f9b8..d9c18f5b 100644
--- a/app/Http/Controllers/Admin/PasskeysController.php
+++ b/app/Http/Controllers/Admin/PasskeysController.php
@@ -254,7 +254,7 @@ class PasskeysController extends Controller
], 400);
}
- $passkey = Passkey::firstWhere('passkey_id', $publicKeyCredential->id);
+ $passkey = Passkey::firstWhere('passkey_id', Base64UrlSafe::encodeUnpadded($publicKeyCredential->rawId));
if (! $passkey) {
return response()->json([
'success' => false,
diff --git a/app/Http/Controllers/Admin/SettingsController.php b/app/Http/Controllers/Admin/SettingsController.php
new file mode 100644
index 00000000..99d283bb
--- /dev/null
+++ b/app/Http/Controllers/Admin/SettingsController.php
@@ -0,0 +1,32 @@
+ $settings,
+ ]);
+ }
+
+ public function update(Request $request): RedirectResponse
+ {
+ $settings = Setting::firstOrNew();
+ $settings->winter_effect_enabled = $request->boolean('winter_effect_enabled');
+ $settings->save();
+
+ return redirect()->route('admin.settings.show');
+ }
+}
diff --git a/app/Http/Controllers/Admin/TokensController.php b/app/Http/Controllers/Admin/TokensController.php
new file mode 100644
index 00000000..02b9660c
--- /dev/null
+++ b/app/Http/Controllers/Admin/TokensController.php
@@ -0,0 +1,65 @@
+get();
+
+ return view('admin.tokens.index', compact('tokens'));
+ }
+
+ /**
+ * Show the form to manually generate a new Micropub token.
+ *
+ * This is for clients (e.g. iA Writer) that don't support the IndieAuth
+ * PKCE flow and instead expect to be given a token directly.
+ */
+ public function create(): View
+ {
+ return view('admin.tokens.create');
+ }
+
+ /**
+ * Manually generate a new Micropub token.
+ */
+ public function store(Request $request): RedirectResponse
+ {
+ $validated = $request->validate([
+ 'client_id' => 'required|string',
+ 'scope' => 'required|array|min:1',
+ ]);
+
+ $token = resolve(TokenService::class)->getNewToken([
+ 'me' => config('app.url'),
+ 'client_id' => $validated['client_id'],
+ 'scope' => implode(' ', $validated['scope']),
+ ]);
+
+ return redirect('/admin/tokens')->with('new_token', $token);
+ }
+
+ /**
+ * Revoke a Micropub token.
+ */
+ public function revoke(MicropubToken $token): RedirectResponse
+ {
+ $token->revoke();
+
+ return redirect('/admin/tokens');
+ }
+}
diff --git a/app/Http/Controllers/ArticlesController.php b/app/Http/Controllers/ArticlesController.php
index ff28fd50..b2da783f 100644
--- a/app/Http/Controllers/ArticlesController.php
+++ b/app/Http/Controllers/ArticlesController.php
@@ -17,7 +17,7 @@ class ArticlesController extends Controller
*/
public function index(?int $year = null, ?int $month = null): View
{
- $articles = Article::where('published', '1')
+ $articles = Article::published()
->date($year, $month)
->orderBy('updated_at', 'desc')
->simplePaginate(5);
diff --git a/app/Http/Controllers/FeedsController.php b/app/Http/Controllers/FeedsController.php
index a30c89dc..0e312882 100644
--- a/app/Http/Controllers/FeedsController.php
+++ b/app/Http/Controllers/FeedsController.php
@@ -7,68 +7,15 @@ namespace App\Http\Controllers;
use App\Models\Article;
use App\Models\Note;
use Illuminate\Http\JsonResponse;
-use Illuminate\Http\Response;
class FeedsController extends Controller
{
- /**
- * Returns the blog RSS feed.
- */
- public function blogRss(): Response
- {
- $articles = Article::where('published', '1')->latest('updated_at')->take(20)->get();
- $buildDate = $articles->first()->updated_at->toRssString();
-
- return response()
- ->view('articles.rss', compact('articles', 'buildDate'))
- ->header('Content-Type', 'application/rss+xml; charset=utf-8');
- }
-
- /**
- * Returns the blog Atom feed.
- */
- public function blogAtom(): Response
- {
- $articles = Article::where('published', '1')->latest('updated_at')->take(20)->get();
-
- return response()
- ->view('articles.atom', compact('articles'))
- ->header('Content-Type', 'application/atom+xml; charset=utf-8');
- }
-
- /**
- * Returns the notes RSS feed.
- */
- public function notesRss(): Response
- {
- $notes = Note::latest()->take(20)->get();
- $buildDate = $notes->first()->updated_at->toRssString();
-
- return response()
- ->view('notes.rss', compact('notes', 'buildDate'))
- ->header('Content-Type', 'application/rss+xml; charset=utf-8');
- }
-
- /**
- * Returns the notes Atom feed.
- */
- public function notesAtom(): Response
- {
- $notes = Note::latest()->take(20)->get();
-
- return response()
- ->view('notes.atom', compact('notes'))
- ->header('Content-Type', 'application/atom+xml; charset=utf-8');
- }
-
- /** @todo sort out return type for json responses */
-
/**
* Returns the blog JSON feed.
*/
- public function blogJson(): array
+ public function blogJson(): JsonResponse
{
- $articles = Article::where('published', '1')->latest('updated_at')->take(20)->get();
+ $articles = Article::published()->latest('updated_at')->take(20)->get();
$data = [
'version' => 'https://jsonfeed.org/version/1.1',
'title' => 'The JSON Feed for '.config('user.display_name').'’s blog',
@@ -94,13 +41,15 @@ class FeedsController extends Controller
];
}
- return $data;
+ return response()->json($data, 200, [
+ 'Content-Type' => 'application/feed+json',
+ ]);
}
/**
* Returns the notes JSON feed.
*/
- public function notesJson(): array
+ public function notesJson(): JsonResponse
{
$notes = Note::latest()->with('media', 'place', 'tags')->take(20)->get();
$data = [
@@ -130,7 +79,9 @@ class FeedsController extends Controller
}
}
- return $data;
+ return response()->json($data, 200, [
+ 'Content-Type' => 'application/feed+json',
+ ]);
}
/**
@@ -138,7 +89,7 @@ class FeedsController extends Controller
*/
public function blogJf2(): JsonResponse
{
- $articles = Article::where('published', '1')->latest('updated_at')->take(20)->get();
+ $articles = Article::published()->latest('updated_at')->take(20)->get();
$items = [];
foreach ($articles as $article) {
$items[] = [
diff --git a/app/Http/Controllers/FrontPageController.php b/app/Http/Controllers/FrontPageController.php
index 19537663..47833f45 100644
--- a/app/Http/Controllers/FrontPageController.php
+++ b/app/Http/Controllers/FrontPageController.php
@@ -26,7 +26,7 @@ class FrontPageController extends Controller
->withCount(['webmentions AS reposts' => function ($query) {
$query->where('type', 'repost-of');
}])->get();
- $articles = Article::latest()->get();
+ $articles = Article::published()->latest()->get();
$bookmarks = Bookmark::latest()->with('tags')->get();
$likes = Like::latest()->get();
diff --git a/app/Http/Controllers/IndieAuthController.php b/app/Http/Controllers/IndieAuthController.php
index 45b488da..a795bce8 100644
--- a/app/Http/Controllers/IndieAuthController.php
+++ b/app/Http/Controllers/IndieAuthController.php
@@ -4,14 +4,14 @@ declare(strict_types=1);
namespace App\Http\Controllers;
+use App\Models\MicropubToken;
use App\Services\TokenService;
-use Exception;
-use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Uri;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Validator;
use Illuminate\View\View;
use Random\RandomException;
@@ -25,9 +25,10 @@ class IndieAuthController extends Controller
'issuer' => config('app.url'),
'authorization_endpoint' => route('indieauth.start'),
'token_endpoint' => route('indieauth.token'),
+ 'revocation_endpoint' => route('indieauth.revocation'),
+ 'introspection_endpoint' => route('indieauth.introspection'),
+ 'introspection_endpoint_auth_methods_supported' => ['Bearer'],
'code_challenge_methods_supported' => ['S256'],
- // 'introspection_endpoint' => route('indieauth.introspection'),
- // 'introspection_endpoint_auth_methods_supported' => ['none'],
]);
}
@@ -179,6 +180,50 @@ class IndieAuthController extends Controller
]);
}
+ /**
+ * Process a POST request to the IndieAuth revocation endpoint (RFC 7009).
+ *
+ * Per spec this always returns HTTP 200, whether the token was revoked,
+ * unknown, or already revoked, so callers can't probe token validity.
+ */
+ public function processRevocationRequest(Request $request): JsonResponse
+ {
+ MicropubToken::findActive($request->get('token'))?->revoke();
+
+ return response()->json([], 200);
+ }
+
+ /**
+ * Process a POST request to the IndieAuth token introspection endpoint
+ * (RFC 7662, extended by IndieAuth to require the `me` property).
+ *
+ * The caller must itself present a currently-active token as a Bearer
+ * credential to use this endpoint, per spec ("MUST also require some
+ * form of authorization"). Per spec, an inactive token being introspected
+ * still gets a 200 response containing only `active: false` - no other
+ * information about why it's inactive is given.
+ */
+ public function processIntrospectionRequest(Request $request): JsonResponse
+ {
+ if (! MicropubToken::findActive($request->bearerToken())) {
+ return response()->json([], 401);
+ }
+
+ $token = MicropubToken::findActive($request->get('token'));
+
+ if (! $token) {
+ return response()->json(['active' => false]);
+ }
+
+ return response()->json([
+ 'active' => true,
+ 'me' => $token->me,
+ 'client_id' => $token->client_id,
+ 'scope' => $token->scope,
+ 'iat' => $token->created_at->timestamp,
+ ]);
+ }
+
protected function isValidRedirectUri(string $clientId, string $redirectUri): bool
{
// If client_id is not a valid URL, then it's not valid
@@ -199,15 +244,13 @@ class IndieAuthController extends Controller
}
// Otherwise we need to check the redirect_uri is in the client_id's redirect_uris
- $guzzle = resolve(Client::class);
-
try {
- $clientInfo = $guzzle->get($clientId);
- } catch (Exception) {
+ $clientInfo = Http::throw()->get($clientId);
+ } catch (\Throwable) {
return false;
}
- $clientInfoParsed = \Mf2\parse($clientInfo->getBody()->getContents(), $clientId);
+ $clientInfoParsed = \Mf2\parse($clientInfo->body(), $clientId);
$redirectUris = $clientInfoParsed['rels']['redirect_uri'] ?? [];
diff --git a/app/Http/Controllers/MicropubController.php b/app/Http/Controllers/MicropubController.php
index c6008a9c..1d26894f 100644
--- a/app/Http/Controllers/MicropubController.php
+++ b/app/Http/Controllers/MicropubController.php
@@ -12,10 +12,12 @@ use App\Models\Place;
use App\Models\SyndicationTarget;
use App\Services\Micropub\Data\MicropubData;
use App\Services\Micropub\MicropubHandlerRegistry;
+use App\Services\Micropub\NoteResolver;
+use App\Services\Micropub\NoteSource;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
-use Lcobucci\JWT\Token;
+use Illuminate\Support\Arr;
class MicropubController extends Controller
{
@@ -47,8 +49,15 @@ class MicropubController extends Controller
try {
$handler = $this->handlerRegistry->getHandler($type);
$dataClass = $handler->dataClass();
- /** @var MicropubData $data */
- $data = $dataClass::fromRequest($request);
+
+ try {
+ /** @var MicropubData $data */
+ $data = $dataClass::fromRequest($request);
+ } catch (\TypeError) {
+ // the data objects are typed, so this means a property has the wrong shape
+ return $this->invalidRequest('A property in the request has an invalid value');
+ }
+
$result = $handler->handle($data);
if ($result['response'] === 'updated') {
@@ -65,28 +74,20 @@ class MicropubController extends Controller
return response()->json([
'error' => 'insufficient_scope',
'error_description' => 'The token does not have the required scope for this request',
- ], 401);
+ ], 403);
} catch (ModelNotFoundException) {
return response()->json([
'error' => 'invalid_request',
'error_description' => 'No known note with given ID',
], 404);
- } catch (MicropubUnsupportedModelException) {
- return response()->json([
- 'error' => 'invalid',
- 'error_description' => 'This implementation currently only supports the updating of notes',
- ], 500);
- } catch (\InvalidArgumentException $e) {
+ } catch (MicropubUnsupportedModelException|MicropubHandlerException|\InvalidArgumentException $e) {
return response()->json([
'error' => 'invalid_request',
'error_description' => $e->getMessage(),
], 400);
- } catch (MicropubHandlerException) {
- return response()->json([
- 'error' => 'unsupported_operation',
- 'error_description' => 'The request could not be processed by this server',
- ], 500);
- } catch (\Exception $e) {
+ } catch (\Throwable $e) {
+ report($e);
+
return response()->json([
'error' => 'server_error',
'error_description' => 'An error occurred processing the request',
@@ -98,44 +99,40 @@ class MicropubController extends Controller
* Respond to a GET request to the micropub endpoint.
*
* Token validation is handled by the VerifyMicropubToken middleware.
- * Supports q=syndicate-to, q=config, and q=geo:, queries.
+ * Supports q=syndicate-to, q=config, q=source, and q=geo:, queries.
* The default response returns the token metadata.
*/
public function get(Request $request): JsonResponse
{
- if ($request->input('q') === 'syndicate-to') {
+ $q = $request->input('q');
+
+ if ($q === 'syndicate-to') {
return response()->json([
'syndicate-to' => SyndicationTarget::all(),
]);
}
- if ($request->input('q') === 'config') {
+ if ($q === 'config') {
return response()->json([
'syndicate-to' => SyndicationTarget::all(),
'media-endpoint' => route('media-endpoint'),
]);
}
- if ($request->has('q') && str_starts_with($request->input('q'), 'geo:')) {
- preg_match_all(
- '/([0-9.\-]+)/',
- $request->input('q'),
- $matches
- );
- $distance = (count($matches[0]) === 3) ? 100 * $matches[0][2] : 1000;
- $places = Place::near(
- (object) ['latitude' => $matches[0][0], 'longitude' => $matches[0][1]],
- $distance
- )->get();
+ if ($q === 'source') {
+ return $this->sourceResponse($request);
+ }
- return response()->json([
- 'response' => 'places',
- 'places' => $places,
- ]);
+ if (is_string($q) && str_starts_with($q, 'geo:')) {
+ return $this->placesResponse($q);
+ }
+
+ if ($request->has('q')) {
+ return $this->invalidRequest('This server does not know how to handle this q parameter');
}
// the default response is just to return the token data
- /** @var Token $tokenData */
+ /** @var array $tokenData */
$tokenData = $request->input('token_data');
return response()->json([
@@ -147,4 +144,59 @@ class MicropubController extends Controller
],
]);
}
+
+ /**
+ * Respond to a q=source query with the microformats2 JSON of a post.
+ */
+ private function sourceResponse(Request $request): JsonResponse
+ {
+ $url = $request->input('url');
+
+ if (! is_string($url)) {
+ return $this->invalidRequest('The url parameter is required');
+ }
+
+ try {
+ $note = resolve(NoteResolver::class)->fromUrl($url);
+ } catch (MicropubUnsupportedModelException $e) {
+ return $this->invalidRequest($e->getMessage());
+ } catch (ModelNotFoundException) {
+ return $this->invalidRequest('No known note with given ID', 404);
+ }
+
+ $requested = array_values(array_filter(Arr::wrap($request->input('properties')), 'is_string'));
+
+ return response()->json(resolve(NoteSource::class)->toArray($note, $requested));
+ }
+
+ /**
+ * Respond to a q=geo:, query with the nearby places.
+ */
+ private function placesResponse(string $q): JsonResponse
+ {
+ preg_match_all('/([0-9.\-]+)/', $q, $matches);
+
+ if (count($matches[0]) < 2 || count(array_filter($matches[0], 'is_numeric')) !== count($matches[0])) {
+ return $this->invalidRequest('The geo query must contain a latitude and longitude');
+ }
+
+ $distance = (count($matches[0]) === 3) ? 100 * $matches[0][2] : 1000;
+ $places = Place::near(
+ (object) ['latitude' => $matches[0][0], 'longitude' => $matches[0][1]],
+ $distance
+ )->get();
+
+ return response()->json([
+ 'response' => 'places',
+ 'places' => $places,
+ ]);
+ }
+
+ private function invalidRequest(string $description, int $status = 400): JsonResponse
+ {
+ return response()->json([
+ 'error' => 'invalid_request',
+ 'error_description' => $description,
+ ], $status);
+ }
}
diff --git a/app/Http/Controllers/MicropubMediaController.php b/app/Http/Controllers/MicropubMediaController.php
index 1cca74b3..d9f8ea32 100644
--- a/app/Http/Controllers/MicropubMediaController.php
+++ b/app/Http/Controllers/MicropubMediaController.php
@@ -13,9 +13,10 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Http\UploadedFile;
+use Illuminate\Image\ImageException;
use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\Image;
use Illuminate\Support\Facades\Storage;
-use Intervention\Image\ImageManager;
use Ramsey\Uuid\Uuid;
class MicropubMediaController extends Controller
@@ -25,9 +26,7 @@ class MicropubMediaController extends Controller
$tokenData = $request->input('token_data');
$scopes = $tokenData['scope'];
- if (is_string($scopes)) {
- $scopes = explode(' ', $scopes);
- }
+ $scopes = explode(' ', $scopes);
if (! in_array('create', $scopes, true)) {
return (new MicropubResponses)->insufficientScopeResponse();
}
@@ -83,9 +82,7 @@ class MicropubMediaController extends Controller
$tokenData = $request->input('token_data');
$scopes = $tokenData['scope'];
- if (is_string($scopes)) {
- $scopes = explode(' ', $scopes);
- }
+ $scopes = explode(' ', $scopes);
if (! in_array('create', $scopes, true)) {
return (new MicropubResponses)->insufficientScopeResponse();
}
@@ -111,12 +108,9 @@ class MicropubMediaController extends Controller
$filename = Storage::disk('local')->putFile('media', $file);
- /** @var ImageManager $manager */
- $manager = resolve(ImageManager::class);
try {
- $image = $manager->read($request->file('file'));
- $width = $image->width();
- } catch (Exception) {
+ $width = Image::fromUpload($request->file('file'))->width();
+ } catch (ImageException) {
// not an image
$width = null;
}
diff --git a/app/Http/Middleware/LinkHeadersMiddleware.php b/app/Http/Middleware/LinkHeadersMiddleware.php
index b9e55139..e2810f87 100644
--- a/app/Http/Middleware/LinkHeadersMiddleware.php
+++ b/app/Http/Middleware/LinkHeadersMiddleware.php
@@ -17,6 +17,8 @@ class LinkHeadersMiddleware
$response->header('Link', '<'.route('indieauth.metadata').'>; rel="indieauth-metadata"', false);
$response->header('Link', '<'.route('indieauth.start').'>; rel="authorization_endpoint"', false);
$response->header('Link', '<'.route('indieauth.token').'>; rel="token_endpoint"', false);
+ $response->header('Link', '<'.route('indieauth.revocation').'>; rel="revocation_endpoint"', false);
+ $response->header('Link', '<'.route('indieauth.introspection').'>; rel="introspection_endpoint"', false);
$response->header('Link', '<'.route('micropub-endpoint').'>; rel="micropub"', false);
$response->header('Link', '<'.route('webmention-endpoint').'>; rel="webmention"', false);
diff --git a/app/Http/Middleware/VerifyMicropubToken.php b/app/Http/Middleware/VerifyMicropubToken.php
index 33d2cb12..530995ae 100644
--- a/app/Http/Middleware/VerifyMicropubToken.php
+++ b/app/Http/Middleware/VerifyMicropubToken.php
@@ -5,13 +5,9 @@ declare(strict_types=1);
namespace App\Http\Middleware;
use App\Http\Responses\MicropubResponses;
+use App\Models\MicropubToken;
use Closure;
use Illuminate\Http\Request;
-use Lcobucci\JWT\Configuration;
-use Lcobucci\JWT\Encoding\CannotDecodeContent;
-use Lcobucci\JWT\Token;
-use Lcobucci\JWT\Token\InvalidTokenStructure;
-use Lcobucci\JWT\Validation\RequiredConstraintsViolated;
use Symfony\Component\HttpFoundation\Response;
class VerifyMicropubToken
@@ -39,15 +35,15 @@ class VerifyMicropubToken
], 401);
}
- try {
- $tokenData = $this->validateToken($rawToken);
- } catch (RequiredConstraintsViolated|InvalidTokenStructure|CannotDecodeContent) {
+ $token = MicropubToken::findActive($rawToken);
+
+ if (! $token) {
$micropubResponses = new MicropubResponses;
return $micropubResponses->invalidTokenResponse();
}
- if ($tokenData->claims()->has('scope') === false) {
+ if ($token->scope === '') {
$micropubResponses = new MicropubResponses;
return $micropubResponses->tokenHasNoScopeResponse();
@@ -56,26 +52,10 @@ class VerifyMicropubToken
return $next($request->merge([
'access_token' => $rawToken,
'token_data' => [
- 'me' => $tokenData->claims()->get('me'),
- 'scope' => $tokenData->claims()->get('scope'),
- 'client_id' => $tokenData->claims()->get('client_id'),
+ 'me' => $token->me,
+ 'scope' => $token->scope,
+ 'client_id' => $token->client_id,
],
]));
}
-
- /**
- * Check the token signature is valid.
- */
- private function validateToken(string $bearerToken): Token
- {
- $config = resolve(Configuration::class);
-
- $token = $config->parser()->parse($bearerToken);
-
- $constraints = $config->validationConstraints();
-
- $config->validator()->assert($token, ...$constraints);
-
- return $token;
- }
}
diff --git a/app/Http/Requests/MicropubRequest.php b/app/Http/Requests/MicropubRequest.php
index ab4fde74..7cbabc31 100644
--- a/app/Http/Requests/MicropubRequest.php
+++ b/app/Http/Requests/MicropubRequest.php
@@ -15,25 +15,36 @@ class MicropubRequest extends FormRequest
];
}
+ /**
+ * Determine the request type: the action (e.g. "update") if one is given,
+ * otherwise the microformat type without its "h-" prefix. Per the spec, a
+ * request with no type is treated as an h-entry.
+ */
public function getType(): ?string
{
if ($this->isJson()) {
$data = $this->json()->all();
- if (isset($data['action']) && $data['action'] === 'update') {
- return 'update';
+ if (isset($data['action']) && is_string($data['action'])) {
+ return $data['action'];
}
if (isset($data['type']) && is_array($data['type'])) {
$type = current($data['type']);
- if (str_starts_with($type, 'h-')) {
+ if (is_string($type) && str_starts_with($type, 'h-')) {
return substr($type, 2);
}
+
+ return null;
}
- return null;
+ return 'entry';
}
- return $this->input('h') ?: null;
+ if ($this->filled('action')) {
+ return $this->input('action');
+ }
+
+ return $this->input('h') ?: 'entry';
}
}
diff --git a/app/Http/Responses/MicropubResponses.php b/app/Http/Responses/MicropubResponses.php
index 4f7240c2..d26dbf90 100644
--- a/app/Http/Responses/MicropubResponses.php
+++ b/app/Http/Responses/MicropubResponses.php
@@ -17,7 +17,7 @@ class MicropubResponses
'response' => 'error',
'error' => 'insufficient_scope',
'error_description' => 'The token’s scope does not have the necessary requirements.',
- ], 401);
+ ], 403);
}
/**
@@ -29,7 +29,7 @@ class MicropubResponses
'response' => 'error',
'error' => 'invalid_token',
'error_description' => 'The provided token did not pass validation',
- ], 400);
+ ], 401);
}
/**
diff --git a/app/Jobs/DownloadWebMention.php b/app/Jobs/DownloadWebMention.php
index 341c35c8..0cb073d5 100644
--- a/app/Jobs/DownloadWebMention.php
+++ b/app/Jobs/DownloadWebMention.php
@@ -4,14 +4,14 @@ declare(strict_types=1);
namespace App\Jobs;
-use GuzzleHttp\Client;
-use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\FileSystem\FileSystem;
+use Illuminate\Http\Client\RequestException;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Facades\Http;
class DownloadWebMention implements ShouldQueue
{
@@ -29,15 +29,15 @@ class DownloadWebMention implements ShouldQueue
/**
* Execute the job.
*
- * @throws GuzzleException
+ * @throws RequestException
* @throws FileNotFoundException
*/
- public function handle(Client $guzzle): void
+ public function handle(): void
{
- $response = $guzzle->request('GET', $this->source);
- // 4XX and 5XX responses should get Guzzle to throw an exception,
- // Laravel should catch and retry these automatically.
- if ($response->getStatusCode() === 200) {
+ // 4XX and 5XX responses should throw so Laravel can catch and
+ // retry these automatically.
+ $response = Http::throw()->get($this->source);
+ if ($response->status() === 200) {
$filesystem = new FileSystem;
$filename = storage_path('HTML').'/'.$this->createFilenameFromURL($this->source);
// backup file first
@@ -56,7 +56,7 @@ class DownloadWebMention implements ShouldQueue
// save new HTML
$filesystem->put(
$filename,
- (string) $response->getBody()
+ $response->body()
);
// remove backup if the same
if ($filesystem->exists($filenameBackup)) {
diff --git a/app/Jobs/NotifyBrrrOfWebMention.php b/app/Jobs/NotifyBrrrOfWebMention.php
new file mode 100644
index 00000000..3273b7d6
--- /dev/null
+++ b/app/Jobs/NotifyBrrrOfWebMention.php
@@ -0,0 +1,56 @@
+ $this->title(),
+ 'message' => "From {$this->webMention->source}",
+ 'open_url' => $this->webMention->target,
+ ]);
+ }
+
+ /**
+ * Build a notification title based on the webmention type.
+ */
+ private function title(): string
+ {
+ return match ($this->webMention->type) {
+ 'in-reply-to' => 'New reply',
+ 'like-of' => 'New like',
+ 'repost-of' => 'New repost',
+ default => 'New webmention',
+ };
+ }
+}
diff --git a/app/Jobs/ProcessLike.php b/app/Jobs/ProcessLike.php
index 49302885..7bf7618e 100644
--- a/app/Jobs/ProcessLike.php
+++ b/app/Jobs/ProcessLike.php
@@ -4,17 +4,16 @@ declare(strict_types=1);
namespace App\Jobs;
+use App\Exceptions\AuthorshipParserException;
use App\Models\Like;
-use GuzzleHttp\Client;
-use GuzzleHttp\Exception\GuzzleException;
+use App\Services\WebMention\Authorship;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Arr;
-use Jonnybarnes\WebmentionsParser\Authorship;
-use Jonnybarnes\WebmentionsParser\Exceptions\AuthorshipParserException;
+use Illuminate\Support\Facades\Http;
class ProcessLike implements ShouldQueue
{
@@ -32,13 +31,11 @@ class ProcessLike implements ShouldQueue
/**
* Execute the job.
- *
- * @throws GuzzleException
*/
- public function handle(Client $client, Authorship $authorship): int
+ public function handle(Authorship $authorship): int
{
- $response = $client->request('GET', $this->like->url);
- $mf2 = \Mf2\parse((string) $response->getBody(), $this->like->url);
+ $response = Http::throw()->get($this->like->url);
+ $mf2 = \Mf2\parse($response->body(), $this->like->url);
if (Arr::has($mf2, 'items.0.properties.content')) {
$this->like->content = $mf2['items'][0]['properties']['content'][0]['html'];
}
diff --git a/app/Jobs/ProcessMedia.php b/app/Jobs/ProcessMedia.php
index f9d8af50..78aeba3e 100644
--- a/app/Jobs/ProcessMedia.php
+++ b/app/Jobs/ProcessMedia.php
@@ -7,11 +7,11 @@ namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Image\ImageException;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Facades\Image;
use Illuminate\Support\Facades\Storage;
-use Intervention\Image\Exceptions\DecoderException;
-use Intervention\Image\ImageManager;
class ProcessMedia implements ShouldQueue
{
@@ -30,15 +30,16 @@ class ProcessMedia implements ShouldQueue
/**
* Execute the job.
*/
- public function handle(ImageManager $manager): void
+ public function handle(): void
{
// Load file
$file = Storage::disk('local')->get($this->filename);
// Open file
+ $image = Image::fromStorage($this->filename, 'local');
try {
- $image = $manager->read($file);
- } catch (DecoderException) {
+ $width = $image->width();
+ } catch (ImageException) {
// not an image; delete file and end job
Storage::disk('local')->delete($this->filename);
@@ -49,18 +50,15 @@ class ProcessMedia implements ShouldQueue
Storage::disk('public')->put($this->filename, $file);
// Create smaller versions if necessary
- if ($image->width() > 1000) {
+ if ($width > 1000) {
$filenameParts = explode('.', $this->filename);
$extension = array_pop($filenameParts);
// the following achieves this data flow
// foo.bar.png => ['foo', 'bar', 'png'] => ['foo', 'bar'] => foo.bar
$basename = trim(implode('.', $filenameParts), '.');
- $medium = $image->scale(width: 1000);
- Storage::disk('public')->put($basename.'-medium.'.$extension, (string) $medium->encode());
-
- $small = $image->scale(width: 500);
- Storage::disk('public')->put($basename.'-small.'.$extension, (string) $small->encode());
+ Storage::disk('public')->put($basename.'-medium.'.$extension, $image->scale(width: 1000)->toBytes());
+ Storage::disk('public')->put($basename.'-small.'.$extension, $image->scale(width: 500)->toBytes());
}
// Now we can delete the locally saved image
diff --git a/app/Jobs/ProcessWebMention.php b/app/Jobs/ProcessWebMention.php
index 6677b285..730b3ad4 100644
--- a/app/Jobs/ProcessWebMention.php
+++ b/app/Jobs/ProcessWebMention.php
@@ -4,18 +4,17 @@ declare(strict_types=1);
namespace App\Jobs;
+use App\Exceptions\InvalidMentionException;
use App\Exceptions\RemoteContentNotFoundException;
use App\Models\Note;
use App\Models\WebMention;
-use GuzzleHttp\Client;
-use GuzzleHttp\Exception\GuzzleException;
-use GuzzleHttp\Exception\RequestException;
+use App\Services\WebMention\Parser;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Http\Client\ConnectionException;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
-use Jonnybarnes\WebmentionsParser\Exceptions\InvalidMentionException;
-use Jonnybarnes\WebmentionsParser\Parser;
+use Illuminate\Support\Facades\Http;
use Mf2;
class ProcessWebMention implements ShouldQueue
@@ -36,18 +35,20 @@ class ProcessWebMention implements ShouldQueue
* Execute the job.
*
* @throws RemoteContentNotFoundException
- * @throws GuzzleException
* @throws InvalidMentionException
*/
- public function handle(Parser $parser, Client $guzzle): void
+ public function handle(Parser $parser): void
{
try {
- $response = $guzzle->request('GET', $this->source);
- } catch (RequestException $e) {
+ $response = Http::get($this->source);
+ } catch (ConnectionException) {
throw new RemoteContentNotFoundException;
}
- $this->saveRemoteContent((string) $response->getBody(), $this->source);
- $microformats = Mf2\parse((string) $response->getBody(), $this->source);
+ if ($response->failed()) {
+ throw new RemoteContentNotFoundException;
+ }
+ $this->saveRemoteContent($response->body(), $this->source);
+ $microformats = Mf2\parse($response->body(), $this->source);
$webmentions = WebMention::where('source', $this->source)->get();
foreach ($webmentions as $webmention) {
// check webmention still references target
@@ -95,6 +96,7 @@ class ProcessWebMention implements ShouldQueue
$webmention->type = $type;
$webmention->mf2 = json_encode($microformats);
$webmention->save();
+ dispatch(new NotifyBrrrOfWebMention($webmention));
}
/**
diff --git a/app/Jobs/SaveProfileImage.php b/app/Jobs/SaveProfileImage.php
index 0bcbd4e7..90f0b661 100644
--- a/app/Jobs/SaveProfileImage.php
+++ b/app/Jobs/SaveProfileImage.php
@@ -4,15 +4,16 @@ declare(strict_types=1);
namespace App\Jobs;
-use GuzzleHttp\Client;
-use GuzzleHttp\Exception\RequestException;
+use App\Exceptions\AuthorshipParserException;
+use App\Services\WebMention\Authorship;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Http\Client\ConnectionException;
+use Illuminate\Http\Client\RequestException;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Arr;
-use Jonnybarnes\WebmentionsParser\Authorship;
-use Jonnybarnes\WebmentionsParser\Exceptions\AuthorshipParserException;
+use Illuminate\Support\Facades\Http;
class SaveProfileImage implements ShouldQueue
{
@@ -55,12 +56,10 @@ class SaveProfileImage implements ShouldQueue
&& parse_url($photo, PHP_URL_HOST) !== 'pbs.twimg.com'
&& parse_url($photo, PHP_URL_HOST) !== 'twitter.com'
) {
- $client = resolve(Client::class);
-
try {
- $response = $client->get($photo);
- $image = $response->getBody();
- } catch (RequestException) {
+ $response = Http::throw()->get($photo);
+ $image = $response->body();
+ } catch (ConnectionException|RequestException) {
// we are opening and reading the default image so that
$default = public_path().'/assets/profile-images/default-image';
$handle = fopen($default, 'rb');
diff --git a/app/Jobs/SaveScreenshot.php b/app/Jobs/SaveScreenshot.php
index 4661ccfe..b72da7b0 100755
--- a/app/Jobs/SaveScreenshot.php
+++ b/app/Jobs/SaveScreenshot.php
@@ -5,14 +5,15 @@ declare(strict_types=1);
namespace App\Jobs;
use App\Models\Bookmark;
-use GuzzleHttp\Client;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Http\Client\PendingRequest;
+use Illuminate\Http\Client\Response;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
-use JsonException;
class SaveScreenshot implements ShouldQueue
{
@@ -27,77 +28,68 @@ class SaveScreenshot implements ShouldQueue
/**
* Execute the job.
- *
- *
- * @throws JsonException
*/
public function handle(): void
{
- // A normal Guzzle client
- $client = resolve(Client::class);
- // A Guzzle client with a custom Middleware to retry the CloudConvert API requests
- $retryClient = resolve('RetryGuzzle');
+ $cloudConvert = Http::baseUrl('https://api.cloudconvert.com/v2')
+ ->withToken(config('services.cloudconvert.token'))
+ ->throw();
// First request that CloudConvert takes a screenshot of the URL
- $takeScreenshotJobResponse = $client->request('POST', 'https://api.cloudconvert.com/v2/capture-website', [
- 'headers' => [
- 'Authorization' => 'Bearer '.config('services.cloudconvert.token'),
- ],
- 'json' => [
- 'url' => $this->bookmark->url,
- 'output_format' => 'png',
- 'screen_width' => 1440,
- 'screen_height' => 900,
- 'wait_until' => 'networkidle0',
- 'wait_time' => 100,
- ],
+ $takeScreenshotJobResponse = $cloudConvert->post('/capture-website', [
+ 'url' => $this->bookmark->url,
+ 'output_format' => 'png',
+ 'screen_width' => 1440,
+ 'screen_height' => 900,
+ 'wait_until' => 'networkidle0',
+ 'wait_time' => 100,
]);
- $taskId = json_decode($takeScreenshotJobResponse->getBody()->getContents(), false, 512, JSON_THROW_ON_ERROR)->data->id;
+ $taskId = $takeScreenshotJobResponse->json('data.id');
// Now wait till the status job is finished
- $screenshotJobStatusResponse = $retryClient->request('GET', 'https://api.cloudconvert.com/v2/tasks/'.$taskId, [
- 'headers' => [
- 'Authorization' => 'Bearer '.config('services.cloudconvert.token'),
- ],
- 'query' => [
- 'include' => 'payload',
- ],
- ]);
+ $screenshotJobStatusResponse = $this->pollUntilFinished($cloudConvert, $taskId);
- $finishedCaptureId = json_decode($screenshotJobStatusResponse->getBody()->getContents(), false, 512, JSON_THROW_ON_ERROR)->data->id;
+ $finishedCaptureId = $screenshotJobStatusResponse->json('data.id');
// Now we can create a new job to request thst the screenshot is exported to a temporary URL we can download the screenshot from
- $exportImageJob = $client->request('POST', 'https://api.cloudconvert.com/v2/export/url', [
- 'headers' => [
- 'Authorization' => 'Bearer '.config('services.cloudconvert.token'),
- ],
- 'json' => [
- 'input' => $finishedCaptureId,
- 'archive_multiple_files' => false,
- ],
+ $exportImageJob = $cloudConvert->post('/export/url', [
+ 'input' => $finishedCaptureId,
+ 'archive_multiple_files' => false,
]);
- $exportImageJobId = json_decode($exportImageJob->getBody()->getContents(), false, 512, JSON_THROW_ON_ERROR)->data->id;
+ $exportImageJobId = $exportImageJob->json('data.id');
// Again, wait till the status of this export job is finished
- $finalImageUrlResponse = $retryClient->request('GET', 'https://api.cloudconvert.com/v2/tasks/'.$exportImageJobId, [
- 'headers' => [
- 'Authorization' => 'Bearer '.config('services.cloudconvert.token'),
- ],
- 'query' => [
- 'include' => 'payload',
- ],
- ]);
+ $finalImageUrlResponse = $this->pollUntilFinished($cloudConvert, $exportImageJobId);
// Now we can download the screenshot and save it to the storage
- $finalImageUrl = json_decode($finalImageUrlResponse->getBody()->getContents(), false, 512, JSON_THROW_ON_ERROR)->data->result->files[0]->url;
+ $finalImageUrl = $finalImageUrlResponse->json('data.result.files.0.url');
- $finalImageUrlContent = $client->request('GET', $finalImageUrl);
+ $finalImageUrlContent = Http::throw()->get($finalImageUrl);
- Storage::disk('public')->put('/assets/img/bookmarks/'.$taskId.'.png', $finalImageUrlContent->getBody()->getContents());
+ Storage::disk('public')->put('/assets/img/bookmarks/'.$taskId.'.png', $finalImageUrlContent->body());
$this->bookmark->screenshot = $taskId;
$this->bookmark->save();
}
+
+ /**
+ * Poll a CloudConvert task until it reports a "finished" status.
+ */
+ private function pollUntilFinished(PendingRequest $client, string $taskId): Response
+ {
+ $attempts = 0;
+
+ do {
+ $response = $client->get('/tasks/'.$taskId, ['include' => 'payload']);
+ $finished = $response->json('data.status') === 'finished';
+ if (! $finished) {
+ $attempts++;
+ usleep(1_000_000); // 1 second, matches CloudConvert's own polling guidance
+ }
+ } while (! $finished && $attempts < 5);
+
+ return $response;
+ }
}
diff --git a/app/Jobs/SendWebMentions.php b/app/Jobs/SendWebMentions.php
index 827aaf0a..d8e962e3 100644
--- a/app/Jobs/SendWebMentions.php
+++ b/app/Jobs/SendWebMentions.php
@@ -5,8 +5,6 @@ declare(strict_types=1);
namespace App\Jobs;
use App\Models\Note;
-use GuzzleHttp\Client;
-use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Psr7\Header;
use GuzzleHttp\Psr7\UriResolver;
use GuzzleHttp\Psr7\Utils;
@@ -14,6 +12,7 @@ use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Mf2\Parser;
@@ -32,8 +31,6 @@ class SendWebMentions implements ShouldQueue
/**
* Execute the job.
- *
- * @throws GuzzleException
*/
public function handle(): void
{
@@ -43,12 +40,9 @@ class SendWebMentions implements ShouldQueue
foreach ($urls as $url) {
$endpoint = $this->discoverWebmentionEndpoint($url);
if ($endpoint !== null) {
- $guzzle = resolve(Client::class);
- $guzzle->post($endpoint, [
- 'form_params' => [
- 'source' => $this->note->uri,
- 'target' => $url,
- ],
+ Http::asForm()->post($endpoint, [
+ 'source' => $this->note->uri,
+ 'target' => $url,
]);
}
}
@@ -56,8 +50,6 @@ class SendWebMentions implements ShouldQueue
/**
* Discover if a URL has a webmention endpoint.
- *
- * @throws GuzzleException
*/
public function discoverWebmentionEndpoint(string $url): ?string
{
@@ -71,10 +63,9 @@ class SendWebMentions implements ShouldQueue
$endpoint = null;
- $guzzle = resolve(Client::class);
- $response = $guzzle->get($url);
+ $response = Http::get($url);
// check HTTP Headers for webmention endpoint
- $links = Header::parse($response->getHeader('Link'));
+ $links = Header::parse($response->header('Link'));
foreach ($links as $link) {
if (array_key_exists('rel', $link) && mb_stristr($link['rel'], 'webmention')) {
return $this->resolveUri(trim($link[0], '<>'), $url);
@@ -82,7 +73,7 @@ class SendWebMentions implements ShouldQueue
}
// failed to find a header so parse HTML
- $html = (string) $response->getBody();
+ $html = $response->body();
if ($html === '') {
return null;
diff --git a/app/Jobs/SyndicateNoteToBluesky.php b/app/Jobs/SyndicateNoteToBluesky.php
index a306801b..582ef760 100644
--- a/app/Jobs/SyndicateNoteToBluesky.php
+++ b/app/Jobs/SyndicateNoteToBluesky.php
@@ -5,13 +5,12 @@ declare(strict_types=1);
namespace App\Jobs;
use App\Models\Note;
-use GuzzleHttp\Client;
-use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Facades\Http;
class SyndicateNoteToBluesky implements ShouldQueue
{
@@ -31,29 +30,18 @@ class SyndicateNoteToBluesky implements ShouldQueue
/**
* Execute the job.
- *
- * @throws GuzzleException
*/
- public function handle(Client $guzzle): void
+ public function handle(): void
{
- $response = $guzzle->request(
- 'POST',
- 'https://brid.gy/publish/webmention',
- [
- 'headers' => [
- 'Accept' => 'application/json',
- ],
- 'form_params' => [
- 'source' => $this->note->uri,
- 'target' => 'https://brid.gy/publish/bluesky',
- ],
- 'http_errors' => false,
- ]
- );
+ // no ->throw()/->retry() here — Bridgy would duplicate-publish on retry, see $tries above
+ $response = Http::acceptJson()->asForm()->post('https://brid.gy/publish/webmention', [
+ 'source' => $this->note->uri,
+ 'target' => 'https://brid.gy/publish/bluesky',
+ ]);
- $body = json_decode((string) $response->getBody(), true);
+ $body = $response->json();
- if ($response->getStatusCode() === 201) {
+ if ($response->status() === 201) {
$this->note->bluesky_url = $body['url'];
$this->note->save();
@@ -61,7 +49,7 @@ class SyndicateNoteToBluesky implements ShouldQueue
}
throw new \RuntimeException(
- 'Bridgy publish to Bluesky failed: '.($body['error'] ?? (string) $response->getBody())
+ 'Bridgy publish to Bluesky failed: '.($body['error'] ?? $response->body())
);
}
}
diff --git a/app/Jobs/SyndicateNoteToMastodon.php b/app/Jobs/SyndicateNoteToMastodon.php
index 456680e2..3f5cfcd4 100644
--- a/app/Jobs/SyndicateNoteToMastodon.php
+++ b/app/Jobs/SyndicateNoteToMastodon.php
@@ -5,13 +5,12 @@ declare(strict_types=1);
namespace App\Jobs;
use App\Models\Note;
-use GuzzleHttp\Client;
-use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Facades\Http;
class SyndicateNoteToMastodon implements ShouldQueue
{
@@ -31,29 +30,18 @@ class SyndicateNoteToMastodon implements ShouldQueue
/**
* Execute the job.
- *
- * @throws GuzzleException
*/
- public function handle(Client $guzzle): void
+ public function handle(): void
{
- $response = $guzzle->request(
- 'POST',
- 'https://brid.gy/publish/webmention',
- [
- 'headers' => [
- 'Accept' => 'application/json',
- ],
- 'form_params' => [
- 'source' => $this->note->uri,
- 'target' => 'https://brid.gy/publish/mastodon',
- ],
- 'http_errors' => false,
- ]
- );
+ // no ->throw()/->retry() here — Bridgy would duplicate-publish on retry, see $tries above
+ $response = Http::acceptJson()->asForm()->post('https://brid.gy/publish/webmention', [
+ 'source' => $this->note->uri,
+ 'target' => 'https://brid.gy/publish/mastodon',
+ ]);
- $body = json_decode((string) $response->getBody(), true);
+ $body = $response->json();
- if ($response->getStatusCode() === 201) {
+ if ($response->status() === 201) {
$this->note->mastodon_url = $body['url'];
$this->note->save();
@@ -61,7 +49,7 @@ class SyndicateNoteToMastodon implements ShouldQueue
}
throw new \RuntimeException(
- 'Bridgy publish to Mastodon failed: '.($body['error'] ?? (string) $response->getBody())
+ 'Bridgy publish to Mastodon failed: '.($body['error'] ?? $response->body())
);
}
}
diff --git a/app/Models/About.php b/app/Models/About.php
new file mode 100644
index 00000000..26b6a719
--- /dev/null
+++ b/app/Models/About.php
@@ -0,0 +1,13 @@
+ [
'source' => 'title',
+ 'includeTrashed' => true,
],
];
}
@@ -93,6 +94,21 @@ class Article extends Model
);
}
+ protected function uri(): Attribute
+ {
+ return Attribute::get(
+ get: fn () => config('app.url').$this->link,
+ );
+ }
+
+ /**
+ * Scope a query to only include published (non-draft) articles.
+ */
+ public function scopePublished(Builder $query): Builder
+ {
+ return $query->where('published', 1);
+ }
+
/**
* Scope a query to only include articles from a particular year/month.
*/
diff --git a/app/Models/Bookmark.php b/app/Models/Bookmark.php
index 1c5ae6e4..5b37d84c 100644
--- a/app/Models/Bookmark.php
+++ b/app/Models/Bookmark.php
@@ -25,7 +25,7 @@ class Bookmark extends Model
return $this->belongsToMany('App\Models\Tag');
}
- protected function localUri(): Attribute
+ protected function uri(): Attribute
{
return Attribute::get(
get: fn () => config('app.url').'/bookmarks/'.$this->id,
diff --git a/app/Models/Like.php b/app/Models/Like.php
index 44f25b91..8f2521ef 100644
--- a/app/Models/Like.php
+++ b/app/Models/Like.php
@@ -18,6 +18,13 @@ class Like extends Model
use FilterHtml;
use HasFactory;
+ protected function uri(): Attribute
+ {
+ return Attribute::get(
+ get: fn () => config('app.url').'/likes/'.$this->id,
+ );
+ }
+
protected function url(): Attribute
{
return Attribute::set(
diff --git a/app/Models/MicropubToken.php b/app/Models/MicropubToken.php
new file mode 100644
index 00000000..c4df41bc
--- /dev/null
+++ b/app/Models/MicropubToken.php
@@ -0,0 +1,50 @@
+ 'datetime',
+ ];
+ }
+
+ public function revoke(): void
+ {
+ $this->forceFill(['revoked_at' => now()])->save();
+ }
+
+ /**
+ * Find the active (non-revoked) token matching a raw bearer token value.
+ *
+ * Accepts mixed because callers pass request input directly, which PHP
+ * lets be an array (e.g. a client sending token[]=a) - casting that to
+ * string would throw, so anything non-string is just treated as absent.
+ */
+ public static function findActive(mixed $rawToken): ?self
+ {
+ if (! is_string($rawToken) || $rawToken === '') {
+ return null;
+ }
+
+ return self::where('token_hash', hash('sha256', $rawToken))
+ ->whereNull('revoked_at')
+ ->first();
+ }
+
+ protected function isRevoked(): Attribute
+ {
+ return Attribute::make(
+ get: fn () => $this->revoked_at !== null,
+ );
+ }
+}
diff --git a/app/Models/Note.php b/app/Models/Note.php
index af7d2c3d..89ce6b63 100644
--- a/app/Models/Note.php
+++ b/app/Models/Note.php
@@ -7,7 +7,6 @@ namespace App\Models;
use App\CommonMark\Generators\MentionGenerator;
use App\CommonMark\Renderers\MentionRenderer;
use App\Observers\NoteObserver;
-use GuzzleHttp\Client;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
@@ -20,6 +19,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\Http;
use Jonnybarnes\IndieWeb\Numbers;
use Laravel\Scout\Searchable;
use League\CommonMark\Environment\Environment;
@@ -363,18 +363,15 @@ class Note extends Model
$latLng = $latitude.','.$longitude;
return Cache::get($latLng, function () use ($latLng, $latitude, $longitude) {
- $guzzle = resolve(Client::class);
- $response = $guzzle->request('GET', 'https://nominatim.openstreetmap.org/reverse', [
- 'query' => [
+ $response = Http::withHeaders(['User-Agent' => 'jonnybarnes.uk, email jonny@jonnybarnes.uk'])
+ ->get('https://nominatim.openstreetmap.org/reverse', [
'format' => 'json',
'lat' => $latitude,
'lon' => $longitude,
'zoom' => 18,
'addressdetails' => 1,
- ],
- 'headers' => ['User-Agent' => 'jonnybarnes.uk via Guzzle, email jonny@jonnybarnes.uk'],
- ]);
- $json = json_decode((string) $response->getBody());
+ ]);
+ $json = $response->object();
if (isset($json->address->suburb)) {
$locality = $json->address->suburb;
if (isset($json->address->city)) {
diff --git a/app/Models/Setting.php b/app/Models/Setting.php
new file mode 100644
index 00000000..0c84ea36
--- /dev/null
+++ b/app/Models/Setting.php
@@ -0,0 +1,18 @@
+
+ */
+ protected $casts = [
+ 'winter_effect_enabled' => 'boolean',
+ ];
+}
diff --git a/app/Models/WebMention.php b/app/Models/WebMention.php
index 2cdebee8..2c566d9e 100644
--- a/app/Models/WebMention.php
+++ b/app/Models/WebMention.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Models;
+use App\Services\WebMention\Authorship;
use App\Traits\FilterHtml;
use Exception;
use Illuminate\Database\Eloquent\Attributes\Guarded;
@@ -13,7 +14,6 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Filesystem\Filesystem;
-use Jonnybarnes\WebmentionsParser\Authorship;
#[Table('webmentions')]
#[Guarded(['id'])]
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index ba42853e..a40ae43f 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -2,19 +2,13 @@
namespace App\Providers;
-use GuzzleHttp\Client;
-use GuzzleHttp\Exception\ConnectException;
-use GuzzleHttp\HandlerStack;
-use GuzzleHttp\Middleware;
+use App\Models\Setting;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\URL;
+use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
-use Intervention\Image\ImageManager;
-use Lcobucci\JWT\Configuration;
-use Lcobucci\JWT\Signer\Hmac\Sha256;
-use Lcobucci\JWT\Signer\Key\InMemory;
-use Lcobucci\JWT\Validation\Constraint\SignedWith;
use Symfony\Component\HtmlSanitizer\HtmlSanitizer;
use Symfony\Component\HtmlSanitizer\HtmlSanitizerConfig;
@@ -33,11 +27,6 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot(): void
{
- // configure Intervention/Image
- $this->app->bind('Intervention\Image\ImageManager', function () {
- return ImageManager::withDriver(config('image.driver'));
- });
-
/**
* Paginate a standard Laravel Collection.
*
@@ -62,17 +51,6 @@ class AppServiceProvider extends ServiceProvider
);
});
- // Configure JWT builder
- $this->app->bind('Lcobucci\JWT\Configuration', function () {
- $key = InMemory::plainText(config('app.key'));
-
- $config = Configuration::forSymmetricSigner(new Sha256, $key);
-
- $config->setValidationConstraints(new SignedWith(new Sha256, $key));
-
- return $config;
- });
-
// Configure HtmlSanitizer
$this->app->bind(HtmlSanitizer::class, function () {
return new HtmlSanitizer(
@@ -82,39 +60,15 @@ class AppServiceProvider extends ServiceProvider
);
});
- // Configure Guzzle
- $this->app->bind('RetryGuzzle', function () {
- $handlerStack = HandlerStack::create();
- $handlerStack->push(Middleware::retry(
- function ($retries, $request, $response, $exception) {
- // Limit the number of retries to 5
- if ($retries >= 5) {
- return false;
- }
-
- // Retry connection exceptions
- if ($exception instanceof ConnectException) {
- return true;
- }
-
- // Retry on server errors
- if ($response && $response->getStatusCode() >= 500) {
- return true;
- }
-
- // Finally for CloudConvert, retry if status is not final
- return json_decode($response, false, 512, JSON_THROW_ON_ERROR)->data->status !== 'finished';
- },
- function () {
- // Retry after 1 second
- return 1000;
- }
- ));
-
- return new Client(['handler' => $handlerStack]);
- });
-
// Turn on Eloquent strict mode when developing
Model::shouldBeStrict(! $this->app->isProduction());
+
+ // Force HTTPS URL generation in production
+ URL::forceHttps($this->app->isProduction());
+
+ // Share whether the winter snow effect is enabled with the base layout
+ View::composer('master', function ($view) {
+ $view->with('winterEffectEnabled', Setting::first()?->winter_effect_enabled ?? false);
+ });
}
}
diff --git a/app/Services/ArticleService.php b/app/Services/ArticleService.php
index 3d5dcc56..ab91f9e4 100644
--- a/app/Services/ArticleService.php
+++ b/app/Services/ArticleService.php
@@ -8,12 +8,29 @@ use App\Models\Article;
class ArticleService
{
+ /**
+ * @throws \InvalidArgumentException if a published article already has this title
+ */
public function create(array $data): Article
{
- return Article::create([
+ $attributes = [
'title' => $data['name'],
'main' => $data['content'],
- 'published' => true,
- ]);
+ 'published' => ($data['post-status'] ?? null) !== 'draft',
+ ];
+
+ $existing = Article::where('title', $data['name'])->first();
+
+ if ($existing !== null) {
+ if ($existing->published) {
+ throw new \InvalidArgumentException("An article titled \"{$data['name']}\" has already been published");
+ }
+
+ $existing->update($attributes);
+
+ return $existing;
+ }
+
+ return Article::create($attributes);
}
}
diff --git a/app/Services/BookmarkService.php b/app/Services/BookmarkService.php
index 25017e16..b873610f 100644
--- a/app/Services/BookmarkService.php
+++ b/app/Services/BookmarkService.php
@@ -8,10 +8,8 @@ use App\Exceptions\InternetArchiveException;
use App\Jobs\ProcessBookmark;
use App\Models\Bookmark;
use App\Models\Tag;
-use GuzzleHttp\Client;
-use GuzzleHttp\Exception\ClientException;
-use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Arr;
+use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
class BookmarkService
@@ -55,21 +53,19 @@ class BookmarkService
* Given a URL, attempt to save it to the Internet Archive.
*
* @throws InternetArchiveException
- * @throws GuzzleException
*/
public function getArchiveLink(string $url): string
{
- $client = resolve(Client::class);
- try {
- $response = $client->request('GET', 'https://web.archive.org/save/'.$url);
- } catch (ClientException $e) {
+ $response = Http::get('https://web.archive.org/save/'.$url);
+
+ if ($response->clientError()) {
// throw an exception to be caught
throw new InternetArchiveException;
}
- if ($response->hasHeader('Content-Location')) {
- if (Str::startsWith(Arr::get($response->getHeader('Content-Location'), 0), '/web')) {
- return $response->getHeader('Content-Location')[0];
- }
+
+ $contentLocation = $response->header('Content-Location');
+ if ($contentLocation !== '' && Str::startsWith($contentLocation, '/web')) {
+ return $contentLocation;
}
// throw an exception to be caught
diff --git a/app/Services/Micropub/Data/EntryData.php b/app/Services/Micropub/Data/EntryData.php
index 52dde72d..044127ce 100644
--- a/app/Services/Micropub/Data/EntryData.php
+++ b/app/Services/Micropub/Data/EntryData.php
@@ -24,6 +24,8 @@ class EntryData extends MicropubData
public readonly mixed $checkin,
public readonly mixed $syndication,
public readonly ?array $photos,
+ public readonly ?string $postStatus,
+ public readonly ?array $category,
) {}
public static function fromRequest(Request $request): static
@@ -49,6 +51,8 @@ class EntryData extends MicropubData
checkin: Arr::get($data, 'properties.checkin.0'),
syndication: Arr::get($data, 'properties.syndication.0'),
photos: Arr::get($data, 'properties.photo'),
+ postStatus: Arr::get($data, 'properties.post-status.0'),
+ category: Arr::get($data, 'properties.category'),
);
}
@@ -60,16 +64,27 @@ class EntryData extends MicropubData
location: $request->input('location'),
bookmarkOf: $request->input('bookmark-of'),
likeOf: $request->input('like-of'),
- mpSyndicateTo: $request->input('mp-syndicate-to'),
+ mpSyndicateTo: self::wrapFormValue($request->input('mp-syndicate-to')),
name: $request->input('name'),
description: $request->input('description'),
geo: $request->input('geo'),
checkin: $request->input('checkin'),
syndication: $request->input('syndication'),
- photos: $request->input('photos'),
+ photos: self::wrapFormValue($request->input('photo')),
+ postStatus: $request->input('post-status'),
+ category: self::wrapFormValue($request->input('category')),
);
}
+ /**
+ * Form-encoded multi-value properties may be sent with or without the []
+ * suffix, so a single value arrives as a string rather than an array.
+ */
+ private static function wrapFormValue(mixed $value): ?array
+ {
+ return $value === null ? null : Arr::wrap($value);
+ }
+
private static function extractLocationData(array $data): array|string|null
{
if (! Arr::has($data, 'properties.location')) {
@@ -100,6 +115,8 @@ class EntryData extends MicropubData
checkin: $data['checkin'] ?? null,
syndication: $data['syndication'] ?? null,
photos: $data['photos'] ?? null,
+ postStatus: $data['post-status'] ?? null,
+ category: $data['category'] ?? null,
);
}
@@ -120,6 +137,8 @@ class EntryData extends MicropubData
'checkin' => $this->checkin,
'syndication' => $this->syndication,
'photos' => $this->photos,
+ 'post-status' => $this->postStatus,
+ 'category' => $this->category,
];
}
}
diff --git a/app/Services/Micropub/Handlers/CardHandler.php b/app/Services/Micropub/Handlers/CardHandler.php
index 02e3a066..6b24f21b 100644
--- a/app/Services/Micropub/Handlers/CardHandler.php
+++ b/app/Services/Micropub/Handlers/CardHandler.php
@@ -24,9 +24,7 @@ class CardHandler implements MicropubHandlerInterface
assert($data instanceof CardData);
$scopes = $data->tokenData['scope'];
- if (is_string($scopes)) {
- $scopes = explode(' ', $scopes);
- }
+ $scopes = explode(' ', $scopes);
if (! in_array('create', $scopes, true)) {
throw new InvalidTokenScopeException;
diff --git a/app/Services/Micropub/Handlers/EntryHandler.php b/app/Services/Micropub/Handlers/EntryHandler.php
index ef9740f2..6b68b88c 100644
--- a/app/Services/Micropub/Handlers/EntryHandler.php
+++ b/app/Services/Micropub/Handlers/EntryHandler.php
@@ -27,9 +27,7 @@ class EntryHandler implements MicropubHandlerInterface
assert($data instanceof EntryData);
$scopes = $data->tokenData['scope'];
- if (is_string($scopes)) {
- $scopes = explode(' ', $scopes);
- }
+ $scopes = explode(' ', $scopes);
if (! in_array('create', $scopes, true)) {
throw new InvalidTokenScopeException;
@@ -37,9 +35,9 @@ class EntryHandler implements MicropubHandlerInterface
$dataArray = $data->toArray();
$location = match (true) {
- isset($dataArray['like-of']) => resolve(LikeService::class)->create($dataArray)->url,
+ isset($dataArray['like-of']) => resolve(LikeService::class)->create($dataArray)->uri,
isset($dataArray['bookmark-of']) => resolve(BookmarkService::class)->create($dataArray)->uri,
- isset($dataArray['name']) => resolve(ArticleService::class)->create($dataArray)->link,
+ isset($dataArray['name']) => resolve(ArticleService::class)->create($dataArray)->uri,
default => resolve(NoteService::class)->create($dataArray)->uri,
};
diff --git a/app/Services/Micropub/Handlers/UpdateHandler.php b/app/Services/Micropub/Handlers/UpdateHandler.php
index 49f86063..5515444d 100644
--- a/app/Services/Micropub/Handlers/UpdateHandler.php
+++ b/app/Services/Micropub/Handlers/UpdateHandler.php
@@ -9,12 +9,34 @@ use App\Exceptions\MicropubHandlerException;
use App\Exceptions\MicropubUnsupportedModelException;
use App\Models\Media;
use App\Models\Note;
+use App\Models\SyndicationTarget;
use App\Services\Micropub\Data\MicropubData;
use App\Services\Micropub\Data\UpdateData;
+use App\Services\Micropub\NoteResolver;
use Illuminate\Support\Str;
class UpdateHandler implements MicropubHandlerInterface
{
+ /**
+ * The properties each update operation can change.
+ */
+ private const SUPPORTED_PROPERTIES = [
+ 'replace' => ['content', 'syndication'],
+ 'add' => ['syndication', 'photo'],
+ 'delete' => ['syndication', 'photo'],
+ ];
+
+ /**
+ * The syndication URLs we have somewhere to store. Mastodon URLs are also
+ * accepted, based on the instances in our syndication targets.
+ */
+ private const SYNDICATION_PREFIXES = [
+ 'https://www.facebook.com',
+ 'https://www.swarmapp.com',
+ 'https://twitter.com',
+ 'https://bsky.app',
+ ];
+
public function dataClass(): string
{
return UpdateData::class;
@@ -30,32 +52,29 @@ class UpdateHandler implements MicropubHandlerInterface
assert($data instanceof UpdateData);
$scopes = $data->tokenData['scope'];
- if (is_string($scopes)) {
- $scopes = explode(' ', $scopes);
- }
+ $scopes = explode(' ', $scopes);
if (! in_array('update', $scopes, true)) {
throw new InvalidTokenScopeException;
}
- $urlPath = parse_url($data->updateUrl, PHP_URL_PATH);
-
- if (mb_substr($urlPath, 1, 5) !== 'notes') {
- throw new MicropubUnsupportedModelException('This implementation currently only supports the updating of notes');
+ if ($data->updateUrl === null) {
+ throw new MicropubHandlerException('The url parameter is required');
}
- $note = Note::nb60(basename($urlPath))->firstOrFail();
+ $note = resolve(NoteResolver::class)->fromUrl($data->updateUrl);
- if ($data->updateReplace === null && $data->updateAdd === null && $data->updateDelete === null) {
+ if (! $data->updateReplace && ! $data->updateAdd && ! $data->updateDelete) {
throw new MicropubHandlerException('Unsupported update operation');
}
+ $this->validateOperations($data);
+
if ($data->updateReplace !== null) {
foreach ($data->updateReplace as $property => $value) {
match ($property) {
'content' => $note->note = is_array($value[0]) ? ($value[0]['html'] ?? $value[0]['value'] ?? null) : $value[0],
'syndication' => $this->applySyndication($note, $value),
- default => null,
};
}
}
@@ -67,13 +86,11 @@ class UpdateHandler implements MicropubHandlerInterface
}
if ($property === 'photo') {
foreach ($value as $photoURL) {
- if (Str::startsWith($photoURL, 'https://')) {
- $media = new Media;
- $media->path = $photoURL;
- $media->type = 'image';
- $media->save();
- $note->media()->save($media);
- }
+ $media = new Media;
+ $media->path = $photoURL;
+ $media->type = 'image';
+ $media->save();
+ $note->media()->save($media);
}
}
}
@@ -91,6 +108,77 @@ class UpdateHandler implements MicropubHandlerInterface
];
}
+ /**
+ * Check the whole request before applying any of it, so that a bad value
+ * can't leave a note partially updated, and a client is never told an
+ * update worked when we ignored it. The spec requires the values of each
+ * property to be arrays.
+ *
+ * @throws MicropubHandlerException
+ */
+ private function validateOperations(UpdateData $data): void
+ {
+ foreach (['replace' => $data->updateReplace ?? [], 'add' => $data->updateAdd ?? []] as $operation => $properties) {
+ foreach ($properties as $property => $values) {
+ if (! is_string($property) || ! is_array($values) || $values === [] || ! array_is_list($values)) {
+ throw new MicropubHandlerException('The values of each property must be a non-empty array');
+ }
+
+ $this->validateProperty($operation, $property, $values);
+ }
+ }
+
+ $delete = $data->updateDelete ?? [];
+
+ if (array_is_list($delete)) {
+ foreach ($delete as $property) {
+ if (! is_string($property)) {
+ throw new MicropubHandlerException('The properties to delete must be strings');
+ }
+
+ $this->validateProperty('delete', $property, []);
+ }
+
+ return;
+ }
+
+ foreach ($delete as $property => $values) {
+ if (! is_array($values) || ! array_is_list($values)) {
+ throw new MicropubHandlerException('The values of each property must be an array');
+ }
+
+ $this->validateProperty('delete', $property, $values);
+ }
+ }
+
+ /**
+ * @throws MicropubHandlerException
+ */
+ private function validateProperty(string $operation, string $property, array $values): void
+ {
+ if (! in_array($property, self::SUPPORTED_PROPERTIES[$operation], true)) {
+ throw new MicropubHandlerException("This server does not support the {$operation} operation on the {$property} property");
+ }
+
+ foreach ($values as $value) {
+ if ($property === 'content' && is_array($value)) {
+ $value = $value['html'] ?? $value['value'] ?? null;
+ }
+
+ if (! is_string($value)) {
+ throw new MicropubHandlerException("The {$property} property has an invalid value");
+ }
+
+ if ($property === 'syndication' && ! Str::startsWith($value, [...self::SYNDICATION_PREFIXES, ...$this->mastodonPrefixes()])) {
+ throw new MicropubHandlerException("This server can not store the syndication URL {$value}");
+ }
+
+ if ($operation === 'add' && $property === 'photo' && ! Str::startsWith($value, 'https://')) {
+ throw new MicropubHandlerException('Photos must be added using an https URL');
+ }
+ }
+ }
+
private function applyDelete(Note $note, array $delete): void
{
if (array_is_list($delete)) {
@@ -98,7 +186,6 @@ class UpdateHandler implements MicropubHandlerInterface
match ($property) {
'syndication' => $this->clearSyndication($note),
'photo' => $note->media()->delete(),
- default => null,
};
}
@@ -115,11 +202,28 @@ class UpdateHandler implements MicropubHandlerInterface
}
}
+ /**
+ * Mastodon can be on any host, so use the instances we syndicate to.
+ *
+ * @return string[]
+ */
+ private function mastodonPrefixes(): array
+ {
+ return SyndicationTarget::where('service_name', 'Mastodon')
+ ->pluck('uid')
+ ->map(fn (string $uid) => parse_url($uid, PHP_URL_HOST))
+ ->filter()
+ ->map(fn (string $host) => "https://{$host}/")
+ ->all();
+ }
+
private function clearSyndication(Note $note): void
{
$note->facebook_url = null;
$note->swarm_url = null;
$note->tweet_id = null;
+ $note->mastodon_url = null;
+ $note->bluesky_url = null;
}
private function removeSyndicationValues(Note $note, array $urls): void
@@ -131,6 +235,10 @@ class UpdateHandler implements MicropubHandlerInterface
$note->swarm_url = null;
} elseif (Str::startsWith($url, 'https://twitter.com')) {
$note->tweet_id = null;
+ } elseif (Str::startsWith($url, $this->mastodonPrefixes()) && $note->mastodon_url === $url) {
+ $note->mastodon_url = null;
+ } elseif (Str::startsWith($url, 'https://bsky.app') && $note->bluesky_url === $url) {
+ $note->bluesky_url = null;
}
}
}
@@ -144,6 +252,10 @@ class UpdateHandler implements MicropubHandlerInterface
$note->swarm_url = $url;
} elseif (Str::startsWith($url, 'https://twitter.com')) {
$note->tweet_id = basename(parse_url($url, PHP_URL_PATH));
+ } elseif (Str::startsWith($url, $this->mastodonPrefixes())) {
+ $note->mastodon_url = $url;
+ } elseif (Str::startsWith($url, 'https://bsky.app')) {
+ $note->bluesky_url = $url;
}
}
}
diff --git a/app/Services/Micropub/MicropubHandlerRegistry.php b/app/Services/Micropub/MicropubHandlerRegistry.php
index be393bf5..e6438fa9 100644
--- a/app/Services/Micropub/MicropubHandlerRegistry.php
+++ b/app/Services/Micropub/MicropubHandlerRegistry.php
@@ -51,7 +51,7 @@ class MicropubHandlerRegistry
public function getHandler(string $type): MicropubHandlerInterface
{
if (! isset($this->handlers[$type])) {
- throw new MicropubHandlerException("No handler registered for '{$type}'");
+ throw new MicropubHandlerException("Unsupported Micropub request type '{$type}'");
}
return $this->handlers[$type];
diff --git a/app/Services/Micropub/NoteResolver.php b/app/Services/Micropub/NoteResolver.php
new file mode 100644
index 00000000..26d8d39a
--- /dev/null
+++ b/app/Services/Micropub/NoteResolver.php
@@ -0,0 +1,43 @@
+firstOrFail();
+ } catch (NotFoundHttpException) {
+ // Note::scopeNb60() aborts when the ID is too big for the database
+ throw (new ModelNotFoundException)->setModel(Note::class);
+ }
+ }
+}
diff --git a/app/Services/Micropub/NoteSource.php b/app/Services/Micropub/NoteSource.php
new file mode 100644
index 00000000..e0360e8b
--- /dev/null
+++ b/app/Services/Micropub/NoteSource.php
@@ -0,0 +1,68 @@
+properties($note);
+
+ if ($requested !== []) {
+ return ['properties' => (object) array_intersect_key($properties, array_flip($requested))];
+ }
+
+ return ['type' => ['h-entry'], 'properties' => (object) $properties];
+ }
+
+ private function properties(Note $note): array
+ {
+ $media = $note->media;
+
+ return array_filter([
+ // the raw source, as the note accessor returns the rendered HTML
+ 'content' => array_filter([$note->getRawOriginal('note')], fn ($value) => $value !== null),
+ 'published' => [$note->created_at->toIso8601String()],
+ 'in-reply-to' => array_filter([$note->in_reply_to]),
+ 'category' => $note->tags->pluck('tag')->all(),
+ 'photo' => $media->where('type', 'image')->map(fn ($item) => $item->pivot->alt_text
+ ? ['value' => $item->url, 'alt' => $item->pivot->alt_text]
+ : $item->url)->values()->all(),
+ 'video' => $media->where('type', 'video')->pluck('url')->all(),
+ 'audio' => $media->where('type', 'audio')->pluck('url')->all(),
+ 'syndication' => array_values(array_filter([
+ $note->tweet_id ? 'https://twitter.com/i/web/status/'.$note->tweet_id : null,
+ $note->facebook_url,
+ $note->swarm_url,
+ $note->mastodon_url,
+ $note->bluesky_url,
+ ])),
+ 'location' => $this->location($note),
+ ], fn (array $values) => $values !== []);
+ }
+
+ private function location(Note $note): array
+ {
+ if ($note->place !== null) {
+ return [$note->place->uri];
+ }
+
+ if ($note->getRawOriginal('location') !== null) {
+ return ['geo:'.$note->latitude.','.$note->longitude];
+ }
+
+ return [];
+ }
+}
diff --git a/app/Services/NoteService.php b/app/Services/NoteService.php
index 2fbe45a2..87c4007f 100644
--- a/app/Services/NoteService.php
+++ b/app/Services/NoteService.php
@@ -30,6 +30,9 @@ class NoteService
$content = null;
}
+ // an invalid date throws, so parse it before anything is saved
+ $published = $this->getPublished($data);
+
$note = Note::create(
[
'note' => $content,
@@ -38,7 +41,7 @@ class NoteService
]
);
- if ($published = $this->getPublished($data)) {
+ if ($published !== null) {
$note->created_at = $note->updated_at = $published;
}
@@ -205,11 +208,11 @@ class NoteService
if (is_string($photo)) {
$photoUrl = $photo;
} elseif (is_array($photo)) {
- $photoUrl = $photo['value'];
- $photoAlt = $photo['alt'];
+ $photoUrl = $photo['value'] ?? null;
+ $photoAlt = is_string($photo['alt'] ?? null) ? $photo['alt'] : null;
}
- if (empty($photoUrl)) {
+ if (! is_string($photoUrl) || $photoUrl === '') {
continue;
}
diff --git a/app/Services/TokenService.php b/app/Services/TokenService.php
index 68a9293b..2941c28b 100644
--- a/app/Services/TokenService.php
+++ b/app/Services/TokenService.php
@@ -5,28 +5,26 @@ declare(strict_types=1);
namespace App\Services;
use App\Jobs\AddClientToDatabase;
-use DateTimeImmutable;
-use Lcobucci\JWT\Configuration;
+use App\Models\MicropubToken;
class TokenService
{
/**
- * Generate a JWT token.
+ * Generate a new bearer token.
*/
public function getNewToken(array $data): string
{
- $config = resolve(Configuration::class);
+ $token = rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=');
- $token = $config->builder()
- ->issuedAt(new DateTimeImmutable)
- ->withClaim('client_id', $data['client_id'])
- ->withClaim('me', $data['me'])
- ->withClaim('scope', $data['scope'])
- ->withClaim('nonce', bin2hex(random_bytes(8)))
- ->getToken($config->signer(), $config->signingKey());
+ MicropubToken::create([
+ 'token_hash' => hash('sha256', $token),
+ 'client_id' => $data['client_id'],
+ 'me' => $data['me'],
+ 'scope' => $data['scope'],
+ ]);
dispatch(new AddClientToDatabase($data['client_id']));
- return $token->toString();
+ return $token;
}
}
diff --git a/app/Services/WebMention/Authorship.php b/app/Services/WebMention/Authorship.php
new file mode 100644
index 00000000..fb0e6c9f
--- /dev/null
+++ b/app/Services/WebMention/Authorship.php
@@ -0,0 +1,152 @@
+normalise($author);
+ }
+ }
+
+ // If no author-page and h-entry is a permalink then use the rel-author link
+ if ($authorPage === null && $permalink && isset($mf['rels']['author'])) {
+ $authorPage = is_array($mf['rels']['author']) ? $mf['rels']['author'][0] : $mf['rels']['author'];
+ }
+
+ if ($authorPage === null) {
+ return false;
+ }
+
+ return $this->findAuthorOnPage($authorPage);
+ }
+
+ /**
+ * Fetch the author-page and look for a representative h-card on it.
+ *
+ * @throws AuthorshipParserException
+ */
+ private function findAuthorOnPage(string $authorPage): array|false
+ {
+ try {
+ $response = Http::get($authorPage);
+ } catch (ConnectionException) {
+ throw new AuthorshipParserException('Unable to connect to the author’s page');
+ }
+
+ if ($response->failed()) {
+ throw new AuthorshipParserException('Unable to get the content from the author’s page');
+ }
+
+ $authorMf2 = parse($response->body(), $authorPage);
+ $hCards = array_filter(
+ $authorMf2['items'] ?? [],
+ fn (array $item): bool => in_array('h-card', $item['type'] ?? [], true)
+ );
+
+ // Use the first h-card where url == uid == author-page
+ foreach ($hCards as $hCard) {
+ if (
+ in_array($authorPage, $hCard['properties']['url'] ?? [], true)
+ && in_array($authorPage, $hCard['properties']['uid'] ?? [], true)
+ ) {
+ return $this->normalise($hCard);
+ }
+ }
+
+ // Else the first h-card with a url that matches a rel-me link on the page
+ $relMeLinks = $authorMf2['rels']['me'] ?? [];
+ foreach ($hCards as $hCard) {
+ foreach ($hCard['properties']['url'] ?? [] as $url) {
+ if (in_array($url, $relMeLinks, true)) {
+ return $this->normalise($hCard);
+ }
+ }
+ }
+
+ // Else the first h-card with url == author-page
+ foreach ($hCards as $hCard) {
+ if (in_array($authorPage, $hCard['properties']['url'] ?? [], true)) {
+ return $this->normalise($hCard);
+ }
+ }
+
+ return false;
+ }
+
+ private function normalise(array|string $author): array|string
+ {
+ if (is_array($author) && array_key_exists(0, $author)) {
+ $author = $author[0];
+ }
+
+ if (is_string($author)) {
+ return $author;
+ }
+
+ unset($author['value'], $author['children']);
+
+ return $author;
+ }
+}
diff --git a/app/Services/WebMention/Parser.php b/app/Services/WebMention/Parser.php
new file mode 100644
index 00000000..e3e47a17
--- /dev/null
+++ b/app/Services/WebMention/Parser.php
@@ -0,0 +1,86 @@
+arrayKeyExistsRecursive($type, $microformats)) {
+ return $type;
+ }
+ }
+
+ throw new InvalidMentionException;
+ }
+
+ /**
+ * Check a reply is to the intended target.
+ */
+ public function checkInReplyTo(array $microformats, string $target): bool
+ {
+ foreach ($microformats['items'] ?? [] as $item) {
+ $inReplyTo = $item['properties']['in-reply-to'] ?? null;
+ if ($inReplyTo === null) {
+ continue;
+ }
+
+ // The reply context may be an h-cite rather than a plain URL
+ if (is_array($inReplyTo[0]) && ($inReplyTo[0]['properties']['url'][0] ?? null) === $target) {
+ return true;
+ }
+
+ if (in_array($target, $inReplyTo, true)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Check the microformats contain a like of the target.
+ */
+ public function checkLikeOf(array $microformats, string $target): bool
+ {
+ return in_array($target, $microformats['items'][0]['properties']['like-of'] ?? [], true);
+ }
+
+ /**
+ * Check the microformats contain a repost of the target.
+ */
+ public function checkRepostOf(array $microformats, string $target): bool
+ {
+ return in_array($target, $microformats['items'][0]['properties']['repost-of'] ?? [], true);
+ }
+
+ private function arrayKeyExistsRecursive(string $needle, array $haystack): bool
+ {
+ if (array_key_exists($needle, $haystack)) {
+ return true;
+ }
+
+ foreach ($haystack as $value) {
+ if (is_array($value) && $this->arrayKeyExistsRecursive($needle, $value)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/bootstrap/app.php b/bootstrap/app.php
index 9c73bdb9..e29a3598 100644
--- a/bootstrap/app.php
+++ b/bootstrap/app.php
@@ -17,8 +17,10 @@ return Application::configure(basePath: dirname(__DIR__))
->append(LinkHeadersMiddleware::class)
->preventRequestForgery(
except: [
- 'auth', // This is the IndieAuth auth endpoint
- 'token', // This is the IndieAuth token endpoint
+ 'auth', // This is the IndieAuth auth endpoint
+ 'token', // This is the IndieAuth token endpoint
+ 'revocation', // This is the IndieAuth revocation endpoint
+ 'introspect', // This is the IndieAuth introspection endpoint
'api/post',
'api/media',
'micropub/places',
diff --git a/composer.json b/composer.json
index 1b94abe8..07b3f142 100644
--- a/composer.json
+++ b/composer.json
@@ -14,20 +14,18 @@
"ext-pgsql": "*",
"ext-sodium": "*",
"cviebrock/eloquent-sluggable": "^13.0",
- "guzzlehttp/guzzle": "^7.2",
+ "guzzlehttp/psr7": "^3.0",
"indieauth/client": "^1.1",
- "intervention/image": "^3",
+ "intervention/image": "^4.0",
"jonnybarnes/indieweb": "~0.2",
- "jonnybarnes/webmentions-parser": "~0.5",
"laravel/framework": "^13.0",
"laravel/horizon": "^5.0",
- "laravel/scout": "^10.1",
+ "laravel/scout": "^11.0",
"laravel/tinker": "^3.0",
- "lcobucci/jwt": "^5.0",
"league/commonmark": "^2.0",
"league/flysystem-aws-s3-v3": "^3.0",
"mf2/mf2": "~0.3",
- "spatie/laravel-flare": "^2.2",
+ "spatie/laravel-flare": "^3.0",
"symfony/html-sanitizer": "^8.0",
"tempest/highlight": "^2.27",
"web-auth/webauthn-lib": "^5.0"
@@ -42,8 +40,8 @@
"laravel/sail": "^1.41",
"mockery/mockery": "^1.6",
"nunomaduro/collision": "^8.6",
- "phpunit/php-code-coverage": "^12.0",
- "phpunit/phpunit": "^12.5.12",
+ "phpunit/php-code-coverage": "^14.0",
+ "phpunit/phpunit": "^13.0",
"spatie/laravel-ray": "^1.12",
"spatie/x-ray": "^1.2"
},
diff --git a/composer.lock b/composer.lock
index 65ec1857..445378f9 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "30db4db4dcfdc487f28e738f0d22d68c",
+ "content-hash": "fce4f734e2344a88fcfb374527a5e061",
"packages": [
{
"name": "aws/aws-crt-php",
@@ -62,16 +62,16 @@
},
{
"name": "aws/aws-sdk-php",
- "version": "3.386.1",
+ "version": "3.403.1",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
- "reference": "e36bc0e97e82d68acc92b9e06f5dc544913d819a"
+ "reference": "608a2c79f57fd3dd54d0dff1e98e9c124f3cb96c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/e36bc0e97e82d68acc92b9e06f5dc544913d819a",
- "reference": "e36bc0e97e82d68acc92b9e06f5dc544913d819a",
+ "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/608a2c79f57fd3dd54d0dff1e98e9c124f3cb96c",
+ "reference": "608a2c79f57fd3dd54d0dff1e98e9c124f3cb96c",
"shasum": ""
},
"require": {
@@ -79,11 +79,11 @@
"ext-json": "*",
"ext-pcre": "*",
"ext-simplexml": "*",
- "guzzlehttp/guzzle": "^7.4.5",
- "guzzlehttp/promises": "^2.0",
- "guzzlehttp/psr7": "^2.4.5",
+ "guzzlehttp/guzzle": "^7.8.2 || ^8.0",
+ "guzzlehttp/promises": "^2.0.3 || ^3.0",
+ "guzzlehttp/psr7": "^2.6.3 || ^3.0",
"mtdowling/jmespath.php": "^2.9.1",
- "php": ">=8.1",
+ "php": ">=8.2",
"psr/http-message": "^1.0 || ^2.0",
"symfony/filesystem": "^v5.4.45 || ^v6.4.3 || ^v7.1.0 || ^v8.0.0"
},
@@ -153,29 +153,30 @@
"support": {
"forum": "https://github.com/aws/aws-sdk-php/discussions",
"issues": "https://github.com/aws/aws-sdk-php/issues",
- "source": "https://github.com/aws/aws-sdk-php/tree/3.386.1"
+ "source": "https://github.com/aws/aws-sdk-php/tree/3.403.1"
},
- "time": "2026-06-23T01:24:07+00:00"
+ "time": "2026-11-06T19:34:26+00:00"
},
{
"name": "brick/math",
- "version": "0.17.2",
+ "version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/brick/math.git",
- "reference": "8189e751995f9e15729c1aa2f89fa8f166ffe818"
+ "reference": "2effe05d2177c451b86c6a073196a4034c02f211"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/brick/math/zipball/8189e751995f9e15729c1aa2f89fa8f166ffe818",
- "reference": "8189e751995f9e15729c1aa2f89fa8f166ffe818",
+ "url": "https://api.github.com/repos/brick/math/zipball/2effe05d2177c451b86c6a073196a4034c02f211",
+ "reference": "2effe05d2177c451b86c6a073196a4034c02f211",
"shasum": ""
},
"require": {
"php": "^8.2"
},
"require-dev": {
- "phpstan/phpstan": "2.1.22",
+ "phpstan/phpstan": "2.2.13",
+ "phpstan/phpstan-phpunit": "2.0.18",
"phpunit/phpunit": "^11.5"
},
"type": "library",
@@ -206,7 +207,7 @@
],
"support": {
"issues": "https://github.com/brick/math/issues",
- "source": "https://github.com/brick/math/tree/0.17.2"
+ "source": "https://github.com/brick/math/tree/1.0.0"
},
"funding": [
{
@@ -214,20 +215,20 @@
"type": "github"
}
],
- "time": "2026-05-25T20:34:43+00:00"
+ "time": "2026-09-12T10:28:18+00:00"
},
{
"name": "carbonphp/carbon-doctrine-types",
- "version": "3.2.0",
+ "version": "3.2.1",
"source": {
"type": "git",
"url": "https://github.com/CarbonPHP/carbon-doctrine-types.git",
- "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d"
+ "reference": "5fa5eacafd9ef47c8c6ab9143fc901ba0194d3dc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d",
- "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d",
+ "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/5fa5eacafd9ef47c8c6ab9143fc901ba0194d3dc",
+ "reference": "5fa5eacafd9ef47c8c6ab9143fc901ba0194d3dc",
"shasum": ""
},
"require": {
@@ -242,6 +243,11 @@
"phpunit/phpunit": "^10.3"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.x-dev"
+ }
+ },
"autoload": {
"psr-4": {
"Carbon\\Doctrine\\": "src/Carbon/Doctrine/"
@@ -267,7 +273,7 @@
],
"support": {
"issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues",
- "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0"
+ "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.1"
},
"funding": [
{
@@ -283,7 +289,7 @@
"type": "tidelift"
}
],
- "time": "2024-02-09T16:56:22+00:00"
+ "time": "2026-09-06T14:11:38+00:00"
},
{
"name": "cocur/slugify",
@@ -361,16 +367,16 @@
},
{
"name": "cviebrock/eloquent-sluggable",
- "version": "13.0.0",
+ "version": "13.0.2",
"source": {
"type": "git",
"url": "https://github.com/cviebrock/eloquent-sluggable.git",
- "reference": "0a023eed5bdc7da3aa9107cb2299757ce4a656e3"
+ "reference": "585c8d7e5a413ab41a69c14547119a29ca575380"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/cviebrock/eloquent-sluggable/zipball/0a023eed5bdc7da3aa9107cb2299757ce4a656e3",
- "reference": "0a023eed5bdc7da3aa9107cb2299757ce4a656e3",
+ "url": "https://api.github.com/repos/cviebrock/eloquent-sluggable/zipball/585c8d7e5a413ab41a69c14547119a29ca575380",
+ "reference": "585c8d7e5a413ab41a69c14547119a29ca575380",
"shasum": ""
},
"require": {
@@ -422,7 +428,7 @@
],
"support": {
"issues": "https://github.com/cviebrock/eloquent-sluggable/issues",
- "source": "https://github.com/cviebrock/eloquent-sluggable/tree/13.0.0"
+ "source": "https://github.com/cviebrock/eloquent-sluggable/tree/13.0.2"
},
"funding": [
{
@@ -430,7 +436,7 @@
"type": "github"
}
],
- "time": "2026-03-19T14:42:10+00:00"
+ "time": "2026-10-15T17:48:08+00:00"
},
{
"name": "dflydev/dot-access-data",
@@ -557,23 +563,23 @@
},
{
"name": "doctrine/inflector",
- "version": "2.1.0",
+ "version": "2.1.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/inflector.git",
- "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b"
+ "reference": "46351b6812b7b6d52b82c3efa5dfb786a198ec88"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/inflector/zipball/6d6c96277ea252fc1304627204c3d5e6e15faa3b",
- "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b",
+ "url": "https://api.github.com/repos/doctrine/inflector/zipball/46351b6812b7b6d52b82c3efa5dfb786a198ec88",
+ "reference": "46351b6812b7b6d52b82c3efa5dfb786a198ec88",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"require-dev": {
- "doctrine/coding-standard": "^12.0 || ^13.0",
+ "doctrine/coding-standard": "^12.0 || ^14.0",
"phpstan/phpstan": "^1.12 || ^2.0",
"phpstan/phpstan-phpunit": "^1.4 || ^2.0",
"phpstan/phpstan-strict-rules": "^1.6 || ^2.0",
@@ -627,7 +633,7 @@
],
"support": {
"issues": "https://github.com/doctrine/inflector/issues",
- "source": "https://github.com/doctrine/inflector/tree/2.1.0"
+ "source": "https://github.com/doctrine/inflector/tree/2.1.1"
},
"funding": [
{
@@ -643,31 +649,29 @@
"type": "tidelift"
}
],
- "time": "2025-08-10T19:31:58+00:00"
+ "time": "2026-10-26T08:14:14+00:00"
},
{
"name": "doctrine/lexer",
- "version": "3.0.1",
+ "version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/doctrine/lexer.git",
- "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd"
+ "reference": "71d305eaa6480d3d3460c7d053d1da7749fa9cca"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
- "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
+ "url": "https://api.github.com/repos/doctrine/lexer/zipball/71d305eaa6480d3d3460c7d053d1da7749fa9cca",
+ "reference": "71d305eaa6480d3d3460c7d053d1da7749fa9cca",
"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"
+ "doctrine/coding-standard": "^14",
+ "phpstan/phpstan": "^2",
+ "phpunit/phpunit": "^10.5.58 || ^12.5.4"
},
"type": "library",
"autoload": {
@@ -704,7 +708,7 @@
],
"support": {
"issues": "https://github.com/doctrine/lexer/issues",
- "source": "https://github.com/doctrine/lexer/tree/3.0.1"
+ "source": "https://github.com/doctrine/lexer/tree/3.0.3"
},
"funding": [
{
@@ -720,20 +724,20 @@
"type": "tidelift"
}
],
- "time": "2024-02-05T11:56:58+00:00"
+ "time": "2026-10-01T06:59:29+00:00"
},
{
"name": "dragonmantank/cron-expression",
- "version": "v3.6.0",
+ "version": "v3.6.1",
"source": {
"type": "git",
"url": "https://github.com/dragonmantank/cron-expression.git",
- "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013"
+ "reference": "4189372ffeff09bf14f731f67a9de90c7b413ebe"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/d61a8a9604ec1f8c3d150d09db6ce98b32675013",
- "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013",
+ "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/4189372ffeff09bf14f731f67a9de90c7b413ebe",
+ "reference": "4189372ffeff09bf14f731f67a9de90c7b413ebe",
"shasum": ""
},
"require": {
@@ -744,8 +748,8 @@
},
"require-dev": {
"phpstan/extension-installer": "^1.4.3",
- "phpstan/phpstan": "^1.12.32|^2.1.31",
- "phpunit/phpunit": "^8.5.48|^9.0"
+ "phpstan/phpstan": "^2.1.31",
+ "phpunit/phpunit": "^11.5.43 || ^12.4"
},
"type": "library",
"extra": {
@@ -776,7 +780,7 @@
],
"support": {
"issues": "https://github.com/dragonmantank/cron-expression/issues",
- "source": "https://github.com/dragonmantank/cron-expression/tree/v3.6.0"
+ "source": "https://github.com/dragonmantank/cron-expression/tree/v3.6.1"
},
"funding": [
{
@@ -784,7 +788,7 @@
"type": "github"
}
],
- "time": "2025-10-31T18:51:33+00:00"
+ "time": "2026-10-19T17:53:57+00:00"
},
{
"name": "egulias/email-validator",
@@ -926,24 +930,24 @@
},
{
"name": "graham-campbell/result-type",
- "version": "v1.1.4",
+ "version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/GrahamCampbell/Result-Type.git",
- "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b"
+ "reference": "adccca3324eece92ca35463648c12b9e6293c05b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/e01f4a821471308ba86aa202fed6698b6b695e3b",
- "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b",
+ "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/adccca3324eece92ca35463648c12b9e6293c05b",
+ "reference": "adccca3324eece92ca35463648c12b9e6293c05b",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0",
- "phpoption/phpoption": "^1.9.5"
+ "phpoption/phpoption": "^1.10"
},
"require-dev": {
- "phpunit/phpunit": "^8.5.41 || ^9.6.22 || ^10.5.45 || ^11.5.7"
+ "phpunit/phpunit": "^8.5.52 || ^9.6.34 || ^10.5.63 || ^11.5.55 || ^12.5.14"
},
"type": "library",
"autoload": {
@@ -972,7 +976,7 @@
],
"support": {
"issues": "https://github.com/GrahamCampbell/Result-Type/issues",
- "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.4"
+ "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.2.0"
},
"funding": [
{
@@ -984,30 +988,31 @@
"type": "tidelift"
}
],
- "time": "2025-12-27T19:43:20+00:00"
+ "time": "2026-08-24T09:06:52+00:00"
},
{
"name": "guzzlehttp/guzzle",
- "version": "7.13.0",
+ "version": "8.3.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
- "reference": "a4decaa9745dc567467970e43f183e260cfa51fd"
+ "reference": "7d9b1f430bb65ac664e120af227bf9a795ad6333"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a4decaa9745dc567467970e43f183e260cfa51fd",
- "reference": "a4decaa9745dc567467970e43f183e260cfa51fd",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7d9b1f430bb65ac664e120af227bf9a795ad6333",
+ "reference": "7d9b1f430bb65ac664e120af227bf9a795ad6333",
"shasum": ""
},
"require": {
"ext-json": "*",
- "guzzlehttp/promises": "^2.5",
- "guzzlehttp/psr7": "^2.12.3",
- "php": "^7.2.5 || ^8.0",
+ "guzzlehttp/promises": "^3.1",
+ "guzzlehttp/psr7": "^3.2",
+ "php": "^7.4 || ^8.0",
"psr/http-client": "^1.0",
- "symfony/deprecation-contracts": "^2.5 || ^3.0",
- "symfony/polyfill-php80": "^1.25"
+ "psr/http-factory": "^1.0",
+ "symfony/polyfill-php80": "^1.25",
+ "symfony/polyfill-php82": "^1.27"
},
"provide": {
"psr/http-client-implementation": "1.0"
@@ -1015,10 +1020,10 @@
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"ext-curl": "*",
- "guzzle/client-integration-tests": "3.0.2",
- "guzzlehttp/test-server": "^0.6",
+ "guzzle/client-integration-tests": "4.0.1",
+ "guzzlehttp/test-server": "^1.1",
"php-http/message-factory": "^1.1",
- "phpunit/phpunit": "^8.5.52 || ^9.6.34",
+ "phpunit/phpunit": "^9.6.34",
"psr/log": "^1.1 || ^2.0 || ^3.0"
},
"suggest": {
@@ -1034,9 +1039,6 @@
}
},
"autoload": {
- "files": [
- "src/functions_include.php"
- ],
"psr-4": {
"GuzzleHttp\\": "src/"
}
@@ -1096,7 +1098,7 @@
],
"support": {
"issues": "https://github.com/guzzle/guzzle/issues",
- "source": "https://github.com/guzzle/guzzle/tree/7.13.0"
+ "source": "https://github.com/guzzle/guzzle/tree/8.3.1"
},
"funding": [
{
@@ -1112,29 +1114,29 @@
"type": "tidelift"
}
],
- "time": "2026-06-29T13:31:06+00:00"
+ "time": "2026-10-25T21:35:34+00:00"
},
{
"name": "guzzlehttp/promises",
- "version": "2.5.0",
+ "version": "3.1.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
- "reference": "4360e982f87f5f258bf872d094647791db2f4c8e"
+ "reference": "094d0ec418eb3b1411ea271a180ec95cae6ae933"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/promises/zipball/4360e982f87f5f258bf872d094647791db2f4c8e",
- "reference": "4360e982f87f5f258bf872d094647791db2f4c8e",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/094d0ec418eb3b1411ea271a180ec95cae6ae933",
+ "reference": "094d0ec418eb3b1411ea271a180ec95cae6ae933",
"shasum": ""
},
"require": {
- "php": "^7.2.5 || ^8.0",
+ "php": "^7.4 || ^8.0",
"symfony/deprecation-contracts": "^2.5 || ^3.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
- "phpunit/phpunit": "^8.5.52 || ^9.6.34"
+ "phpunit/phpunit": "^9.6.34"
},
"type": "library",
"extra": {
@@ -1180,7 +1182,7 @@
],
"support": {
"issues": "https://github.com/guzzle/promises/issues",
- "source": "https://github.com/guzzle/promises/tree/2.5.0"
+ "source": "https://github.com/guzzle/promises/tree/3.1.0"
},
"funding": [
{
@@ -1196,39 +1198,39 @@
"type": "tidelift"
}
],
- "time": "2026-06-02T12:23:43+00:00"
+ "time": "2026-10-18T12:48:16+00:00"
},
{
"name": "guzzlehttp/psr7",
- "version": "2.12.3",
+ "version": "3.2.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
- "reference": "7ec62dc3f44aa218487dbed81a9bf9bc647be55d"
+ "reference": "cdc139396207a5eba10c242d241fb014cb098390"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/7ec62dc3f44aa218487dbed81a9bf9bc647be55d",
- "reference": "7ec62dc3f44aa218487dbed81a9bf9bc647be55d",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/cdc139396207a5eba10c242d241fb014cb098390",
+ "reference": "cdc139396207a5eba10c242d241fb014cb098390",
"shasum": ""
},
"require": {
- "php": "^7.2.5 || ^8.0",
- "psr/http-factory": "^1.0",
- "psr/http-message": "^1.1 || ^2.0",
- "ralouphie/getallheaders": "^3.0",
- "symfony/deprecation-contracts": "^2.5 || ^3.0",
- "symfony/polyfill-php80": "^1.25"
+ "php": "^7.4 || ^8.0",
+ "psr/http-factory": "^1.1",
+ "psr/http-message": "^2.0",
+ "symfony/polyfill-php80": "^1.25",
+ "symfony/polyfill-php82": "^1.27"
},
"provide": {
- "psr/http-factory-implementation": "1.0",
- "psr/http-message-implementation": "1.0"
+ "psr/http-factory-implementation": "1.1",
+ "psr/http-message-implementation": "2.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"http-interop/http-factory-tests": "1.1.0",
"jshttp/mime-db": "1.54.0.1",
- "phpunit/phpunit": "^8.5.52 || ^9.6.34"
+ "php-http/psr7-integration-tests": "^1.5.1",
+ "phpunit/phpunit": "^9.6.34"
},
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
@@ -1299,7 +1301,7 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
- "source": "https://github.com/guzzle/psr7/tree/2.12.3"
+ "source": "https://github.com/guzzle/psr7/tree/3.2.0"
},
"funding": [
{
@@ -1315,30 +1317,30 @@
"type": "tidelift"
}
],
- "time": "2026-06-23T15:21:08+00:00"
+ "time": "2026-10-17T23:57:19+00:00"
},
{
"name": "guzzlehttp/uri-template",
- "version": "v1.0.8",
+ "version": "v2.0.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/uri-template.git",
- "reference": "9c19128923b05a5d7355e5d2318d7808b7e33bbd"
+ "reference": "7a466ad606491eb6528c717482f7cca77f1851f3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/uri-template/zipball/9c19128923b05a5d7355e5d2318d7808b7e33bbd",
- "reference": "9c19128923b05a5d7355e5d2318d7808b7e33bbd",
+ "url": "https://api.github.com/repos/guzzle/uri-template/zipball/7a466ad606491eb6528c717482f7cca77f1851f3",
+ "reference": "7a466ad606491eb6528c717482f7cca77f1851f3",
"shasum": ""
},
"require": {
- "php": "^7.2.5 || ^8.0",
+ "php": "^7.4 || ^8.0",
"symfony/polyfill-php80": "^1.25"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
- "phpunit/phpunit": "^8.5.52 || ^9.6.34",
- "uri-template/tests": "1.0.0"
+ "phpunit/phpunit": "^9.6.34",
+ "uri-template/tests": "1.0.2"
},
"type": "library",
"extra": {
@@ -1385,7 +1387,7 @@
],
"support": {
"issues": "https://github.com/guzzle/uri-template/issues",
- "source": "https://github.com/guzzle/uri-template/tree/v1.0.8"
+ "source": "https://github.com/guzzle/uri-template/tree/v2.0.1"
},
"funding": [
{
@@ -1401,26 +1403,26 @@
"type": "tidelift"
}
],
- "time": "2026-06-23T13:02:23+00:00"
+ "time": "2026-08-24T17:13:02+00:00"
},
{
"name": "indieauth/client",
- "version": "1.1.6",
+ "version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/indieweb/indieauth-client-php.git",
- "reference": "9f3f9cc71a752c371b44d40a979504ffd7026c7d"
+ "reference": "8503c0ca0fbdf808df77dba5b1a3674932fbb0d2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/indieweb/indieauth-client-php/zipball/9f3f9cc71a752c371b44d40a979504ffd7026c7d",
- "reference": "9f3f9cc71a752c371b44d40a979504ffd7026c7d",
+ "url": "https://api.github.com/repos/indieweb/indieauth-client-php/zipball/8503c0ca0fbdf808df77dba5b1a3674932fbb0d2",
+ "reference": "8503c0ca0fbdf808df77dba5b1a3674932fbb0d2",
"shasum": ""
},
"require": {
"indieweb/representative-h-card": "^0.1.2",
"mf2/mf2": "^0.5",
- "p3k/http": "^0.1",
+ "p3k/http": "^0.1 || ^0.2",
"php": ">5.6.0"
},
"require-dev": {
@@ -1445,7 +1447,7 @@
"description": "IndieAuth Client Library",
"support": {
"issues": "https://github.com/indieweb/indieauth-client-php/issues",
- "source": "https://github.com/indieweb/indieauth-client-php/tree/1.1.6"
+ "source": "https://github.com/indieweb/indieauth-client-php/tree/v1.2.0"
},
"funding": [
{
@@ -1453,7 +1455,7 @@
"type": "opencollective"
}
],
- "time": "2022-11-08T21:37:04+00:00"
+ "time": "2026-10-02T22:18:02+00:00"
},
{
"name": "indieweb/link-rel-parser",
@@ -1556,26 +1558,26 @@
},
{
"name": "intervention/gif",
- "version": "4.2.4",
+ "version": "5.0.1",
"source": {
"type": "git",
"url": "https://github.com/Intervention/gif.git",
- "reference": "c3598a16ebe7690cd55640c44144a9df383ea73c"
+ "reference": "bb395af960deffe64d70c976b4df9283f68e762d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Intervention/gif/zipball/c3598a16ebe7690cd55640c44144a9df383ea73c",
- "reference": "c3598a16ebe7690cd55640c44144a9df383ea73c",
+ "url": "https://api.github.com/repos/Intervention/gif/zipball/bb395af960deffe64d70c976b4df9283f68e762d",
+ "reference": "bb395af960deffe64d70c976b4df9283f68e762d",
"shasum": ""
},
"require": {
- "php": "^8.1"
+ "php": "^8.3"
},
"require-dev": {
"phpstan/phpstan": "^2.1",
- "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0",
+ "phpunit/phpunit": "^12.0",
"slevomat/coding-standard": "~8.0",
- "squizlabs/php_codesniffer": "^3.8"
+ "squizlabs/php_codesniffer": "^4"
},
"type": "library",
"autoload": {
@@ -1594,7 +1596,7 @@
"homepage": "https://intervention.io/"
}
],
- "description": "Native PHP GIF Encoder/Decoder",
+ "description": "PHP GIF Encoder/Decoder",
"homepage": "https://github.com/intervention/gif",
"keywords": [
"animation",
@@ -1604,7 +1606,7 @@
],
"support": {
"issues": "https://github.com/Intervention/gif/issues",
- "source": "https://github.com/Intervention/gif/tree/4.2.4"
+ "source": "https://github.com/Intervention/gif/tree/5.0.1"
},
"funding": [
{
@@ -1620,33 +1622,33 @@
"type": "ko_fi"
}
],
- "time": "2026-01-04T09:27:23+00:00"
+ "time": "2026-05-03T06:04:47+00:00"
},
{
"name": "intervention/image",
- "version": "3.11.8",
+ "version": "4.4.1",
"source": {
"type": "git",
"url": "https://github.com/Intervention/image.git",
- "reference": "cf04c8dd245697f701057c13d4bfe140d584e738"
+ "reference": "3a47838f2e0f4ec6c8c9b43a5d73ac985b975830"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Intervention/image/zipball/cf04c8dd245697f701057c13d4bfe140d584e738",
- "reference": "cf04c8dd245697f701057c13d4bfe140d584e738",
+ "url": "https://api.github.com/repos/Intervention/image/zipball/3a47838f2e0f4ec6c8c9b43a5d73ac985b975830",
+ "reference": "3a47838f2e0f4ec6c8c9b43a5d73ac985b975830",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
- "intervention/gif": "^4.2",
- "php": "^8.1"
+ "intervention/gif": "^5",
+ "php": "^8.3"
},
"require-dev": {
+ "intervention/coding-standard": "^1",
"mockery/mockery": "^1.6",
"phpstan/phpstan": "^2.1",
- "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0",
- "slevomat/coding-standard": "~8.0",
- "squizlabs/php_codesniffer": "^4"
+ "phpunit/phpunit": "^12.0",
+ "psr/http-message": "^2"
},
"suggest": {
"ext-exif": "Recommended to be able to read EXIF data properly."
@@ -1680,7 +1682,7 @@
],
"support": {
"issues": "https://github.com/Intervention/image/issues",
- "source": "https://github.com/Intervention/image/tree/3.11.8"
+ "source": "https://github.com/Intervention/image/tree/4.4.1"
},
"funding": [
{
@@ -1696,7 +1698,7 @@
"type": "ko_fi"
}
],
- "time": "2026-05-01T08:20:10+00:00"
+ "time": "2026-10-30T13:38:01+00:00"
},
{
"name": "jonnybarnes/indieweb",
@@ -1748,73 +1750,22 @@
},
"time": "2020-11-29T11:13:10+00:00"
},
- {
- "name": "jonnybarnes/webmentions-parser",
- "version": "v0.6",
- "source": {
- "type": "git",
- "url": "https://github.com/jonnybarnes/webmentions-parser.git",
- "reference": "cac1acb2b252d6eb611fc5f3a2c6e2265bc86b44"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/jonnybarnes/webmentions-parser/zipball/cac1acb2b252d6eb611fc5f3a2c6e2265bc86b44",
- "reference": "cac1acb2b252d6eb611fc5f3a2c6e2265bc86b44",
- "shasum": ""
- },
- "require": {
- "guzzlehttp/guzzle": "^6.0|^7.0",
- "mf2/mf2": "~0.4",
- "php": "^7.3|^8.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^9.0"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Jonnybarnes\\WebmentionsParser\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "CC0-1.0"
- ],
- "authors": [
- {
- "name": "Jonny Barnes",
- "homepage": "https://jonnybarnes.uk"
- }
- ],
- "description": "A PHP library to parse webmentions from HTML",
- "keywords": [
- "html",
- "indieweb",
- "microformats",
- "webmentions"
- ],
- "support": {
- "issues": "https://github.com/jonnybarnes/webmentions-parser/issues",
- "source": "https://github.com/jonnybarnes/webmentions-parser/tree/v0.6"
- },
- "time": "2020-11-29T11:40:36+00:00"
- },
{
"name": "laravel/framework",
- "version": "v13.17.0",
+ "version": "v13.40.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
- "reference": "0802b7a81f3252d78200b8037ac183a686a529f0"
+ "reference": "1449bf241017087fbd38c118ecaabef3f6797fdc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/framework/zipball/0802b7a81f3252d78200b8037ac183a686a529f0",
- "reference": "0802b7a81f3252d78200b8037ac183a686a529f0",
+ "url": "https://api.github.com/repos/laravel/framework/zipball/1449bf241017087fbd38c118ecaabef3f6797fdc",
+ "reference": "1449bf241017087fbd38c118ecaabef3f6797fdc",
"shasum": ""
},
"require": {
- "brick/math": "^0.14.2 || ^0.15 || ^0.16 || ^0.17 || ^0.18",
+ "brick/math": "^0.14.2 || ^0.15 || ^0.16 || ^0.17 || ^0.18 || ^0.19 || ^0.20 || ^1.0",
"composer-runtime-api": "^2.2",
"doctrine/inflector": "^2.0.5",
"dragonmantank/cron-expression": "^3.4",
@@ -1827,20 +1778,22 @@
"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",
+ "guzzlehttp/guzzle": "^7.8.2 || ^8.0",
+ "guzzlehttp/promises": "^2.0.3 || ^3.0",
+ "guzzlehttp/psr7": "^2.9 || ^3.0",
+ "guzzlehttp/uri-template": "^1.0 || ^2.0",
+ "laravel/prompts": "^0.3.25",
"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",
+ "monolog/monolog": "^3.10",
"nesbot/carbon": "^3.8.4",
"nunomaduro/termwind": "^2.0",
"php": "^8.3",
"psr/container": "^1.1.1 || ^2.0.1",
+ "psr/http-message": "^1.0 || ^2.0",
"psr/log": "^1.0 || ^2.0 || ^3.0",
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0",
"ramsey/uuid": "^4.7",
@@ -1889,6 +1842,7 @@
"illuminate/filesystem": "self.version",
"illuminate/hashing": "self.version",
"illuminate/http": "self.version",
+ "illuminate/image": "self.version",
"illuminate/json-schema": "self.version",
"illuminate/log": "self.version",
"illuminate/macroable": "self.version",
@@ -1914,7 +1868,7 @@
"aws/aws-sdk-php": "^3.322.9",
"ext-gmp": "*",
"fakerphp/faker": "^1.24",
- "guzzlehttp/psr7": "^2.9",
+ "intervention/image": "^4.2",
"laravel/pint": "^1.18",
"league/flysystem-aws-s3-v3": "^3.25.1",
"league/flysystem-ftp": "^3.25.1",
@@ -1923,18 +1877,20 @@
"league/flysystem-sftp-v3": "^3.25.1",
"mockery/mockery": "^1.6.10",
"opis/json-schema": "^2.4.1",
- "orchestra/testbench-core": "^11.0.0",
+ "orchestra/testbench-core": "^11.6.0",
"pda/pheanstalk": "^7.0.0 || ^8.0.0",
"php-http/discovery": "^1.15",
- "phpstan/phpstan": "^2.0",
+ "phpstan/phpstan": "2.3.1",
"phpunit/phpunit": "^11.5.50 || ^12.5.8 || ^13.0.3",
"predis/predis": "^2.3 || ^3.0",
- "rector/rector": "^2.3",
+ "rector/rector": "2.6.3",
"resend/resend-php": "^1.0",
"symfony/cache": "^7.4.0 || ^8.0.0",
"symfony/http-client": "^7.4.0 || ^8.0.0",
+ "symfony/mercure": "^0.8.0",
"symfony/psr-http-message-bridge": "^7.4.0 || ^8.0.0",
- "symfony/translation": "^7.4.0 || ^8.0.0"
+ "symfony/translation": "^7.4.0 || ^8.0.0",
+ "web-token/jwt-library": "^4.1"
},
"suggest": {
"ably/ably-php": "Required to use the Ably broadcast driver (^1.0).",
@@ -1951,6 +1907,7 @@
"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).",
+ "intervention/image": "Required to use the image processing features (^4.2).",
"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).",
@@ -1962,7 +1919,6 @@
"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).",
@@ -1970,8 +1926,10 @@
"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/mercure": "Required to use the Mercure broadcast driver (^0.8).",
"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)."
+ "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.4 || ^8.0).",
+ "web-token/jwt-library": "Required to sign Mercure JWTs and use end-to-end encrypted channels (^4.1)."
},
"type": "library",
"extra": {
@@ -2021,20 +1979,20 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
- "time": "2026-06-23T19:42:45+00:00"
+ "time": "2026-11-03T15:07:18+00:00"
},
{
"name": "laravel/horizon",
- "version": "v5.47.2",
+ "version": "v5.50.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/horizon.git",
- "reference": "a6ac142293ad02db4d7cccb961dd32f56ef1462d"
+ "reference": "9d65cae809688179ce2c4ace64eb75e886e245c5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/horizon/zipball/a6ac142293ad02db4d7cccb961dd32f56ef1462d",
- "reference": "a6ac142293ad02db4d7cccb961dd32f56ef1462d",
+ "url": "https://api.github.com/repos/laravel/horizon/zipball/9d65cae809688179ce2c4ace64eb75e886e245c5",
+ "reference": "9d65cae809688179ce2c4ace64eb75e886e245c5",
"shasum": ""
},
"require": {
@@ -2099,22 +2057,22 @@
],
"support": {
"issues": "https://github.com/laravel/horizon/issues",
- "source": "https://github.com/laravel/horizon/tree/v5.47.2"
+ "source": "https://github.com/laravel/horizon/tree/v5.50.1"
},
- "time": "2026-06-03T15:11:37+00:00"
+ "time": "2026-10-13T06:25:19+00:00"
},
{
"name": "laravel/prompts",
- "version": "v0.3.21",
+ "version": "v0.3.26",
"source": {
"type": "git",
"url": "https://github.com/laravel/prompts.git",
- "reference": "7753c65c281c2550c7c183f14e18062073b7d821"
+ "reference": "2d1e9bf6bab8d3f383c254db7f2b4ea8816d55e0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/prompts/zipball/7753c65c281c2550c7c183f14e18062073b7d821",
- "reference": "7753c65c281c2550c7c183f14e18062073b7d821",
+ "url": "https://api.github.com/repos/laravel/prompts/zipball/2d1e9bf6bab8d3f383c254db7f2b4ea8816d55e0",
+ "reference": "2d1e9bf6bab8d3f383c254db7f2b4ea8816d55e0",
"shasum": ""
},
"require": {
@@ -2157,23 +2115,22 @@
],
"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.21"
+ "source": "https://github.com/laravel/prompts/tree/v0.3.26"
},
- "time": "2026-06-26T00:11:25+00:00"
+ "time": "2026-10-09T14:45:13+00:00"
},
{
"name": "laravel/scout",
- "version": "v10.25.0",
+ "version": "v11.9.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/scout.git",
- "reference": "f28630dca44a63d80c15e596bedc5af42c8985d5"
+ "reference": "07a6255b0cf2420426a80fd0e58a96b44afbfd40"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/scout/zipball/f28630dca44a63d80c15e596bedc5af42c8985d5",
- "reference": "f28630dca44a63d80c15e596bedc5af42c8985d5",
+ "url": "https://api.github.com/repos/laravel/scout/zipball/07a6255b0cf2420426a80fd0e58a96b44afbfd40",
+ "reference": "07a6255b0cf2420426a80fd0e58a96b44afbfd40",
"shasum": ""
},
"require": {
@@ -2201,6 +2158,7 @@
},
"suggest": {
"algolia/algoliasearch-client-php": "Required to use the Algolia engine (^3.2).",
+ "laravel/ai": "Required to generate embeddings for semantic and hybrid search.",
"meilisearch/meilisearch-php": "Required to use the Meilisearch engine (^1.0).",
"typesense/typesense-php": "Required to use the Typesense engine (^4.9)."
},
@@ -2212,7 +2170,7 @@
]
},
"branch-alias": {
- "dev-master": "10.x-dev"
+ "dev-master": "11.x-dev"
}
},
"autoload": {
@@ -2240,7 +2198,7 @@
"issues": "https://github.com/laravel/scout/issues",
"source": "https://github.com/laravel/scout"
},
- "time": "2026-03-10T16:16:46+00:00"
+ "time": "2026-10-06T14:26:28+00:00"
},
{
"name": "laravel/sentinel",
@@ -2300,16 +2258,16 @@
},
{
"name": "laravel/serializable-closure",
- "version": "v2.0.13",
+ "version": "v2.1.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/serializable-closure.git",
- "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce"
+ "reference": "2d5869a838bbcf37e0d8b0568fc41914e81374b5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/b566ee0dd251f3c4078bed003a7ce015f5ea6dce",
- "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce",
+ "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/2d5869a838bbcf37e0d8b0568fc41914e81374b5",
+ "reference": "2d5869a838bbcf37e0d8b0568fc41914e81374b5",
"shasum": ""
},
"require": {
@@ -2357,7 +2315,7 @@
"issues": "https://github.com/laravel/serializable-closure/issues",
"source": "https://github.com/laravel/serializable-closure"
},
- "time": "2026-04-16T14:03:50+00:00"
+ "time": "2026-09-22T14:32:34+00:00"
},
{
"name": "laravel/tinker",
@@ -2428,91 +2386,18 @@
},
"time": "2026-03-17T14:54:13+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",
+ "version": "2.10.7",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
- "reference": "59fb075d2101740c337c7216e3f32b36c204218b"
+ "reference": "8eb53e906fd60c67038d22f1f1cab420ed58b8be"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/59fb075d2101740c337c7216e3f32b36c204218b",
- "reference": "59fb075d2101740c337c7216e3f32b36c204218b",
+ "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/8eb53e906fd60c67038d22f1f1cab420ed58b8be",
+ "reference": "8eb53e906fd60c67038d22f1f1cab420ed58b8be",
"shasum": ""
},
"require": {
@@ -2534,8 +2419,8 @@
"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",
+ "phpstan/phpstan": "^2.0.0",
+ "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0 || ^12.0.0 || ^13.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",
@@ -2549,7 +2434,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "2.9-dev"
+ "dev-main": "2.11-dev"
}
},
"autoload": {
@@ -2606,7 +2491,7 @@
"type": "tidelift"
}
],
- "time": "2026-03-19T13:16:38+00:00"
+ "time": "2026-10-31T13:35:37+00:00"
},
{
"name": "league/config",
@@ -2692,16 +2577,16 @@
},
{
"name": "league/flysystem",
- "version": "3.35.1",
+ "version": "3.36.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
- "reference": "f23af6c5aafd958a7593029a271d77baf5ed793c"
+ "reference": "f7fb152932f30072d573510cbd4dd657d6475b25"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/f23af6c5aafd958a7593029a271d77baf5ed793c",
- "reference": "f23af6c5aafd958a7593029a271d77baf5ed793c",
+ "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/f7fb152932f30072d573510cbd4dd657d6475b25",
+ "reference": "f7fb152932f30072d573510cbd4dd657d6475b25",
"shasum": ""
},
"require": {
@@ -2769,22 +2654,22 @@
],
"support": {
"issues": "https://github.com/thephpleague/flysystem/issues",
- "source": "https://github.com/thephpleague/flysystem/tree/3.35.1"
+ "source": "https://github.com/thephpleague/flysystem/tree/3.36.0"
},
- "time": "2026-06-25T06:52:23+00:00"
+ "time": "2026-09-02T08:00:27+00:00"
},
{
"name": "league/flysystem-aws-s3-v3",
- "version": "3.35.1",
+ "version": "3.35.3",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git",
- "reference": "3f93d3f4bd5c12a5dfb34a7267c40b1bc4587b94"
+ "reference": "b03780cb97585ee7e48977f40ed599b33b751634"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/3f93d3f4bd5c12a5dfb34a7267c40b1bc4587b94",
- "reference": "3f93d3f4bd5c12a5dfb34a7267c40b1bc4587b94",
+ "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/b03780cb97585ee7e48977f40ed599b33b751634",
+ "reference": "b03780cb97585ee7e48977f40ed599b33b751634",
"shasum": ""
},
"require": {
@@ -2824,22 +2709,22 @@
"storage"
],
"support": {
- "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.35.1"
+ "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.35.3"
},
- "time": "2026-06-25T06:51:08+00:00"
+ "time": "2026-08-08T16:19:23+00:00"
},
{
"name": "league/flysystem-local",
- "version": "3.31.0",
+ "version": "3.35.3",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem-local.git",
- "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079"
+ "reference": "a099b24dce160f3b2239043d13d47c4a1a214ea4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/2f669db18a4c20c755c2bb7d3a7b0b2340488079",
- "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079",
+ "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/a099b24dce160f3b2239043d13d47c4a1a214ea4",
+ "reference": "a099b24dce160f3b2239043d13d47c4a1a214ea4",
"shasum": ""
},
"require": {
@@ -2873,22 +2758,22 @@
"local"
],
"support": {
- "source": "https://github.com/thephpleague/flysystem-local/tree/3.31.0"
+ "source": "https://github.com/thephpleague/flysystem-local/tree/3.35.3"
},
- "time": "2026-01-23T15:30:45+00:00"
+ "time": "2026-08-12T13:29:21+00:00"
},
{
"name": "league/mime-type-detection",
- "version": "1.16.0",
+ "version": "1.17.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/mime-type-detection.git",
- "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9"
+ "reference": "f5f47eff7c48ed1003069a2ca67f316fb4021c76"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9",
- "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9",
+ "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/f5f47eff7c48ed1003069a2ca67f316fb4021c76",
+ "reference": "f5f47eff7c48ed1003069a2ca67f316fb4021c76",
"shasum": ""
},
"require": {
@@ -2898,7 +2783,7 @@
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.2",
"phpstan/phpstan": "^0.12.68",
- "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0"
+ "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0 || ^11.0 || ^12.0"
},
"type": "library",
"autoload": {
@@ -2919,7 +2804,7 @@
"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"
+ "source": "https://github.com/thephpleague/mime-type-detection/tree/1.17.0"
},
"funding": [
{
@@ -2931,24 +2816,25 @@
"type": "tidelift"
}
],
- "time": "2024-09-21T08:32:55+00:00"
+ "time": "2026-07-09T11:49:27+00:00"
},
{
"name": "league/uri",
- "version": "7.8.1",
+ "version": "7.10.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/uri.git",
- "reference": "08cf38e3924d4f56238125547b5720496fac8fd4"
+ "reference": "be89e2382e37acdef232259071ade5180821397b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/uri/zipball/08cf38e3924d4f56238125547b5720496fac8fd4",
- "reference": "08cf38e3924d4f56238125547b5720496fac8fd4",
+ "url": "https://api.github.com/repos/thephpleague/uri/zipball/be89e2382e37acdef232259071ade5180821397b",
+ "reference": "be89e2382e37acdef232259071ade5180821397b",
"shasum": ""
},
"require": {
- "league/uri-interfaces": "^7.8.1",
+ "ext-mbstring": "*",
+ "league/uri-interfaces": "^7.10.0",
"php": "^8.1",
"psr/http-factory": "^1"
},
@@ -3021,7 +2907,7 @@
"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"
+ "source": "https://github.com/thephpleague/uri/tree/7.10.0"
},
"funding": [
{
@@ -3029,20 +2915,20 @@
"type": "github"
}
],
- "time": "2026-03-15T20:22:25+00:00"
+ "time": "2026-11-04T12:45:07+00:00"
},
{
"name": "league/uri-interfaces",
- "version": "7.8.1",
+ "version": "7.10.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/uri-interfaces.git",
- "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928"
+ "reference": "ea66240cff4ae9a56ce85d577a04d038b771e51c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/85d5c77c5d6d3af6c54db4a78246364908f3c928",
- "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928",
+ "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/ea66240cff4ae9a56ce85d577a04d038b771e51c",
+ "reference": "ea66240cff4ae9a56ce85d577a04d038b771e51c",
"shasum": ""
},
"require": {
@@ -3105,7 +2991,7 @@
"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"
+ "source": "https://github.com/thephpleague/uri-interfaces/tree/7.10.0"
},
"funding": [
{
@@ -3113,31 +2999,31 @@
"type": "github"
}
],
- "time": "2026-03-08T20:05:35+00:00"
+ "time": "2026-11-04T12:45:07+00:00"
},
{
"name": "mf2/mf2",
- "version": "v0.5.0",
+ "version": "v0.5.1",
"source": {
"type": "git",
"url": "https://github.com/microformats/php-mf2.git",
- "reference": "ddc56de6be62ed4a21f569de9b80e17af678ca50"
+ "reference": "5ebf105d9f6568576b375664171403705f22f92b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/microformats/php-mf2/zipball/ddc56de6be62ed4a21f569de9b80e17af678ca50",
- "reference": "ddc56de6be62ed4a21f569de9b80e17af678ca50",
+ "url": "https://api.github.com/repos/microformats/php-mf2/zipball/5ebf105d9f6568576b375664171403705f22f92b",
+ "reference": "5ebf105d9f6568576b375664171403705f22f92b",
"shasum": ""
},
"require": {
"php": ">=5.6.0"
},
"require-dev": {
- "dealerdirect/phpcodesniffer-composer-installer": "^0.7",
+ "dealerdirect/phpcodesniffer-composer-installer": "^1.0",
"mf2/tests": "dev-master#e9e2b905821ba0a5b59dab1a8eaf40634ce9cd49",
"phpcompatibility/php-compatibility": "^9.3",
- "phpunit/phpunit": "^5.7",
- "squizlabs/php_codesniffer": "^3.6.2"
+ "squizlabs/php_codesniffer": "^3.10.2",
+ "yoast/phpunit-polyfills": "^1.0"
},
"suggest": {
"barnabywalters/mf-cleaner": "To more easily handle the canonical data php-mf2 gives you",
@@ -3173,22 +3059,22 @@
],
"support": {
"issues": "https://github.com/microformats/php-mf2/issues",
- "source": "https://github.com/microformats/php-mf2/tree/v0.5.0"
+ "source": "https://github.com/microformats/php-mf2/tree/v0.5.1"
},
- "time": "2022-02-10T01:05:27+00:00"
+ "time": "2026-11-01T18:33:55+00:00"
},
{
"name": "monolog/monolog",
- "version": "3.10.0",
+ "version": "3.12.1",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
- "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0"
+ "reference": "d7059e4c691d05ea1222b5124bed0f961be46e15"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0",
- "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0",
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/d7059e4c691d05ea1222b5124bed0f961be46e15",
+ "reference": "d7059e4c691d05ea1222b5124bed0f961be46e15",
"shasum": ""
},
"require": {
@@ -3214,6 +3100,7 @@
"phpstan/phpstan-strict-rules": "^2",
"phpunit/phpunit": "^10.5.17 || ^11.0.7",
"predis/predis": "^1.1 || ^2",
+ "psr/clock": "^1.0",
"rollbar/rollbar": "^4.0",
"ruflin/elastica": "^7 || ^8",
"symfony/mailer": "^5.4 || ^6",
@@ -3232,6 +3119,7 @@
"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",
+ "psr/clock": "Required to pass a clock to the Logger and control the timestamp of log records",
"rollbar/rollbar": "Allow sending log messages to Rollbar",
"ruflin/elastica": "Allow sending log messages to an Elastic Search server"
},
@@ -3266,7 +3154,7 @@
],
"support": {
"issues": "https://github.com/Seldaek/monolog/issues",
- "source": "https://github.com/Seldaek/monolog/tree/3.10.0"
+ "source": "https://github.com/Seldaek/monolog/tree/3.12.1"
},
"funding": [
{
@@ -3278,20 +3166,20 @@
"type": "tidelift"
}
],
- "time": "2026-01-02T08:56:05+00:00"
+ "time": "2026-09-29T19:21:12+00:00"
},
{
"name": "mtdowling/jmespath.php",
- "version": "2.9.1",
+ "version": "2.9.2",
"source": {
"type": "git",
"url": "https://github.com/jmespath/jmespath.php.git",
- "reference": "9c208ba27ae7d90853c288b3795d6702eb251d34"
+ "reference": "2157c5e50e813ec6a96c1eed3be7f64a20fb32a8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/9c208ba27ae7d90853c288b3795d6702eb251d34",
- "reference": "9c208ba27ae7d90853c288b3795d6702eb251d34",
+ "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/2157c5e50e813ec6a96c1eed3be7f64a20fb32a8",
+ "reference": "2157c5e50e813ec6a96c1eed3be7f64a20fb32a8",
"shasum": ""
},
"require": {
@@ -3342,22 +3230,22 @@
],
"support": {
"issues": "https://github.com/jmespath/jmespath.php/issues",
- "source": "https://github.com/jmespath/jmespath.php/tree/2.9.1"
+ "source": "https://github.com/jmespath/jmespath.php/tree/2.9.2"
},
- "time": "2026-06-11T10:43:56+00:00"
+ "time": "2026-07-06T18:56:19+00:00"
},
{
"name": "nesbot/carbon",
- "version": "3.13.0",
+ "version": "3.15.1",
"source": {
"type": "git",
"url": "https://github.com/CarbonPHP/carbon.git",
- "reference": "40f6618f052df16b545f626fbf9a878e6497d16a"
+ "reference": "ce0e5636fae7d1e99856eb70cae4c719a284aa08"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/40f6618f052df16b545f626fbf9a878e6497d16a",
- "reference": "40f6618f052df16b545f626fbf9a878e6497d16a",
+ "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/ce0e5636fae7d1e99856eb70cae4c719a284aa08",
+ "reference": "ce0e5636fae7d1e99856eb70cae4c719a284aa08",
"shasum": ""
},
"require": {
@@ -3367,6 +3255,7 @@
"psr/clock": "^1.0",
"symfony/clock": "^6.3.12 || ^7.0 || ^8.0",
"symfony/polyfill-mbstring": "^1.0",
+ "symfony/polyfill-time": "^1.0",
"symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0 || ^8.0"
},
"provide": {
@@ -3377,7 +3266,7 @@
"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",
+ "phpmd/phpmd": "^3.0@dev",
"phpstan/extension-installer": "^1.4.3",
"phpstan/phpstan": "^2.1.22",
"phpunit/phpunit": "^10.5.53",
@@ -3449,37 +3338,37 @@
"type": "tidelift"
}
],
- "time": "2026-06-18T13:49:15+00:00"
+ "time": "2026-10-25T14:32:48+00:00"
},
{
"name": "nette/schema",
- "version": "v1.3.5",
+ "version": "v1.4.0",
"source": {
"type": "git",
"url": "https://github.com/nette/schema.git",
- "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002"
+ "reference": "af9fa8a86bfca9b02b10346220db26e62ef942ec"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/schema/zipball/f0ab1a3cda782dbc5da270d28545236aa80c4002",
- "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002",
+ "url": "https://api.github.com/repos/nette/schema/zipball/af9fa8a86bfca9b02b10346220db26e62ef942ec",
+ "reference": "af9fa8a86bfca9b02b10346220db26e62ef942ec",
"shasum": ""
},
"require": {
"nette/utils": "^4.0",
- "php": "8.1 - 8.5"
+ "php": "8.1 - 8.6"
},
"require-dev": {
- "nette/phpstan-rules": "^1.0",
+ "nette/phpstan-rules": "^1.0.7",
"nette/tester": "^2.6",
"phpstan/extension-installer": "^1.4@stable",
- "phpstan/phpstan": "^2.1.39@stable",
+ "phpstan/phpstan": "^2.3@stable",
"tracy/tracy": "^2.8"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.3-dev"
+ "dev-master": "1.4-dev"
}
},
"autoload": {
@@ -3500,40 +3389,40 @@
{
"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",
+ "description": "📐 Nette Schema: validates and normalizes data such as configuration or API input against a schema described in a few readable lines of PHP, with precise error messages.",
+ "homepage": "https://doc.nette.org/schema",
"keywords": [
- "config",
- "nette"
+ "configuration",
+ "data validation",
+ "nette",
+ "normalization",
+ "schema",
+ "validation"
],
"support": {
"issues": "https://github.com/nette/schema/issues",
- "source": "https://github.com/nette/schema/tree/v1.3.5"
+ "source": "https://github.com/nette/schema/tree/v1.4.0"
},
- "time": "2026-02-23T03:47:12+00:00"
+ "time": "2026-10-22T02:12:50+00:00"
},
{
"name": "nette/utils",
- "version": "v4.1.4",
+ "version": "v4.1.6",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
- "reference": "7da6c396d7ebe142bc857c20479d5e70a5e1aac7"
+ "reference": "6bf24518accf32cf845bca305e0b92078700fd01"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/utils/zipball/7da6c396d7ebe142bc857c20479d5e70a5e1aac7",
- "reference": "7da6c396d7ebe142bc857c20479d5e70a5e1aac7",
+ "url": "https://api.github.com/repos/nette/utils/zipball/6bf24518accf32cf845bca305e0b92078700fd01",
+ "reference": "6bf24518accf32cf845bca305e0b92078700fd01",
"shasum": ""
},
"require": {
- "php": "8.2 - 8.5"
+ "php": "8.2 - 8.6"
},
"conflict": {
"nette/finder": "<3",
@@ -3549,7 +3438,7 @@
},
"suggest": {
"ext-gd": "to use Image",
- "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()",
+ "ext-iconv": "to use Strings::chr(), ord() 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...",
@@ -3605,26 +3494,25 @@
],
"support": {
"issues": "https://github.com/nette/utils/issues",
- "source": "https://github.com/nette/utils/tree/v4.1.4"
+ "source": "https://github.com/nette/utils/tree/v4.1.6"
},
- "time": "2026-05-11T20:49:54+00:00"
+ "time": "2026-10-20T17:07:56+00:00"
},
{
"name": "nikic/php-parser",
- "version": "v5.7.0",
+ "version": "v5.9.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82"
+ "reference": "9e33da9553fe7786f0962b35f4e4ecf01be89def"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82",
- "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/9e33da9553fe7786f0962b35f4e4ecf01be89def",
+ "reference": "9e33da9553fe7786f0962b35f4e4ecf01be89def",
"shasum": ""
},
"require": {
- "ext-ctype": "*",
"ext-json": "*",
"ext-tokenizer": "*",
"php": ">=7.4"
@@ -3663,37 +3551,37 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
- "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0"
+ "source": "https://github.com/nikic/PHP-Parser/tree/v5.9.0"
},
- "time": "2025-12-06T11:56:16+00:00"
+ "time": "2026-09-13T18:51:52+00:00"
},
{
"name": "nunomaduro/termwind",
- "version": "v2.4.0",
+ "version": "v2.4.1",
"source": {
"type": "git",
"url": "https://github.com/nunomaduro/termwind.git",
- "reference": "712a31b768f5daea284c2169a7d227031001b9a8"
+ "reference": "9b85ae4d802403bfc004ea633ce542bc262ee5c3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/712a31b768f5daea284c2169a7d227031001b9a8",
- "reference": "712a31b768f5daea284c2169a7d227031001b9a8",
+ "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/9b85ae4d802403bfc004ea633ce542bc262ee5c3",
+ "reference": "9b85ae4d802403bfc004ea633ce542bc262ee5c3",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": "^8.2",
- "symfony/console": "^7.4.4 || ^8.0.4"
+ "symfony/console": "^7.4.23 || ^8.1.11"
},
"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",
+ "illuminate/console": "^11.51 || ^12.70 || ^13.40",
+ "laravel/pint": "^1.30.4",
+ "mockery/mockery": "^1.6.15",
+ "pestphp/pest": "^2.36.1 || ^3.8.7 || ^4.7.8 || ^5.3.5",
+ "phpstan/phpstan": "^1.12.34",
"phpstan/phpstan-strict-rules": "^1.6.2",
- "symfony/var-dumper": "^7.3.5 || ^8.0.4",
+ "symfony/var-dumper": "^7.4.22 || ^8.1.10",
"thecodingmachine/phpstan-strict-rules": "^1.0.0"
},
"type": "library",
@@ -3736,7 +3624,7 @@
],
"support": {
"issues": "https://github.com/nunomaduro/termwind/issues",
- "source": "https://github.com/nunomaduro/termwind/tree/v2.4.0"
+ "source": "https://github.com/nunomaduro/termwind/tree/v2.4.1"
},
"funding": [
{
@@ -3752,25 +3640,29 @@
"type": "github"
}
],
- "time": "2026-02-16T23:10:27+00:00"
+ "time": "2026-11-07T03:57:16+00:00"
},
{
"name": "p3k/http",
- "version": "0.1.13",
+ "version": "0.2.2",
"source": {
"type": "git",
"url": "https://github.com/aaronpk/p3k-http.git",
- "reference": "ae4988ba19f4bc57ca3fe1f6dcd2087478fea53a"
+ "reference": "5eaf3df2008c5d1aaad3ab661efc0e6f586bb46e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/aaronpk/p3k-http/zipball/ae4988ba19f4bc57ca3fe1f6dcd2087478fea53a",
- "reference": "ae4988ba19f4bc57ca3fe1f6dcd2087478fea53a",
+ "url": "https://api.github.com/repos/aaronpk/p3k-http/zipball/5eaf3df2008c5d1aaad3ab661efc0e6f586bb46e",
+ "reference": "5eaf3df2008c5d1aaad3ab661efc0e6f586bb46e",
"shasum": ""
},
"require": {
"indieweb/link-rel-parser": "0.1.*",
- "mf2/mf2": ">=0.3.2"
+ "mf2/mf2": ">=0.3.2",
+ "php": ">=7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.6 || ^10 || ^11"
},
"type": "library",
"autoload": {
@@ -3792,22 +3684,22 @@
"homepage": "https://github.com/aaronpk/p3k-http",
"support": {
"issues": "https://github.com/aaronpk/p3k-http/issues",
- "source": "https://github.com/aaronpk/p3k-http/tree/0.1.13"
+ "source": "https://github.com/aaronpk/p3k-http/tree/0.2.2"
},
- "time": "2024-10-20T19:46:46+00:00"
+ "time": "2026-10-03T14:37:43+00:00"
},
{
"name": "paragonie/constant_time_encoding",
- "version": "v3.1.3",
+ "version": "v3.1.4",
"source": {
"type": "git",
"url": "https://github.com/paragonie/constant_time_encoding.git",
- "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77"
+ "reference": "5efef6e6cb43e088ccab7d0c1e2f2ab25b9e8b54"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77",
- "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77",
+ "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/5efef6e6cb43e088ccab7d0c1e2f2ab25b9e8b54",
+ "reference": "5efef6e6cb43e088ccab7d0c1e2f2ab25b9e8b54",
"shasum": ""
},
"require": {
@@ -3863,24 +3755,29 @@
"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"
+ "time": "2026-11-06T20:31:19+00:00"
},
{
"name": "phpdocumentor/reflection-common",
- "version": "2.2.0",
+ "version": "2.2.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
- "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
+ "reference": "ee15a5a2022c8383906b225055e9496a6a5e6e3b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
- "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/ee15a5a2022c8383906b225055e9496a6a5e6e3b",
+ "reference": "ee15a5a2022c8383906b225055e9496a6a5e6e3b",
"shasum": ""
},
"require": {
- "php": "^7.2 || ^8.0"
+ "php": "^7.4 || ^8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^1.8",
+ "phpunit/phpunit": "^9.5",
+ "vimeo/psalm": "^4.25"
},
"type": "library",
"extra": {
@@ -3904,7 +3801,7 @@
}
],
"description": "Common reflection classes used by phpdocumentor to reflect the code structure",
- "homepage": "http://www.phpdoc.org",
+ "homepage": "https://www.phpdoc.org",
"keywords": [
"FQSEN",
"phpDocumentor",
@@ -3914,9 +3811,9 @@
],
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
- "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
+ "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.2.1"
},
- "time": "2020-06-27T09:03:43+00:00"
+ "time": "2025-11-10T21:21:55+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
@@ -3985,16 +3882,16 @@
},
{
"name": "phpdocumentor/type-resolver",
- "version": "2.0.0",
+ "version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9"
+ "reference": "dbe2133bb23e2e33a6834f4ed417f24a1b167769"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9",
- "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/dbe2133bb23e2e33a6834f4ed417f24a1b167769",
+ "reference": "dbe2133bb23e2e33a6834f4ed417f24a1b167769",
"shasum": ""
},
"require": {
@@ -4037,22 +3934,22 @@
"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"
+ "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.1.0"
},
- "time": "2026-01-06T21:53:42+00:00"
+ "time": "2026-09-27T19:32:54+00:00"
},
{
"name": "phpoption/phpoption",
- "version": "1.9.5",
+ "version": "1.10.0",
"source": {
"type": "git",
"url": "https://github.com/schmittjoh/php-option.git",
- "reference": "75365b91986c2405cf5e1e012c5595cd487a98be"
+ "reference": "67b192b6a42ec03944b972d6e633ddec78ad2c6d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/75365b91986c2405cf5e1e012c5595cd487a98be",
- "reference": "75365b91986c2405cf5e1e012c5595cd487a98be",
+ "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/67b192b6a42ec03944b972d6e633ddec78ad2c6d",
+ "reference": "67b192b6a42ec03944b972d6e633ddec78ad2c6d",
"shasum": ""
},
"require": {
@@ -4060,7 +3957,7 @@
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
- "phpunit/phpunit": "^8.5.44 || ^9.6.25 || ^10.5.53 || ^11.5.34"
+ "phpunit/phpunit": "^8.5.54 || ^9.6.36 || ^10.5.64 || ^11.5.56 || ^12.5.33"
},
"type": "library",
"extra": {
@@ -4102,7 +3999,7 @@
],
"support": {
"issues": "https://github.com/schmittjoh/php-option/issues",
- "source": "https://github.com/schmittjoh/php-option/tree/1.9.5"
+ "source": "https://github.com/schmittjoh/php-option/tree/1.10.0"
},
"funding": [
{
@@ -4114,20 +4011,20 @@
"type": "tidelift"
}
],
- "time": "2025-12-27T19:41:33+00:00"
+ "time": "2026-08-24T00:54:40+00:00"
},
{
"name": "phpstan/phpdoc-parser",
- "version": "2.3.2",
+ "version": "2.4.1",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpdoc-parser.git",
- "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a"
+ "reference": "af8e840551031d254cfdb3a18a62c3470a309c10"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a",
- "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a",
+ "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/af8e840551031d254cfdb3a18a62c3470a309c10",
+ "reference": "af8e840551031d254cfdb3a18a62c3470a309c10",
"shasum": ""
},
"require": {
@@ -4159,9 +4056,9 @@
"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"
+ "source": "https://github.com/phpstan/phpdoc-parser/tree/2.4.1"
},
- "time": "2026-01-25T14:56:51+00:00"
+ "time": "2026-10-30T19:36:28+00:00"
},
{
"name": "psr/clock",
@@ -4654,50 +4551,6 @@
},
"time": "2026-06-29T15:41:09+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",
@@ -4776,20 +4629,20 @@
},
{
"name": "ramsey/uuid",
- "version": "4.9.3",
+ "version": "4.9.4",
"source": {
"type": "git",
"url": "https://github.com/ramsey/uuid.git",
- "reference": "1df15849d00943a67d677dc9cfd80795f038c9f8"
+ "reference": "75d73f48d02797c2c285a7e9f348fadc0102ffe2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/ramsey/uuid/zipball/1df15849d00943a67d677dc9cfd80795f038c9f8",
- "reference": "1df15849d00943a67d677dc9cfd80795f038c9f8",
+ "url": "https://api.github.com/repos/ramsey/uuid/zipball/75d73f48d02797c2c285a7e9f348fadc0102ffe2",
+ "reference": "75d73f48d02797c2c285a7e9f348fadc0102ffe2",
"shasum": ""
},
"require": {
- "brick/math": ">=0.8.16 <=0.18",
+ "brick/math": "^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14 || ^0.15 || ^0.16 || ^0.17 || ^0.18 || ^0.19 || ^0.20 || ^1.0",
"php": "^8.0",
"ramsey/collection": "^1.2 || ^2.0"
},
@@ -4848,9 +4701,9 @@
],
"support": {
"issues": "https://github.com/ramsey/uuid/issues",
- "source": "https://github.com/ramsey/uuid/tree/4.9.3"
+ "source": "https://github.com/ramsey/uuid/tree/4.9.4"
},
- "time": "2026-06-18T03:57:49+00:00"
+ "time": "2026-09-16T11:39:30+00:00"
},
{
"name": "spatie/backtrace",
@@ -4916,99 +4769,29 @@
],
"time": "2026-03-11T13:48:28+00:00"
},
- {
- "name": "spatie/error-solutions",
- "version": "2.0.5",
- "source": {
- "type": "git",
- "url": "https://github.com/spatie/error-solutions.git",
- "reference": "0392eff7f36f01249a6e9f8eb22a7d54651881bc"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/spatie/error-solutions/zipball/0392eff7f36f01249a6e9f8eb22a7d54651881bc",
- "reference": "0392eff7f36f01249a6e9f8eb22a7d54651881bc",
- "shasum": ""
- },
- "require": {
- "php": "^8.2"
- },
- "require-dev": {
- "illuminate/broadcasting": "^10.0|^11.0|^12.0|^13.0",
- "illuminate/cache": "^10.0|^11.0|^12.0|^13.0",
- "illuminate/support": "^10.0|^11.0|^12.0|^13.0",
- "livewire/livewire": "^2.11|^3.5.20|^4.0",
- "openai-php/client": "^0.13.0",
- "orchestra/testbench": "8.22.3|^9.0|^10.0|^11.0",
- "pestphp/pest": "^2.20|^3.0",
- "phpstan/phpstan": "^2.1",
- "psr/simple-cache": "^3.0",
- "psr/simple-cache-implementation": "^3.0",
- "spatie/ray": "^1.28",
- "symfony/cache": "^5.4|^6.0|^7.0|^8.0",
- "symfony/process": "^5.4|^6.0|^7.0|^8.0",
- "vlucas/phpdotenv": "^5.5"
- },
- "suggest": {
- "openai-php/client": "Require get solutions from OpenAI",
- "simple-cache-implementation": "To cache solutions from OpenAI"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Spatie\\ErrorSolutions\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Ruben Van Assche",
- "email": "ruben@spatie.be",
- "role": "Developer"
- }
- ],
- "description": "This is my package error-solutions",
- "homepage": "https://github.com/spatie/error-solutions",
- "keywords": [
- "error-solutions",
- "spatie"
- ],
- "support": {
- "issues": "https://github.com/spatie/error-solutions/issues",
- "source": "https://github.com/spatie/error-solutions/tree/2.0.5"
- },
- "funding": [
- {
- "url": "https://github.com/Spatie",
- "type": "github"
- }
- ],
- "time": "2026-02-27T15:32:49+00:00"
- },
{
"name": "spatie/flare-client-php",
- "version": "2.10.2",
+ "version": "3.6.0",
"source": {
"type": "git",
"url": "https://github.com/spatie/flare-client-php.git",
- "reference": "056aa9cb10e41d7490d51d2f15875143e6d12ce2"
+ "reference": "1723f59279fe3bbec8d25910cc1464694bea7f74"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/056aa9cb10e41d7490d51d2f15875143e6d12ce2",
- "reference": "056aa9cb10e41d7490d51d2f15875143e6d12ce2",
+ "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/1723f59279fe3bbec8d25910cc1464694bea7f74",
+ "reference": "1723f59279fe3bbec8d25910cc1464694bea7f74",
"shasum": ""
},
"require": {
"ext-curl": "*",
- "guzzlehttp/guzzle": "^7.9",
- "php": "^8.2",
+ "guzzlehttp/guzzle": "^7.9|^8.0",
+ "monolog/monolog": "^3.0",
+ "php": "^8.1",
"psr/container": "^2.0",
"spatie/backtrace": "^1.8.0",
- "spatie/error-solutions": "^2.0",
+ "spatie/flare-daemon": "^0.3",
+ "symfony/console": "^5.2|^6.0|^7.0|^8.0",
"symfony/http-foundation": "^5.2|^6.0|^7.0|^8.0",
"symfony/mime": "^5.2|^6.0|^7.0|^8.0",
"symfony/process": "^5.2|^6.0|^7.0|^8.0",
@@ -5018,14 +4801,16 @@
"friendsofphp/php-cs-fixer": "^3.89",
"pestphp/pest": "^2.36.0|^3.0|^4.0",
"phpstan/extension-installer": "^1.4",
- "phpstan/phpstan-deprecation-rules": "^1.2",
- "phpstan/phpstan-phpunit": "^1.4",
+ "phpstan/phpstan": "^2.0",
+ "phpstan/phpstan-deprecation-rules": "^2.0",
+ "phpstan/phpstan-phpunit": "^2.0",
+ "spatie/invade": "^2.1",
"spatie/pest-plugin-snapshots": "^2.2"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "1.3.x-dev"
+ "dev-main": "3.x-dev"
}
},
"autoload": {
@@ -5047,7 +4832,7 @@
],
"support": {
"issues": "https://github.com/spatie/flare-client-php/issues",
- "source": "https://github.com/spatie/flare-client-php/tree/2.10.2"
+ "source": "https://github.com/spatie/flare-client-php/tree/3.6.0"
},
"funding": [
{
@@ -5055,25 +4840,94 @@
"type": "github"
}
],
- "time": "2026-02-23T14:14:53+00:00"
+ "time": "2026-11-06T14:28:13+00:00"
},
{
- "name": "spatie/laravel-error-share",
- "version": "1.0.9",
+ "name": "spatie/flare-daemon",
+ "version": "0.3.2",
"source": {
"type": "git",
- "url": "https://github.com/spatie/laravel-error-share.git",
- "reference": "52e65ee35a7f782e27460cb307cc97cec8332793"
+ "url": "https://github.com/spatie/flare-daemon.git",
+ "reference": "a60de5a2f8b4e6796a8d429f9ec95d9d3f0cc00f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/spatie/laravel-error-share/zipball/52e65ee35a7f782e27460cb307cc97cec8332793",
- "reference": "52e65ee35a7f782e27460cb307cc97cec8332793",
+ "url": "https://api.github.com/repos/spatie/flare-daemon/zipball/a60de5a2f8b4e6796a8d429f9ec95d9d3f0cc00f",
+ "reference": "a60de5a2f8b4e6796a8d429f9ec95d9d3f0cc00f",
"shasum": ""
},
"require": {
- "illuminate/contracts": "^12.50|^13.0",
- "php": "^8.2",
+ "composer-runtime-api": "^2.2",
+ "ext-zlib": "*",
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "laravel/pint": "^1.0",
+ "pestphp/pest": "^3.0 || ^4.0",
+ "phpstan/phpstan": "^2.1",
+ "react/async": "^4.3",
+ "spatie/flare-daemon-runtime": "*",
+ "spatie/ray": "^1.28",
+ "symfony/process": "^8.1"
+ },
+ "bin": [
+ "bin/flare-daemon"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Spatie\\FlareDaemon\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Alex Vanderbist",
+ "email": "alex@spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Local HTTP daemon for asynchronous Flare delivery",
+ "homepage": "https://github.com/spatie/flare-daemon",
+ "keywords": [
+ "error-tracking",
+ "flare",
+ "flare-daemon",
+ "performance-monitoring",
+ "spatie"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/flare-daemon/issues",
+ "source": "https://github.com/spatie/flare-daemon/tree/0.3.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2026-11-06T12:24:47+00:00"
+ },
+ {
+ "name": "spatie/laravel-error-share",
+ "version": "1.0.11",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/laravel-error-share.git",
+ "reference": "7822ce87e76b26c14099d45901ce8ac453ee349a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/laravel-error-share/zipball/7822ce87e76b26c14099d45901ce8ac453ee349a",
+ "reference": "7822ce87e76b26c14099d45901ce8ac453ee349a",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/contracts": "^10.0|^11.0|^12.50|^13.0",
+ "php": "^8.1",
"spatie/laravel-package-tools": "^1.16"
},
"require-dev": {
@@ -5092,9 +4946,6 @@
"type": "library",
"extra": {
"laravel": {
- "aliases": {
- "LaravelErrorShare": "Spatie\\LaravelErrorShare\\Facades\\LaravelErrorShare"
- },
"providers": [
"Spatie\\LaravelErrorShare\\LaravelErrorShareServiceProvider"
]
@@ -5129,7 +4980,7 @@
],
"support": {
"issues": "https://github.com/spatie/laravel-error-share/issues",
- "source": "https://github.com/spatie/laravel-error-share/tree/1.0.9"
+ "source": "https://github.com/spatie/laravel-error-share/tree/1.0.11"
},
"funding": [
{
@@ -5137,51 +4988,46 @@
"type": "github"
}
],
- "time": "2026-05-11T08:16:59+00:00"
+ "time": "2026-11-04T11:34:57+00:00"
},
{
"name": "spatie/laravel-flare",
- "version": "2.8.0",
+ "version": "3.6.1",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-flare.git",
- "reference": "c2722a270ba2653baef2c9e29b893e28955717ce"
+ "reference": "b691401afe223ad20aa5e6e1d38516aeb36ff0a6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/spatie/laravel-flare/zipball/c2722a270ba2653baef2c9e29b893e28955717ce",
- "reference": "c2722a270ba2653baef2c9e29b893e28955717ce",
+ "url": "https://api.github.com/repos/spatie/laravel-flare/zipball/b691401afe223ad20aa5e6e1d38516aeb36ff0a6",
+ "reference": "b691401afe223ad20aa5e6e1d38516aeb36ff0a6",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
- "illuminate/support": "^11.46|^12.0|^13.0",
+ "illuminate/support": "^10.14|^11.47|^12.42|^13.0",
"php": "^8.2",
- "spatie/error-solutions": "^2.0",
- "spatie/flare-client-php": "^2.10.2",
+ "spatie/flare-client-php": "^3.5",
"spatie/laravel-error-share": "^1.0.3",
- "symfony/console": "^7.2.1|^8.0",
- "symfony/var-dumper": "^7.2.3|^8.0"
+ "symfony/console": "^6.4|^7.2.1|^8.0",
+ "symfony/var-dumper": "^6.4|^7.2.3|^8.0"
},
"require-dev": {
- "laravel/serializable-closure": "^2.0",
- "livewire/livewire": "^3.6.0|^4.0",
+ "laravel/serializable-closure": "^1.3|^2.0",
+ "livewire/livewire": "^3.6.0|^4.2",
"mockery/mockery": "^1.6.12",
- "openai-php/client": "^0.8.5",
- "orchestra/testbench": "^9.14|^10.8|^11.0",
+ "orchestra/testbench": "^8.31|^9.14|^10.8|^11.0",
"pestphp/pest": "^2.34|^3.7.4|^4.1",
"pestphp/pest-plugin-laravel": "^2.4|^3.0|^4.0",
"phpstan/extension-installer": "^1.4.3",
"phpstan/phpstan-deprecation-rules": "^1.1.1|^2.0.1",
"phpstan/phpstan-phpunit": "^1.3.16|^2.0.4",
+ "spatie/ray": "^1.45",
"vlucas/phpdotenv": "^5.6.1"
},
- "suggest": {
- "openai-php/client": "Required to get solutions from OpenAI",
- "psr/simple-cache-implementation": "Used to cache solutions from OpenAI"
- },
"type": "library",
"extra": {
"laravel": {
@@ -5228,20 +5074,20 @@
"type": "github"
}
],
- "time": "2026-04-08T13:26:20+00:00"
+ "time": "2026-09-09T09:54:07+00:00"
},
{
"name": "spatie/laravel-package-tools",
- "version": "1.93.1",
+ "version": "1.93.3",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-package-tools.git",
- "reference": "d5552849801f2642aea710557463234b59ef65eb"
+ "reference": "7aeef26bd8d4909bec744dbf47aee7d1395588c1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/d5552849801f2642aea710557463234b59ef65eb",
- "reference": "d5552849801f2642aea710557463234b59ef65eb",
+ "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/7aeef26bd8d4909bec744dbf47aee7d1395588c1",
+ "reference": "7aeef26bd8d4909bec744dbf47aee7d1395588c1",
"shasum": ""
},
"require": {
@@ -5281,7 +5127,7 @@
],
"support": {
"issues": "https://github.com/spatie/laravel-package-tools/issues",
- "source": "https://github.com/spatie/laravel-package-tools/tree/1.93.1"
+ "source": "https://github.com/spatie/laravel-package-tools/tree/1.93.3"
},
"funding": [
{
@@ -5289,26 +5135,27 @@
"type": "github"
}
],
- "time": "2026-05-19T14:06:37+00:00"
+ "time": "2026-09-28T07:16:50+00:00"
},
{
"name": "spomky-labs/cbor-php",
- "version": "3.2.3",
+ "version": "3.4.2",
"source": {
"type": "git",
"url": "https://github.com/Spomky-Labs/cbor-php.git",
- "reference": "dd6eb84e6d92f7b8bd0da56b4b4dd7235aed0c32"
+ "reference": "8f5ea00a07ad529d20886505cdbeb2b9ac7bb2d6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Spomky-Labs/cbor-php/zipball/dd6eb84e6d92f7b8bd0da56b4b4dd7235aed0c32",
- "reference": "dd6eb84e6d92f7b8bd0da56b4b4dd7235aed0c32",
+ "url": "https://api.github.com/repos/Spomky-Labs/cbor-php/zipball/8f5ea00a07ad529d20886505cdbeb2b9ac7bb2d6",
+ "reference": "8f5ea00a07ad529d20886505cdbeb2b9ac7bb2d6",
"shasum": ""
},
"require": {
- "brick/math": "^0.9|^0.10|^0.11|^0.12|^0.13|^0.14|^0.15|^0.16|^0.17",
+ "brick/math": "^0.9|^0.10|^0.11|^0.12|^0.13|^0.14|^0.15|^0.16|^0.17|^0.18|^0.19|^0.20|^1.0",
"ext-mbstring": "*",
- "php": ">=8.0"
+ "php": ">=8.0",
+ "symfony/polyfill-php81": "^1.32"
},
"require-dev": {
"ext-json": "*",
@@ -5317,8 +5164,8 @@
"symfony/var-dumper": "^6.4|^7.1|^8.0"
},
"suggest": {
- "ext-bcmath": "GMP or BCMath extensions will drastically improve the library performance. BCMath extension needed to handle the Big Float and Decimal Fraction Tags",
- "ext-gmp": "GMP or BCMath extensions will drastically improve the library performance"
+ "ext-bcmath": "Improves the library performance when ext-gmp is missing, and is required to handle the Big Float and Decimal Fraction Tags (4 and 5)",
+ "ext-gmp": "Strongly recommended when decoding untrusted input: without it, converting the byte string of a Big Number Tag (2 and 3) is quadratic in its length. Also improves the library performance overall"
},
"type": "library",
"autoload": {
@@ -5348,7 +5195,7 @@
],
"support": {
"issues": "https://github.com/Spomky-Labs/cbor-php/issues",
- "source": "https://github.com/Spomky-Labs/cbor-php/tree/3.2.3"
+ "source": "https://github.com/Spomky-Labs/cbor-php/tree/3.4.2"
},
"funding": [
{
@@ -5360,50 +5207,50 @@
"type": "patreon"
}
],
- "time": "2026-04-01T12:15:20+00:00"
+ "time": "2026-09-15T06:55:29+00:00"
},
{
"name": "spomky-labs/pki-framework",
- "version": "1.4.2",
+ "version": "1.6.3",
"source": {
"type": "git",
"url": "https://github.com/Spomky-Labs/pki-framework.git",
- "reference": "aa576cbd07128075bef97ac2f8af9854e67513d8"
+ "reference": "792e909d4e387adffe3c4f404451c7d57a3d2022"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Spomky-Labs/pki-framework/zipball/aa576cbd07128075bef97ac2f8af9854e67513d8",
- "reference": "aa576cbd07128075bef97ac2f8af9854e67513d8",
+ "url": "https://api.github.com/repos/Spomky-Labs/pki-framework/zipball/792e909d4e387adffe3c4f404451c7d57a3d2022",
+ "reference": "792e909d4e387adffe3c4f404451c7d57a3d2022",
"shasum": ""
},
"require": {
- "brick/math": "^0.10|^0.11|^0.12|^0.13|^0.14|^0.15|^0.16|^0.17",
+ "brick/math": "^0.10|^0.11|^0.12|^0.13|^0.14|^0.15|^0.16|^0.17|^0.18|^0.19|^0.20|^1.0",
"ext-mbstring": "*",
- "php": ">=8.1",
- "psr/clock": "^1.0"
+ "php": ">=8.1"
},
"require-dev": {
"ekino/phpstan-banned-code": "^1.0|^2.0|^3.0",
"ext-gmp": "*",
"ext-openssl": "*",
- "infection/infection": "^0.28|^0.29|^0.31|^0.32",
+ "infection/infection": "^0.28|^0.29|^0.31",
"php-parallel-lint/php-parallel-lint": "^1.3",
"phpstan/extension-installer": "^1.3|^2.0",
"phpstan/phpstan": "^1.8|^2.0",
"phpstan/phpstan-deprecation-rules": "^1.0|^2.0",
"phpstan/phpstan-phpunit": "^1.1|^2.0",
"phpstan/phpstan-strict-rules": "^1.3|^2.0",
- "phpunit/phpunit": "^10.1|^11.0|^12.0|^13.0",
+ "phpunit/phpunit": "^10.1|^11.0|^12.0",
"rector/rector": "^1.0|^2.0",
"roave/security-advisories": "dev-latest",
"symfony/string": "^6.4|^7.0|^8.0",
"symfony/var-dumper": "^6.4|^7.0|^8.0",
- "symplify/easy-coding-standard": "^12.0|^13.0"
+ "symplify/easy-coding-standard": "^12.0 || ^13.0"
},
"suggest": {
"ext-bcmath": "For better performance (or GMP)",
"ext-gmp": "For better performance (or BCMath)",
- "ext-openssl": "For OpenSSL based cyphering"
+ "ext-openssl": "For OpenSSL based cyphering",
+ "ext-sodium": "To verify Ed25519 signatures where the OpenSSL extension has no EdDSA"
},
"type": "library",
"autoload": {
@@ -5458,7 +5305,7 @@
],
"support": {
"issues": "https://github.com/Spomky-Labs/pki-framework/issues",
- "source": "https://github.com/Spomky-Labs/pki-framework/tree/1.4.2"
+ "source": "https://github.com/Spomky-Labs/pki-framework/tree/1.6.3"
},
"funding": [
{
@@ -5470,20 +5317,20 @@
"type": "patreon"
}
],
- "time": "2026-03-23T22:56:56+00:00"
+ "time": "2026-09-12T19:02:49+00:00"
},
{
"name": "symfony/clock",
- "version": "v8.1.0",
+ "version": "v8.1.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/clock.git",
- "reference": "701ef4de9705d6c32292ebee5e8044094a09fbf6"
+ "reference": "945ea3b64d6da9c1c2c354fe5c07b27455df6442"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/clock/zipball/701ef4de9705d6c32292ebee5e8044094a09fbf6",
- "reference": "701ef4de9705d6c32292ebee5e8044094a09fbf6",
+ "url": "https://api.github.com/repos/symfony/clock/zipball/945ea3b64d6da9c1c2c354fe5c07b27455df6442",
+ "reference": "945ea3b64d6da9c1c2c354fe5c07b27455df6442",
"shasum": ""
},
"require": {
@@ -5527,7 +5374,7 @@
"time"
],
"support": {
- "source": "https://github.com/symfony/clock/tree/v8.1.0"
+ "source": "https://github.com/symfony/clock/tree/v8.1.9"
},
"funding": [
{
@@ -5547,20 +5394,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-29T05:06:50+00:00"
+ "time": "2026-10-12T14:32:04+00:00"
},
{
"name": "symfony/console",
- "version": "v8.1.1",
+ "version": "v8.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "b711a8ab808b6c074c6b8caef70d0fd8d6b6d07d"
+ "reference": "5a315b092b81f3e920e9daea1a2ae4c66ed298b9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/b711a8ab808b6c074c6b8caef70d0fd8d6b6d07d",
- "reference": "b711a8ab808b6c074c6b8caef70d0fd8d6b6d07d",
+ "url": "https://api.github.com/repos/symfony/console/zipball/5a315b092b81f3e920e9daea1a2ae4c66ed298b9",
+ "reference": "5a315b092b81f3e920e9daea1a2ae4c66ed298b9",
"shasum": ""
},
"require": {
@@ -5627,7 +5474,7 @@
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v8.1.1"
+ "source": "https://github.com/symfony/console/tree/v8.1.11"
},
"funding": [
{
@@ -5647,20 +5494,20 @@
"type": "tidelift"
}
],
- "time": "2026-06-16T12:55:20+00:00"
+ "time": "2026-11-04T07:07:11+00:00"
},
{
"name": "symfony/css-selector",
- "version": "v8.1.0",
+ "version": "v8.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "dc0e2be45c9b5588c82414f02ac574b4b986abcd"
+ "reference": "9cfd588b8b07cf83e3426b030dbafd2291c132d9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/dc0e2be45c9b5588c82414f02ac574b4b986abcd",
- "reference": "dc0e2be45c9b5588c82414f02ac574b4b986abcd",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/9cfd588b8b07cf83e3426b030dbafd2291c132d9",
+ "reference": "9cfd588b8b07cf83e3426b030dbafd2291c132d9",
"shasum": ""
},
"require": {
@@ -5696,7 +5543,7 @@
"description": "Converts CSS selectors to XPath expressions",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/css-selector/tree/v8.1.0"
+ "source": "https://github.com/symfony/css-selector/tree/v8.1.10"
},
"funding": [
{
@@ -5716,20 +5563,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-29T05:06:50+00:00"
+ "time": "2026-10-18T14:56:39+00:00"
},
{
"name": "symfony/deprecation-contracts",
- "version": "v3.7.1",
+ "version": "v3.8.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
- "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d"
+ "reference": "feb1edf4e546af3b85c5caebe8359a20db230ca3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/f3202fa1b5097b0af062dc978b32ecf63404e31d",
- "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/feb1edf4e546af3b85c5caebe8359a20db230ca3",
+ "reference": "feb1edf4e546af3b85c5caebe8359a20db230ca3",
"shasum": ""
},
"require": {
@@ -5742,7 +5589,7 @@
"name": "symfony/contracts"
},
"branch-alias": {
- "dev-main": "3.7-dev"
+ "dev-main": "3.8-dev"
}
},
"autoload": {
@@ -5767,7 +5614,7 @@
"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.1"
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.8.1"
},
"funding": [
{
@@ -5787,20 +5634,20 @@
"type": "tidelift"
}
],
- "time": "2026-06-05T06:23:12+00:00"
+ "time": "2026-09-16T14:15:10+00:00"
},
{
"name": "symfony/error-handler",
- "version": "v8.1.0",
+ "version": "v8.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/error-handler.git",
- "reference": "d8aeb1abd3fef84795567850d3a567bdb5945ee5"
+ "reference": "84c6d73f990ae22dbd45625c056d7ff99ca6810d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/error-handler/zipball/d8aeb1abd3fef84795567850d3a567bdb5945ee5",
- "reference": "d8aeb1abd3fef84795567850d3a567bdb5945ee5",
+ "url": "https://api.github.com/repos/symfony/error-handler/zipball/84c6d73f990ae22dbd45625c056d7ff99ca6810d",
+ "reference": "84c6d73f990ae22dbd45625c056d7ff99ca6810d",
"shasum": ""
},
"require": {
@@ -5848,7 +5695,7 @@
"description": "Provides tools to manage errors and ease debugging PHP code",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/error-handler/tree/v8.1.0"
+ "source": "https://github.com/symfony/error-handler/tree/v8.1.10"
},
"funding": [
{
@@ -5868,20 +5715,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-29T05:06:50+00:00"
+ "time": "2026-10-25T14:40:25+00:00"
},
{
"name": "symfony/event-dispatcher",
- "version": "v8.1.1",
+ "version": "v8.1.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "abd6c11dc468725d1627302ad10f6cd486e9e3d0"
+ "reference": "7458da64220376b2e0dc2d8451bf43382c1ad297"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/abd6c11dc468725d1627302ad10f6cd486e9e3d0",
- "reference": "abd6c11dc468725d1627302ad10f6cd486e9e3d0",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/7458da64220376b2e0dc2d8451bf43382c1ad297",
+ "reference": "7458da64220376b2e0dc2d8451bf43382c1ad297",
"shasum": ""
},
"require": {
@@ -5934,7 +5781,7 @@
"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/v8.1.1"
+ "source": "https://github.com/symfony/event-dispatcher/tree/v8.1.5"
},
"funding": [
{
@@ -5954,20 +5801,20 @@
"type": "tidelift"
}
],
- "time": "2026-06-09T12:28:30+00:00"
+ "time": "2026-08-21T17:47:34+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
- "version": "v3.7.1",
+ "version": "v3.8.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher-contracts.git",
- "reference": "c7de7a00ffb67842132da02ea92988a39ccd9f4e"
+ "reference": "658e29751424da3ef4758c60f769e59d1b2981eb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c7de7a00ffb67842132da02ea92988a39ccd9f4e",
- "reference": "c7de7a00ffb67842132da02ea92988a39ccd9f4e",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/658e29751424da3ef4758c60f769e59d1b2981eb",
+ "reference": "658e29751424da3ef4758c60f769e59d1b2981eb",
"shasum": ""
},
"require": {
@@ -5981,7 +5828,7 @@
"name": "symfony/contracts"
},
"branch-alias": {
- "dev-main": "3.7-dev"
+ "dev-main": "3.8-dev"
}
},
"autoload": {
@@ -6014,7 +5861,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.7.1"
+ "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.8.1"
},
"funding": [
{
@@ -6034,20 +5881,20 @@
"type": "tidelift"
}
],
- "time": "2026-06-05T06:23:12+00:00"
+ "time": "2026-09-16T14:15:10+00:00"
},
{
"name": "symfony/filesystem",
- "version": "v8.1.0",
+ "version": "v8.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "99aec13b82b4967ec5088222c4a3ecca955949c2"
+ "reference": "58f57b6a33e3495f7f41e01258f1ae5ef76cccd2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/99aec13b82b4967ec5088222c4a3ecca955949c2",
- "reference": "99aec13b82b4967ec5088222c4a3ecca955949c2",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/58f57b6a33e3495f7f41e01258f1ae5ef76cccd2",
+ "reference": "58f57b6a33e3495f7f41e01258f1ae5ef76cccd2",
"shasum": ""
},
"require": {
@@ -6085,7 +5932,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/filesystem/tree/v8.1.0"
+ "source": "https://github.com/symfony/filesystem/tree/v8.1.11"
},
"funding": [
{
@@ -6105,20 +5952,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-29T05:06:50+00:00"
+ "time": "2026-11-04T08:39:20+00:00"
},
{
"name": "symfony/finder",
- "version": "v8.1.1",
+ "version": "v8.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "e2989e762c70f9490fa3a00a0ac0fae5aa97a531"
+ "reference": "a2902e479ba5691d20d51d100a715ea19ad2c837"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/e2989e762c70f9490fa3a00a0ac0fae5aa97a531",
- "reference": "e2989e762c70f9490fa3a00a0ac0fae5aa97a531",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/a2902e479ba5691d20d51d100a715ea19ad2c837",
+ "reference": "a2902e479ba5691d20d51d100a715ea19ad2c837",
"shasum": ""
},
"require": {
@@ -6153,7 +6000,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/finder/tree/v8.1.1"
+ "source": "https://github.com/symfony/finder/tree/v8.1.11"
},
"funding": [
{
@@ -6173,20 +6020,20 @@
"type": "tidelift"
}
],
- "time": "2026-06-27T09:05:56+00:00"
+ "time": "2026-11-02T10:58:30+00:00"
},
{
"name": "symfony/html-sanitizer",
- "version": "v8.1.1",
+ "version": "v8.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/html-sanitizer.git",
- "reference": "09e1f2f9a3c8dcdca072587dc71999c1921c07cb"
+ "reference": "1ecf13d98b75f5d8a2dcc1ffecde7184d29506ef"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/html-sanitizer/zipball/09e1f2f9a3c8dcdca072587dc71999c1921c07cb",
- "reference": "09e1f2f9a3c8dcdca072587dc71999c1921c07cb",
+ "url": "https://api.github.com/repos/symfony/html-sanitizer/zipball/1ecf13d98b75f5d8a2dcc1ffecde7184d29506ef",
+ "reference": "1ecf13d98b75f5d8a2dcc1ffecde7184d29506ef",
"shasum": ""
},
"require": {
@@ -6225,7 +6072,7 @@
"sanitizer"
],
"support": {
- "source": "https://github.com/symfony/html-sanitizer/tree/v8.1.1"
+ "source": "https://github.com/symfony/html-sanitizer/tree/v8.1.11"
},
"funding": [
{
@@ -6245,20 +6092,20 @@
"type": "tidelift"
}
],
- "time": "2026-06-06T11:11:44+00:00"
+ "time": "2026-11-04T08:39:20+00:00"
},
{
"name": "symfony/http-foundation",
- "version": "v8.1.1",
+ "version": "v8.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "6a168c8fcee806b57ac020244da14293d1f9a883"
+ "reference": "30fa3efe6e736b0d06f5331cc6abe813582c0a26"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6a168c8fcee806b57ac020244da14293d1f9a883",
- "reference": "6a168c8fcee806b57ac020244da14293d1f9a883",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/30fa3efe6e736b0d06f5331cc6abe813582c0a26",
+ "reference": "30fa3efe6e736b0d06f5331cc6abe813582c0a26",
"shasum": ""
},
"require": {
@@ -6306,7 +6153,7 @@
"description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-foundation/tree/v8.1.1"
+ "source": "https://github.com/symfony/http-foundation/tree/v8.1.11"
},
"funding": [
{
@@ -6326,20 +6173,20 @@
"type": "tidelift"
}
],
- "time": "2026-06-12T08:43:41+00:00"
+ "time": "2026-11-04T08:39:20+00:00"
},
{
"name": "symfony/http-kernel",
- "version": "v8.1.1",
+ "version": "v8.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "89d8d6e7fbab3d9eda89ccb5ecdf44a74c4ec9d2"
+ "reference": "460658504e26a2794aa614b4fbe6cf9bac2076fe"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/89d8d6e7fbab3d9eda89ccb5ecdf44a74c4ec9d2",
- "reference": "89d8d6e7fbab3d9eda89ccb5ecdf44a74c4ec9d2",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/460658504e26a2794aa614b4fbe6cf9bac2076fe",
+ "reference": "460658504e26a2794aa614b4fbe6cf9bac2076fe",
"shasum": ""
},
"require": {
@@ -6355,6 +6202,7 @@
"symfony/dependency-injection": "<8.1",
"symfony/flex": "<2.10",
"symfony/http-client-contracts": "<2.5",
+ "symfony/serializer": "<7.4.15|>=8.0,<8.0.15|>=8.1,<8.1.2",
"symfony/translation-contracts": "<2.5",
"symfony/var-dumper": "<8.1",
"symfony/web-profiler-bundle": "<8.1",
@@ -6387,7 +6235,7 @@
"symfony/validator": "^7.4|^8.0",
"symfony/var-dumper": "^8.1",
"symfony/var-exporter": "^7.4|^8.0",
- "twig/twig": "^3.21"
+ "twig/twig": "^3.21|^4.0"
},
"type": "library",
"autoload": {
@@ -6415,7 +6263,7 @@
"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/v8.1.1"
+ "source": "https://github.com/symfony/http-kernel/tree/v8.1.11"
},
"funding": [
{
@@ -6435,20 +6283,20 @@
"type": "tidelift"
}
],
- "time": "2026-06-27T09:27:36+00:00"
+ "time": "2026-11-04T11:29:46+00:00"
},
{
"name": "symfony/mailer",
- "version": "v8.1.1",
+ "version": "v8.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailer.git",
- "reference": "4fa583a7377f28d54e4de442fba76375b2e20a12"
+ "reference": "4ba81a8f04fbf0bb1691f7bff760b301f1956fd7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mailer/zipball/4fa583a7377f28d54e4de442fba76375b2e20a12",
- "reference": "4fa583a7377f28d54e4de442fba76375b2e20a12",
+ "url": "https://api.github.com/repos/symfony/mailer/zipball/4ba81a8f04fbf0bb1691f7bff760b301f1956fd7",
+ "reference": "4ba81a8f04fbf0bb1691f7bff760b301f1956fd7",
"shasum": ""
},
"require": {
@@ -6495,7 +6343,7 @@
"description": "Helps sending emails",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/mailer/tree/v8.1.1"
+ "source": "https://github.com/symfony/mailer/tree/v8.1.10"
},
"funding": [
{
@@ -6515,20 +6363,20 @@
"type": "tidelift"
}
],
- "time": "2026-06-16T12:55:20+00:00"
+ "time": "2026-10-23T17:06:53+00:00"
},
{
"name": "symfony/mime",
- "version": "v8.1.0",
+ "version": "v8.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/mime.git",
- "reference": "b164ae7e3f7915aacfe9ee155f2f358502440664"
+ "reference": "8d1232052c9cdef170ed9608b3147bca4f61ff69"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mime/zipball/b164ae7e3f7915aacfe9ee155f2f358502440664",
- "reference": "b164ae7e3f7915aacfe9ee155f2f358502440664",
+ "url": "https://api.github.com/repos/symfony/mime/zipball/8d1232052c9cdef170ed9608b3147bca4f61ff69",
+ "reference": "8d1232052c9cdef170ed9608b3147bca4f61ff69",
"shasum": ""
},
"require": {
@@ -6549,7 +6397,7 @@
"symfony/process": "^7.4|^8.0",
"symfony/property-access": "^7.4|^8.0",
"symfony/property-info": "^7.4|^8.0",
- "symfony/serializer": "^7.4|^8.0"
+ "symfony/serializer": "^7.4.17|^8.1.5"
},
"type": "library",
"autoload": {
@@ -6581,7 +6429,7 @@
"mime-type"
],
"support": {
- "source": "https://github.com/symfony/mime/tree/v8.1.0"
+ "source": "https://github.com/symfony/mime/tree/v8.1.10"
},
"funding": [
{
@@ -6601,7 +6449,7 @@
"type": "tidelift"
}
],
- "time": "2026-05-29T05:06:50+00:00"
+ "time": "2026-10-28T17:58:38+00:00"
},
{
"name": "symfony/polyfill-ctype",
@@ -6688,16 +6536,16 @@
},
{
"name": "symfony/polyfill-intl-grapheme",
- "version": "v1.38.1",
+ "version": "v1.43.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
- "reference": "e9247d281d694a5120554d9afaf54e070e88a603"
+ "reference": "5a8f33c87aeecffce24e721b5064fab05f4becf8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/e9247d281d694a5120554d9afaf54e070e88a603",
- "reference": "e9247d281d694a5120554d9afaf54e070e88a603",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5a8f33c87aeecffce24e721b5064fab05f4becf8",
+ "reference": "5a8f33c87aeecffce24e721b5064fab05f4becf8",
"shasum": ""
},
"require": {
@@ -6746,7 +6594,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.38.1"
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.43.3"
},
"funding": [
{
@@ -6766,20 +6614,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-26T05:58:03+00:00"
+ "time": "2026-10-15T09:18:53+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
- "version": "v1.38.1",
+ "version": "v1.43.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
- "reference": "dc21118016c039a66235cf93d96b435ffb282412"
+ "reference": "533d68cf99c8f8ee2e8893c59ed59192e92cfd74"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/dc21118016c039a66235cf93d96b435ffb282412",
- "reference": "dc21118016c039a66235cf93d96b435ffb282412",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/533d68cf99c8f8ee2e8893c59ed59192e92cfd74",
+ "reference": "533d68cf99c8f8ee2e8893c59ed59192e92cfd74",
"shasum": ""
},
"require": {
@@ -6833,7 +6681,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.38.1"
+ "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.43.0"
},
"funding": [
{
@@ -6853,20 +6701,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-25T15:22:23+00:00"
+ "time": "2026-09-23T14:40:04+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
- "version": "v1.38.0",
+ "version": "v1.43.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
- "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b"
+ "reference": "ebd57ccc7edb93d632e184efbe7693d2517bab3b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/2d446c214bdbe5b71bde5011b060a05fece3ae6b",
- "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/ebd57ccc7edb93d632e184efbe7693d2517bab3b",
+ "reference": "ebd57ccc7edb93d632e184efbe7693d2517bab3b",
"shasum": ""
},
"require": {
@@ -6918,7 +6766,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.38.0"
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.43.0"
},
"funding": [
{
@@ -6938,20 +6786,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-25T13:48:31+00:00"
+ "time": "2026-09-23T22:02:09+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.38.2",
+ "version": "v1.43.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6"
+ "reference": "122889ed24dc000165bcbfd77ec412f15cbdfc6a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6",
- "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/122889ed24dc000165bcbfd77ec412f15cbdfc6a",
+ "reference": "122889ed24dc000165bcbfd77ec412f15cbdfc6a",
"shasum": ""
},
"require": {
@@ -7003,7 +6851,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2"
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.43.3"
},
"funding": [
{
@@ -7023,20 +6871,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-27T06:59:30+00:00"
+ "time": "2026-10-28T09:35:49+00:00"
},
{
"name": "symfony/polyfill-php80",
- "version": "v1.37.0",
+ "version": "v1.43.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
- "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411"
+ "reference": "9c6a5d6b01ca51d486c813e9a9c0ed55f208bb74"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411",
- "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/9c6a5d6b01ca51d486c813e9a9c0ed55f208bb74",
+ "reference": "9c6a5d6b01ca51d486c813e9a9c0ed55f208bb74",
"shasum": ""
},
"require": {
@@ -7087,7 +6935,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0"
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.43.0"
},
"funding": [
{
@@ -7107,20 +6955,180 @@
"type": "tidelift"
}
],
- "time": "2026-04-10T16:19:22+00:00"
+ "time": "2026-09-25T15:50:05+00:00"
},
{
- "name": "symfony/polyfill-php83",
- "version": "v1.38.2",
+ "name": "symfony/polyfill-php81",
+ "version": "v1.38.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-php83.git",
- "reference": "796a26abb75ce49f3a84433cd81bf1009d73d5f8"
+ "url": "https://github.com/symfony/polyfill-php81.git",
+ "reference": "6bfb9c766cacffbc8e118cb87217d08ed84e5cd7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/796a26abb75ce49f3a84433cd81bf1009d73d5f8",
- "reference": "796a26abb75ce49f3a84433cd81bf1009d73d5f8",
+ "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/6bfb9c766cacffbc8e118cb87217d08ed84e5cd7",
+ "reference": "6bfb9c766cacffbc8e118cb87217d08ed84e5cd7",
+ "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\\Php81\\": ""
+ },
+ "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.1+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php81/tree/v1.38.1"
+ },
+ "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-26T12:45:58+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php82",
+ "version": "v1.43.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php82.git",
+ "reference": "843bbe8b2a7934307b749751eede0f111f5d1cfc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php82/zipball/843bbe8b2a7934307b749751eede0f111f5d1cfc",
+ "reference": "843bbe8b2a7934307b749751eede0f111f5d1cfc",
+ "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\\Php82\\": ""
+ },
+ "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.2+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php82/tree/v1.43.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-09-25T15:50:05+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php83",
+ "version": "v1.43.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php83.git",
+ "reference": "80ccff923a8d61f73ebe9da0aa94e25232f004ce"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/80ccff923a8d61f73ebe9da0aa94e25232f004ce",
+ "reference": "80ccff923a8d61f73ebe9da0aa94e25232f004ce",
"shasum": ""
},
"require": {
@@ -7167,7 +7175,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.2"
+ "source": "https://github.com/symfony/polyfill-php83/tree/v1.43.0"
},
"funding": [
{
@@ -7187,20 +7195,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-27T06:51:48+00:00"
+ "time": "2026-09-25T15:50:05+00:00"
},
{
"name": "symfony/polyfill-php84",
- "version": "v1.38.1",
+ "version": "v1.43.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php84.git",
- "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa"
+ "reference": "22c6548499cbe5c5bb072fc0c42312dff062a015"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa",
- "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa",
+ "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/22c6548499cbe5c5bb072fc0c42312dff062a015",
+ "reference": "22c6548499cbe5c5bb072fc0c42312dff062a015",
"shasum": ""
},
"require": {
@@ -7247,7 +7255,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php84/tree/v1.38.1"
+ "source": "https://github.com/symfony/polyfill-php84/tree/v1.43.0"
},
"funding": [
{
@@ -7267,20 +7275,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-26T12:51:13+00:00"
+ "time": "2026-09-23T22:01:09+00:00"
},
{
"name": "symfony/polyfill-php85",
- "version": "v1.38.1",
+ "version": "v1.43.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php85.git",
- "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1"
+ "reference": "86a42cbcc07adc331481a5ab310a4024bfc227f6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1",
- "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1",
+ "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/86a42cbcc07adc331481a5ab310a4024bfc227f6",
+ "reference": "86a42cbcc07adc331481a5ab310a4024bfc227f6",
"shasum": ""
},
"require": {
@@ -7327,7 +7335,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php85/tree/v1.38.1"
+ "source": "https://github.com/symfony/polyfill-php85/tree/v1.43.0"
},
"funding": [
{
@@ -7347,20 +7355,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-26T02:25:22+00:00"
+ "time": "2026-09-25T15:46:47+00:00"
},
{
"name": "symfony/polyfill-php86",
- "version": "v1.38.0",
+ "version": "v1.43.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php86.git",
- "reference": "fcec68d64f46dc84e1f6ffcf2c6dda40ff3143ad"
+ "reference": "8840df45b24f33a49dc419fa18dc0057231ae1d8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php86/zipball/fcec68d64f46dc84e1f6ffcf2c6dda40ff3143ad",
- "reference": "fcec68d64f46dc84e1f6ffcf2c6dda40ff3143ad",
+ "url": "https://api.github.com/repos/symfony/polyfill-php86/zipball/8840df45b24f33a49dc419fa18dc0057231ae1d8",
+ "reference": "8840df45b24f33a49dc419fa18dc0057231ae1d8",
"shasum": ""
},
"require": {
@@ -7407,7 +7415,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php86/tree/v1.38.0"
+ "source": "https://github.com/symfony/polyfill-php86/tree/v1.43.0"
},
"funding": [
{
@@ -7427,20 +7435,103 @@
"type": "tidelift"
}
],
- "time": "2026-05-25T11:52:35+00:00"
+ "time": "2026-09-25T15:46:47+00:00"
},
{
- "name": "symfony/polyfill-uuid",
- "version": "v1.37.0",
+ "name": "symfony/polyfill-time",
+ "version": "v1.42.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-uuid.git",
- "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94"
+ "url": "https://github.com/symfony/polyfill-time.git",
+ "reference": "ac9f1ed802dd58f37e720388130c088434aa09fc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/26dfec253c4cf3e51b541b52ddf7e42cb0908e94",
- "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94",
+ "url": "https://api.github.com/repos/symfony/polyfill-time/zipball/ac9f1ed802dd58f37e720388130c088434aa09fc",
+ "reference": "ac9f1ed802dd58f37e720388130c088434aa09fc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "type": "library",
+ "extra": {
+ "thanks": {
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Time\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ignace Philippe Nyamagana Butera",
+ "email": "nyamsprod@gmail.com"
+ },
+ {
+ "name": "Tim Düsterhus",
+ "email": "tim@tideways-gmbh.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Time API added to PHP 8.6",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "duration",
+ "polyfill",
+ "portable",
+ "shim",
+ "time"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-time/tree/v1.42.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-08-07T13:08:13+00:00"
+ },
+ {
+ "name": "symfony/polyfill-uuid",
+ "version": "v1.43.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-uuid.git",
+ "reference": "b23ff8245cc5c4479ea2be3d0132d2e6dd433993"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/b23ff8245cc5c4479ea2be3d0132d2e6dd433993",
+ "reference": "b23ff8245cc5c4479ea2be3d0132d2e6dd433993",
"shasum": ""
},
"require": {
@@ -7490,7 +7581,7 @@
"uuid"
],
"support": {
- "source": "https://github.com/symfony/polyfill-uuid/tree/v1.37.0"
+ "source": "https://github.com/symfony/polyfill-uuid/tree/v1.43.0"
},
"funding": [
{
@@ -7510,20 +7601,20 @@
"type": "tidelift"
}
],
- "time": "2026-04-10T16:19:22+00:00"
+ "time": "2026-09-24T05:20:52+00:00"
},
{
"name": "symfony/process",
- "version": "v8.1.0",
+ "version": "v8.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "c4a9e58f235a6bf7f97ffbfedae2687353ac79e5"
+ "reference": "08aa69fa0998bb65a089f9e148a2c0f8b391398e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/c4a9e58f235a6bf7f97ffbfedae2687353ac79e5",
- "reference": "c4a9e58f235a6bf7f97ffbfedae2687353ac79e5",
+ "url": "https://api.github.com/repos/symfony/process/zipball/08aa69fa0998bb65a089f9e148a2c0f8b391398e",
+ "reference": "08aa69fa0998bb65a089f9e148a2c0f8b391398e",
"shasum": ""
},
"require": {
@@ -7555,7 +7646,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/process/tree/v8.1.0"
+ "source": "https://github.com/symfony/process/tree/v8.1.10"
},
"funding": [
{
@@ -7575,20 +7666,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-29T05:06:50+00:00"
+ "time": "2026-10-25T14:40:25+00:00"
},
{
"name": "symfony/property-access",
- "version": "v8.1.0",
+ "version": "v8.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/property-access.git",
- "reference": "9261ef060f26cc7b728f67f141ba19b98a6209a9"
+ "reference": "d080c2afa37114d46e4f950ed8593667f01f7cab"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/property-access/zipball/9261ef060f26cc7b728f67f141ba19b98a6209a9",
- "reference": "9261ef060f26cc7b728f67f141ba19b98a6209a9",
+ "url": "https://api.github.com/repos/symfony/property-access/zipball/d080c2afa37114d46e4f950ed8593667f01f7cab",
+ "reference": "d080c2afa37114d46e4f950ed8593667f01f7cab",
"shasum": ""
},
"require": {
@@ -7636,7 +7727,7 @@
"reflection"
],
"support": {
- "source": "https://github.com/symfony/property-access/tree/v8.1.0"
+ "source": "https://github.com/symfony/property-access/tree/v8.1.11"
},
"funding": [
{
@@ -7656,20 +7747,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-29T05:06:50+00:00"
+ "time": "2026-11-01T19:30:44+00:00"
},
{
"name": "symfony/property-info",
- "version": "v8.1.0",
+ "version": "v8.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/property-info.git",
- "reference": "4721e8c56d0cd2378e0ef9a9899f810008b859f7"
+ "reference": "b5afa379a5b54f15a594c1d45ceaa19969d38a16"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/property-info/zipball/4721e8c56d0cd2378e0ef9a9899f810008b859f7",
- "reference": "4721e8c56d0cd2378e0ef9a9899f810008b859f7",
+ "url": "https://api.github.com/repos/symfony/property-info/zipball/b5afa379a5b54f15a594c1d45ceaa19969d38a16",
+ "reference": "b5afa379a5b54f15a594c1d45ceaa19969d38a16",
"shasum": ""
},
"require": {
@@ -7722,7 +7813,7 @@
"validator"
],
"support": {
- "source": "https://github.com/symfony/property-info/tree/v8.1.0"
+ "source": "https://github.com/symfony/property-info/tree/v8.1.11"
},
"funding": [
{
@@ -7742,20 +7833,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-29T05:06:50+00:00"
+ "time": "2026-11-02T10:58:30+00:00"
},
{
"name": "symfony/routing",
- "version": "v8.1.0",
+ "version": "v8.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
- "reference": "fe0bfec72c8a806109fb9c3a5f2b898fe0c76eb3"
+ "reference": "f3fefc6cad3748d538be970ca81b71f06d7aa8b3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/fe0bfec72c8a806109fb9c3a5f2b898fe0c76eb3",
- "reference": "fe0bfec72c8a806109fb9c3a5f2b898fe0c76eb3",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/f3fefc6cad3748d538be970ca81b71f06d7aa8b3",
+ "reference": "f3fefc6cad3748d538be970ca81b71f06d7aa8b3",
"shasum": ""
},
"require": {
@@ -7802,7 +7893,7 @@
"url"
],
"support": {
- "source": "https://github.com/symfony/routing/tree/v8.1.0"
+ "source": "https://github.com/symfony/routing/tree/v8.1.11"
},
"funding": [
{
@@ -7822,20 +7913,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-29T05:06:50+00:00"
+ "time": "2026-11-04T08:39:20+00:00"
},
{
"name": "symfony/serializer",
- "version": "v8.1.1",
+ "version": "v8.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/serializer.git",
- "reference": "f911b744bc24658f435ea30439cfe536f0173a3a"
+ "reference": "05624c94507c3acf065b6486bb626f0d741af459"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/serializer/zipball/f911b744bc24658f435ea30439cfe536f0173a3a",
- "reference": "f911b744bc24658f435ea30439cfe536f0173a3a",
+ "url": "https://api.github.com/repos/symfony/serializer/zipball/05624c94507c3acf065b6486bb626f0d741af459",
+ "reference": "05624c94507c3acf065b6486bb626f0d741af459",
"shasum": ""
},
"require": {
@@ -7847,7 +7938,7 @@
"phpdocumentor/reflection-docblock": "<5.2|>=7",
"phpdocumentor/type-resolver": "<1.5.1",
"symfony/property-access": "<8.1",
- "symfony/property-info": "<7.4",
+ "symfony/property-info": "<7.4.15",
"symfony/type-info": "<7.4"
},
"require-dev": {
@@ -7866,7 +7957,7 @@
"symfony/messenger": "^7.4|^8.0",
"symfony/mime": "^7.4|^8.0",
"symfony/property-access": "^8.1",
- "symfony/property-info": "^7.4|^8.0",
+ "symfony/property-info": "^7.4.15|~8.0.15|^8.1.2",
"symfony/translation-contracts": "^2.5|^3",
"symfony/type-info": "^7.4|^8.0",
"symfony/uid": "^7.4|^8.0",
@@ -7901,7 +7992,7 @@
"description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/serializer/tree/v8.1.1"
+ "source": "https://github.com/symfony/serializer/tree/v8.1.11"
},
"funding": [
{
@@ -7921,20 +8012,20 @@
"type": "tidelift"
}
],
- "time": "2026-06-27T09:05:56+00:00"
+ "time": "2026-11-04T08:39:20+00:00"
},
{
"name": "symfony/service-contracts",
- "version": "v3.7.1",
+ "version": "v3.8.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
- "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0"
+ "reference": "052852a96fd5e5ebdb617dba22031e41a3300fb5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/c0a284bab1ed8aa0417e3d69250ab437739563a0",
- "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/052852a96fd5e5ebdb617dba22031e41a3300fb5",
+ "reference": "052852a96fd5e5ebdb617dba22031e41a3300fb5",
"shasum": ""
},
"require": {
@@ -7952,7 +8043,7 @@
"name": "symfony/contracts"
},
"branch-alias": {
- "dev-main": "3.7-dev"
+ "dev-main": "3.8-dev"
}
},
"autoload": {
@@ -7988,7 +8079,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/service-contracts/tree/v3.7.1"
+ "source": "https://github.com/symfony/service-contracts/tree/v3.8.1"
},
"funding": [
{
@@ -8008,20 +8099,20 @@
"type": "tidelift"
}
],
- "time": "2026-06-16T09:55:08+00:00"
+ "time": "2026-10-20T17:38:25+00:00"
},
{
"name": "symfony/string",
- "version": "v8.1.0",
+ "version": "v8.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "afd5944f4005862d961efb85c8bbd5c523c4e3c9"
+ "reference": "6c6110979c0150393bbb336170e286d51ab4d76c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/afd5944f4005862d961efb85c8bbd5c523c4e3c9",
- "reference": "afd5944f4005862d961efb85c8bbd5c523c4e3c9",
+ "url": "https://api.github.com/repos/symfony/string/zipball/6c6110979c0150393bbb336170e286d51ab4d76c",
+ "reference": "6c6110979c0150393bbb336170e286d51ab4d76c",
"shasum": ""
},
"require": {
@@ -8078,7 +8169,7 @@
"utf8"
],
"support": {
- "source": "https://github.com/symfony/string/tree/v8.1.0"
+ "source": "https://github.com/symfony/string/tree/v8.1.10"
},
"funding": [
{
@@ -8098,20 +8189,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-29T05:06:50+00:00"
+ "time": "2026-10-23T17:06:53+00:00"
},
{
"name": "symfony/translation",
- "version": "v8.1.1",
+ "version": "v8.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
- "reference": "342b4218630dc2cf284cedcb2080c80b13404014"
+ "reference": "d065adf56e5508293e80d7c140b0a9e043b63e9c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation/zipball/342b4218630dc2cf284cedcb2080c80b13404014",
- "reference": "342b4218630dc2cf284cedcb2080c80b13404014",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/d065adf56e5508293e80d7c140b0a9e043b63e9c",
+ "reference": "d065adf56e5508293e80d7c140b0a9e043b63e9c",
"shasum": ""
},
"require": {
@@ -8171,7 +8262,7 @@
"description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/translation/tree/v8.1.1"
+ "source": "https://github.com/symfony/translation/tree/v8.1.11"
},
"funding": [
{
@@ -8191,20 +8282,20 @@
"type": "tidelift"
}
],
- "time": "2026-06-06T11:11:44+00:00"
+ "time": "2026-11-01T22:27:46+00:00"
},
{
"name": "symfony/translation-contracts",
- "version": "v3.7.1",
+ "version": "v3.8.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation-contracts.git",
- "reference": "ccb206b98faccc511ebae8e5fad50f2dc0b30621"
+ "reference": "0a3ae917402632fcba2aeddae9c98332f3d7dd05"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/ccb206b98faccc511ebae8e5fad50f2dc0b30621",
- "reference": "ccb206b98faccc511ebae8e5fad50f2dc0b30621",
+ "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/0a3ae917402632fcba2aeddae9c98332f3d7dd05",
+ "reference": "0a3ae917402632fcba2aeddae9c98332f3d7dd05",
"shasum": ""
},
"require": {
@@ -8217,7 +8308,7 @@
"name": "symfony/contracts"
},
"branch-alias": {
- "dev-main": "3.7-dev"
+ "dev-main": "3.8-dev"
}
},
"autoload": {
@@ -8253,7 +8344,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/translation-contracts/tree/v3.7.1"
+ "source": "https://github.com/symfony/translation-contracts/tree/v3.8.1"
},
"funding": [
{
@@ -8273,20 +8364,20 @@
"type": "tidelift"
}
],
- "time": "2026-06-05T06:23:12+00:00"
+ "time": "2026-10-03T08:17:19+00:00"
},
{
"name": "symfony/type-info",
- "version": "v8.1.0",
+ "version": "v8.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/type-info.git",
- "reference": "9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7"
+ "reference": "9fd1414061c4bbf953bcfc183b133cbfa0a73c73"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/type-info/zipball/9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7",
- "reference": "9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7",
+ "url": "https://api.github.com/repos/symfony/type-info/zipball/9fd1414061c4bbf953bcfc183b133cbfa0a73c73",
+ "reference": "9fd1414061c4bbf953bcfc183b133cbfa0a73c73",
"shasum": ""
},
"require": {
@@ -8335,7 +8426,7 @@
"type"
],
"support": {
- "source": "https://github.com/symfony/type-info/tree/v8.1.0"
+ "source": "https://github.com/symfony/type-info/tree/v8.1.11"
},
"funding": [
{
@@ -8355,20 +8446,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-29T05:06:50+00:00"
+ "time": "2026-11-02T10:58:30+00:00"
},
{
"name": "symfony/uid",
- "version": "v8.1.0",
+ "version": "v8.1.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/uid.git",
- "reference": "7393f157a55f7e70a4de0334435c55a5a8fe749a"
+ "reference": "cb487cf30380f0b0b090973bb9c0588193c06685"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/uid/zipball/7393f157a55f7e70a4de0334435c55a5a8fe749a",
- "reference": "7393f157a55f7e70a4de0334435c55a5a8fe749a",
+ "url": "https://api.github.com/repos/symfony/uid/zipball/cb487cf30380f0b0b090973bb9c0588193c06685",
+ "reference": "cb487cf30380f0b0b090973bb9c0588193c06685",
"shasum": ""
},
"require": {
@@ -8413,7 +8504,7 @@
"uuid"
],
"support": {
- "source": "https://github.com/symfony/uid/tree/v8.1.0"
+ "source": "https://github.com/symfony/uid/tree/v8.1.9"
},
"funding": [
{
@@ -8433,20 +8524,20 @@
"type": "tidelift"
}
],
- "time": "2026-05-29T05:06:50+00:00"
+ "time": "2026-10-12T14:32:04+00:00"
},
{
"name": "symfony/var-dumper",
- "version": "v8.1.1",
+ "version": "v8.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "40096a2515a979f3125c5c928603995b8664c62a"
+ "reference": "3412a5af7d34a19515a77890fc804fe8e50d1a4f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/40096a2515a979f3125c5c928603995b8664c62a",
- "reference": "40096a2515a979f3125c5c928603995b8664c62a",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/3412a5af7d34a19515a77890fc804fe8e50d1a4f",
+ "reference": "3412a5af7d34a19515a77890fc804fe8e50d1a4f",
"shasum": ""
},
"require": {
@@ -8462,7 +8553,7 @@
"symfony/http-kernel": "^7.4|^8.0",
"symfony/process": "^7.4|^8.0",
"symfony/uid": "^7.4|^8.0",
- "twig/twig": "^3.12"
+ "twig/twig": "^3.12|^4.0"
},
"bin": [
"Resources/bin/var-dump-server"
@@ -8500,7 +8591,7 @@
"dump"
],
"support": {
- "source": "https://github.com/symfony/var-dumper/tree/v8.1.1"
+ "source": "https://github.com/symfony/var-dumper/tree/v8.1.10"
},
"funding": [
{
@@ -8520,20 +8611,20 @@
"type": "tidelift"
}
],
- "time": "2026-06-09T10:54:51+00:00"
+ "time": "2026-10-26T21:55:04+00:00"
},
{
"name": "tempest/highlight",
- "version": "2.27.0",
+ "version": "2.30.0",
"source": {
"type": "git",
"url": "https://github.com/tempestphp/highlight.git",
- "reference": "7eaf2f4030cc218320672902608b6226bb13a39a"
+ "reference": "fca3aa7803709df398e287361fab9fc7e59dcff6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/tempestphp/highlight/zipball/7eaf2f4030cc218320672902608b6226bb13a39a",
- "reference": "7eaf2f4030cc218320672902608b6226bb13a39a",
+ "url": "https://api.github.com/repos/tempestphp/highlight/zipball/fca3aa7803709df398e287361fab9fc7e59dcff6",
+ "reference": "fca3aa7803709df398e287361fab9fc7e59dcff6",
"shasum": ""
},
"require": {
@@ -8571,7 +8662,7 @@
"description": "Fast, extensible, server-side code highlighting",
"support": {
"issues": "https://github.com/tempestphp/highlight/issues",
- "source": "https://github.com/tempestphp/highlight/tree/2.27.0"
+ "source": "https://github.com/tempestphp/highlight/tree/2.30.0"
},
"funding": [
{
@@ -8579,7 +8670,7 @@
"type": "github"
}
],
- "time": "2026-06-29T09:11:42+00:00"
+ "time": "2026-10-27T07:32:29+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
@@ -8638,23 +8729,23 @@
},
{
"name": "vlucas/phpdotenv",
- "version": "v5.6.3",
+ "version": "v5.8.0",
"source": {
"type": "git",
- "url": "https://github.com/vlucas/phpdotenv.git",
- "reference": "955e7815d677a3eaa7075231212f2110983adecc"
+ "url": "https://github.com/phpdotenv/phpdotenv.git",
+ "reference": "96149103e62ac67e915f6d2ef59b72dee2e011e0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/955e7815d677a3eaa7075231212f2110983adecc",
- "reference": "955e7815d677a3eaa7075231212f2110983adecc",
+ "url": "https://api.github.com/repos/phpdotenv/phpdotenv/zipball/96149103e62ac67e915f6d2ef59b72dee2e011e0",
+ "reference": "96149103e62ac67e915f6d2ef59b72dee2e011e0",
"shasum": ""
},
"require": {
"ext-pcre": "*",
- "graham-campbell/result-type": "^1.1.4",
+ "graham-campbell/result-type": "^1.2",
"php": "^7.2.5 || ^8.0",
- "phpoption/phpoption": "^1.9.5",
+ "phpoption/phpoption": "^1.10",
"symfony/polyfill-ctype": "^1.26",
"symfony/polyfill-mbstring": "^1.26",
"symfony/polyfill-php80": "^1.26"
@@ -8674,7 +8765,7 @@
"forward-command": false
},
"branch-alias": {
- "dev-master": "5.6-dev"
+ "dev-master": "5.8-dev"
}
},
"autoload": {
@@ -8698,15 +8789,15 @@
"homepage": "https://github.com/vlucas"
}
],
- "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
+ "description": "Loads environment variables from `.env` to `$_ENV` and `$_SERVER` automagically, and optionally to `getenv()`.",
"keywords": [
"dotenv",
"env",
"environment"
],
"support": {
- "issues": "https://github.com/vlucas/phpdotenv/issues",
- "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.3"
+ "issues": "https://github.com/phpdotenv/phpdotenv/issues",
+ "source": "https://github.com/phpdotenv/phpdotenv/tree/v5.8.0"
},
"funding": [
{
@@ -8718,7 +8809,7 @@
"type": "tidelift"
}
],
- "time": "2025-12-27T19:49:13+00:00"
+ "time": "2026-10-25T16:26:19+00:00"
},
{
"name": "voku/portable-ascii",
@@ -8796,32 +8887,36 @@
},
{
"name": "web-auth/cose-lib",
- "version": "4.5.2",
+ "version": "4.8.2",
"source": {
"type": "git",
"url": "https://github.com/web-auth/cose-lib.git",
- "reference": "5b38660f90070a8e45f3dbc9528ade3b608dd77d"
+ "reference": "8849e8bf043a2d42d0bec5bda5db2469ad376148"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/web-auth/cose-lib/zipball/5b38660f90070a8e45f3dbc9528ade3b608dd77d",
- "reference": "5b38660f90070a8e45f3dbc9528ade3b608dd77d",
+ "url": "https://api.github.com/repos/web-auth/cose-lib/zipball/8849e8bf043a2d42d0bec5bda5db2469ad376148",
+ "reference": "8849e8bf043a2d42d0bec5bda5db2469ad376148",
"shasum": ""
},
"require": {
- "brick/math": "^0.9|^0.10|^0.11|^0.12|^0.13|^0.14|^0.15|^0.16|^0.17",
+ "brick/math": "^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14 || ^0.15 || ^0.16 || ^0.17 || ^0.18 || ^0.19 || ^0.20 || ^1.0",
"ext-json": "*",
"ext-openssl": "*",
"php": ">=8.1",
"spomky-labs/pki-framework": "^1.0"
},
+ "conflict": {
+ "spomky-labs/cbor-php": "<3.4.0"
+ },
"require-dev": {
- "spomky-labs/cbor-php": "^3.2.2"
+ "spomky-labs/cbor-php": "^3.4"
},
"suggest": {
- "ext-bcmath": "For better performance, please install either GMP (recommended) or BCMath extension",
- "ext-gmp": "For better performance, please install either GMP (recommended) or BCMath extension",
- "spomky-labs/cbor-php": "For COSE Signature support"
+ "ext-bcmath": "Recommended: without GMP or BCMath, signing with RSASSA-PSS (PS256/PS384/PS512) blinds its private exponentiation in pure PHP",
+ "ext-gmp": "Recommended: without GMP or BCMath, signing with RSASSA-PSS (PS256/PS384/PS512) blinds its private exponentiation in pure PHP",
+ "ext-sodium": "Required by the EdDSA/Ed25519 signature algorithms (-8, -19, -260, -261) and to recompute an OKP public key from its private key",
+ "spomky-labs/cbor-php": "Required by the RFC 9052 header reader and cryptographic structures. 3.4.0 or later: it ships the six COSE message classes (CBOR\\Tag\\CoseSign1Tag and its siblings) that replace the deprecated Cose\\...Tag classes, and its decoder is what enforces the RFC 9052 label uniqueness and nesting bounds this library relies on"
},
"type": "library",
"autoload": {
@@ -8851,7 +8946,7 @@
],
"support": {
"issues": "https://github.com/web-auth/cose-lib/issues",
- "source": "https://github.com/web-auth/cose-lib/tree/4.5.2"
+ "source": "https://github.com/web-auth/cose-lib/tree/4.8.2"
},
"funding": [
{
@@ -8863,20 +8958,20 @@
"type": "patreon"
}
],
- "time": "2026-05-03T09:49:50+00:00"
+ "time": "2026-09-15T17:30:33+00:00"
},
{
"name": "web-auth/webauthn-lib",
- "version": "5.3.5",
+ "version": "5.3.12",
"source": {
"type": "git",
"url": "https://github.com/web-auth/webauthn-lib.git",
- "reference": "9e0986d999f4102e24ac8a598d3a80d98b56c19f"
+ "reference": "c7aeeb1d35e39b7d32ab5146cce4b668f271a68e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/9e0986d999f4102e24ac8a598d3a80d98b56c19f",
- "reference": "9e0986d999f4102e24ac8a598d3a80d98b56c19f",
+ "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/c7aeeb1d35e39b7d32ab5146cce4b668f271a68e",
+ "reference": "c7aeeb1d35e39b7d32ab5146cce4b668f271a68e",
"shasum": ""
},
"require": {
@@ -8888,7 +8983,7 @@
"psr/clock": "^1.0",
"psr/event-dispatcher": "^1.0",
"psr/log": "^1.0|^2.0|^3.0",
- "spomky-labs/cbor-php": "^3.0",
+ "spomky-labs/cbor-php": "^3.4",
"spomky-labs/pki-framework": "^1.0",
"symfony/clock": "^6.4|^7.0|^8.0",
"symfony/deprecation-contracts": "^3.2",
@@ -8896,7 +8991,7 @@
"symfony/property-info": "^6.4|^7.0|^8.0",
"symfony/serializer": "^6.4|^7.0|^8.0",
"symfony/uid": "^6.4|^7.0|^8.0",
- "web-auth/cose-lib": "^4.2.3"
+ "web-auth/cose-lib": "^4.8"
},
"suggest": {
"psr/log-implementation": "Recommended to receive logs from the library",
@@ -8937,7 +9032,7 @@
"webauthn"
],
"support": {
- "source": "https://github.com/web-auth/webauthn-lib/tree/5.3.5"
+ "source": "https://github.com/web-auth/webauthn-lib/tree/5.3.12"
},
"funding": [
{
@@ -8949,20 +9044,20 @@
"type": "patreon"
}
],
- "time": "2026-05-31T15:00:08+00:00"
+ "time": "2026-11-03T09:21:08+00:00"
},
{
"name": "webmozart/assert",
- "version": "2.4.1",
+ "version": "2.5.0",
"source": {
"type": "git",
"url": "https://github.com/webmozarts/assert.git",
- "reference": "2ccb7c2e821038c03a3e6e1700c570c158c55f70"
+ "reference": "8a163706bbcac613733dba03f51e13b5eb1bb819"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozarts/assert/zipball/2ccb7c2e821038c03a3e6e1700c570c158c55f70",
- "reference": "2ccb7c2e821038c03a3e6e1700c570c158c55f70",
+ "url": "https://api.github.com/repos/webmozarts/assert/zipball/8a163706bbcac613733dba03f51e13b5eb1bb819",
+ "reference": "8a163706bbcac613733dba03f51e13b5eb1bb819",
"shasum": ""
},
"require": {
@@ -9013,24 +9108,24 @@
],
"support": {
"issues": "https://github.com/webmozarts/assert/issues",
- "source": "https://github.com/webmozarts/assert/tree/2.4.1"
+ "source": "https://github.com/webmozarts/assert/tree/2.5.0"
},
- "time": "2026-06-15T15:31:57+00:00"
+ "time": "2026-10-05T23:14:19+00:00"
}
],
"packages-dev": [
{
"name": "barryvdh/laravel-debugbar",
- "version": "v4.3.0",
+ "version": "v4.4.5",
"source": {
"type": "git",
"url": "https://github.com/fruitcake/laravel-debugbar.git",
- "reference": "3d76ea8d78b82225b92789de65fc630c1cd8e80c"
+ "reference": "679c389306cd6255dbb3d2a9350d846c2e991dcc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fruitcake/laravel-debugbar/zipball/3d76ea8d78b82225b92789de65fc630c1cd8e80c",
- "reference": "3d76ea8d78b82225b92789de65fc630c1cd8e80c",
+ "url": "https://api.github.com/repos/fruitcake/laravel-debugbar/zipball/679c389306cd6255dbb3d2a9350d846c2e991dcc",
+ "reference": "679c389306cd6255dbb3d2a9350d846c2e991dcc",
"shasum": ""
},
"require": {
@@ -9038,11 +9133,12 @@
"illuminate/session": "^11|^12|^13.0",
"illuminate/support": "^11|^12|^13.0",
"php": "^8.2",
- "php-debugbar/php-debugbar": "^3.7.2",
+ "php-debugbar/php-debugbar": "^3.8.0",
"php-debugbar/symfony-bridge": "^1.1"
},
"require-dev": {
"larastan/larastan": "^3",
+ "laravel/ai": "^0.8|^0.9|^0.10|^0.11|^1.0",
"laravel/octane": "^2",
"laravel/pennant": "^1",
"laravel/pint": "^1",
@@ -9104,7 +9200,7 @@
],
"support": {
"issues": "https://github.com/fruitcake/laravel-debugbar/issues",
- "source": "https://github.com/fruitcake/laravel-debugbar/tree/v4.3.0"
+ "source": "https://github.com/fruitcake/laravel-debugbar/tree/v4.4.5"
},
"funding": [
{
@@ -9116,20 +9212,20 @@
"type": "github"
}
],
- "time": "2026-06-04T07:54:01+00:00"
+ "time": "2026-10-28T13:25:29+00:00"
},
{
"name": "barryvdh/laravel-ide-helper",
- "version": "v3.7.0",
+ "version": "v3.8.0",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-ide-helper.git",
- "reference": "ad7e37676f1ff985d55ef1b6b96a0c0a40f2609a"
+ "reference": "f9521af2a0ed5ff1d70386cac3fae547a96be947"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/ad7e37676f1ff985d55ef1b6b96a0c0a40f2609a",
- "reference": "ad7e37676f1ff985d55ef1b6b96a0c0a40f2609a",
+ "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/f9521af2a0ed5ff1d70386cac3fae547a96be947",
+ "reference": "f9521af2a0ed5ff1d70386cac3fae547a96be947",
"shasum": ""
},
"require": {
@@ -9166,7 +9262,7 @@
]
},
"branch-alias": {
- "dev-master": "3.6-dev"
+ "dev-master": "3.7-dev"
}
},
"autoload": {
@@ -9199,7 +9295,7 @@
],
"support": {
"issues": "https://github.com/barryvdh/laravel-ide-helper/issues",
- "source": "https://github.com/barryvdh/laravel-ide-helper/tree/v3.7.0"
+ "source": "https://github.com/barryvdh/laravel-ide-helper/tree/v3.8.0"
},
"funding": [
{
@@ -9211,7 +9307,7 @@
"type": "github"
}
],
- "time": "2026-03-17T14:12:51+00:00"
+ "time": "2026-09-15T12:58:37+00:00"
},
{
"name": "barryvdh/reflection-docblock",
@@ -9267,16 +9363,16 @@
},
{
"name": "composer/class-map-generator",
- "version": "1.7.3",
+ "version": "1.9.0",
"source": {
"type": "git",
"url": "https://github.com/composer/class-map-generator.git",
- "reference": "86d8208fc3c649a3a999daf1a63c25201be2990f"
+ "reference": "5fa48e0e1992ea8a786df3ceca80625c9a643b75"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/class-map-generator/zipball/86d8208fc3c649a3a999daf1a63c25201be2990f",
- "reference": "86d8208fc3c649a3a999daf1a63c25201be2990f",
+ "url": "https://api.github.com/repos/composer/class-map-generator/zipball/5fa48e0e1992ea8a786df3ceca80625c9a643b75",
+ "reference": "5fa48e0e1992ea8a786df3ceca80625c9a643b75",
"shasum": ""
},
"require": {
@@ -9320,7 +9416,7 @@
],
"support": {
"issues": "https://github.com/composer/class-map-generator/issues",
- "source": "https://github.com/composer/class-map-generator/tree/1.7.3"
+ "source": "https://github.com/composer/class-map-generator/tree/1.9.0"
},
"funding": [
{
@@ -9332,7 +9428,7 @@
"type": "github"
}
],
- "time": "2026-05-05T09:17:07+00:00"
+ "time": "2026-11-03T10:10:19+00:00"
},
{
"name": "composer/pcre",
@@ -9475,16 +9571,16 @@
},
{
"name": "filp/whoops",
- "version": "2.18.4",
+ "version": "2.19.2",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
- "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d"
+ "reference": "84e33631273138ac103d045dc02b0fb7e5485582"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/filp/whoops/zipball/d2102955e48b9fd9ab24280a7ad12ed552752c4d",
- "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d",
+ "url": "https://api.github.com/repos/filp/whoops/zipball/84e33631273138ac103d045dc02b0fb7e5485582",
+ "reference": "84e33631273138ac103d045dc02b0fb7e5485582",
"shasum": ""
},
"require": {
@@ -9493,8 +9589,8 @@
},
"require-dev": {
"mockery/mockery": "^1.0",
- "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3",
- "symfony/var-dumper": "^4.0 || ^5.0"
+ "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3 || ^10.5.58",
+ "symfony/var-dumper": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0"
},
"suggest": {
"symfony/var-dumper": "Pretty print complex values better with var-dumper available",
@@ -9534,7 +9630,7 @@
],
"support": {
"issues": "https://github.com/filp/whoops/issues",
- "source": "https://github.com/filp/whoops/tree/2.18.4"
+ "source": "https://github.com/filp/whoops/tree/2.19.2"
},
"funding": [
{
@@ -9542,23 +9638,25 @@
"type": "github"
}
],
- "time": "2025-08-08T12:00:00+00:00"
+ "time": "2026-11-03T23:38:01+00:00"
},
{
"name": "hamcrest/hamcrest-php",
- "version": "v2.1.1",
+ "version": "v3.0.0",
"source": {
"type": "git",
"url": "https://github.com/hamcrest/hamcrest-php.git",
- "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487"
+ "reference": "b61cd040da1a4925bc90a51c074f5297e7c0fa52"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487",
- "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487",
+ "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b61cd040da1a4925bc90a51c074f5297e7c0fa52",
+ "reference": "b61cd040da1a4925bc90a51c074f5297e7c0fa52",
"shasum": ""
},
"require": {
+ "ext-ctype": "*",
+ "ext-dom": "*",
"php": "^7.4|^8.0"
},
"replace": {
@@ -9567,13 +9665,15 @@
"kodova/hamcrest-php": "*"
},
"require-dev": {
+ "phpstan/phpstan": "^2.1",
+ "phpstan/phpstan-phpunit": "^2.0",
"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"
+ "dev-master": "3.0-dev"
}
},
"autoload": {
@@ -9591,28 +9691,28 @@
],
"support": {
"issues": "https://github.com/hamcrest/hamcrest-php/issues",
- "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.1.1"
+ "source": "https://github.com/hamcrest/hamcrest-php/tree/v3.0.0"
},
- "time": "2025-04-30T06:54:44+00:00"
+ "time": "2026-03-17T11:56:53+00:00"
},
{
"name": "laravel/dusk",
- "version": "v8.6.0",
+ "version": "v8.7.2",
"source": {
"type": "git",
"url": "https://github.com/laravel/dusk.git",
- "reference": "e7fd48762c6a82ad2cd311db07587aa2a97ce143"
+ "reference": "a12cbd9d33d44006ba08e36407cb9f19ac73e944"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/dusk/zipball/e7fd48762c6a82ad2cd311db07587aa2a97ce143",
- "reference": "e7fd48762c6a82ad2cd311db07587aa2a97ce143",
+ "url": "https://api.github.com/repos/laravel/dusk/zipball/a12cbd9d33d44006ba08e36407cb9f19ac73e944",
+ "reference": "a12cbd9d33d44006ba08e36407cb9f19ac73e944",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-zip": "*",
- "guzzlehttp/guzzle": "^7.5",
+ "guzzlehttp/guzzle": "^7.5|^8.0",
"illuminate/console": "^10.0|^11.0|^12.0|^13.0",
"illuminate/support": "^10.0|^11.0|^12.0|^13.0",
"php": "^8.1",
@@ -9626,8 +9726,8 @@
"laravel/framework": "^10.0|^11.0|^12.0|^13.0",
"mockery/mockery": "^1.6",
"orchestra/testbench-core": "^8.19|^9.17|^10.8|^11.0",
- "phpstan/phpstan": "^1.10",
- "phpunit/phpunit": "^10.1|^11.0|^12.0.1",
+ "phpstan/phpstan": "2.2.15",
+ "phpunit/phpunit": "^10.1|^11.0|^12.0.1|^13.0",
"psy/psysh": "^0.11.12|^0.12",
"symfony/yaml": "^6.2|^7.0|^8.0"
},
@@ -9664,10 +9764,9 @@
"webdriver"
],
"support": {
- "issues": "https://github.com/laravel/dusk/issues",
- "source": "https://github.com/laravel/dusk/tree/v8.6.0"
+ "source": "https://github.com/laravel/dusk/tree/v8.7.2"
},
- "time": "2026-04-15T14:50:40+00:00"
+ "time": "2026-10-07T21:51:28+00:00"
},
{
"name": "laravel/pail",
@@ -9751,16 +9850,16 @@
},
{
"name": "laravel/pint",
- "version": "v1.29.3",
+ "version": "v1.32.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/pint.git",
- "reference": "da1d1111a6aa2e082d2a388b194afe1ba0a05d14"
+ "reference": "006bd7825eb01daf92959d060b89cd9514fe4253"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/pint/zipball/da1d1111a6aa2e082d2a388b194afe1ba0a05d14",
- "reference": "da1d1111a6aa2e082d2a388b194afe1ba0a05d14",
+ "url": "https://api.github.com/repos/laravel/pint/zipball/006bd7825eb01daf92959d060b89cd9514fe4253",
+ "reference": "006bd7825eb01daf92959d060b89cd9514fe4253",
"shasum": ""
},
"require": {
@@ -9768,17 +9867,19 @@
"ext-mbstring": "*",
"ext-tokenizer": "*",
"ext-xml": "*",
- "php": "^8.2.0"
+ "php": "^8.3.0"
},
"require-dev": {
- "friendsofphp/php-cs-fixer": "^3.95.8",
- "illuminate/view": "^12.62.0",
- "larastan/larastan": "^3.10.0",
- "laravel-zero/framework": "^12.1.0",
+ "composer/semver": "^3.4.4",
+ "friendsofphp/php-cs-fixer": "^3.95.25",
+ "illuminate/view": "^13.31.0",
+ "larastan/larastan": "^3.11.0",
+ "laravel-zero/framework": "^13.0.0",
"laravel/agent-detector": "^2.0.2",
- "mockery/mockery": "^1.6.12",
+ "laravel/prompts": "^0.3.24",
+ "mockery/mockery": "^1.6.15",
"nunomaduro/termwind": "^2.4.0",
- "pestphp/pest": "^3.8.6"
+ "pestphp/pest": "^4.7.8"
},
"bin": [
"builds/pint"
@@ -9815,20 +9916,20 @@
"issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint"
},
- "time": "2026-06-16T15:34:04+00:00"
+ "time": "2026-09-10T10:47:55+00:00"
},
{
"name": "laravel/sail",
- "version": "v1.63.0",
+ "version": "v1.69.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/sail.git",
- "reference": "51bbce3f803c1d386cabbb44e618c955a12ff5fc"
+ "reference": "3587ac9d68e8f2eaf36bd9fb003a4555861dca9d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/sail/zipball/51bbce3f803c1d386cabbb44e618c955a12ff5fc",
- "reference": "51bbce3f803c1d386cabbb44e618c955a12ff5fc",
+ "url": "https://api.github.com/repos/laravel/sail/zipball/3587ac9d68e8f2eaf36bd9fb003a4555861dca9d",
+ "reference": "3587ac9d68e8f2eaf36bd9fb003a4555861dca9d",
"shasum": ""
},
"require": {
@@ -9878,33 +9979,32 @@
"issues": "https://github.com/laravel/sail/issues",
"source": "https://github.com/laravel/sail"
},
- "time": "2026-06-18T08:54:14+00:00"
+ "time": "2026-10-08T20:06:52+00:00"
},
{
"name": "mockery/mockery",
- "version": "1.6.12",
+ "version": "1.6.15",
"source": {
"type": "git",
"url": "https://github.com/mockery/mockery.git",
- "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699"
+ "reference": "967a801bd188989a5669bd280f252d51c0fdc9ee"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699",
- "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699",
+ "url": "https://api.github.com/repos/mockery/mockery/zipball/967a801bd188989a5669bd280f252d51c0fdc9ee",
+ "reference": "967a801bd188989a5669bd280f252d51c0fdc9ee",
"shasum": ""
},
"require": {
- "hamcrest/hamcrest-php": "^2.0.1",
- "lib-pcre": ">=7.0",
+ "hamcrest/hamcrest-php": "^2.0 || ^3.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"
+ "phpunit/phpunit": "^9.6.36",
+ "symplify/easy-coding-standard": "^13.2.17"
},
"type": "library",
"autoload": {
@@ -9961,24 +10061,24 @@
"security": "https://github.com/mockery/mockery/security/advisories",
"source": "https://github.com/mockery/mockery"
},
- "time": "2024-05-16T03:13:13+00:00"
+ "time": "2026-08-19T19:37:52+00:00"
},
{
"name": "myclabs/deep-copy",
- "version": "1.13.4",
+ "version": "1.14.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
- "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
+ "reference": "8680aa248f8e07bc8fb43f56f0f5fc77a0c96aae"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
- "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/8680aa248f8e07bc8fb43f56f0f5fc77a0c96aae",
+ "reference": "8680aa248f8e07bc8fb43f56f0f5fc77a0c96aae",
"shasum": ""
},
"require": {
- "php": "^7.1 || ^8.0"
+ "php": "^8.0"
},
"conflict": {
"doctrine/collections": "<1.6.8",
@@ -10013,35 +10113,35 @@
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
- "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
+ "source": "https://github.com/myclabs/DeepCopy/tree/1.14.0"
},
"funding": [
{
- "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
- "type": "tidelift"
+ "url": "https://github.com/mnapoli",
+ "type": "github"
}
],
- "time": "2025-08-01T08:46:24+00:00"
+ "time": "2026-08-11T10:17:44+00:00"
},
{
"name": "nunomaduro/collision",
- "version": "v8.9.4",
+ "version": "v8.9.5",
"source": {
"type": "git",
"url": "https://github.com/nunomaduro/collision.git",
- "reference": "716af8f95a470e9094cfca09ed897b023be191a5"
+ "reference": "fb53eacd509a1d303858e2d20cfebf2d630254ec"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nunomaduro/collision/zipball/716af8f95a470e9094cfca09ed897b023be191a5",
- "reference": "716af8f95a470e9094cfca09ed897b023be191a5",
+ "url": "https://api.github.com/repos/nunomaduro/collision/zipball/fb53eacd509a1d303858e2d20cfebf2d630254ec",
+ "reference": "fb53eacd509a1d303858e2d20cfebf2d630254ec",
"shasum": ""
},
"require": {
"filp/whoops": "^2.18.4",
"nunomaduro/termwind": "^2.4.0",
"php": "^8.2.0",
- "symfony/console": "^7.4.8 || ^8.0.8"
+ "symfony/console": "^7.4.14 || ^8.1.1"
},
"conflict": {
"laravel/framework": "<11.48.0 || >=14.0.0",
@@ -10049,12 +10149,12 @@
},
"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"
+ "larastan/larastan": "^3.10.0",
+ "laravel/framework": "^11.48.0 || ^12.56.0 || ^13.20.0",
+ "laravel/pint": "^1.29.3",
+ "orchestra/testbench-core": "^9.12.0 || ^10.12.1 || ^11.3.5",
+ "pestphp/pest": "^3.8.5 || ^4.7.5 || ^5.0.0",
+ "sebastian/environment": "^7.2.1 || ^8.1.2 || ^9.3.2"
},
"type": "library",
"extra": {
@@ -10117,7 +10217,7 @@
"type": "patreon"
}
],
- "time": "2026-04-21T14:04:20+00:00"
+ "time": "2026-07-15T19:09:14+00:00"
},
{
"name": "permafrost-dev/code-snippets",
@@ -10183,16 +10283,16 @@
},
{
"name": "permafrost-dev/php-code-search",
- "version": "1.12.0",
+ "version": "1.13.0",
"source": {
"type": "git",
"url": "https://github.com/permafrost-dev/php-code-search.git",
- "reference": "dbbca18f7dc2950e88121bb62f8ed2c697df799a"
+ "reference": "07d18cbb54f266322583c74c7b17b97306831bb8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/permafrost-dev/php-code-search/zipball/dbbca18f7dc2950e88121bb62f8ed2c697df799a",
- "reference": "dbbca18f7dc2950e88121bb62f8ed2c697df799a",
+ "url": "https://api.github.com/repos/permafrost-dev/php-code-search/zipball/07d18cbb54f266322583c74c7b17b97306831bb8",
+ "reference": "07d18cbb54f266322583c74c7b17b97306831bb8",
"shasum": ""
},
"require": {
@@ -10202,7 +10302,10 @@
},
"require-dev": {
"phpunit/phpunit": "^9.5",
- "spatie/phpunit-snapshot-assertions": "^4.2"
+ "spatie/phpunit-snapshot-assertions": "^4.2",
+ "symfony/property-access": "^5.4",
+ "symfony/property-info": "^5.4",
+ "symfony/serializer": "^5.4"
},
"type": "library",
"autoload": {
@@ -10236,7 +10339,7 @@
],
"support": {
"issues": "https://github.com/permafrost-dev/php-code-search/issues",
- "source": "https://github.com/permafrost-dev/php-code-search/tree/1.12.0"
+ "source": "https://github.com/permafrost-dev/php-code-search/tree/1.13.0"
},
"funding": [
{
@@ -10244,7 +10347,7 @@
"type": "github"
}
],
- "time": "2024-09-03T04:33:45+00:00"
+ "time": "2026-10-29T21:12:23+00:00"
},
{
"name": "phar-io/manifest",
@@ -10366,16 +10469,16 @@
},
{
"name": "php-debugbar/php-debugbar",
- "version": "v3.7.6",
+ "version": "v3.8.1",
"source": {
"type": "git",
"url": "https://github.com/php-debugbar/php-debugbar.git",
- "reference": "1690ee1728827f9deb4b60457fa387cf44672c56"
+ "reference": "d04a382b80e320c7abdbe9fc66e83b34e80edef4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/1690ee1728827f9deb4b60457fa387cf44672c56",
- "reference": "1690ee1728827f9deb4b60457fa387cf44672c56",
+ "url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/d04a382b80e320c7abdbe9fc66e83b34e80edef4",
+ "reference": "d04a382b80e320c7abdbe9fc66e83b34e80edef4",
"shasum": ""
},
"require": {
@@ -10417,7 +10520,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "3.8-dev"
}
},
"autoload": {
@@ -10452,7 +10555,7 @@
],
"support": {
"issues": "https://github.com/php-debugbar/php-debugbar/issues",
- "source": "https://github.com/php-debugbar/php-debugbar/tree/v3.7.6"
+ "source": "https://github.com/php-debugbar/php-debugbar/tree/v3.8.1"
},
"funding": [
{
@@ -10464,7 +10567,7 @@
"type": "github"
}
],
- "time": "2026-04-30T07:31:44+00:00"
+ "time": "2026-10-25T20:20:41+00:00"
},
{
"name": "php-debugbar/symfony-bridge",
@@ -10728,33 +10831,34 @@
},
{
"name": "phpunit/php-code-coverage",
- "version": "12.5.7",
+ "version": "14.5.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "186dab580576598076de6818596d12b61801880e"
+ "reference": "4063552c678ce3beb4b7f131a5b7354a19ff3e2a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/186dab580576598076de6818596d12b61801880e",
- "reference": "186dab580576598076de6818596d12b61801880e",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4063552c678ce3beb4b7f131a5b7354a19ff3e2a",
+ "reference": "4063552c678ce3beb4b7f131a5b7354a19ff3e2a",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-libxml": "*",
+ "ext-mbstring": "*",
"ext-xmlwriter": "*",
- "nikic/php-parser": "^5.7.0",
- "php": ">=8.3",
- "phpunit/php-text-template": "^5.0",
- "sebastian/complexity": "^5.0",
- "sebastian/environment": "^8.1.2",
- "sebastian/lines-of-code": "^4.0.1",
- "sebastian/version": "^6.0",
- "theseer/tokenizer": "^2.0.1"
+ "nikic/php-parser": "^5.9.0",
+ "php": ">=8.4",
+ "phpunit/php-text-template": "^6.0.1",
+ "sebastian/complexity": "^6.0",
+ "sebastian/environment": "^9.3.3",
+ "sebastian/git-state": "^1.1.0",
+ "sebastian/lines-of-code": "^5.0.2",
+ "sebastian/version": "^7.0.1"
},
"require-dev": {
- "phpunit/phpunit": "^12.5.28"
+ "phpunit/phpunit": "^13.4.5"
},
"suggest": {
"ext-pcov": "PHP extension that provides line coverage",
@@ -10763,7 +10867,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "12.5.x-dev"
+ "dev-main": "14.5.x-dev"
}
},
"autoload": {
@@ -10792,7 +10896,7 @@
"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.7"
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/14.5.1"
},
"funding": [
{
@@ -10812,32 +10916,32 @@
"type": "tidelift"
}
],
- "time": "2026-06-01T13:24:19+00:00"
+ "time": "2026-11-02T11:47:37+00:00"
},
{
"name": "phpunit/php-file-iterator",
- "version": "6.0.1",
+ "version": "7.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
- "reference": "3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5"
+ "reference": "9bb4e6c58b62c1e043be995c66abec7c97307aae"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5",
- "reference": "3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/9bb4e6c58b62c1e043be995c66abec7c97307aae",
+ "reference": "9bb4e6c58b62c1e043be995c66abec7c97307aae",
"shasum": ""
},
"require": {
- "php": ">=8.3"
+ "php": ">=8.4"
},
"require-dev": {
- "phpunit/phpunit": "^12.0"
+ "phpunit/phpunit": "^13.3.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "6.0-dev"
+ "dev-main": "7.0-dev"
}
},
"autoload": {
@@ -10865,7 +10969,7 @@
"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"
+ "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/7.0.2"
},
"funding": [
{
@@ -10885,28 +10989,28 @@
"type": "tidelift"
}
],
- "time": "2026-02-02T14:04:18+00:00"
+ "time": "2026-08-25T14:47:43+00:00"
},
{
"name": "phpunit/php-invoker",
- "version": "6.0.0",
+ "version": "7.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-invoker.git",
- "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406"
+ "reference": "42e5c5cae0c65df12d1b1a3ab52bf3f50f244d88"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/12b54e689b07a25a9b41e57736dfab6ec9ae5406",
- "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/42e5c5cae0c65df12d1b1a3ab52bf3f50f244d88",
+ "reference": "42e5c5cae0c65df12d1b1a3ab52bf3f50f244d88",
"shasum": ""
},
"require": {
- "php": ">=8.3"
+ "php": ">=8.4"
},
"require-dev": {
"ext-pcntl": "*",
- "phpunit/phpunit": "^12.0"
+ "phpunit/phpunit": "^13.0"
},
"suggest": {
"ext-pcntl": "*"
@@ -10914,7 +11018,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "6.0-dev"
+ "dev-main": "7.0-dev"
}
},
"autoload": {
@@ -10941,40 +11045,52 @@
"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"
+ "source": "https://github.com/sebastianbergmann/php-invoker/tree/7.0.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/phpunit/php-invoker",
+ "type": "tidelift"
}
],
- "time": "2025-02-07T04:58:58+00:00"
+ "time": "2026-02-06T04:34:47+00:00"
},
{
"name": "phpunit/php-text-template",
- "version": "5.0.0",
+ "version": "6.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-text-template.git",
- "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53"
+ "reference": "97107691cb2b6c743b5e0c44be19e983cb337a02"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/e1367a453f0eda562eedb4f659e13aa900d66c53",
- "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/97107691cb2b6c743b5e0c44be19e983cb337a02",
+ "reference": "97107691cb2b6c743b5e0c44be19e983cb337a02",
"shasum": ""
},
"require": {
- "php": ">=8.3"
+ "php": ">=8.4"
},
"require-dev": {
- "phpunit/phpunit": "^12.0"
+ "phpunit/phpunit": "^13.3.6"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "5.0-dev"
+ "dev-main": "6.0-dev"
}
},
"autoload": {
@@ -11001,40 +11117,52 @@
"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"
+ "source": "https://github.com/sebastianbergmann/php-text-template/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-text-template",
+ "type": "tidelift"
}
],
- "time": "2025-02-07T04:59:16+00:00"
+ "time": "2026-10-03T04:54:24+00:00"
},
{
"name": "phpunit/php-timer",
- "version": "8.0.0",
+ "version": "9.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
- "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc"
+ "reference": "a0e12065831f6ab0d83120dc61513eb8d9a966f6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc",
- "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/a0e12065831f6ab0d83120dc61513eb8d9a966f6",
+ "reference": "a0e12065831f6ab0d83120dc61513eb8d9a966f6",
"shasum": ""
},
"require": {
- "php": ">=8.3"
+ "php": ">=8.4"
},
"require-dev": {
- "phpunit/phpunit": "^12.0"
+ "phpunit/phpunit": "^13.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "8.0-dev"
+ "dev-main": "9.0-dev"
}
},
"autoload": {
@@ -11061,56 +11189,70 @@
"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"
+ "source": "https://github.com/sebastianbergmann/php-timer/tree/9.0.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/phpunit/php-timer",
+ "type": "tidelift"
}
],
- "time": "2025-02-07T04:59:38+00:00"
+ "time": "2026-02-06T04:37:53+00:00"
},
{
"name": "phpunit/phpunit",
- "version": "12.5.30",
+ "version": "13.4.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "900400a5b616d6fb306f9549f6da33ba615d3fbb"
+ "reference": "4821376960d0e1e5a7b7b700955ebcab33ecd71b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/900400a5b616d6fb306f9549f6da33ba615d3fbb",
- "reference": "900400a5b616d6fb306f9549f6da33ba615d3fbb",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4821376960d0e1e5a7b7b700955ebcab33ecd71b",
+ "reference": "4821376960d0e1e5a7b7b700955ebcab33ecd71b",
"shasum": ""
},
"require": {
"ext-dom": "*",
+ "ext-filter": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
- "ext-xml": "*",
"ext-xmlwriter": "*",
- "myclabs/deep-copy": "^1.13.4",
+ "myclabs/deep-copy": "^1.14.0",
"phar-io/manifest": "^2.0.4",
"phar-io/version": "^3.2.1",
- "php": ">=8.3",
- "phpunit/php-code-coverage": "^12.5.7",
- "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.1",
- "sebastian/comparator": "^7.1.8",
- "sebastian/diff": "^7.0.0",
- "sebastian/environment": "^8.1.2",
- "sebastian/exporter": "^7.0.3",
- "sebastian/global-state": "^8.0.3",
- "sebastian/object-enumerator": "^7.0.0",
- "sebastian/recursion-context": "^7.0.1",
- "sebastian/type": "^6.0.4",
- "sebastian/version": "^6.0.0",
+ "php": ">=8.4.1",
+ "phpunit/php-code-coverage": "^14.5.0",
+ "phpunit/php-file-iterator": "^7.0.2",
+ "phpunit/php-invoker": "^7.0.0",
+ "phpunit/php-text-template": "^6.0.1",
+ "phpunit/php-timer": "^9.0.0",
+ "sebastian/cli-parser": "^5.0.1",
+ "sebastian/comparator": "^8.4",
+ "sebastian/diff": "^9.0.1",
+ "sebastian/environment": "^9.3.3",
+ "sebastian/exporter": "^8.2.1",
+ "sebastian/file-filter": "^1.0",
+ "sebastian/git-state": "^1.1",
+ "sebastian/global-state": "^9.0.1",
+ "sebastian/object-enumerator": "^8.1.0",
+ "sebastian/recursion-context": "^8.0.1",
+ "sebastian/type": "^7.0.2",
+ "sebastian/version": "^7.0.1",
"staabm/side-effects-detector": "^1.0.5"
},
"bin": [
@@ -11119,7 +11261,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "12.5-dev"
+ "dev-main": "13.4-dev"
}
},
"autoload": {
@@ -11151,7 +11293,7 @@
"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.30"
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/13.4.6"
},
"funding": [
{
@@ -11159,32 +11301,32 @@
"type": "other"
}
],
- "time": "2026-06-15T13:12:30+00:00"
+ "time": "2026-11-02T07:12:28+00:00"
},
{
"name": "sebastian/cli-parser",
- "version": "4.2.1",
+ "version": "5.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/cli-parser.git",
- "reference": "7d05781b13f7dec9043a629a21d086ed74582a15"
+ "reference": "eeb759ad3146b7096fb59c3195d39e071cd409e3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/7d05781b13f7dec9043a629a21d086ed74582a15",
- "reference": "7d05781b13f7dec9043a629a21d086ed74582a15",
+ "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/eeb759ad3146b7096fb59c3195d39e071cd409e3",
+ "reference": "eeb759ad3146b7096fb59c3195d39e071cd409e3",
"shasum": ""
},
"require": {
- "php": ">=8.3"
+ "php": ">=8.4"
},
"require-dev": {
- "phpunit/phpunit": "^12.5.25"
+ "phpunit/phpunit": "^13.2.6"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "4.2-dev"
+ "dev-main": "5.0-dev"
}
},
"autoload": {
@@ -11208,7 +11350,7 @@
"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.1"
+ "source": "https://github.com/sebastianbergmann/cli-parser/tree/5.0.1"
},
"funding": [
{
@@ -11228,31 +11370,31 @@
"type": "tidelift"
}
],
- "time": "2026-05-17T05:29:34+00:00"
+ "time": "2026-08-01T04:27:14+00:00"
},
{
"name": "sebastian/comparator",
- "version": "7.1.8",
+ "version": "8.4.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "7c65c1e79836812819705b473a90c12399542485"
+ "reference": "3b070e608146cba00fd6fd1f0ffba89e5a8897fb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/7c65c1e79836812819705b473a90c12399542485",
- "reference": "7c65c1e79836812819705b473a90c12399542485",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/3b070e608146cba00fd6fd1f0ffba89e5a8897fb",
+ "reference": "3b070e608146cba00fd6fd1f0ffba89e5a8897fb",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-mbstring": "*",
- "php": ">=8.3",
- "sebastian/diff": "^7.0",
- "sebastian/exporter": "^7.0.3"
+ "php": ">=8.4",
+ "sebastian/diff": "^9.0",
+ "sebastian/exporter": "^8.2"
},
"require-dev": {
- "phpunit/phpunit": "^12.5.25"
+ "phpunit/phpunit": "^13.3"
},
"suggest": {
"ext-bcmath": "For comparing BcMath\\Number objects"
@@ -11260,7 +11402,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "7.1-dev"
+ "dev-main": "8.4-dev"
}
},
"autoload": {
@@ -11300,7 +11442,7 @@
"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.8"
+ "source": "https://github.com/sebastianbergmann/comparator/tree/8.4.0"
},
"funding": [
{
@@ -11320,33 +11462,33 @@
"type": "tidelift"
}
],
- "time": "2026-05-21T04:45:25+00:00"
+ "time": "2026-08-07T07:23:13+00:00"
},
{
"name": "sebastian/complexity",
- "version": "5.0.0",
+ "version": "6.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/complexity.git",
- "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb"
+ "reference": "c5651c795c98093480df79350cb050813fc7a2f3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/bad4316aba5303d0221f43f8cee37eb58d384bbb",
- "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb",
+ "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/c5651c795c98093480df79350cb050813fc7a2f3",
+ "reference": "c5651c795c98093480df79350cb050813fc7a2f3",
"shasum": ""
},
"require": {
"nikic/php-parser": "^5.0",
- "php": ">=8.3"
+ "php": ">=8.4"
},
"require-dev": {
- "phpunit/phpunit": "^12.0"
+ "phpunit/phpunit": "^13.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "5.0-dev"
+ "dev-main": "6.0-dev"
}
},
"autoload": {
@@ -11370,41 +11512,53 @@
"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"
+ "source": "https://github.com/sebastianbergmann/complexity/tree/6.0.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/complexity",
+ "type": "tidelift"
}
],
- "time": "2025-02-07T04:55:25+00:00"
+ "time": "2026-02-06T04:41:32+00:00"
},
{
"name": "sebastian/diff",
- "version": "7.0.0",
+ "version": "9.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "7ab1ea946c012266ca32390913653d844ecd085f"
+ "reference": "a2df6626c1baf31d5a88674882a3072f151b5a26"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f",
- "reference": "7ab1ea946c012266ca32390913653d844ecd085f",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/a2df6626c1baf31d5a88674882a3072f151b5a26",
+ "reference": "a2df6626c1baf31d5a88674882a3072f151b5a26",
"shasum": ""
},
"require": {
- "php": ">=8.3"
+ "php": ">=8.4"
},
"require-dev": {
- "phpunit/phpunit": "^12.0",
- "symfony/process": "^7.2"
+ "phpunit/phpunit": "^13.3.1",
+ "symfony/process": "^7.4.17"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "7.0-dev"
+ "dev-main": "9.0-dev"
}
},
"autoload": {
@@ -11437,35 +11591,47 @@
"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"
+ "source": "https://github.com/sebastianbergmann/diff/tree/9.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/diff",
+ "type": "tidelift"
}
],
- "time": "2025-02-07T04:55:46+00:00"
+ "time": "2026-08-25T15:38:55+00:00"
},
{
"name": "sebastian/environment",
- "version": "8.1.2",
+ "version": "9.3.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/environment.git",
- "reference": "9d32c685773823b1983e256ae4ecd48a10d6e439"
+ "reference": "d4dd10267a11055066a2a78ae04583d8ddd4f595"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/9d32c685773823b1983e256ae4ecd48a10d6e439",
- "reference": "9d32c685773823b1983e256ae4ecd48a10d6e439",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d4dd10267a11055066a2a78ae04583d8ddd4f595",
+ "reference": "d4dd10267a11055066a2a78ae04583d8ddd4f595",
"shasum": ""
},
"require": {
- "php": ">=8.3"
+ "php": ">=8.4"
},
"require-dev": {
- "phpunit/phpunit": "^12.5.26"
+ "phpunit/phpunit": "^13.3.6"
},
"suggest": {
"ext-posix": "*"
@@ -11473,7 +11639,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "8.1-dev"
+ "dev-main": "9.3-dev"
}
},
"autoload": {
@@ -11501,7 +11667,7 @@
"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.2"
+ "source": "https://github.com/sebastianbergmann/environment/tree/9.3.3"
},
"funding": [
{
@@ -11521,34 +11687,34 @@
"type": "tidelift"
}
],
- "time": "2026-05-25T13:40:20+00:00"
+ "time": "2026-10-01T12:37:56+00:00"
},
{
"name": "sebastian/exporter",
- "version": "7.0.3",
+ "version": "8.2.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "c5e21b5de653ce0a769fb36f5cdfcb5e7a32cf23"
+ "reference": "24a3b69bba4a12ab615fca9d34680c5598d9ab7a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c5e21b5de653ce0a769fb36f5cdfcb5e7a32cf23",
- "reference": "c5e21b5de653ce0a769fb36f5cdfcb5e7a32cf23",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/24a3b69bba4a12ab615fca9d34680c5598d9ab7a",
+ "reference": "24a3b69bba4a12ab615fca9d34680c5598d9ab7a",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
- "php": ">=8.3",
- "sebastian/recursion-context": "^7.0.1"
+ "php": ">=8.4",
+ "sebastian/recursion-context": "^8.0.1"
},
"require-dev": {
- "phpunit/phpunit": "^12.5.25"
+ "phpunit/phpunit": "^13.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "7.0-dev"
+ "dev-main": "8.2-dev"
}
},
"autoload": {
@@ -11591,7 +11757,7 @@
"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.3"
+ "source": "https://github.com/sebastianbergmann/exporter/tree/8.2.1"
},
"funding": [
{
@@ -11611,35 +11777,173 @@
"type": "tidelift"
}
],
- "time": "2026-05-20T04:37:17+00:00"
+ "time": "2026-08-07T07:22:06+00:00"
},
{
- "name": "sebastian/global-state",
- "version": "8.0.3",
+ "name": "sebastian/file-filter",
+ "version": "1.0.0",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "b164d3274d6537ab462591c5755f76a8f5b1aae9"
+ "url": "https://github.com/sebastianbergmann/file-filter.git",
+ "reference": "33a26f394330f6faa7684bb9cc73afb7727aae93"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b164d3274d6537ab462591c5755f76a8f5b1aae9",
- "reference": "b164d3274d6537ab462591c5755f76a8f5b1aae9",
+ "url": "https://api.github.com/repos/sebastianbergmann/file-filter/zipball/33a26f394330f6faa7684bb9cc73afb7727aae93",
+ "reference": "33a26f394330f6faa7684bb9cc73afb7727aae93",
"shasum": ""
},
"require": {
- "php": ">=8.3",
- "sebastian/object-reflector": "^5.0",
- "sebastian/recursion-context": "^7.0.1"
+ "php": ">=8.4"
},
"require-dev": {
- "ext-dom": "*",
- "phpunit/phpunit": "^12.5.28"
+ "phpunit/phpunit": "^13.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "8.0-dev"
+ "dev-main": "1.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 filtering files",
+ "homepage": "https://github.com/sebastianbergmann/file-filter",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/file-filter/issues",
+ "security": "https://github.com/sebastianbergmann/file-filter/security/policy",
+ "source": "https://github.com/sebastianbergmann/file-filter/tree/1.0.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/file-filter",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2026-04-22T07:20:04+00:00"
+ },
+ {
+ "name": "sebastian/git-state",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/git-state.git",
+ "reference": "31a565f463686f0eefa85f899549256bf5805985"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/git-state/zipball/31a565f463686f0eefa85f899549256bf5805985",
+ "reference": "31a565f463686f0eefa85f899549256bf5805985",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.4"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^13.4.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.1-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 describing the state of a Git checkout",
+ "homepage": "https://github.com/sebastianbergmann/git-state",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/git-state/issues",
+ "security": "https://github.com/sebastianbergmann/git-state/security/policy",
+ "source": "https://github.com/sebastianbergmann/git-state/tree/1.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/git-state",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2026-10-21T05:59:52+00:00"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "9.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "ba68ba79da690cf7eddefd3ce5b78b20b9ba9945"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/ba68ba79da690cf7eddefd3ce5b78b20b9ba9945",
+ "reference": "ba68ba79da690cf7eddefd3ce5b78b20b9ba9945",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.4",
+ "sebastian/object-reflector": "^6.0",
+ "sebastian/recursion-context": "^8.0"
+ },
+ "require-dev": {
+ "ext-dom": "*",
+ "phpunit/phpunit": "^13.1.13"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "9.0-dev"
}
},
"autoload": {
@@ -11665,7 +11969,7 @@
"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.3"
+ "source": "https://github.com/sebastianbergmann/global-state/tree/9.0.1"
},
"funding": [
{
@@ -11685,33 +11989,33 @@
"type": "tidelift"
}
],
- "time": "2026-06-01T15:10:33+00:00"
+ "time": "2026-06-01T15:11:33+00:00"
},
{
"name": "sebastian/lines-of-code",
- "version": "4.0.1",
+ "version": "5.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/lines-of-code.git",
- "reference": "d543b8ef219dcd8da262cbb958639a96bedba10e"
+ "reference": "d1b6f8fce682505dbd048977f1abedf1b8ad3ff8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d543b8ef219dcd8da262cbb958639a96bedba10e",
- "reference": "d543b8ef219dcd8da262cbb958639a96bedba10e",
+ "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d1b6f8fce682505dbd048977f1abedf1b8ad3ff8",
+ "reference": "d1b6f8fce682505dbd048977f1abedf1b8ad3ff8",
"shasum": ""
},
"require": {
- "nikic/php-parser": "^5.7.0",
- "php": ">=8.3"
+ "nikic/php-parser": "^5.8.0",
+ "php": ">=8.4"
},
"require-dev": {
- "phpunit/phpunit": "^12.5.25"
+ "phpunit/phpunit": "^13.2.4"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "4.0-dev"
+ "dev-main": "5.0-dev"
}
},
"autoload": {
@@ -11735,7 +12039,7 @@
"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.1"
+ "source": "https://github.com/sebastianbergmann/lines-of-code/tree/5.0.2"
},
"funding": [
{
@@ -11755,34 +12059,33 @@
"type": "tidelift"
}
],
- "time": "2026-05-19T16:22:07+00:00"
+ "time": "2026-07-09T08:42:34+00:00"
},
{
"name": "sebastian/object-enumerator",
- "version": "7.0.0",
+ "version": "8.1.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-enumerator.git",
- "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894"
+ "reference": "511064ecde82bd747e2ba2fab3dda8d977b59576"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894",
- "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/511064ecde82bd747e2ba2fab3dda8d977b59576",
+ "reference": "511064ecde82bd747e2ba2fab3dda8d977b59576",
"shasum": ""
},
"require": {
- "php": ">=8.3",
- "sebastian/object-reflector": "^5.0",
- "sebastian/recursion-context": "^7.0"
+ "php": ">=8.4",
+ "sebastian/recursion-context": "^8.0.1"
},
"require-dev": {
- "phpunit/phpunit": "^12.0"
+ "phpunit/phpunit": "^13.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "7.0-dev"
+ "dev-main": "8.1-dev"
}
},
"autoload": {
@@ -11805,40 +12108,52 @@
"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"
+ "source": "https://github.com/sebastianbergmann/object-enumerator/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/object-enumerator",
+ "type": "tidelift"
}
],
- "time": "2025-02-07T04:57:48+00:00"
+ "time": "2026-08-13T07:05:05+00:00"
},
{
"name": "sebastian/object-reflector",
- "version": "5.0.0",
+ "version": "6.1.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-reflector.git",
- "reference": "4bfa827c969c98be1e527abd576533293c634f6a"
+ "reference": "f71bbcdc4f95456b4622810bec64eb06372e25b2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a",
- "reference": "4bfa827c969c98be1e527abd576533293c634f6a",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/f71bbcdc4f95456b4622810bec64eb06372e25b2",
+ "reference": "f71bbcdc4f95456b4622810bec64eb06372e25b2",
"shasum": ""
},
"require": {
- "php": ">=8.3"
+ "php": ">=8.4"
},
"require-dev": {
- "phpunit/phpunit": "^12.0"
+ "phpunit/phpunit": "^13.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "5.0-dev"
+ "dev-main": "6.0-dev"
}
},
"autoload": {
@@ -11861,40 +12176,52 @@
"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"
+ "source": "https://github.com/sebastianbergmann/object-reflector/tree/6.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/object-reflector",
+ "type": "tidelift"
}
],
- "time": "2025-02-07T04:58:17+00:00"
+ "time": "2026-08-13T06:34:36+00:00"
},
{
"name": "sebastian/recursion-context",
- "version": "7.0.1",
+ "version": "8.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
- "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c"
+ "reference": "32dba72f2b4642d6a93db22d6c0a9280ff2e3ca0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/0b01998a7d5b1f122911a66bebcb8d46f0c82d8c",
- "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/32dba72f2b4642d6a93db22d6c0a9280ff2e3ca0",
+ "reference": "32dba72f2b4642d6a93db22d6c0a9280ff2e3ca0",
"shasum": ""
},
"require": {
- "php": ">=8.3"
+ "php": ">=8.4"
},
"require-dev": {
- "phpunit/phpunit": "^12.0"
+ "phpunit/phpunit": "^13.2.6"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "7.0-dev"
+ "dev-main": "8.0-dev"
}
},
"autoload": {
@@ -11925,7 +12252,7 @@
"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"
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/8.0.1"
},
"funding": [
{
@@ -11945,32 +12272,32 @@
"type": "tidelift"
}
],
- "time": "2025-08-13T04:44:59+00:00"
+ "time": "2026-08-03T05:58:12+00:00"
},
{
"name": "sebastian/type",
- "version": "6.0.4",
+ "version": "7.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/type.git",
- "reference": "82ff822c2edc46724be9f7411d3163021f602773"
+ "reference": "bd1df467864cb95140414059a535b2d906173fcf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/82ff822c2edc46724be9f7411d3163021f602773",
- "reference": "82ff822c2edc46724be9f7411d3163021f602773",
+ "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/bd1df467864cb95140414059a535b2d906173fcf",
+ "reference": "bd1df467864cb95140414059a535b2d906173fcf",
"shasum": ""
},
"require": {
- "php": ">=8.3"
+ "php": ">=8.4"
},
"require-dev": {
- "phpunit/phpunit": "^12.5.25"
+ "phpunit/phpunit": "^13.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "6.0-dev"
+ "dev-main": "7.0-dev"
}
},
"autoload": {
@@ -11994,7 +12321,7 @@
"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.4"
+ "source": "https://github.com/sebastianbergmann/type/tree/7.0.2"
},
"funding": [
{
@@ -12014,29 +12341,29 @@
"type": "tidelift"
}
],
- "time": "2026-05-20T06:45:45+00:00"
+ "time": "2026-08-10T08:00:57+00:00"
},
{
"name": "sebastian/version",
- "version": "6.0.0",
+ "version": "7.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/version.git",
- "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c"
+ "reference": "f1598cf1d8d1ca4c0f194a52f2fe72a559a7b0b1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c",
- "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/f1598cf1d8d1ca4c0f194a52f2fe72a559a7b0b1",
+ "reference": "f1598cf1d8d1ca4c0f194a52f2fe72a559a7b0b1",
"shasum": ""
},
"require": {
- "php": ">=8.3"
+ "php": ">=8.4"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "6.0-dev"
+ "dev-main": "7.0-dev"
}
},
"autoload": {
@@ -12060,15 +12387,27 @@
"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"
+ "source": "https://github.com/sebastianbergmann/version/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/version",
+ "type": "tidelift"
}
],
- "time": "2025-02-07T05:00:38+00:00"
+ "time": "2026-10-04T05:51:14+00:00"
},
{
"name": "spatie/laravel-ray",
@@ -12212,16 +12551,16 @@
},
{
"name": "spatie/ray",
- "version": "1.48.0",
+ "version": "1.48.1",
"source": {
"type": "git",
"url": "https://github.com/spatie/ray.git",
- "reference": "974ac9c6e315033ab8ace883d60e094522f88ede"
+ "reference": "1b82467e05eb4cabccd876344d2a48c4e98c6dd5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/spatie/ray/zipball/974ac9c6e315033ab8ace883d60e094522f88ede",
- "reference": "974ac9c6e315033ab8ace883d60e094522f88ede",
+ "url": "https://api.github.com/repos/spatie/ray/zipball/1b82467e05eb4cabccd876344d2a48c4e98c6dd5",
+ "reference": "1b82467e05eb4cabccd876344d2a48c4e98c6dd5",
"shasum": ""
},
"require": {
@@ -12281,7 +12620,7 @@
],
"support": {
"issues": "https://github.com/spatie/ray/issues",
- "source": "https://github.com/spatie/ray/tree/1.48.0"
+ "source": "https://github.com/spatie/ray/tree/1.48.1"
},
"funding": [
{
@@ -12293,34 +12632,34 @@
"type": "other"
}
],
- "time": "2026-03-31T12:44:31+00:00"
+ "time": "2026-11-05T09:15:00+00:00"
},
{
"name": "spatie/x-ray",
- "version": "1.2.2",
+ "version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/spatie/x-ray.git",
- "reference": "9f816cba11d9674d070b898ab572e01fd3690ae0"
+ "reference": "853703a6a32ab6a48b295af7110160dd785e06a6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/spatie/x-ray/zipball/9f816cba11d9674d070b898ab572e01fd3690ae0",
- "reference": "9f816cba11d9674d070b898ab572e01fd3690ae0",
+ "url": "https://api.github.com/repos/spatie/x-ray/zipball/853703a6a32ab6a48b295af7110160dd785e06a6",
+ "reference": "853703a6a32ab6a48b295af7110160dd785e06a6",
"shasum": ""
},
"require": {
"permafrost-dev/code-snippets": "^1.2.0",
"permafrost-dev/php-code-search": "^1.10.5",
- "php": "^8.0",
+ "php": "^8.3",
"symfony/console": "^5.3|^6.0|^7.0|^8.0",
"symfony/finder": "^5.3|^6.0|^7.0|^8.0",
"symfony/yaml": "^5.3|^6.0|^7.0|^8.0"
},
"require-dev": {
"phpstan/phpstan": "^2.0.0",
- "phpunit/phpunit": "^9.5",
- "spatie/phpunit-snapshot-assertions": "^4.2"
+ "phpunit/phpunit": "^12.5",
+ "spatie/phpunit-snapshot-assertions": "^5.4"
},
"bin": [
"bin/x-ray"
@@ -12353,7 +12692,7 @@
],
"support": {
"issues": "https://github.com/spatie/x-ray/issues",
- "source": "https://github.com/spatie/x-ray/tree/1.2.2"
+ "source": "https://github.com/spatie/x-ray/tree/1.3.0"
},
"funding": [
{
@@ -12365,7 +12704,7 @@
"type": "github"
}
],
- "time": "2026-02-09T20:03:00+00:00"
+ "time": "2026-11-06T12:06:13+00:00"
},
{
"name": "staabm/side-effects-detector",
@@ -12421,16 +12760,16 @@
},
{
"name": "symfony/polyfill-iconv",
- "version": "v1.37.0",
+ "version": "v1.43.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-iconv.git",
- "reference": "2c5729fd241b4b22f6e4b436bc3354a4f262df57"
+ "reference": "254724d95fe01b679cd97d88786e9623ee00bfb7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/2c5729fd241b4b22f6e4b436bc3354a4f262df57",
- "reference": "2c5729fd241b4b22f6e4b436bc3354a4f262df57",
+ "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/254724d95fe01b679cd97d88786e9623ee00bfb7",
+ "reference": "254724d95fe01b679cd97d88786e9623ee00bfb7",
"shasum": ""
},
"require": {
@@ -12481,7 +12820,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-iconv/tree/v1.37.0"
+ "source": "https://github.com/symfony/polyfill-iconv/tree/v1.43.0"
},
"funding": [
{
@@ -12501,7 +12840,7 @@
"type": "tidelift"
}
],
- "time": "2026-04-10T16:19:22+00:00"
+ "time": "2026-09-29T06:25:14+00:00"
},
{
"name": "symfony/stopwatch",
@@ -12571,16 +12910,16 @@
},
{
"name": "symfony/yaml",
- "version": "v8.1.1",
+ "version": "v8.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "8e4cdd4311683516be06944f4b85244063cdb886"
+ "reference": "e8266f55160f674f290a5f567cb55e11e21f921b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/8e4cdd4311683516be06944f4b85244063cdb886",
- "reference": "8e4cdd4311683516be06944f4b85244063cdb886",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/e8266f55160f674f290a5f567cb55e11e21f921b",
+ "reference": "e8266f55160f674f290a5f567cb55e11e21f921b",
"shasum": ""
},
"require": {
@@ -12623,7 +12962,7 @@
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/yaml/tree/v8.1.1"
+ "source": "https://github.com/symfony/yaml/tree/v8.1.11"
},
"funding": [
{
@@ -12643,74 +12982,24 @@
"type": "tidelift"
}
],
- "time": "2026-06-09T11:06:24+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"
+ "time": "2026-11-04T08:39:20+00:00"
},
{
"name": "zbateson/mail-mime-parser",
- "version": "4.0.2",
+ "version": "4.0.8",
"source": {
"type": "git",
"url": "https://github.com/zbateson/mail-mime-parser.git",
- "reference": "0f268ceb5a60738f082da6881414ed2c8e0bb088"
+ "reference": "21a8a6ff886f6ab19c065655f84f5a9ac4f86266"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/zbateson/mail-mime-parser/zipball/0f268ceb5a60738f082da6881414ed2c8e0bb088",
- "reference": "0f268ceb5a60738f082da6881414ed2c8e0bb088",
+ "url": "https://api.github.com/repos/zbateson/mail-mime-parser/zipball/21a8a6ff886f6ab19c065655f84f5a9ac4f86266",
+ "reference": "21a8a6ff886f6ab19c065655f84f5a9ac4f86266",
"shasum": ""
},
"require": {
- "guzzlehttp/psr7": "^2.5",
+ "guzzlehttp/psr7": "^2.5 || ^3.0",
"php": ">=8.1",
"php-di/php-di": "^6.0|^7.0",
"psr/log": "^1|^2|^3",
@@ -12769,7 +13058,7 @@
"type": "github"
}
],
- "time": "2026-06-24T03:13:44+00:00"
+ "time": "2026-10-27T16:17:50+00:00"
},
{
"name": "zbateson/mb-wrapper",
@@ -12842,20 +13131,20 @@
},
{
"name": "zbateson/stream-decorators",
- "version": "3.0.1",
+ "version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/zbateson/stream-decorators.git",
- "reference": "093a898753e95e0063d0ca67c04b7b2619742ae9"
+ "reference": "4776323764ec592de417ef54f3c8fc96fd242849"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/zbateson/stream-decorators/zipball/093a898753e95e0063d0ca67c04b7b2619742ae9",
- "reference": "093a898753e95e0063d0ca67c04b7b2619742ae9",
+ "url": "https://api.github.com/repos/zbateson/stream-decorators/zipball/4776323764ec592de417ef54f3c8fc96fd242849",
+ "reference": "4776323764ec592de417ef54f3c8fc96fd242849",
"shasum": ""
},
"require": {
- "guzzlehttp/psr7": "^2.5",
+ "guzzlehttp/psr7": "^2.5 || ^3.0",
"php": ">=8.1",
"zbateson/mb-wrapper": "^2.0 || ^3.0"
},
@@ -12893,7 +13182,7 @@
],
"support": {
"issues": "https://github.com/zbateson/stream-decorators/issues",
- "source": "https://github.com/zbateson/stream-decorators/tree/3.0.1"
+ "source": "https://github.com/zbateson/stream-decorators/tree/3.0.2"
},
"funding": [
{
@@ -12901,7 +13190,7 @@
"type": "github"
}
],
- "time": "2026-06-24T02:55:37+00:00"
+ "time": "2026-07-24T23:09:40+00:00"
}
],
"aliases": [],
diff --git a/config/flare.php b/config/flare.php
index 9edd19f5..0b8c6187 100644
--- a/config/flare.php
+++ b/config/flare.php
@@ -1,8 +1,6 @@
env('FLARE_KEY'),
- /*
- |
- |--------------------------------------------------------------------------
- | Flare Base URL
- |--------------------------------------------------------------------------
- |
- | Which server should be used to send the reports/traces to.
- |
- */
- 'base_url' => env('FLARE_BASE_URL', Api::BASE_URL),
-
/*
|--------------------------------------------------------------------------
| Collects
@@ -47,22 +34,6 @@ return [
extra: []
),
- /*
- |--------------------------------------------------------------------------
- | Attribute providers
- |--------------------------------------------------------------------------
- |
- | When sending an error report or trace to Flare attributes can be added to
- | the report or trace for common entries. An example of such an entry is
- | the currently authenticated user. In an attribute provider you can
- | specify which attributes should be sent.
- |
- */
-
- 'attribute_providers' => [
- 'user' => LaravelUserAttributesProvider::class,
- ],
-
/*
|--------------------------------------------------------------------------
| Censor data
@@ -88,19 +59,49 @@ return [
'X-XSRF-TOKEN',
],
'client_ips' => false,
+ 'cookies' => false,
+ 'session' => false,
],
/*
|--------------------------------------------------------------------------
- | Reporting log statements
+ | Sender
|--------------------------------------------------------------------------
|
- | If this setting is `false` log statements won't be sent as events to Flare,
- | no matter which error level you specified in the Flare log channel.
+ | The sender is responsible for sending the error reports and traces to
+ | Flare. By default, Laravel Flare sends them over HTTP. To use the local
+ | Flare daemon, switch the sender class to
+ | `Spatie\FlareClient\Senders\DaemonSender::class` and set `daemon_url`.
+ | The daemon sender defaults to localhost on port 8787 and uses its own
+ | default timeouts and fallback sender config unless you override them.
|
*/
- 'send_logs_as_events' => true,
+ 'sender' => [
+ 'class' => LaravelHttpSender::class,
+ 'config' => [
+ 'timeout' => 10,
+ ],
+ ],
+
+ // Daemon sender example
+ // 'sender' => [
+ // 'class' => \Spatie\FlareClient\Senders\DaemonSender::class,
+ // 'config' => [
+ // 'daemon_url' => env('FLARE_DAEMON_URL', 'http://127.0.0.1:8787'),
+ // ],
+ // ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Report
+ |--------------------------------------------------------------------------
+ |
+ | Flare reports errors and exceptions happening within your application.
+ |
+ */
+
+ 'report' => env('FLARE_REPORT', true),
/*
|--------------------------------------------------------------------------
@@ -109,10 +110,27 @@ return [
| When reporting errors, you can specify which error levels should be
| reported. By default, all error levels are reported by setting
| this value to `null`.
- */
+ */
'report_error_levels' => null,
+ /*
+ |--------------------------------------------------------------------------
+ | Override grouping
+ |--------------------------------------------------------------------------
+ |
+ | Flare will try to group errors and exceptions as best as possible, that
+ | being said, sometimes you might want to override the grouping. You can
+ | do this by adding exception classes to this array which should always
+ | be grouped by exception class, exception message or exception class
+ | and message.
+ |
+ */
+
+ 'overridden_groupings' => [
+ // Illuminate\Http\Client\ConnectionException::class => Spatie\FlareClient\Enums\OverriddenGrouping::ExceptionMessageAndClass,
+ ],
+
/*
|--------------------------------------------------------------------------
| Share button
@@ -126,40 +144,6 @@ return [
'enable_share_button' => true,
- /*
- |--------------------------------------------------------------------------
- | Override grouping
- |--------------------------------------------------------------------------
- |
- | Flare will try to group errors and exceptions as best as possible, that
- | being said, sometimes you might want to override the grouping. You can
- | do this by adding exception classes to this array which should always
- | be grouped by exception class, exception message or exception class
- | and message.
- |
- */
-
- 'overridden_groupings' => [
- // Illuminate\Http\Client\ConnectionException::class => Spatie\FlareClient\Enums\OverriddenGrouping::ExceptionMessageAndClass,
- ],
-
- /*
- |--------------------------------------------------------------------------
- | Sender
- |--------------------------------------------------------------------------
- |
- | The sender is responsible for sending the error reports and traces to
- | Flare it can be configured if needed.
- |
- */
-
- 'sender' => [
- 'class' => LaravelHttpSender::class,
- 'config' => [
- 'timeout' => 10,
- ],
- ],
-
/*
|--------------------------------------------------------------------------
| Trace
@@ -170,7 +154,7 @@ return [
|
*/
- 'trace' => env('FLARE_TRACE', false),
+ 'trace' => env('FLARE_TRACE', true),
/*
|--------------------------------------------------------------------------
@@ -183,26 +167,35 @@ return [
| which means that 10% of the traces will be recorded.
|
*/
+
'sampler' => [
'class' => RateSampler::class,
'config' => [
- 'rate' => 0.1,
+ 'rate' => env('FLARE_SAMPLER_RATE', 0.1),
],
],
/*
|--------------------------------------------------------------------------
- | Trace limits
+ | Log
|--------------------------------------------------------------------------
|
- | Limits for the tracing data. These limits are used to prevent
- | the tracing data from growing too large.
+ | Logging show you an overview of log entries within your application.
|
*/
- 'trace_limits' => [
- 'max_spans' => 512,
- 'max_attributes_per_span' => 128,
- 'max_span_events_per_span' => 128,
- 'max_attributes_per_span_event' => 128,
- ],
+
+ 'log' => env('FLARE_LOG', false),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Minimal log level
+ |--------------------------------------------------------------------------
+ |
+ | You can specify the minimal (Monolog) log level that should be sent to Flare.
+ | Log levels lower than the specified level will be ignored.
+ | If null all log levels will be sent to Flare.
+ |
+ */
+
+ 'minimal_log_level' => null,
];
diff --git a/config/image.php b/config/image.php
deleted file mode 100644
index b984a0f0..00000000
--- a/config/image.php
+++ /dev/null
@@ -1,22 +0,0 @@
- Driver::class,
-
-];
diff --git a/config/services.php b/config/services.php
index b784e544..7a5cdfa5 100644
--- a/config/services.php
+++ b/config/services.php
@@ -39,4 +39,8 @@ return [
'token' => env('CLOUDCONVERT_API_TOKEN'),
],
+ 'brrr' => [
+ 'webhook_url' => env('BRRR_WEBHOOK_URL'),
+ ],
+
];
diff --git a/database/factories/AboutFactory.php b/database/factories/AboutFactory.php
new file mode 100644
index 00000000..5af2532e
--- /dev/null
+++ b/database/factories/AboutFactory.php
@@ -0,0 +1,24 @@
+
+ */
+class AboutFactory extends Factory
+{
+ /**
+ * Define the model's default state.
+ *
+ * @return array
+ */
+ public function definition(): array
+ {
+ return [
+ 'content' => $this->faker->paragraph,
+ ];
+ }
+}
diff --git a/database/factories/SettingFactory.php b/database/factories/SettingFactory.php
new file mode 100644
index 00000000..8df15756
--- /dev/null
+++ b/database/factories/SettingFactory.php
@@ -0,0 +1,24 @@
+
+ */
+class SettingFactory extends Factory
+{
+ /**
+ * Define the model's default state.
+ *
+ * @return array
+ */
+ public function definition(): array
+ {
+ return [
+ 'winter_effect_enabled' => false,
+ ];
+ }
+}
diff --git a/database/migrations/2026_08_13_120924_create_micropub_tokens_table.php b/database/migrations/2026_08_13_120924_create_micropub_tokens_table.php
new file mode 100644
index 00000000..e336912f
--- /dev/null
+++ b/database/migrations/2026_08_13_120924_create_micropub_tokens_table.php
@@ -0,0 +1,30 @@
+id();
+ $table->string('token_hash', 64)->unique();
+ $table->string('client_id');
+ $table->string('me');
+ $table->string('scope');
+ $table->timestamp('revoked_at')->nullable();
+ $table->timestamps();
+
+ $table->index('client_id');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('micropub_tokens');
+ }
+};
diff --git a/database/migrations/2026_08_23_101358_create_settings_table.php b/database/migrations/2026_08_23_101358_create_settings_table.php
new file mode 100644
index 00000000..a4ea86d2
--- /dev/null
+++ b/database/migrations/2026_08_23_101358_create_settings_table.php
@@ -0,0 +1,28 @@
+id();
+ $table->boolean('winter_effect_enabled')->default(false);
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('settings');
+ }
+};
diff --git a/database/migrations/2026_08_28_142830_create_about_table.php b/database/migrations/2026_08_28_142830_create_about_table.php
new file mode 100644
index 00000000..15ab6f84
--- /dev/null
+++ b/database/migrations/2026_08_28_142830_create_about_table.php
@@ -0,0 +1,28 @@
+id();
+ $table->text('content');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('about');
+ }
+};
diff --git a/database/migrations/2026_11_01_120000_drop_shorturl_from_notes_table.php b/database/migrations/2026_11_01_120000_drop_shorturl_from_notes_table.php
new file mode 100644
index 00000000..e4f73202
--- /dev/null
+++ b/database/migrations/2026_11_01_120000_drop_shorturl_from_notes_table.php
@@ -0,0 +1,28 @@
+dropColumn('shorturl');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('notes', function (Blueprint $table) {
+ $table->string('shorturl', 20)->nullable();
+ });
+ }
+};
diff --git a/package-lock.json b/package-lock.json
index 55d97494..b0bbccb2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,45 +20,20 @@
"globals": "^17.3.0",
"lightningcss": "^1.29.3",
"lightningcss-cli": "^1.29.3",
- "stylelint": "^17.3.0",
- "stylelint-config-standard": "^40.0.0"
+ "stylelint": "^18.0.0",
+ "stylelint-config-standard": "^41.0.0"
}
},
"node_modules/@11ty/is-land": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@11ty/is-land/-/is-land-5.0.1.tgz",
- "integrity": "sha512-Rh/sLhE4vrc2JaSjeY385v2UxnDY9BhnQtitETb3SKyr0A48Q5Vn06q2AvDBHObtk9+dcFWsoZX4jhT+O9g+xQ==",
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@11ty/is-land/-/is-land-5.3.0.tgz",
+ "integrity": "sha512-gjeOvZh0G+6t5fHu2s3dcaQ8zeMtw2yfPS7Vwv13gh8A50Nf1ZFGCLbhqU2uLbEBmLCDsff9XFRWdDkPEFOMJQ==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/11ty"
}
},
- "node_modules/@babel/code-frame": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
- "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.29.7",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.1.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
- "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@cacheable/memory": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.2.0.tgz",
@@ -72,33 +47,6 @@
"keyv": "^5.6.0"
}
},
- "node_modules/@cacheable/memory/node_modules/@keyv/bigmap": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.1.tgz",
- "integrity": "sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "hashery": "^1.4.0",
- "hookified": "^1.15.0"
- },
- "engines": {
- "node": ">= 18"
- },
- "peerDependencies": {
- "keyv": "^5.6.0"
- }
- },
- "node_modules/@cacheable/memory/node_modules/keyv": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz",
- "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@keyv/serialize": "^1.1.1"
- }
- },
"node_modules/@cacheable/utils": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.5.0.tgz",
@@ -110,20 +58,10 @@
"keyv": "^5.6.0"
}
},
- "node_modules/@cacheable/utils/node_modules/keyv": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz",
- "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@keyv/serialize": "^1.1.1"
- }
- },
"node_modules/@csstools/css-calc": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.1.tgz",
- "integrity": "sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==",
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.4.3.tgz",
+ "integrity": "sha512-iex20d8CHVkyvg6B7UKV7uHnI2Bqo9g+EFfT9E0y+GvTvhZ/DwONJ+9aKb1dlqm0ZiGsL5RXjp0fCoJYnkeDjA==",
"dev": true,
"funding": [
{
@@ -140,14 +78,14 @@
"node": ">=20.19.0"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^4.0.0",
- "@csstools/css-tokenizer": "^4.0.0"
+ "@csstools/css-parser-algorithms": "^4.0.2",
+ "@csstools/css-tokenizer": "^4.0.2"
}
},
"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==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.2.tgz",
+ "integrity": "sha512-40cSKyMvK+tq4qz6Awrlye2WGuOKt3FwPgtGg6KTfbHOWNw+Rk1rzbAtZnZ6IBhsY491HLRnDXwoyBAijmmILA==",
"dev": true,
"funding": [
{
@@ -164,13 +102,13 @@
"node": ">=20.19.0"
},
"peerDependencies": {
- "@csstools/css-tokenizer": "^4.0.0"
+ "@csstools/css-tokenizer": "^4.0.2"
}
},
"node_modules/@csstools/css-syntax-patches-for-csstree": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.6.tgz",
- "integrity": "sha512-TcJCWFbXLPpJYq6z7bfOyjWYJDiDg2/I4gyUC9pqPNqHFRIey0EB0q0L5cSnQDfWJg8Jd6VadakxdIez/3zkqQ==",
+ "version": "1.1.16",
+ "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.16.tgz",
+ "integrity": "sha512-LsDbJPP/B8cPasUJyTA5S99F7C4G93ngW8hUluXz8CFeOaaRnBPtBiIlvgcPYU0HmHNz8CXg+1vwFrIB4F6Dgw==",
"dev": true,
"funding": [
{
@@ -193,9 +131,9 @@
}
},
"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==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.2.tgz",
+ "integrity": "sha512-OoKoR0f76dCY666JlcbhmVTs2drYj1GUXZTYTcbUgJjh9Nv41aFfZ21bPQTERm5+L5cBDo466NltB2lplS5GBw==",
"dev": true,
"funding": [
{
@@ -213,9 +151,9 @@
}
},
"node_modules/@csstools/media-query-list-parser": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-5.0.0.tgz",
- "integrity": "sha512-T9lXmZOfnam3eMERPsszjY5NK0jX8RmThmmm99FZ8b7z8yMaFZWKwLWGZuTwdO3ddRY5fy13GmmEYZXB4I98Eg==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-5.0.2.tgz",
+ "integrity": "sha512-qx19O8AbbLLbDSAcI6YOby/Vq8rV51psgIvlF5OZT/L8fQJDCyQifL6k+kYU4a8ySpzJ4RBzZkIs530bAn8y4Q==",
"dev": true,
"funding": [
{
@@ -232,14 +170,14 @@
"node": ">=20.19.0"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^4.0.0",
- "@csstools/css-tokenizer": "^4.0.0"
+ "@csstools/css-parser-algorithms": "^4.0.2",
+ "@csstools/css-tokenizer": "^4.0.2"
}
},
"node_modules/@csstools/selector-resolve-nested": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-4.0.0.tgz",
- "integrity": "sha512-9vAPxmp+Dx3wQBIUwc1v7Mdisw1kbbaGqXUM8QLTgWg7SoPGYtXBsMXvsFs/0Bn5yoFhcktzxNZGNaUt0VjgjA==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-4.0.2.tgz",
+ "integrity": "sha512-JpjNBJFA+4OnAHKRK4AMp8xrYyLhI9XapOeBlP2PhRU/IylSw+1ep3BFNTksBJnrTS3KT6kqKNVfpzLLwZUW5Q==",
"dev": true,
"funding": [
{
@@ -260,9 +198,9 @@
}
},
"node_modules/@csstools/selector-specificity": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-6.0.0.tgz",
- "integrity": "sha512-4sSgl78OtOXEX/2d++8A83zHNTgwCJMaR24FvsYL7Uf/VS8HZk9PTwR51elTbGqMuwH3szLvvOXEaVnqn0Z3zA==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-6.0.1.tgz",
+ "integrity": "sha512-MBuqFIIvqk4S593MGAskTkPpEUUzZNvGzh8mMxEwl3oHwjQlXmqHEDxNbN3Y0Tsh+xjmem4GZjeg7I0qkwBivg==",
"dev": true,
"funding": [
{
@@ -283,9 +221,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
- "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz",
+ "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==",
"cpu": [
"ppc64"
],
@@ -300,9 +238,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
- "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz",
+ "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==",
"cpu": [
"arm"
],
@@ -317,9 +255,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
- "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz",
+ "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==",
"cpu": [
"arm64"
],
@@ -334,9 +272,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
- "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz",
+ "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==",
"cpu": [
"x64"
],
@@ -351,9 +289,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
- "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz",
+ "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==",
"cpu": [
"arm64"
],
@@ -368,9 +306,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
- "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz",
+ "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==",
"cpu": [
"x64"
],
@@ -385,9 +323,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
- "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz",
+ "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==",
"cpu": [
"arm64"
],
@@ -402,9 +340,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
- "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz",
+ "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==",
"cpu": [
"x64"
],
@@ -419,9 +357,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
- "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz",
+ "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==",
"cpu": [
"arm"
],
@@ -436,9 +374,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
- "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz",
+ "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==",
"cpu": [
"arm64"
],
@@ -453,9 +391,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
- "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz",
+ "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==",
"cpu": [
"ia32"
],
@@ -470,9 +408,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
- "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz",
+ "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==",
"cpu": [
"loong64"
],
@@ -487,9 +425,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
- "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz",
+ "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==",
"cpu": [
"mips64el"
],
@@ -504,9 +442,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
- "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz",
+ "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==",
"cpu": [
"ppc64"
],
@@ -521,9 +459,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
- "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz",
+ "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==",
"cpu": [
"riscv64"
],
@@ -538,9 +476,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
- "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz",
+ "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==",
"cpu": [
"s390x"
],
@@ -555,9 +493,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
- "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz",
+ "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==",
"cpu": [
"x64"
],
@@ -572,9 +510,9 @@
}
},
"node_modules/@esbuild/netbsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
- "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz",
+ "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==",
"cpu": [
"arm64"
],
@@ -589,9 +527,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
- "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz",
+ "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==",
"cpu": [
"x64"
],
@@ -606,9 +544,9 @@
}
},
"node_modules/@esbuild/openbsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
- "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz",
+ "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==",
"cpu": [
"arm64"
],
@@ -623,9 +561,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
- "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz",
+ "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==",
"cpu": [
"x64"
],
@@ -640,9 +578,9 @@
}
},
"node_modules/@esbuild/openharmony-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
- "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz",
+ "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==",
"cpu": [
"arm64"
],
@@ -657,9 +595,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
- "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz",
+ "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==",
"cpu": [
"x64"
],
@@ -674,9 +612,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
- "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz",
+ "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==",
"cpu": [
"arm64"
],
@@ -691,9 +629,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
- "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz",
+ "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==",
"cpu": [
"ia32"
],
@@ -708,9 +646,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
- "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz",
+ "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==",
"cpu": [
"x64"
],
@@ -725,9 +663,9 @@
}
},
"node_modules/@eslint-community/eslint-utils": {
- "version": "4.9.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
- "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz",
+ "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -782,9 +720,9 @@
}
},
"node_modules/@eslint/config-helpers": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz",
- "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==",
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.7.0.tgz",
+ "integrity": "sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -839,9 +777,9 @@
}
},
"node_modules/@eslint/plugin-kit": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz",
- "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==",
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.3.tgz",
+ "integrity": "sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -918,6 +856,23 @@
"url": "https://github.com/sponsors/nzakas"
}
},
+ "node_modules/@keyv/bigmap": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.1.tgz",
+ "integrity": "sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hashery": "^1.4.0",
+ "hookified": "^1.15.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "keyv": "^5.6.0"
+ }
+ },
"node_modules/@keyv/serialize": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz",
@@ -925,57 +880,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@sindresorhus/merge-streams": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
- "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/@stylistic/eslint-plugin": {
"version": "5.10.0",
"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz",
@@ -1005,9 +909,9 @@
"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==",
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.10.tgz",
+ "integrity": "sha512-lTyOMnOcmRBzdCv6/4zUZCrEhV0xrqQiUZBZtVcbmLHBXKLnN8q89v/wKRF/Q0HbwVsqbIG3o5HDoFl9sduM+g==",
"dev": true,
"license": "MIT"
},
@@ -1019,9 +923,9 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/types": {
- "version": "8.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.0.tgz",
- "integrity": "sha512-KvAclkktORPvM54TgLgA4z9HIV1M8zOgw9ZVNXl9f/8dLYfXYX1wkMXP7qmabpijQRV5bHJLOmoyGQbLMaUYeg==",
+ "version": "8.72.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.72.1.tgz",
+ "integrity": "sha512-LmE5IhQet1BWOWEXqBrVtBPsMAOQ6Nzk35d+WLh3mk4EUF33sqlfxjio1MdYeSvKSG5skactKKuixBIKXhL4Rw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1039,9 +943,9 @@
"license": "MIT"
},
"node_modules/acorn": {
- "version": "8.17.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz",
- "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz",
+ "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==",
"dev": true,
"license": "MIT",
"bin": {
@@ -1078,51 +982,22 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
- "node_modules/ansi-regex": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
- "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
- }
- },
- "node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
"node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-3.0.4.tgz",
+ "integrity": "sha512-fwWK3Zq22l4XJJjx5mcBHGikIk+hJqO+32dPm0Jur7+rtG5x1scOjSfdT9ZKeWHPpsya/l0HHK4tDImBkTrtvA==",
"dev": true,
- "license": "Python-2.0"
- },
- "node_modules/astral-regex": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
- "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/puzrin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/nodeca"
+ }
+ ],
+ "license": "PSF-2.0"
},
"node_modules/balanced-match": {
"version": "4.0.4",
@@ -1135,29 +1010,16 @@
}
},
"node_modules/brace-expansion": {
- "version": "5.0.7",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz",
- "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==",
+ "version": "5.0.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
+ "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^4.0.2"
},
"engines": {
- "node": "18 || 20 || >=22"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
+ "node": "20 || >=22"
}
},
"node_modules/cacheable": {
@@ -1174,78 +1036,28 @@
"qified": "^0.10.1"
}
},
- "node_modules/cacheable/node_modules/keyv": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz",
- "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@keyv/serialize": "^1.1.1"
- }
- },
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/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/colord": {
- "version": "2.9.3",
- "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
- "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/colord/-/colord-2.10.0.tgz",
+ "integrity": "sha512-AidJptpBJmjTclAp9BkLwJi0T93fo5epJnbaZslpg6QVzpHjAiveF55mE9AcUJiGMqRHgMDY8soMsQtuNYMHfw==",
"dev": true,
"license": "MIT"
},
"node_modules/cosmiconfig": {
- "version": "9.0.2",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.2.tgz",
- "integrity": "sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==",
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-10.0.1.tgz",
+ "integrity": "sha512-/zvGoYn0y27QTBmK+0B+oPdEPC4fKGUmJsMTQbDjqph00TrkqfVFW/M+C6ya54sYCgHC6QCwK/mI6djt8cEGHQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"env-paths": "^2.2.1",
- "import-fresh": "^3.3.0",
- "js-yaml": "^4.1.0",
- "parse-json": "^5.2.0"
+ "js-yaml": "^5.4.1"
},
"engines": {
- "node": ">=14"
+ "node": "^22.18 || >= 24"
},
"funding": {
"url": "https://github.com/sponsors/d-fischer"
- },
- "peerDependencies": {
- "typescript": ">=4.9.5"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
}
},
"node_modules/cross-spawn": {
@@ -1263,16 +1075,6 @@
"node": ">= 8"
}
},
- "node_modules/css-functions-list": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.3.3.tgz",
- "integrity": "sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/css-tree": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
@@ -1335,13 +1137,6 @@
"node": ">=8"
}
},
- "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/env-paths": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
@@ -1352,20 +1147,10 @@
"node": ">=6"
}
},
- "node_modules/error-ex": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz",
- "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-arrayish": "^0.2.1"
- }
- },
"node_modules/esbuild": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
- "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz",
+ "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -1376,32 +1161,32 @@
"node": ">=18"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.28.1",
- "@esbuild/android-arm": "0.28.1",
- "@esbuild/android-arm64": "0.28.1",
- "@esbuild/android-x64": "0.28.1",
- "@esbuild/darwin-arm64": "0.28.1",
- "@esbuild/darwin-x64": "0.28.1",
- "@esbuild/freebsd-arm64": "0.28.1",
- "@esbuild/freebsd-x64": "0.28.1",
- "@esbuild/linux-arm": "0.28.1",
- "@esbuild/linux-arm64": "0.28.1",
- "@esbuild/linux-ia32": "0.28.1",
- "@esbuild/linux-loong64": "0.28.1",
- "@esbuild/linux-mips64el": "0.28.1",
- "@esbuild/linux-ppc64": "0.28.1",
- "@esbuild/linux-riscv64": "0.28.1",
- "@esbuild/linux-s390x": "0.28.1",
- "@esbuild/linux-x64": "0.28.1",
- "@esbuild/netbsd-arm64": "0.28.1",
- "@esbuild/netbsd-x64": "0.28.1",
- "@esbuild/openbsd-arm64": "0.28.1",
- "@esbuild/openbsd-x64": "0.28.1",
- "@esbuild/openharmony-arm64": "0.28.1",
- "@esbuild/sunos-x64": "0.28.1",
- "@esbuild/win32-arm64": "0.28.1",
- "@esbuild/win32-ia32": "0.28.1",
- "@esbuild/win32-x64": "0.28.1"
+ "@esbuild/aix-ppc64": "0.28.2",
+ "@esbuild/android-arm": "0.28.2",
+ "@esbuild/android-arm64": "0.28.2",
+ "@esbuild/android-x64": "0.28.2",
+ "@esbuild/darwin-arm64": "0.28.2",
+ "@esbuild/darwin-x64": "0.28.2",
+ "@esbuild/freebsd-arm64": "0.28.2",
+ "@esbuild/freebsd-x64": "0.28.2",
+ "@esbuild/linux-arm": "0.28.2",
+ "@esbuild/linux-arm64": "0.28.2",
+ "@esbuild/linux-ia32": "0.28.2",
+ "@esbuild/linux-loong64": "0.28.2",
+ "@esbuild/linux-mips64el": "0.28.2",
+ "@esbuild/linux-ppc64": "0.28.2",
+ "@esbuild/linux-riscv64": "0.28.2",
+ "@esbuild/linux-s390x": "0.28.2",
+ "@esbuild/linux-x64": "0.28.2",
+ "@esbuild/netbsd-arm64": "0.28.2",
+ "@esbuild/netbsd-x64": "0.28.2",
+ "@esbuild/openbsd-arm64": "0.28.2",
+ "@esbuild/openbsd-x64": "0.28.2",
+ "@esbuild/openharmony-arm64": "0.28.2",
+ "@esbuild/sunos-x64": "0.28.2",
+ "@esbuild/win32-arm64": "0.28.2",
+ "@esbuild/win32-ia32": "0.28.2",
+ "@esbuild/win32-x64": "0.28.2"
}
},
"node_modules/escape-string-regexp": {
@@ -1418,9 +1203,9 @@
}
},
"node_modules/eslint": {
- "version": "10.6.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.6.0.tgz",
- "integrity": "sha512-6lVbcqSodALYo+4ELD0heG6lFiFxnLMuLkiMi2qV8LMp54N8tE8FT1GMH+ev4Ti00nFjNze2+Su6DsV5OQW3Dg==",
+ "version": "10.14.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.14.0.tgz",
+ "integrity": "sha512-T0pNsxkb9IKmtQjhpK3d7nWOpFv+YHuMbTJnSVMoQblF0onvXfErrtp4V1jHtsQPan7dKaGVD0q1WCXnzMF31A==",
"dev": true,
"license": "MIT",
"workspaces": [
@@ -1430,10 +1215,10 @@
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.2",
"@eslint/config-array": "^0.23.5",
- "@eslint/config-helpers": "^0.6.0",
+ "@eslint/config-helpers": "^0.7.0",
"@eslint/core": "^1.2.1",
- "@eslint/plugin-kit": "^0.7.2",
- "@humanfs/node": "^0.16.6",
+ "@eslint/plugin-kit": "^0.7.3",
+ "@humanfs/node": "^0.16.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.2",
"@types/estree": "^1.0.6",
@@ -1447,14 +1232,14 @@
"esquery": "^1.7.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^8.0.0",
+ "file-entry-cache": "11.1.5 || >11.1.6 <12",
"find-up": "^5.0.0",
"glob-parent": "^6.0.2",
"ignore": "^5.2.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
- "minimatch": "^10.2.4",
+ "minimatch": "^10.2.6",
"natural-compare": "^1.4.0",
"optionator": "^0.9.3"
},
@@ -1610,36 +1395,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/fast-glob": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
- "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.8"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/fast-glob/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -1654,67 +1409,32 @@
"dev": true,
"license": "MIT"
},
- "node_modules/fast-uri": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz",
- "integrity": "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "BSD-3-Clause"
- },
- "node_modules/fastest-levenshtein": {
- "version": "1.0.16",
- "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
- "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+ "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": ">= 4.9.1"
- }
- },
- "node_modules/fastq": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
- "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "reusify": "^1.0.4"
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
}
},
"node_modules/file-entry-cache": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
- "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "version": "11.1.5",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.5.tgz",
+ "integrity": "sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "flat-cache": "^4.0.0"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
+ "flat-cache": "^6.1.23"
}
},
"node_modules/find-up": {
@@ -1735,39 +1455,24 @@
}
},
"node_modules/flat-cache": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
- "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "version": "6.1.23",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.23.tgz",
+ "integrity": "sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "flatted": "^3.2.9",
- "keyv": "^4.5.4"
- },
- "engines": {
- "node": ">=16"
+ "cacheable": "^2.5.0",
+ "flatted": "^3.4.2",
+ "hookified": "^1.15.0"
}
},
"node_modules/flatted": {
- "version": "3.4.2",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
- "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz",
+ "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==",
"dev": true,
"license": "ISC"
},
- "node_modules/get-east-asian-width": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
- "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -1781,51 +1486,10 @@
"node": ">=10.13.0"
}
},
- "node_modules/global-modules": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
- "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "global-prefix": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/global-prefix": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
- "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ini": "^1.3.5",
- "kind-of": "^6.0.2",
- "which": "^1.3.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/global-prefix/node_modules/which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "which": "bin/which"
- }
- },
"node_modules/globals": {
- "version": "17.7.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-17.7.0.tgz",
- "integrity": "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==",
+ "version": "17.14.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-17.14.0.tgz",
+ "integrity": "sha512-UtdkTVyAJePQv0J2M9Xe4L0ruNSDV314XiIJsADI2Zf40bcdAonE/D/OhAU8AT99oij9mhLByb+NvA3QWZYgCg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1835,57 +1499,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/globby": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-16.2.0.tgz",
- "integrity": "sha512-QrJia2qDf5BB/V6HYlDTs0I0lBahyjLzpGQg3KT7FnCdTonAyPy2RtY802m2k4ALx6Dp752f82WsOczEVr3l6Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sindresorhus/merge-streams": "^4.0.0",
- "fast-glob": "^3.3.3",
- "ignore": "^7.0.5",
- "is-path-inside": "^4.0.0",
- "slash": "^5.1.0",
- "unicorn-magic": "^0.4.0"
- },
- "engines": {
- "node": ">=20"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/globby/node_modules/ignore": {
- "version": "7.0.5",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
- "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/globjoin": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
- "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/has-flag": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz",
- "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/hashery": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz",
@@ -1906,19 +1519,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/html-tags": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-5.1.0.tgz",
- "integrity": "sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=20.10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -1929,23 +1529,6 @@
"node": ">= 4"
}
},
- "node_modules/import-fresh": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
- "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/import-meta-resolve": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz",
@@ -1967,20 +1550,6 @@
"node": ">=0.8.19"
}
},
- "node_modules/ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/is-arrayish": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -1991,16 +1560,6 @@
"node": ">=0.10.0"
}
},
- "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-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@@ -2014,29 +1573,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/is-path-inside": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz",
- "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -2044,17 +1580,10 @@
"dev": true,
"license": "ISC"
},
- "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==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/js-yaml": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
- "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==",
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.5.0.tgz",
+ "integrity": "sha512-paNr4LFIFPjeeSmwNYdrb8FafLLG/Cr2Af3GjbsHJ5CxIjH4r0c2emlmRdAtpPAieP1gRVzk6buBbVP5gBMGAg==",
"dev": true,
"funding": [
{
@@ -2068,26 +1597,12 @@
],
"license": "MIT",
"dependencies": {
- "argparse": "^2.0.1"
+ "argparse": "^3.0.3"
},
"bin": {
- "js-yaml": "bin/js-yaml.js"
+ "js-yaml": "bin/js-yaml.mjs"
}
},
- "node_modules/json-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
- "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json-parse-even-better-errors": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
- "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -2103,23 +1618,13 @@
"license": "MIT"
},
"node_modules/keyv": {
- "version": "4.5.4",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
- "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz",
+ "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "json-buffer": "3.0.1"
- }
- },
- "node_modules/kind-of": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
- "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
+ "@keyv/serialize": "^1.1.1"
}
},
"node_modules/levn": {
@@ -2137,9 +1642,9 @@
}
},
"node_modules/lightningcss": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
- "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz",
+ "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==",
"dev": true,
"license": "MPL-2.0",
"dependencies": {
@@ -2153,23 +1658,23 @@
"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"
+ "lightningcss-android-arm64": "1.33.0",
+ "lightningcss-darwin-arm64": "1.33.0",
+ "lightningcss-darwin-x64": "1.33.0",
+ "lightningcss-freebsd-x64": "1.33.0",
+ "lightningcss-linux-arm-gnueabihf": "1.33.0",
+ "lightningcss-linux-arm64-gnu": "1.33.0",
+ "lightningcss-linux-arm64-musl": "1.33.0",
+ "lightningcss-linux-x64-gnu": "1.33.0",
+ "lightningcss-linux-x64-musl": "1.33.0",
+ "lightningcss-win32-arm64-msvc": "1.33.0",
+ "lightningcss-win32-x64-msvc": "1.33.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==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz",
+ "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==",
"cpu": [
"arm64"
],
@@ -2188,9 +1693,9 @@
}
},
"node_modules/lightningcss-cli": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-cli/-/lightningcss-cli-1.32.0.tgz",
- "integrity": "sha512-IFb/ChmSEbeWU3xeRybR6WFlJXCvfDS84//PUzLrRACgvoWrwRJBmcPS9azSo7LMh5QqEuyKanPBByhKM5z01Q==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-cli/-/lightningcss-cli-1.33.0.tgz",
+ "integrity": "sha512-/tBcBZlBFFxy1iYKDC/HSH/NEjv7Frq6dmDVKRbhGJQI/gFJIJ1/4ZXclxJkd0eEjBjDc5MY0YugHcvJVVGJVg==",
"dev": true,
"hasInstallScript": true,
"license": "MPL-2.0",
@@ -2208,23 +1713,23 @@
"url": "https://opencollective.com/parcel"
},
"optionalDependencies": {
- "lightningcss-cli-android-arm64": "1.32.0",
- "lightningcss-cli-darwin-arm64": "1.32.0",
- "lightningcss-cli-darwin-x64": "1.32.0",
- "lightningcss-cli-freebsd-x64": "1.32.0",
- "lightningcss-cli-linux-arm-gnueabihf": "1.32.0",
- "lightningcss-cli-linux-arm64-gnu": "1.32.0",
- "lightningcss-cli-linux-arm64-musl": "1.32.0",
- "lightningcss-cli-linux-x64-gnu": "1.32.0",
- "lightningcss-cli-linux-x64-musl": "1.32.0",
- "lightningcss-cli-win32-arm64-msvc": "1.32.0",
- "lightningcss-cli-win32-x64-msvc": "1.32.0"
+ "lightningcss-cli-android-arm64": "1.33.0",
+ "lightningcss-cli-darwin-arm64": "1.33.0",
+ "lightningcss-cli-darwin-x64": "1.33.0",
+ "lightningcss-cli-freebsd-x64": "1.33.0",
+ "lightningcss-cli-linux-arm-gnueabihf": "1.33.0",
+ "lightningcss-cli-linux-arm64-gnu": "1.33.0",
+ "lightningcss-cli-linux-arm64-musl": "1.33.0",
+ "lightningcss-cli-linux-x64-gnu": "1.33.0",
+ "lightningcss-cli-linux-x64-musl": "1.33.0",
+ "lightningcss-cli-win32-arm64-msvc": "1.33.0",
+ "lightningcss-cli-win32-x64-msvc": "1.33.0"
}
},
"node_modules/lightningcss-cli-android-arm64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-cli-android-arm64/-/lightningcss-cli-android-arm64-1.32.0.tgz",
- "integrity": "sha512-4O3QY+VdgpBZLIq4crcKOEPVAXX0p7zDoykuTVstRtyolg9XU8CntdtbxcMPSC4SkzAuM/W4KsnPAzmv6Jb5LA==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-cli-android-arm64/-/lightningcss-cli-android-arm64-1.33.0.tgz",
+ "integrity": "sha512-c0Xd7Gxaw3mNOyrb9ET1JH3JjuB69GY/6pHO4vgwEbIoHCXAt6DBg6kxr5t/oZL9LRxdnZCXF+o0Evz6kuR/xA==",
"cpu": [
"arm64"
],
@@ -2243,9 +1748,9 @@
}
},
"node_modules/lightningcss-cli-darwin-arm64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-cli-darwin-arm64/-/lightningcss-cli-darwin-arm64-1.32.0.tgz",
- "integrity": "sha512-Xx+zeD7bDKJZwbd1N63TJfIUHEtYspf+tqObdnQEJEvZAwmGfA4iEGrkCRT8R57tDRBDSXg3XHMDDvo/cq7gBQ==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-cli-darwin-arm64/-/lightningcss-cli-darwin-arm64-1.33.0.tgz",
+ "integrity": "sha512-sso5hSFPis7ldw2FcBopsZviSVAXWRGX8ybUwMhQHssTlERenQJ88WihZs08tCdSnQULo2kunnrGhh4VjRw8Fg==",
"cpu": [
"arm64"
],
@@ -2264,9 +1769,9 @@
}
},
"node_modules/lightningcss-cli-darwin-x64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-cli-darwin-x64/-/lightningcss-cli-darwin-x64-1.32.0.tgz",
- "integrity": "sha512-fYWANZ8RJDpI0tBcPQ7oBOYihfXmgDBHR4lZ6d4z7rcRLlZAOeI00mTO0IXAKfSm/UgnatjM4aBuNlLh8L9noA==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-cli-darwin-x64/-/lightningcss-cli-darwin-x64-1.33.0.tgz",
+ "integrity": "sha512-/aDYpMv2QKpJoSIwvwpIs4tIX9SCU894eospSm55FR5MxDZkJDy4fEX6elsXkHCBDqbAknb4qd2h/oDMLTC4Ew==",
"cpu": [
"x64"
],
@@ -2285,9 +1790,9 @@
}
},
"node_modules/lightningcss-cli-freebsd-x64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-cli-freebsd-x64/-/lightningcss-cli-freebsd-x64-1.32.0.tgz",
- "integrity": "sha512-TJm7z1Ghvo9FKAza2KvfkFgH/9rcV1xAhCYQZlLrV0CiuTZ17uzLobBWb9oelGWUG+wTnEs6XEl4h/ve61YySg==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-cli-freebsd-x64/-/lightningcss-cli-freebsd-x64-1.33.0.tgz",
+ "integrity": "sha512-kK9u4IEAvt3+1m7lkloyfZNfXykXq2vCH7lgZ5aEqa8VuBZYqvcAIQ4Qt1593QJxbko9HEKUP0erdSxw7k7eFw==",
"cpu": [
"x64"
],
@@ -2306,9 +1811,9 @@
}
},
"node_modules/lightningcss-cli-linux-arm-gnueabihf": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-cli-linux-arm-gnueabihf/-/lightningcss-cli-linux-arm-gnueabihf-1.32.0.tgz",
- "integrity": "sha512-/jS9L5p3eexs5QJvARiDGxibz1umKJmmtff86fWXl3r7RbEUFrMAD4q1WhAR7DurRFgc1YWld6r0mX1YHEYttA==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-cli-linux-arm-gnueabihf/-/lightningcss-cli-linux-arm-gnueabihf-1.33.0.tgz",
+ "integrity": "sha512-4bHmUlYCb8WKdPKx2yhk8y/kD034JVuUatDMWav0uU/hEIYJrxPimWBJJ4w2lgpcWchVnk/Kuihs4vaLjO/ozw==",
"cpu": [
"arm"
],
@@ -2327,9 +1832,9 @@
}
},
"node_modules/lightningcss-cli-linux-arm64-gnu": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-cli-linux-arm64-gnu/-/lightningcss-cli-linux-arm64-gnu-1.32.0.tgz",
- "integrity": "sha512-PSdjwcRtSrJpsaqnY3ebnCfDOJ5ePi8s/0ItL3CX1b1Eu0iy44xo7MjgES1ZOQ2ntOthPRqaGsbAiVBLbgFLYQ==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-cli-linux-arm64-gnu/-/lightningcss-cli-linux-arm64-gnu-1.33.0.tgz",
+ "integrity": "sha512-DkYmkBix3icAZKZsxGsjBAj59CIV0zflZtsT66lCPd2z3OqBLJlhKRrw4TlAW7mIkYeOEYWKVz/G00ZGXNse4A==",
"cpu": [
"arm64"
],
@@ -2351,9 +1856,9 @@
}
},
"node_modules/lightningcss-cli-linux-arm64-musl": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-cli-linux-arm64-musl/-/lightningcss-cli-linux-arm64-musl-1.32.0.tgz",
- "integrity": "sha512-t6DdpXFtEdonZHzRgH8cmqhC2o4tl0KrD33cDBBniJz5TmWS20MJxb4YEr4WqBLksqW8GE399HJo+g8/YVuKcA==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-cli-linux-arm64-musl/-/lightningcss-cli-linux-arm64-musl-1.33.0.tgz",
+ "integrity": "sha512-euNOhzo1ysRl719HfFzRe9r9usWO2Z/Nb8RnmqXxb/kvzOgAv2BcflpoTu6tWhSrbHX6YS/WP6mMFrmII6T7Hw==",
"cpu": [
"arm64"
],
@@ -2375,9 +1880,9 @@
}
},
"node_modules/lightningcss-cli-linux-x64-gnu": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-cli-linux-x64-gnu/-/lightningcss-cli-linux-x64-gnu-1.32.0.tgz",
- "integrity": "sha512-QMQllbHYkbkQ4N+v8OGExQlGHBc3YZIcKlVkYucQQj66thkFQsRjmv8p5q3iCB0inNsCoSZ8lBspugkU1iPlPg==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-cli-linux-x64-gnu/-/lightningcss-cli-linux-x64-gnu-1.33.0.tgz",
+ "integrity": "sha512-9Q4DAglm17bLhA+HZPB+vxjrHXdhR/8U44zyc8MQNA5Rw+tisvcoR/lv4iuBUFn2qreYVRWQq0wP0rgdhTSxyQ==",
"cpu": [
"x64"
],
@@ -2399,9 +1904,9 @@
}
},
"node_modules/lightningcss-cli-linux-x64-musl": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-cli-linux-x64-musl/-/lightningcss-cli-linux-x64-musl-1.32.0.tgz",
- "integrity": "sha512-dMSWdk4kMAi5f+J1xetxRCDQOvPix2whT0UdjuwP8r/5Xcdl2SQU/c80MQzu1S82kVDEANs1vHVEHp/+26LUnA==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-cli-linux-x64-musl/-/lightningcss-cli-linux-x64-musl-1.33.0.tgz",
+ "integrity": "sha512-+EobHdqxQ21SUMF8OU0qcizNIrLpPDaPTKQCaGbra9gL3NrW3ELG+exZl5y+WzJsEjLZ0hhjbCFjHUL/03H2JA==",
"cpu": [
"x64"
],
@@ -2423,9 +1928,9 @@
}
},
"node_modules/lightningcss-cli-win32-arm64-msvc": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-cli-win32-arm64-msvc/-/lightningcss-cli-win32-arm64-msvc-1.32.0.tgz",
- "integrity": "sha512-MJo22OqSp9FLV10nTRDJQhP6zkEBFqBFQe9mnjfCs+G1Ft+QimIPmC+gBqZHFXveOBOsjFLzU72q0FPvRWFmZQ==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-cli-win32-arm64-msvc/-/lightningcss-cli-win32-arm64-msvc-1.33.0.tgz",
+ "integrity": "sha512-iwQ+8rHQy3ewC4c43Ik3UZ8TCC/rjShP3r/8TOPw4fT8wQmW7dS3BNNHPK+LWz9qNrObATJ4MZEEZVRneckOBw==",
"cpu": [
"arm64"
],
@@ -2444,9 +1949,9 @@
}
},
"node_modules/lightningcss-cli-win32-x64-msvc": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-cli-win32-x64-msvc/-/lightningcss-cli-win32-x64-msvc-1.32.0.tgz",
- "integrity": "sha512-nOBHLPeePXZpGR4Ptp+gkOIkr9pxlq2dFmO954ol5zBi/iOKxuD1hUTIQ7aG+ldKIx4eH9jwoTfZ6owUkm1paA==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-cli-win32-x64-msvc/-/lightningcss-cli-win32-x64-msvc-1.33.0.tgz",
+ "integrity": "sha512-sgtNPw2gxnY8OzCCMTKCkHSIiBYb/wfXLpLMmDIJFzcX2OETY+VOnQd7OBHx+hVSlrMU7iWL6oJ5rc+nQwteVA==",
"cpu": [
"x64"
],
@@ -2465,9 +1970,9 @@
}
},
"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==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz",
+ "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==",
"cpu": [
"arm64"
],
@@ -2486,9 +1991,9 @@
}
},
"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==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz",
+ "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==",
"cpu": [
"x64"
],
@@ -2507,9 +2012,9 @@
}
},
"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==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz",
+ "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==",
"cpu": [
"x64"
],
@@ -2528,9 +2033,9 @@
}
},
"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==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz",
+ "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==",
"cpu": [
"arm"
],
@@ -2549,9 +2054,9 @@
}
},
"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==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz",
+ "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==",
"cpu": [
"arm64"
],
@@ -2573,9 +2078,9 @@
}
},
"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==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz",
+ "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==",
"cpu": [
"arm64"
],
@@ -2597,9 +2102,9 @@
}
},
"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==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz",
+ "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==",
"cpu": [
"x64"
],
@@ -2621,9 +2126,9 @@
}
},
"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==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz",
+ "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==",
"cpu": [
"x64"
],
@@ -2645,9 +2150,9 @@
}
},
"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==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz",
+ "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==",
"cpu": [
"arm64"
],
@@ -2666,9 +2171,9 @@
}
},
"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==",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz",
+ "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==",
"cpu": [
"x64"
],
@@ -2686,13 +2191,6 @@
"url": "https://opencollective.com/parcel"
}
},
- "node_modules/lines-and-columns": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -2709,24 +2207,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/lodash.truncate": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
- "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/mathml-tag-names": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-4.0.0.tgz",
- "integrity": "sha512-aa6AU2Pcx0VP/XWnh8IGL0SYSgQHDT6Ucror2j2mXeFAlN3ahaNs8EZtG1YiticMkSLj3Gt6VPFfZogt7G5iFQ==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/mdn-data": {
"version": "2.27.1",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
@@ -2734,64 +2214,14 @@
"dev": true,
"license": "CC0-1.0"
},
- "node_modules/meow": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/meow/-/meow-14.1.0.tgz",
- "integrity": "sha512-EDYo6VlmtnumlcBCbh1gLJ//9jvM/ndXHfVXIFrZVr6fGcwTUyCTFNTLCKuY3ffbK8L/+3Mzqnd58RojiZqHVw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=20"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/micromatch/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/minimatch": {
- "version": "10.2.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
- "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
+ "version": "10.2.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz",
+ "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
- "brace-expansion": "^5.0.5"
+ "brace-expansion": "^5.0.8"
},
"engines": {
"node": "18 || 20 || >=22"
@@ -2808,9 +2238,9 @@
"license": "MIT"
},
"node_modules/nanoid": {
- "version": "3.3.15",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz",
- "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==",
+ "version": "3.3.20",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz",
+ "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==",
"dev": true,
"funding": [
{
@@ -2833,16 +2263,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -2893,38 +2313,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/parent-module": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
- "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "callsites": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/parse-json": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
- "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.0.0",
- "error-ex": "^1.3.1",
- "json-parse-even-better-errors": "^2.3.0",
- "lines-and-columns": "^1.1.6"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -2953,9 +2341,9 @@
"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==",
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
+ "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2966,9 +2354,9 @@
}
},
"node_modules/postcss": {
- "version": "8.5.16",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz",
- "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==",
+ "version": "8.5.32",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.32.tgz",
+ "integrity": "sha512-LJlKCCAUFKOuZxipUdYw1NzIITEsPcgyOG9LkvRJvuKj/bRzbuRY0ARXvL0pWGpsZvn8jku+LMep2eU0seHp8g==",
"dev": true,
"funding": [
{
@@ -2986,18 +2374,18 @@
],
"license": "MIT",
"dependencies": {
- "nanoid": "^3.3.12",
+ "nanoid": "^3.3.20",
"picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
+ "source-map-js": "^1.2.2"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/postcss-safe-parser": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz",
- "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.1.0.tgz",
+ "integrity": "sha512-1WzZxRLaAFwEh6Do+zyGpjWV3nGJNxxhuh7Ubu/q1ICImMgZJnLwhoaEpRbG4pJppp2Y1ncL9ffA2f+LhrefQg==",
"dev": true,
"funding": [
{
@@ -3022,9 +2410,9 @@
}
},
"node_modules/postcss-selector-parser": {
- "version": "7.1.4",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz",
- "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==",
+ "version": "7.1.7",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.7.tgz",
+ "integrity": "sha512-wWBro/7hJ40ye6TPiXkUQoXKCw23xSsjriUvqd7Uls9Sso3oLiON1flc18cCdnjgCRXw4fBVqUJJeOdDTh3P3g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3082,82 +2470,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/require-from-string": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
- "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/resolve-from": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
- "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/reusify": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
- "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -3194,84 +2506,20 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/slash": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
- "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/slice-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
- "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "astral-regex": "^2.0.0",
- "is-fullwidth-code-point": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/slice-ansi?sponsor=1"
- }
- },
"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==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz",
+ "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/string-width": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz",
- "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "get-east-asian-width": "^1.5.0",
- "strip-ansi": "^7.1.2"
- },
- "engines": {
- "node": ">=20"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/strip-ansi": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
- "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^6.2.2"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
- }
- },
"node_modules/stylelint": {
- "version": "17.14.0",
- "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-17.14.0.tgz",
- "integrity": "sha512-8xkHPpdqYryeIsOgfsYTmr6cIeC4nLYWk5S8BPxpodq8mIuepggkMljsHewWfuAjj/+qpRKou2QerhjMH3iasg==",
+ "version": "18.0.0",
+ "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-18.0.0.tgz",
+ "integrity": "sha512-kI10GsHXQvsH/AcklVZdQgwDuxtHi+A+h1Ujzd7h9LDf3e5jQiLQkWFlPtpynX3E6oVWHG1wo9v6dL0Mr+nnSA==",
"dev": true,
"funding": [
{
@@ -3285,53 +2533,37 @@
],
"license": "MIT",
"dependencies": {
- "@csstools/css-calc": "^3.2.1",
- "@csstools/css-parser-algorithms": "^4.0.0",
- "@csstools/css-syntax-patches-for-csstree": "^1.1.5",
- "@csstools/css-tokenizer": "^4.0.0",
- "@csstools/media-query-list-parser": "^5.0.0",
- "@csstools/selector-resolve-nested": "^4.0.0",
- "@csstools/selector-specificity": "^6.0.0",
- "colord": "^2.9.3",
- "cosmiconfig": "^9.0.2",
- "css-functions-list": "^3.3.3",
+ "@csstools/css-calc": "^3.4.3",
+ "@csstools/css-parser-algorithms": "^4.0.2",
+ "@csstools/css-syntax-patches-for-csstree": "^1.1.15",
+ "@csstools/css-tokenizer": "^4.0.2",
+ "@csstools/media-query-list-parser": "^5.0.2",
+ "@csstools/selector-resolve-nested": "^4.0.2",
+ "@csstools/selector-specificity": "^6.0.1",
+ "colord": "^2.10.0",
+ "cosmiconfig": "^10.0.1",
"css-tree": "^3.2.1",
- "debug": "^4.4.3",
- "fast-glob": "^3.3.3",
- "fastest-levenshtein": "^1.0.16",
- "file-entry-cache": "^11.1.3",
- "global-modules": "^2.0.0",
- "globby": "^16.2.0",
- "globjoin": "^0.1.4",
- "html-tags": "^5.1.0",
- "ignore": "^7.0.5",
+ "ignore": "^7.0.14",
"import-meta-resolve": "^4.2.0",
- "mathml-tag-names": "^4.0.0",
- "meow": "^14.1.0",
- "micromatch": "^4.0.8",
- "normalize-path": "^3.0.0",
- "picocolors": "^1.1.1",
- "postcss": "^8.5.15",
- "postcss-safe-parser": "^7.0.1",
- "postcss-selector-parser": "^7.1.4",
+ "picomatch": "^4.0.7",
+ "postcss": "^8.5.31",
+ "postcss-safe-parser": "^7.1.0",
+ "postcss-selector-parser": "^7.1.7",
"postcss-value-parser": "^4.2.0",
- "string-width": "^8.2.1",
- "supports-hyperlinks": "^4.4.0",
- "svg-tags": "^1.0.0",
- "table": "^6.9.0",
- "write-file-atomic": "^7.0.1"
+ "tinyglobby": "^0.2.17",
+ "write-file-atomic": "^8.0.0"
},
"bin": {
"stylelint": "bin/stylelint.mjs"
},
"engines": {
- "node": ">=20.19.0"
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
}
},
"node_modules/stylelint-config-recommended": {
- "version": "18.0.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-18.0.0.tgz",
- "integrity": "sha512-mxgT2XY6YZ3HWWe3Di8umG6aBmWmHTblTgu/f10rqFXnyWxjKWwNdjSWkgkwCtxIKnqjSJzvFmPT5yabVIRxZg==",
+ "version": "19.0.0",
+ "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-19.0.0.tgz",
+ "integrity": "sha512-Y15XB19RManqBOpbRC42tF8R/Hfe314xYLzedRlnnYxYzZ0777RakDQIGcqYfrz9jWGoVyjaGTdpSl9F+roOOw==",
"dev": true,
"funding": [
{
@@ -3345,16 +2577,16 @@
],
"license": "MIT",
"engines": {
- "node": ">=20.19.0"
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
},
"peerDependencies": {
- "stylelint": "^17.0.0"
+ "stylelint": "^18.0.0"
}
},
"node_modules/stylelint-config-standard": {
- "version": "40.0.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-40.0.0.tgz",
- "integrity": "sha512-EznGJxOUhtWck2r6dJpbgAdPATIzvpLdK9+i5qPd4Lx70es66TkBPljSg4wN3Qnc6c4h2n+WbUrUynQ3fanjHw==",
+ "version": "41.0.0",
+ "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-41.0.0.tgz",
+ "integrity": "sha512-EJIvMOMARieBOLhw2yzN7BaVFiIY2Ex8CkbXahxP6tQZK41+N8OVUo57Uvx9iTr862h+thqDoDH7vQbeth1ryg==",
"dev": true,
"funding": [
{
@@ -3368,173 +2600,40 @@
],
"license": "MIT",
"dependencies": {
- "stylelint-config-recommended": "^18.0.0"
+ "stylelint-config-recommended": "^19.0.0"
},
"engines": {
- "node": ">=20.19.0"
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
},
"peerDependencies": {
- "stylelint": "^17.0.0"
- }
- },
- "node_modules/stylelint/node_modules/file-entry-cache": {
- "version": "11.1.5",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.5.tgz",
- "integrity": "sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "flat-cache": "^6.1.23"
- }
- },
- "node_modules/stylelint/node_modules/flat-cache": {
- "version": "6.1.23",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.23.tgz",
- "integrity": "sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cacheable": "^2.5.0",
- "flatted": "^3.4.2",
- "hookified": "^1.15.0"
+ "stylelint": "^18.0.0"
}
},
"node_modules/stylelint/node_modules/ignore": {
- "version": "7.0.5",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
- "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "version": "7.0.14",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.14.tgz",
+ "integrity": "sha512-wCBiZ77u1tuWde6G/nfOtLaCTYcFDU5yCzARzK10y+rLhzYoL7a7yEemcopcc2Mzow7gZOIjnV2ym1NYmdiJOQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 4"
}
},
- "node_modules/supports-color": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz",
- "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==",
+ "node_modules/tinyglobby": {
+ "version": "0.2.17",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
+ "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.4"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=12.0.0"
},
"funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
- }
- },
- "node_modules/supports-hyperlinks": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-4.5.0.tgz",
- "integrity": "sha512-ZW2OvfeCXrNTbLakPUzjQG922EeGCOteFSVoek5DKStTh898wf7zgtuFlzQN8HfZCxC3Eh02yJVrRW51hADf+w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^5.0.1",
- "supports-color": "^10.2.2"
- },
- "engines": {
- "node": ">=20"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1"
- }
- },
- "node_modules/svg-tags": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
- "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
- "dev": true
- },
- "node_modules/table": {
- "version": "6.9.0",
- "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz",
- "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "ajv": "^8.0.1",
- "lodash.truncate": "^4.4.2",
- "slice-ansi": "^4.0.0",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/table/node_modules/ajv": {
- "version": "8.20.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
- "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.3",
- "fast-uri": "^3.0.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/table/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/table/node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/table/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/table/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/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
+ "url": "https://github.com/sponsors/SuperchupuDev"
}
},
"node_modules/type-check": {
@@ -3550,19 +2649,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/unicorn-magic": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz",
- "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=20"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -3607,16 +2693,16 @@
}
},
"node_modules/write-file-atomic": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-7.0.1.tgz",
- "integrity": "sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-8.0.0.tgz",
+ "integrity": "sha512-dYwyZredl67GyLLIHJnRM3h2PcOmN5SkcgC7eM5DPDEOEl6dLFqVrMg3F1Ea32usj4VSVZtd2H4MtKTNOf6nPg==",
"dev": true,
"license": "ISC",
"dependencies": {
"signal-exit": "^4.0.1"
},
"engines": {
- "node": "^20.17.0 || >=22.9.0"
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
}
},
"node_modules/yocto-queue": {
diff --git a/package.json b/package.json
index b0ac9882..88e61f10 100644
--- a/package.json
+++ b/package.json
@@ -13,8 +13,8 @@
"globals": "^17.3.0",
"lightningcss": "^1.29.3",
"lightningcss-cli": "^1.29.3",
- "stylelint": "^17.3.0",
- "stylelint-config-standard": "^40.0.0"
+ "stylelint": "^18.0.0",
+ "stylelint-config-standard": "^41.0.0"
},
"scripts": {
"eslint": "eslint resources/js/*.js",
@@ -23,7 +23,7 @@
"lightningcss": "lightningcss --output-dir public/assets/css --sourcemap --bundle --minify resources/css/app.css",
"fix-sourcemap": "./scripts/fix-sourcemap.sh",
"build-css": "npm run lightningcss && npm run fix-sourcemap",
- "build-js": "esbuild resources/js/app.js --bundle --minify --sourcemap --outfile=public/assets/js/app.js",
+ "build-js": "esbuild resources/js/app.js resources/js/theme-init.js --bundle --minify --sourcemap --outdir=public/assets/js",
"compress": "./scripts/compress.sh",
"build": "npm run lint && npm run build-css && npm run build-js && npm run compress"
},
diff --git a/public/assets/css/app.css b/public/assets/css/app.css
index 4e2ebd32..06a2b660 100644
--- a/public/assets/css/app.css
+++ b/public/assets/css/app.css
@@ -1,2 +1,2 @@
-@layer reset{*,:before,:after{box-sizing:border-box}html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none}body,h1,h2,h3,h4,p,figure,blockquote,dl,dd{margin-block-end:0}ul[role=list],ol[role=list]{list-style:none}body{line-height:1.5}h1,h2,h3,h4,button,input,label{line-height:1.1}h1,h2,h3,h4{text-wrap:balance}a:not([class]){text-decoration-skip-ink:auto;color:currentColor}img,picture{max-width:100%;height:auto;display:block}input,button,textarea,select{font-family:inherit;font-size:inherit}textarea:not([rows]){min-height:10em}:target{scroll-margin-block:5ex}@media (prefers-reduced-motion){::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}}}@layer base{:root{color-scheme:light dark;--primary-hue:307;--clr-text:light-dark(oklch(5% .1 var(--primary-hue)),oklch(100% .1 var(--primary-hue)));--clr-background:light-dark(oklch(100% .1 var(--primary-hue)),oklch(15% .15 var(--primary-hue)));--clr-border:light-dark(oklch(90% .2 var(--primary-hue)),oklch(25% .1 var(--primary-hue)));--clr-snow-fall:light-dark(oklch(25% .15 var(--primary-hue)),oklch(85% .2 var(--primary-hue)))}body{background-color:var(--clr-background);color:var(--clr-text)}:root{--border-radius:8px}html{font-size:125%}body{grid-template-rows:min-content 1fr min-content;grid-template-columns:1fr min(80ch,80vw) 1fr;padding-inline:4vw;display:grid;&>header{grid-column:1/-1}&>main{grid-column:2/3}&>footer{grid-column:1/-1;margin-block-start:2ex;& search form{flex-direction:row;align-items:center;gap:1ex;display:flex;& input{min-width:0}}}}.h-feed{flex-direction:column;gap:2ex;display:flex}}@layer components{.h-entry{& pre{padding:1rem}}body>header{grid-template-rows:auto auto;grid-template-columns:auto 1fr auto;align-items:baseline;gap:1rem;display:grid;& a{text-decoration:none}& h1{text-wrap:nowrap;margin:0}& nav{flex-direction:row;gap:.5rem;display:flex;@media screen and (width<=1100px){flex-wrap:wrap;grid-area:2/1/auto/span 3}}}.note{border:1px solid var(--clr-border);border-radius:var(--border-radius);flex-direction:column;padding:1ex 2ex;display:flex;& .e-content{&>p:first-child{margin-block-start:0}& .u-photo{width:100%;height:auto}}& .syndication-links{flex-direction:row;gap:1ex;display:flex;& svg{border-radius:4px;width:auto;height:1lh}}}.reply-to{border:1px solid var(--clr-border);border-top-left-radius:var(--border-radius);border-top-right-radius:var(--border-radius);border-bottom:none;margin-inline:2ex;padding-inline:1ex;font-size:85%}.pagination{flex-direction:row;justify-content:center;align-items:center;display:flex;& div{flex-direction:row;gap:1ex;display:flex}}#theme-selector{& button{appearance:none;background:0 0;border:none;&:hover{cursor:pointer}}& #theme-selector-dropdown{position-area:block-end span-inline-start;border:2px solid var(--clr-border);background-color:var(--clr-background);color:var(--clr-text);margin:0;position:absolute;& fieldset{border:0;flex-direction:row;gap:1ch;display:flex;& input{display:none}}}@media (prefers-reduced-motion:no-preference){& #theme-selector-dropdown{&:popover-open{opacity:1;transform:translateY(0)scale(1);@starting-style{opacity:0;transform:translateY(30px)scale(0)}}opacity:0;transition:transform, opacity, display allow-discrete, overlay allow-discrete;transform-origin:100% 0;transition-duration:.5s;transform:translateY(0)scale(0)}}}::view-transition-group(changing-theme){animation-duration:1.25s}::view-transition-new(changing-theme),::view-transition-old(changing-theme){mix-blend-mode:normal}::view-transition-new(changing-theme){animation-name:reveal}::view-transition-old(changing-theme){animation:none}@keyframes reveal{0%{clip-path:polygon(-30% 0,-30% 0,-15% 100%,-10% 115%)}to{clip-path:polygon(-30% 0,130% 0,115% 100%,-10% 115%)}}}
+@layer reset{*,:before,:after{box-sizing:border-box}html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none}body,h1,h2,h3,h4,p,figure,blockquote,dl,dd{margin-block-end:0}ul[role=list],ol[role=list]{list-style:none}body{line-height:1.5}h1,h2,h3,h4,button,input,label{line-height:1.1}h1,h2,h3,h4{text-wrap:balance}a:not([class]){text-decoration-skip-ink:auto;color:currentColor}img,picture{max-width:100%;height:auto;display:block}input,button,textarea,select{font-family:inherit;font-size:inherit}textarea:not([rows]){min-height:10em}:target{scroll-margin-block:5ex}@media (prefers-reduced-motion){::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}}}@layer base{:root{--font-serif:libron, georgia, serif;--font-sans:"Cal Sans", system-ui, sans-serif}body{font-family:var(--font-serif)}h1,h2,h3,h4,h5,h6,body>header nav{font-family:var(--font-sans)}:root{color-scheme:light dark;--primary-hue:307;--clr-text:light-dark(oklch(5% .1 var(--primary-hue)),oklch(100% .1 var(--primary-hue)));--clr-background:light-dark(oklch(100% .1 var(--primary-hue)),oklch(15% .15 var(--primary-hue)));--clr-border:light-dark(oklch(90% .2 var(--primary-hue)),oklch(25% .1 var(--primary-hue)));--clr-snow-fall:light-dark(oklch(25% .15 var(--primary-hue)),oklch(85% .2 var(--primary-hue)))}body{background-color:var(--clr-background);color:var(--clr-text)}:root{--border-radius:8px}html{font-size:125%}body{grid-template-rows:min-content 1fr min-content;grid-template-columns:1fr min(80ch,80vw) 1fr;padding-inline:4vw;display:grid;&>header{grid-column:1/-1}&>main{grid-column:1/-1;grid-template-columns:subgrid;display:grid;&>*{grid-column:2/3}&>.full-bleed{grid-column:1/-1}}&>footer{grid-column:1/-1;margin-block-start:2ex;& search form{flex-direction:row;align-items:center;gap:1ex;display:flex;& input{min-width:0}}}}.h-feed{flex-direction:column;gap:2ex;display:flex}}@layer components{.h-entry{& pre{padding:1rem}& .post-info{font-size:85%}}.draft-notice{border:2px dashed var(--clr-border);background:light-dark(oklch(95% .08 85),oklch(30% .08 85));border-radius:8px;margin-block-end:2ex;padding:1ex 1em}body>header{grid-template-rows:auto auto;grid-template-columns:auto 1fr auto;align-items:baseline;gap:1rem;display:grid;& a{text-decoration:none}& h1{text-wrap:nowrap;margin:0}& nav{flex-direction:row;gap:.5rem;display:flex;@media screen and (width<=1100px){flex-wrap:wrap;grid-area:2/1/auto/span 3}}}.note{border:1px solid var(--clr-border);border-radius:var(--border-radius);flex-direction:column;padding:1ex 2ex;display:flex;& .e-content{font-size:110%;&>p:first-child{margin-block-start:0}& .u-photo{width:100%;height:auto}}& .note-metadata{font-size:85%}& .syndication-links{flex-direction:row;gap:1ex;display:flex;& svg{border-radius:4px;width:auto;height:1lh}}}.reply-to{border:1px solid var(--clr-border);border-top-left-radius:var(--border-radius);border-top-right-radius:var(--border-radius);border-bottom:none;margin-inline:2ex;padding-inline:1ex;font-size:85%}.pagination{flex-direction:row;justify-content:center;align-items:center;display:flex;& div{flex-direction:row;gap:1ex;display:flex}}#theme-selector{background-color:color-mix(in oklch, var(--clr-border) 40%, transparent);border-radius:999px;justify-self:start;align-items:center;gap:.25rem;padding:.25rem;display:flex;& button{appearance:none;color:inherit;background:0 0;border:none;border-radius:999px;place-items:center;padding:.375rem;transition:background-color .2s,color .2s;display:grid;&:hover{cursor:pointer}&:focus-visible{outline:2px solid var(--clr-text);outline-offset:2px}& svg{fill:currentColor;width:1.5rem;height:1.5rem}@media (hover:hover){&:hover{background-color:color-mix(in oklch, var(--clr-border) 70%, transparent)}&[aria-pressed=true]:hover{background-color:var(--clr-text)}}&[aria-pressed=true]{background-color:var(--clr-text);color:var(--clr-background)}}}.sr-only{clip-path:inset(50%);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}::view-transition-group(changing-theme){animation-duration:1.25s}::view-transition-new(changing-theme),::view-transition-old(changing-theme){mix-blend-mode:normal}::view-transition-new(changing-theme){animation-name:reveal}::view-transition-old(changing-theme){animation:none}@keyframes reveal{0%{clip-path:polygon(-30% 0,-30% 0,-15% 100%,-10% 115%)}to{clip-path:polygon(-30% 0,130% 0,115% 100%,-10% 115%)}}.token-list-wrapper{border:1px solid var(--clr-border);background:light-dark(oklch(99% .02 var(--primary-hue)),oklch(22% .05 var(--primary-hue)));border-radius:16px;margin-block-start:1em;overflow:auto hidden}.token-list{table-layout:fixed;border-collapse:collapse;width:100%;min-width:640px;& th,& td{text-align:left;border-bottom:1px solid var(--clr-border);vertical-align:middle;padding:.9em 1.2em}& th{text-transform:uppercase;letter-spacing:.08em;opacity:.7;font-size:.8em;font-weight:700}& tr.is-revoked{opacity:.6}& a{word-break:break-all}& th:first-child,& td:first-child{width:31%}& th:nth-child(2),& td:nth-child(2){width:24%}& th:nth-child(3),& td:nth-child(3){width:15%}& th:nth-child(4),& td:nth-child(4){width:16%}& th:nth-child(5),& td:nth-child(5){text-align:right;width:14%}& tr:last-child td{border-bottom:none}}.scope-chips{flex-wrap:wrap;gap:.4em;display:flex}.scope-chip{background:light-dark(oklch(92% .05 var(--primary-hue)),oklch(35% .08 var(--primary-hue)));white-space:nowrap;border-radius:999px;padding:.2em .7em;font-size:.85em;display:inline-block}.badge,.token-list button.revoke{white-space:nowrap;border-radius:999px;align-items:center;gap:.4em;padding:.3em .8em;font-size:.85em;font-weight:600;line-height:1.5;display:inline-flex}.badge{background:0 0;border:1px solid}.badge-active{color:light-dark(oklch(35% .16 145),oklch(75% .16 145));& .dot{background:currentColor;border-radius:50%;width:6px;height:6px}}.badge-revoked{color:var(--clr-text);opacity:.7}.token-list button.revoke{color:light-dark(oklch(30% .15 25),oklch(92% .12 25));cursor:pointer;background:light-dark(oklch(92% .15 25),oklch(30% .12 25));border:1px solid #0000;transition:background-color .15s}.token-list button.revoke:hover{background:light-dark(oklch(80% .2 25),oklch(45% .18 25))}.token-reveal{border:1px solid var(--clr-border);background:light-dark(oklch(96% .08 145),oklch(28% .08 145));border-radius:16px;margin-block-end:1em;padding:1em 1.2em;& input{border:1px solid var(--clr-border);border-radius:8px;width:100%;padding:.5em .7em;font-family:monospace}}.scope-checkboxes{flex-wrap:wrap;align-items:center;gap:1em;display:flex}}@font-face{font-family:Libron;src:url(/assets/fonts/libron/Libron-Regular.woff2)format("woff2");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:Libron;src:url(/assets/fonts/libron/Libron-Italic.woff2)format("woff2");font-weight:400;font-style:italic;font-display:swap}@font-face{font-family:Libron;src:url(/assets/fonts/libron/Libron-Bold.woff2)format("woff2");font-weight:700;font-style:normal;font-display:swap}@font-face{font-family:Libron;src:url(/assets/fonts/libron/Libron-BoldItalic.woff2)format("woff2");font-weight:700;font-style:italic;font-display:swap}@font-face{font-family:Cal Sans;src:url(/assets/fonts/cal-sans/CalSansVF.woff2)format("woff2");font-weight:400 700;font-style:normal;font-display:swap}
/*# sourceMappingURL=/assets/css/app.css.map */
diff --git a/public/assets/css/app.css.br b/public/assets/css/app.css.br
index eeec79a3..82536e59 100644
Binary files a/public/assets/css/app.css.br and b/public/assets/css/app.css.br differ
diff --git a/public/assets/css/app.css.map b/public/assets/css/app.css.map
index b817d58d..0183bf68 100644
--- a/public/assets/css/app.css.map
+++ b/public/assets/css/app.css.map
@@ -1 +1 @@
-{"version":3,"mappings":"AACA,aCGE,uCAOA,oFASA,8DAMA,4CAMA,qBAKA,+CAMA,8BAMA,gEAMA,qDAQA,mEAOA,qCAKA,gCAKA,gCACE,wGDhFJ,YEAE,oaAwBA,kECxBA,0BAIA,oBAIA,iIAME,0BAIA,uBAIA,iDAIE,yEAME,uBAON,oDHvCF,kBG+CE,SACE,oBChDF,wHAOE,yBAIA,+BAKA,gDAKE,kCAAqC,2CCrBzC,+HAOE,aACE,qCAIA,mCAMF,6DAKE,gDAQJ,4MC/BA,sFAME,+CCNF,gBACE,oDAKE,wBAMF,gMAQE,4DAME,uBAUJ,8CACE,2BACE,yDAQE,gBAAiB,8CAST,0KAahB,iEAIA,kGAKA,4DAIA,qDAIA","sources":["resources/css/app.css","resources/css/layout.css","resources/css/colours.css","resources/css/reset.css","resources/css/theme-selector.css","resources/css/header.css","resources/css/pagination.css","resources/css/notes.css"],"sourcesContent":["/* First thing we need to do is declare our cascade layers */\n@layer reset, base, components;\n\n@import url('reset.css');\n@import url('colours.css');\n@import url('layout.css');\n@import url('header.css');\n@import url('notes.css');\n@import url('pagination.css');\n@import url('theme-selector.css');\n","@layer base {\n :root {\n --border-radius: 8px;\n }\n\n html {\n font-size: 125%;\n }\n\n body {\n display: grid;\n grid-template-columns: 1fr min(80ch, 80vw) 1fr;\n grid-template-rows: min-content 1fr min-content;\n padding-inline: 4vw;\n\n > header {\n grid-column: 1/-1;\n }\n\n > main {\n grid-column: 2/3;\n }\n\n > footer {\n grid-column: 1/-1;\n margin-block-start: 2ex;\n\n search form {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 1ex;\n\n input {\n min-width: 0;\n }\n }\n }\n }\n\n .h-feed {\n display: flex;\n flex-direction: column;\n gap: 2ex;\n }\n}\n\n@layer components {\n .h-entry {\n pre {\n padding: 1rem;\n }\n }\n}\n\n","@layer base {\n :root {\n color-scheme: light dark;\n\n --primary-hue: 307;\n --clr-text: light-dark(\n oklch(5% 0.1 var(--primary-hue)),\n oklch(100% 0.1 var(--primary-hue))\n );\n --clr-background: light-dark(\n oklch(100% 0.1 var(--primary-hue)),\n oklch(15% 0.15 var(--primary-hue))\n );\n --clr-border: light-dark(\n oklch(90% 0.2 var(--primary-hue)),\n oklch(25% 0.1 var(--primary-hue))\n );\n\n /* Adding snow fall colour whilst we are using it */\n --clr-snow-fall: light-dark(\n oklch(25% 0.15 var(--primary-hue)),\n oklch(85% 0.2 var(--primary-hue))\n );\n }\n\n body {\n background-color: var(--clr-background);\n color: var(--clr-text);\n }\n}\n","@layer reset {\n /* Sourced from https://piccalil.li/blog/a-more-modern-css-reset/ */\n\n /* Box sizing rules */\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n }\n\n /* Prevent font size inflation */\n html {\n /* stylelint-disable property-no-vendor-prefix */\n -moz-text-size-adjust: none;\n -webkit-text-size-adjust: none;\n /* stylelint-enable property-no-vendor-prefix */\n text-size-adjust: none;\n }\n\n /* Remove default margin in favour of better control in authored CSS */\n body, h1, h2, h3, h4, p,\n figure, blockquote, dl, dd {\n margin-block-end: 0;\n }\n\n /* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */\n ul[role='list'],\n ol[role='list'] {\n list-style: none;\n }\n\n /* Set core body defaults */\n body {\n line-height: 1.5;\n }\n\n /* Set shorter line heights on headings and interactive elements */\n h1, h2, h3, h4,\n button, input, label {\n line-height: 1.1;\n }\n\n /* Balance text wrapping on headings */\n h1, h2,\n h3, h4 {\n text-wrap: balance;\n }\n\n /* A elements that don't have a class get default styles */\n a:not([class]) {\n text-decoration-skip-ink: auto;\n color: currentcolor;\n }\n\n /* Make images easier to work with */\n img,\n picture {\n max-width: 100%;\n height: auto;\n display: block;\n }\n\n /* Inherit fonts for inputs and buttons */\n input, button,\n textarea, select {\n font-family: inherit;\n font-size: inherit;\n }\n\n /* Make sure textareas without a rows attribute are not tiny */\n textarea:not([rows]) {\n min-height: 10em;\n }\n\n /* Anything that has been anchored to should have extra scroll margin */\n :target {\n scroll-margin-block: 5ex;\n }\n\n /* Disable view transition animations for users who don’t want them */\n @media (prefers-reduced-motion) {\n ::view-transition-group(*),\n ::view-transition-old(*),\n ::view-transition-new(*) {\n animation: none !important;\n }\n }\n}\n","@layer components {\n #theme-selector {\n button {\n appearance: none;\n border: none;\n background: none;\n\n &:hover {\n cursor: pointer;\n }\n }\n\n /* This is the element with the [popover] attribute */\n #theme-selector-dropdown {\n position: absolute;\n position-area: block-end span-inline-start;\n margin: 0;\n border: 2px solid var(--clr-border);\n background-color: var(--clr-background);\n color: var(--clr-text);\n\n fieldset {\n border: 0;\n display: flex;\n flex-direction: row;\n gap: 1ch;\n\n input {\n display: none;\n }\n }\n }\n\n /*\n * This is the element with the [popover] attribute\n * Here we are styling the open and closing animations\n */\n @media (prefers-reduced-motion: no-preference) {\n #theme-selector-dropdown {\n &:popover-open {\n transform: translateY(0) scale(1);\n opacity: 1;\n\n /*\n * Start styles for the opening transition.\n * Added to :popover-open, but after the opened styles.\n */\n @starting-style {\n transform: translateY(30px) scale(0);\n opacity: 0;\n }\n }\n\n /*\n * End styles for the closing transition.\n */\n transform: translateY(0) scale(0);\n opacity: 0;\n\n /*\n * Enumerate transitioning properties, including display and overlay.\n */\n transition: transform, opacity, display allow-discrete, overlay allow-discrete;\n transition-duration: 0.5s;\n transform-origin: top right;\n }\n }\n }\n\n ::view-transition-group(changing-theme) {\n animation-duration: 1.25s;\n }\n\n ::view-transition-new(changing-theme),\n ::view-transition-old(changing-theme) {\n mix-blend-mode: normal;\n }\n\n ::view-transition-new(changing-theme) {\n animation-name: reveal;\n }\n\n ::view-transition-old(changing-theme) {\n animation: none;\n }\n\n @keyframes reveal {\n from {\n clip-path: polygon(-30% 0, -30% 0, -15% 100%, -10% 115%);\n }\n\n to {\n clip-path: polygon(-30% 0, 130% 0, 115% 100%, -10% 115%);\n }\n }\n}\n","@layer components {\n body > header {\n display: grid;\n grid-template-columns: auto 1fr auto;\n grid-template-rows: auto auto;\n align-items: baseline;\n gap: 1rem;\n\n a {\n text-decoration: none;\n }\n\n h1 {\n margin: 0;\n text-wrap: nowrap;\n }\n\n nav {\n display: flex;\n flex-direction: row;\n gap: .5rem;\n\n @media screen and (width <= 1100px) {\n grid-row: 2;\n grid-column: 1 / span 3;\n flex-wrap: wrap;\n }\n }\n }\n}\n","@layer components {\n .pagination {\n display: flex;\n flex-direction: row;\n justify-content: center;\n align-items: center;\n\n div {\n display: flex;\n flex-direction: row;\n gap: 1ex;\n }\n }\n}\n","@layer components {\n .note {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--clr-border);\n border-radius: var(--border-radius);\n padding: 1ex 2ex;\n\n .e-content {\n > p:first-child {\n margin-block-start: 0;\n }\n\n .u-photo {\n width: 100%;\n height: auto;\n }\n }\n\n .syndication-links {\n display: flex;\n flex-direction: row;\n gap: 1ex;\n\n svg {\n border-radius: 4px;\n width: auto;\n height: 1lh;\n }\n }\n }\n\n .reply-to {\n font-size: 85%;\n margin-inline: 2ex;\n padding-inline: 1ex;\n border: 1px solid var(--clr-border);\n border-bottom: none;\n border-top-left-radius: var(--border-radius);\n border-top-right-radius: var(--border-radius);\n }\n}\n"],"names":[]}
\ No newline at end of file
+{"version":3,"mappings":"AACA,aCGE,uCAOA,oFASA,8DAMA,4CAMA,qBAKA,+CAMA,8BAMA,gEAMA,qDAQA,mEAOA,qCAKA,gCAKA,gCACE,wGDhFJ,YK6CE,wFAKA,mCAIA,+DFtDA,oaAwBA,kEKxBA,0BAIA,oBAIA,iIAME,0BAIA,mEAKE,oBAIA,gCAKF,iDAIE,yEAME,uBAON,oDRjDF,kBQyDE,SACE,mBAIA,4BAQF,oKNtEA,wHAOE,yBAIA,+BAKA,gDAKE,kCAAqC,2CKrBzC,+HAOE,4BAGE,qCAIA,mCAMF,+BAIA,6DAKE,gDAQJ,4MHrCA,sFAME,+CENF,0LASE,gLAWE,uBAIA,qEAKA,mDAMA,qBACE,iFAIA,6DAKF,oFAOJ,uIAYA,iEAIA,kGAKA,4DAIA,qDAIA,mIGjFA,iNAWA,mFAME,6GAQA,6FAQA,2BAIA,yBAIA,4CAKA,8CAKA,8CAKA,8CAKA,+DAMA,uCAKF,kDAMA,qMAYA,0LAaA,uCAKA,sEAGE,uEAQF,gDAKA,kNAQA,0FAIA,wKAUE,iHASF,0EJvJF,oJAQA,mJAQA,iJAQA,uJAQA","sources":["resources/css/app.css","resources/css/header.css","resources/css/reset.css","resources/css/colours.css","resources/css/pagination.css","resources/css/theme-selector.css","resources/css/notes.css","resources/css/layout.css","resources/css/fonts.css","resources/css/admin-tokens.css"],"sourcesContent":["/* First thing we need to do is declare our cascade layers */\n@layer reset, base, components;\n\n@import url('reset.css');\n@import url('fonts.css');\n@import url('colours.css');\n@import url('layout.css');\n@import url('header.css');\n@import url('notes.css');\n@import url('pagination.css');\n@import url('theme-selector.css');\n@import url('admin-tokens.css');\n","@layer components {\n body > header {\n display: grid;\n grid-template-columns: auto 1fr auto;\n grid-template-rows: auto auto;\n align-items: baseline;\n gap: 1rem;\n\n a {\n text-decoration: none;\n }\n\n h1 {\n margin: 0;\n text-wrap: nowrap;\n }\n\n nav {\n display: flex;\n flex-direction: row;\n gap: .5rem;\n\n @media screen and (width <= 1100px) {\n grid-row: 2;\n grid-column: 1 / span 3;\n flex-wrap: wrap;\n }\n }\n }\n}\n","@layer reset {\n /* Sourced from https://piccalil.li/blog/a-more-modern-css-reset/ */\n\n /* Box sizing rules */\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n }\n\n /* Prevent font size inflation */\n html {\n /* stylelint-disable property-no-vendor-prefix */\n -moz-text-size-adjust: none;\n -webkit-text-size-adjust: none;\n /* stylelint-enable property-no-vendor-prefix */\n text-size-adjust: none;\n }\n\n /* Remove default margin in favour of better control in authored CSS */\n body, h1, h2, h3, h4, p,\n figure, blockquote, dl, dd {\n margin-block-end: 0;\n }\n\n /* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */\n ul[role='list'],\n ol[role='list'] {\n list-style: none;\n }\n\n /* Set core body defaults */\n body {\n line-height: 1.5;\n }\n\n /* Set shorter line heights on headings and interactive elements */\n h1, h2, h3, h4,\n button, input, label {\n line-height: 1.1;\n }\n\n /* Balance text wrapping on headings */\n h1, h2,\n h3, h4 {\n text-wrap: balance;\n }\n\n /* A elements that don't have a class get default styles */\n a:not([class]) {\n text-decoration-skip-ink: auto;\n color: currentcolor;\n }\n\n /* Make images easier to work with */\n img,\n picture {\n max-width: 100%;\n height: auto;\n display: block;\n }\n\n /* Inherit fonts for inputs and buttons */\n input, button,\n textarea, select {\n font-family: inherit;\n font-size: inherit;\n }\n\n /* Make sure textareas without a rows attribute are not tiny */\n textarea:not([rows]) {\n min-height: 10em;\n }\n\n /* Anything that has been anchored to should have extra scroll margin */\n :target {\n scroll-margin-block: 5ex;\n }\n\n /* Disable view transition animations for users who don’t want them */\n @media (prefers-reduced-motion) {\n ::view-transition-group(*),\n ::view-transition-old(*),\n ::view-transition-new(*) {\n animation: none !important;\n }\n }\n}\n","@layer base {\n :root {\n color-scheme: light dark;\n\n --primary-hue: 307;\n --clr-text: light-dark(\n oklch(5% 0.1 var(--primary-hue)),\n oklch(100% 0.1 var(--primary-hue))\n );\n --clr-background: light-dark(\n oklch(100% 0.1 var(--primary-hue)),\n oklch(15% 0.15 var(--primary-hue))\n );\n --clr-border: light-dark(\n oklch(90% 0.2 var(--primary-hue)),\n oklch(25% 0.1 var(--primary-hue))\n );\n\n /* Adding snow fall colour whilst we are using it */\n --clr-snow-fall: light-dark(\n oklch(25% 0.15 var(--primary-hue)),\n oklch(85% 0.2 var(--primary-hue))\n );\n }\n\n body {\n background-color: var(--clr-background);\n color: var(--clr-text);\n }\n}\n","@layer components {\n .pagination {\n display: flex;\n flex-direction: row;\n justify-content: center;\n align-items: center;\n\n div {\n display: flex;\n flex-direction: row;\n gap: 1ex;\n }\n }\n}\n","@layer components {\n #theme-selector {\n display: flex;\n justify-self: start;\n align-items: center;\n gap: .25rem;\n padding: .25rem;\n border-radius: 999px;\n background-color: color-mix(in oklch, var(--clr-border) 40%, transparent);\n\n button {\n display: grid;\n place-items: center;\n appearance: none;\n border: none;\n border-radius: 999px;\n padding: .375rem;\n background: transparent;\n color: inherit;\n transition: background-color .2s, color .2s;\n\n &:hover {\n cursor: pointer;\n }\n\n &:focus-visible {\n outline: 2px solid var(--clr-text);\n outline-offset: 2px;\n }\n\n svg {\n width: 1.5rem;\n height: 1.5rem;\n fill: currentcolor;\n }\n\n @media (hover: hover) {\n &:hover {\n background-color: color-mix(in oklch, var(--clr-border) 70%, transparent);\n }\n\n &[aria-pressed=\"true\"]:hover {\n background-color: var(--clr-text);\n }\n }\n\n &[aria-pressed=\"true\"] {\n background-color: var(--clr-text);\n color: var(--clr-background);\n }\n }\n }\n\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n }\n\n ::view-transition-group(changing-theme) {\n animation-duration: 1.25s;\n }\n\n ::view-transition-new(changing-theme),\n ::view-transition-old(changing-theme) {\n mix-blend-mode: normal;\n }\n\n ::view-transition-new(changing-theme) {\n animation-name: reveal;\n }\n\n ::view-transition-old(changing-theme) {\n animation: none;\n }\n\n @keyframes reveal {\n from {\n clip-path: polygon(-30% 0, -30% 0, -15% 100%, -10% 115%);\n }\n\n to {\n clip-path: polygon(-30% 0, 130% 0, 115% 100%, -10% 115%);\n }\n }\n}\n","@layer components {\n .note {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--clr-border);\n border-radius: var(--border-radius);\n padding: 1ex 2ex;\n\n .e-content {\n font-size: 110%;\n\n > p:first-child {\n margin-block-start: 0;\n }\n\n .u-photo {\n width: 100%;\n height: auto;\n }\n }\n\n .note-metadata {\n font-size: 85%;\n }\n\n .syndication-links {\n display: flex;\n flex-direction: row;\n gap: 1ex;\n\n svg {\n border-radius: 4px;\n width: auto;\n height: 1lh;\n }\n }\n }\n\n .reply-to {\n font-size: 85%;\n margin-inline: 2ex;\n padding-inline: 1ex;\n border: 1px solid var(--clr-border);\n border-bottom: none;\n border-top-left-radius: var(--border-radius);\n border-top-right-radius: var(--border-radius);\n }\n}\n","@layer base {\n :root {\n --border-radius: 8px;\n }\n\n html {\n font-size: 125%;\n }\n\n body {\n display: grid;\n grid-template-columns: 1fr min(80ch, 80vw) 1fr;\n grid-template-rows: min-content 1fr min-content;\n padding-inline: 4vw;\n\n > header {\n grid-column: 1/-1;\n }\n\n > main {\n grid-column: 1/-1;\n display: grid;\n grid-template-columns: subgrid;\n\n > * {\n grid-column: 2/3;\n }\n\n > .full-bleed {\n grid-column: 1/-1;\n }\n }\n\n > footer {\n grid-column: 1/-1;\n margin-block-start: 2ex;\n\n search form {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 1ex;\n\n input {\n min-width: 0;\n }\n }\n }\n }\n\n .h-feed {\n display: flex;\n flex-direction: column;\n gap: 2ex;\n }\n}\n\n@layer components {\n .h-entry {\n pre {\n padding: 1rem;\n }\n\n .post-info {\n font-size: 85%;\n }\n }\n}\n\n\n@layer components {\n .draft-notice {\n margin-block-end: 2ex;\n padding: 1ex 1em;\n border: 2px dashed var(--clr-border);\n border-radius: 8px;\n background: light-dark(\n oklch(95% 0.08 85deg),\n oklch(30% 0.08 85deg)\n );\n }\n}\n","/*\n * Libron (serif, body text) and Cal Sans (sans, headings), both SIL OFL 1.1\n * Libron v0.31: https://github.com/nicoverbruggen/libron/releases\n * Cal Sans v2.011: https://github.com/calcom/sans/releases\n */\n@font-face {\n font-family: Libron;\n src: url('/assets/fonts/libron/Libron-Regular.woff2') format('woff2');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n}\n\n@font-face {\n font-family: Libron;\n src: url('/assets/fonts/libron/Libron-Italic.woff2') format('woff2');\n font-weight: 400;\n font-style: italic;\n font-display: swap;\n}\n\n@font-face {\n font-family: Libron;\n src: url('/assets/fonts/libron/Libron-Bold.woff2') format('woff2');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n}\n\n@font-face {\n font-family: Libron;\n src: url('/assets/fonts/libron/Libron-BoldItalic.woff2') format('woff2');\n font-weight: 700;\n font-style: italic;\n font-display: swap;\n}\n\n@font-face {\n font-family: 'Cal Sans';\n src: url('/assets/fonts/cal-sans/CalSansVF.woff2') format('woff2');\n font-weight: 400 700;\n font-style: normal;\n font-display: swap;\n}\n\n@layer base {\n :root {\n --font-serif: libron, georgia, serif;\n --font-sans: 'Cal Sans', system-ui, sans-serif;\n }\n\n body {\n font-family: var(--font-serif);\n }\n\n h1, h2, h3,\n h4, h5, h6,\n body > header nav {\n font-family: var(--font-sans);\n }\n}\n","@layer components {\n .token-list-wrapper {\n margin-block-start: 1em;\n border: 1px solid var(--clr-border);\n border-radius: 16px;\n overflow: auto hidden;\n background: light-dark(\n oklch(99% 0.02 var(--primary-hue)),\n oklch(22% 0.05 var(--primary-hue))\n );\n }\n\n .token-list {\n width: 100%;\n min-width: 640px;\n table-layout: fixed;\n border-collapse: collapse;\n\n th,\n td {\n text-align: left;\n padding: 0.9em 1.2em;\n border-bottom: 1px solid var(--clr-border);\n vertical-align: middle;\n }\n\n th {\n font-size: 0.8em;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n opacity: 0.7;\n }\n\n tr.is-revoked {\n opacity: 0.6;\n }\n\n a {\n word-break: break-all;\n }\n\n th:nth-child(1),\n td:nth-child(1) {\n width: 31%;\n }\n\n th:nth-child(2),\n td:nth-child(2) {\n width: 24%;\n }\n\n th:nth-child(3),\n td:nth-child(3) {\n width: 15%;\n }\n\n th:nth-child(4),\n td:nth-child(4) {\n width: 16%;\n }\n\n th:nth-child(5),\n td:nth-child(5) {\n width: 14%;\n text-align: right;\n }\n\n tr:last-child td {\n border-bottom: none;\n }\n }\n\n .scope-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 0.4em;\n }\n\n .scope-chip {\n display: inline-block;\n padding: 0.2em 0.7em;\n border-radius: 999px;\n background: light-dark(\n oklch(92% 0.05 var(--primary-hue)),\n oklch(35% 0.08 var(--primary-hue))\n );\n font-size: 0.85em;\n white-space: nowrap;\n }\n\n .badge,\n .token-list button.revoke {\n display: inline-flex;\n align-items: center;\n gap: 0.4em;\n padding: 0.3em 0.8em;\n border-radius: 999px;\n font-size: 0.85em;\n font-weight: 600;\n line-height: 1.5;\n white-space: nowrap;\n }\n\n .badge {\n background: transparent;\n border: 1px solid currentcolor;\n }\n\n .badge-active {\n color: light-dark(oklch(35% 0.16 145deg), oklch(75% 0.16 145deg));\n\n .dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: currentcolor;\n }\n }\n\n .badge-revoked {\n color: var(--clr-text);\n opacity: 0.7;\n }\n\n .token-list button.revoke {\n background: light-dark(oklch(92% 0.15 25deg), oklch(30% 0.12 25deg));\n color: light-dark(oklch(30% 0.15 25deg), oklch(92% 0.12 25deg));\n border: 1px solid transparent;\n cursor: pointer;\n transition: background-color 150ms ease;\n }\n\n .token-list button.revoke:hover {\n background: light-dark(oklch(80% 0.2 25deg), oklch(45% 0.18 25deg));\n }\n\n .token-reveal {\n margin-block-end: 1em;\n padding: 1em 1.2em;\n border: 1px solid var(--clr-border);\n border-radius: 16px;\n background: light-dark(\n oklch(96% 0.08 145deg),\n oklch(28% 0.08 145deg)\n );\n\n input {\n width: 100%;\n font-family: monospace;\n padding: 0.5em 0.7em;\n border-radius: 8px;\n border: 1px solid var(--clr-border);\n }\n }\n\n .scope-checkboxes {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 1em;\n }\n}\n"],"names":[]}
\ No newline at end of file
diff --git a/public/assets/css/app.css.zst b/public/assets/css/app.css.zst
index d258af49..e11fdb6a 100644
Binary files a/public/assets/css/app.css.zst and b/public/assets/css/app.css.zst differ
diff --git a/public/assets/fonts/cal-sans/CalSansVF.woff2 b/public/assets/fonts/cal-sans/CalSansVF.woff2
new file mode 100644
index 00000000..b4b7aaf9
Binary files /dev/null and b/public/assets/fonts/cal-sans/CalSansVF.woff2 differ
diff --git a/public/assets/fonts/cal-sans/OFL.txt b/public/assets/fonts/cal-sans/OFL.txt
new file mode 100644
index 00000000..52135553
--- /dev/null
+++ b/public/assets/fonts/cal-sans/OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2021 The Cal Sans Project Authors (https://github.com/calcom/font)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://openfontlicense.org
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/public/assets/fonts/libron/Libron-Bold.woff2 b/public/assets/fonts/libron/Libron-Bold.woff2
new file mode 100644
index 00000000..3dd0bc01
Binary files /dev/null and b/public/assets/fonts/libron/Libron-Bold.woff2 differ
diff --git a/public/assets/fonts/libron/Libron-BoldItalic.woff2 b/public/assets/fonts/libron/Libron-BoldItalic.woff2
new file mode 100644
index 00000000..db5aeaf6
Binary files /dev/null and b/public/assets/fonts/libron/Libron-BoldItalic.woff2 differ
diff --git a/public/assets/fonts/libron/Libron-Italic.woff2 b/public/assets/fonts/libron/Libron-Italic.woff2
new file mode 100644
index 00000000..89375364
Binary files /dev/null and b/public/assets/fonts/libron/Libron-Italic.woff2 differ
diff --git a/public/assets/fonts/libron/Libron-Regular.woff2 b/public/assets/fonts/libron/Libron-Regular.woff2
new file mode 100644
index 00000000..b8549d70
Binary files /dev/null and b/public/assets/fonts/libron/Libron-Regular.woff2 differ
diff --git a/public/assets/fonts/libron/OFL.txt b/public/assets/fonts/libron/OFL.txt
new file mode 100644
index 00000000..1a332be8
--- /dev/null
+++ b/public/assets/fonts/libron/OFL.txt
@@ -0,0 +1,95 @@
+Newsreader (c) 2020 The Newsreader Project Authors (http://github.com/productiontype/Newsreader)
+Readerly (c) 2026 Nico Verbruggen (https://github.com/nicoverbruggen/readerly)
+Libron (c) 2026 Nico Verbruggen (https://github.com/nicoverbruggen/libron)
+with Reserved Font Name Libron.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/public/assets/js/app.js b/public/assets/js/app.js
index d19f257c..2992f727 100644
--- a/public/assets/js/app.js
+++ b/public/assets/js/app.js
@@ -1,2 +1,2 @@
-(()=>{var l=class{constructor(){}async register(){let r=await this.getCreateOptions(),e={challenge:this.base64URLStringToBuffer(r.challenge),rp:{id:r.rp.id,name:r.rp.name},user:{id:new TextEncoder().encode(window.atob(r.user.id)),name:r.user.name,displayName:r.user.displayName},pubKeyCredParams:r.pubKeyCredParams,excludeCredentials:[],authenticatorSelection:r.authenticatorSelection,timeout:6e4},t=await navigator.credentials.create({publicKey:e});if(!t)throw new Error("Error generating a passkey");let n={id:t.id?t.id:null,type:t.type?t.type:null,rawId:t.rawId?this.bufferToBase64URLString(t.rawId):null,response:{attestationObject:t.response.attestationObject?this.bufferToBase64URLString(t.response.attestationObject):null,clientDataJSON:t.response.clientDataJSON?this.bufferToBase64URLString(t.response.clientDataJSON):null}};if(!(await window.fetch("/admin/passkeys/register",{method:"POST",body:JSON.stringify(n),cache:"no-cache",headers:{"Content-Type":"application/json","X-CSRF-TOKEN":document.querySelector('meta[name="csrf-token"]').getAttribute("content")}})).ok)throw new Error("Error saving the passkey");window.location.reload()}async getCreateOptions(){return await(await fetch("/admin/passkeys/register",{method:"GET"})).json()}async login(){let r=await this.getLoginData(),e=await navigator.credentials.get({publicKey:{challenge:this.base64URLStringToBuffer(r.challenge),userVerification:r.userVerification,timeout:6e4}});if(!e)throw new Error("Authentication failed");let t={id:e.id?e.id:"",type:e.type?e.type:"",rawId:e.rawId?this.bufferToBase64URLString(e.rawId):"",response:{authenticatorData:e.response.authenticatorData?this.bufferToBase64URLString(e.response.authenticatorData):"",clientDataJSON:e.response.clientDataJSON?this.bufferToBase64URLString(e.response.clientDataJSON):"",signature:e.response.signature?this.bufferToBase64URLString(e.response.signature):"",userHandle:e.response.userHandle?this.bufferToBase64URLString(e.response.userHandle):""}};if(!(await window.fetch("/login/passkey",{method:"POST",body:JSON.stringify(t),headers:{"Content-Type":"application/json","X-CSRF-TOKEN":document.querySelector('meta[name="csrf-token"]').getAttribute("content")}})).ok)throw new Error("Login failed");window.location.assign("/admin")}async getLoginData(){return await(await fetch("/login/passkey",{method:"GET"})).json()}base64URLStringToBuffer(r){let e=r.replace(/-/g,"+").replace(/_/g,"/"),t=(4-e.length%4)%4,n=e.padEnd(e.length+t,"="),a=window.atob(n),o=new ArrayBuffer(a.length),i=new Uint8Array(o);for(let s=0;sr.addEventListener("input",e=>{let t=e.target.value;this.widget.querySelectorAll(".toggle svg").forEach(u=>{u.classList.contains(t)?u.style.display="":u.style.display="none"});let n;switch(t){case"dark":case"light":n=t;break;default:n="light dark"}let a=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light",o=document.querySelector("html"),i=o.style.getPropertyValue("color-scheme");i===""&&(i="light dark");let s=!1;n!==i&&(n==="light dark"?s=i!==a:i==="light dark"?s=n!==a:s=!0),o.style.viewTransitionName="changing-theme",s&&document.startViewTransition?document.startViewTransition(()=>{document.querySelector("#theme-selector-dropdown").togglePopover(),o.style.setProperty("color-scheme",n)}):(document.querySelector("#theme-selector-dropdown").togglePopover(),o.style.setProperty("color-scheme",n))}))}};var h=new l;document.querySelectorAll(".add-passkey").forEach(c=>{c.addEventListener("click",()=>{h.register()})});document.querySelectorAll(".login-passkey").forEach(c=>{c.addEventListener("click",()=>{h.login()})});var p=new d;p.setupEventListeners();})();
+(()=>{var l=class{constructor(){}async register(){let e=await this.getCreateOptions(),t={challenge:this.base64URLStringToBuffer(e.challenge),rp:{id:e.rp.id,name:e.rp.name},user:{id:new TextEncoder().encode(window.atob(e.user.id)),name:e.user.name,displayName:e.user.displayName},pubKeyCredParams:e.pubKeyCredParams,excludeCredentials:[],authenticatorSelection:e.authenticatorSelection,timeout:6e4},r=await navigator.credentials.create({publicKey:t});if(!r)throw new Error("Error generating a passkey");let n={id:r.id?r.id:null,type:r.type?r.type:null,rawId:r.rawId?this.bufferToBase64URLString(r.rawId):null,response:{attestationObject:r.response.attestationObject?this.bufferToBase64URLString(r.response.attestationObject):null,clientDataJSON:r.response.clientDataJSON?this.bufferToBase64URLString(r.response.clientDataJSON):null}};if(!(await window.fetch("/admin/passkeys/register",{method:"POST",body:JSON.stringify(n),cache:"no-cache",headers:{"Content-Type":"application/json","X-CSRF-TOKEN":document.querySelector('meta[name="csrf-token"]').getAttribute("content")}})).ok)throw new Error("Error saving the passkey");window.location.reload()}async getCreateOptions(){return await(await fetch("/admin/passkeys/register",{method:"GET"})).json()}async login(){let e=await this.getLoginData(),t=await navigator.credentials.get({publicKey:{challenge:this.base64URLStringToBuffer(e.challenge),userVerification:e.userVerification,timeout:6e4}});if(!t)throw new Error("Authentication failed");let r={id:t.id?t.id:"",type:t.type?t.type:"",rawId:t.rawId?this.bufferToBase64URLString(t.rawId):"",response:{authenticatorData:t.response.authenticatorData?this.bufferToBase64URLString(t.response.authenticatorData):"",clientDataJSON:t.response.clientDataJSON?this.bufferToBase64URLString(t.response.clientDataJSON):"",signature:t.response.signature?this.bufferToBase64URLString(t.response.signature):"",userHandle:t.response.userHandle?this.bufferToBase64URLString(t.response.userHandle):""}};if(!(await window.fetch("/login/passkey",{method:"POST",body:JSON.stringify(r),headers:{"Content-Type":"application/json","X-CSRF-TOKEN":document.querySelector('meta[name="csrf-token"]').getAttribute("content")}})).ok)throw new Error("Login failed");window.location.assign("/admin")}async getLoginData(){return await(await fetch("/login/passkey",{method:"GET"})).json()}base64URLStringToBuffer(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),r=(4-t.length%4)%4,n=t.padEnd(t.length+r,"="),s=window.atob(n),i=new ArrayBuffer(s.length),o=new Uint8Array(i);for(let c=0;c{this.applyTheme(this.currentTheme==="light"?"system":"light")}),this.btnDark.addEventListener("click",()=>{this.applyTheme(this.currentTheme==="dark"?"system":"dark")})}applyTheme(e){let t=e==="light"||e==="dark"?e:"light dark",r=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light",n=document.documentElement,s=n.style.getPropertyValue("color-scheme");s===""&&(s="light dark");let i=!1;t!==s&&(t==="light dark"?i=s!==r:s==="light dark"?i=t!==r:i=!0);let o=()=>{this.currentTheme=e,n.style.setProperty("color-scheme",t),a.storeTheme(e),this.updateButtons(),this.status.textContent=e==="system"?"Theme set to system default":""};n.style.viewTransitionName="changing-theme",i&&document.startViewTransition?document.startViewTransition(o):o()}};var d=new l;document.querySelectorAll(".add-passkey").forEach(a=>{a.addEventListener("click",()=>{d.register()})});document.querySelectorAll(".login-passkey").forEach(a=>{a.addEventListener("click",()=>{d.login()})});var u=new h;u.setupEventListeners();})();
//# sourceMappingURL=app.js.map
diff --git a/public/assets/js/app.js.br b/public/assets/js/app.js.br
index 40b0dd0d..9393eb4e 100644
Binary files a/public/assets/js/app.js.br and b/public/assets/js/app.js.br differ
diff --git a/public/assets/js/app.js.map b/public/assets/js/app.js.map
index 79c78c67..f7d99cb7 100644
--- a/public/assets/js/app.js.map
+++ b/public/assets/js/app.js.map
@@ -1,7 +1,7 @@
{
"version": 3,
"sources": ["../../../resources/js/auth.js", "../../../resources/js/theme-selector.js", "../../../resources/js/app.js"],
- "sourcesContent": ["class Auth {\n constructor() {}\n\n async register() {\n const createOptions = await this.getCreateOptions();\n\n const publicKeyCredentialCreationOptions = {\n challenge: this.base64URLStringToBuffer(createOptions.challenge),\n rp: {\n id: createOptions.rp.id,\n name: createOptions.rp.name,\n },\n user: {\n id: new TextEncoder().encode(window.atob(createOptions.user.id)),\n name: createOptions.user.name,\n displayName: createOptions.user.displayName,\n },\n pubKeyCredParams: createOptions.pubKeyCredParams,\n excludeCredentials: [],\n authenticatorSelection: createOptions.authenticatorSelection,\n timeout: 60000,\n };\n\n const credential = await navigator.credentials.create({\n publicKey: publicKeyCredentialCreationOptions\n });\n if (!credential) {\n throw new Error('Error generating a passkey');\n }\n\n const authenticatorAttestationResponse = {\n id: credential.id ? credential.id : null,\n type: credential.type ? credential.type : null,\n rawId: credential.rawId ? this.bufferToBase64URLString(credential.rawId) : null,\n response: {\n attestationObject: credential.response.attestationObject ? this.bufferToBase64URLString(credential.response.attestationObject) : null,\n clientDataJSON: credential.response.clientDataJSON ? this.bufferToBase64URLString(credential.response.clientDataJSON) : null,\n }\n };\n\n const registerCredential = await window.fetch('/admin/passkeys/register', {\n method: 'POST',\n body: JSON.stringify(authenticatorAttestationResponse),\n cache: 'no-cache',\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRF-TOKEN': document.querySelector('meta[name=\"csrf-token\"]').getAttribute('content'),\n },\n });\n\n if (!registerCredential.ok) {\n throw new Error('Error saving the passkey');\n }\n\n window.location.reload();\n }\n\n async getCreateOptions() {\n const response = await fetch('/admin/passkeys/register', {\n method: 'GET',\n });\n\n return await response.json();\n }\n\n async login() {\n const loginData = await this.getLoginData();\n\n const publicKeyCredential = await navigator.credentials.get({\n publicKey: {\n challenge: this.base64URLStringToBuffer(loginData.challenge),\n userVerification: loginData.userVerification,\n timeout: 60000,\n }\n });\n\n if (!publicKeyCredential) {\n throw new Error('Authentication failed');\n }\n\n const authenticatorAttestationResponse = {\n id: publicKeyCredential.id ? publicKeyCredential.id : '',\n type: publicKeyCredential.type ? publicKeyCredential.type : '',\n rawId: publicKeyCredential.rawId ? this.bufferToBase64URLString(publicKeyCredential.rawId) : '',\n response: {\n authenticatorData: publicKeyCredential.response.authenticatorData ? this.bufferToBase64URLString(publicKeyCredential.response.authenticatorData) : '',\n clientDataJSON: publicKeyCredential.response.clientDataJSON ? this.bufferToBase64URLString(publicKeyCredential.response.clientDataJSON) : '',\n signature: publicKeyCredential.response.signature ? this.bufferToBase64URLString(publicKeyCredential.response.signature) : '',\n userHandle: publicKeyCredential.response.userHandle ? this.bufferToBase64URLString(publicKeyCredential.response.userHandle) : '',\n },\n };\n\n const loginAttempt = await window.fetch('/login/passkey', {\n method: 'POST',\n body: JSON.stringify(authenticatorAttestationResponse),\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRF-TOKEN': document.querySelector('meta[name=\"csrf-token\"]').getAttribute('content'),\n },\n });\n\n if (!loginAttempt.ok) {\n throw new Error('Login failed');\n }\n\n window.location.assign('/admin');\n }\n\n async getLoginData() {\n const response = await fetch('/login/passkey', {\n method: 'GET',\n });\n\n return await response.json();\n }\n\n /**\n * Convert a base64 URL string to a buffer.\n *\n * Sourced from https://github.com/MasterKale/SimpleWebAuthn/blob/master/packages/browser/src/helpers/base64URLStringToBuffer.ts#L8\n *\n * @param {string} base64URLString\n * @returns {ArrayBuffer}\n */\n base64URLStringToBuffer(base64URLString) {\n // Convert from Base64URL to Base64\n const base64 = base64URLString.replace(/-/g, '+').replace(/_/g, '/');\n /**\n * Pad with '=' until it's a multiple of four\n * (4 - (85 % 4 = 1) = 3) % 4 = 3 padding\n * (4 - (86 % 4 = 2) = 2) % 4 = 2 padding\n * (4 - (87 % 4 = 3) = 1) % 4 = 1 padding\n * (4 - (88 % 4 = 0) = 4) % 4 = 0 padding\n */\n const padLength = (4 - (base64.length % 4)) % 4;\n const padded = base64.padEnd(base64.length + padLength, '=');\n // Convert to a binary string\n const binary = window.atob(padded);\n // Convert binary string to buffer\n const buffer = new ArrayBuffer(binary.length);\n const bytes = new Uint8Array(buffer);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return buffer;\n }\n\n /**\n * Convert a buffer to a base64 URL string.\n *\n * Sourced from https://github.com/MasterKale/SimpleWebAuthn/blob/master/packages/browser/src/helpers/bufferToBase64URLString.ts#L7\n *\n * @param {ArrayBuffer} buffer\n * @returns {string}\n */\n bufferToBase64URLString(buffer) {\n const bytes = new Uint8Array(buffer);\n let str = '';\n for (const charCode of bytes) {\n str += String.fromCharCode(charCode);\n }\n const base64String = btoa(str);\n return base64String.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n }\n}\n\nexport { Auth };\n", "class ThemeSelector {\n constructor() {\n this.widget = document.querySelector('#theme-selector');\n }\n\n setupEventListeners() {\n this.widget.querySelectorAll('#theme-selector-dropdown input').forEach((radioInput) => radioInput.addEventListener('input', (e) => {\n let theme = e.target.value;\n\n // Update current icon\n this.widget.querySelectorAll('.toggle svg').forEach((svg) => {\n if (svg.classList.contains(theme)) {\n svg.style.display = '';\n } else {\n svg.style.display = 'none';\n }\n });\n\n // Set the theme\n let selectedTheme;\n switch (theme) {\n case 'dark':\n case 'light':\n selectedTheme = theme;\n break;\n default:\n selectedTheme = 'light dark';\n }\n\n const systemTheme = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light';\n const html = document.querySelector('html');\n let currentTheme = html.style.getPropertyValue('color-scheme');\n if (currentTheme === '') {\n currentTheme = 'light dark';\n }\n\n /* do we need to transition */\n let doTransition = false;\n\n if (selectedTheme !== currentTheme) {\n if (selectedTheme === 'light dark') {\n doTransition = currentTheme !== systemTheme;\n } else if (currentTheme === 'light dark') {\n doTransition = selectedTheme !== systemTheme;\n } else {\n doTransition = true;\n }\n }\n\n html.style.viewTransitionName = 'changing-theme';\n if (doTransition && document.startViewTransition) {\n document.startViewTransition(() => {\n // Close the popover\n document.querySelector('#theme-selector-dropdown').togglePopover();\n\n // Set the colour theme\n html.style.setProperty('color-scheme', selectedTheme);\n });\n } else {\n // Close the popover\n document.querySelector('#theme-selector-dropdown').togglePopover();\n\n // Set the colour theme\n html.style.setProperty('color-scheme', selectedTheme);\n }\n }));\n }\n}\n\nexport { ThemeSelector };\n", "import { Auth } from './auth.js';\nimport { ThemeSelector } from './theme-selector.js';\n\nlet auth = new Auth();\ndocument.querySelectorAll('.add-passkey').forEach((el) => {\n el.addEventListener('click', () => {\n auth.register();\n });\n});\n\ndocument.querySelectorAll('.login-passkey').forEach((el) => {\n el.addEventListener('click', () => {\n auth.login();\n });\n});\n\nlet themeSelector = new ThemeSelector();\nthemeSelector.setupEventListeners();\n"],
- "mappings": "MAAA,IAAMA,EAAN,KAAW,CACT,aAAc,CAAC,CAEf,MAAM,UAAW,CACf,IAAMC,EAAgB,MAAM,KAAK,iBAAiB,EAE5CC,EAAqC,CACzC,UAAW,KAAK,wBAAwBD,EAAc,SAAS,EAC/D,GAAI,CACF,GAAIA,EAAc,GAAG,GACrB,KAAMA,EAAc,GAAG,IACzB,EACA,KAAM,CACJ,GAAI,IAAI,YAAY,EAAE,OAAO,OAAO,KAAKA,EAAc,KAAK,EAAE,CAAC,EAC/D,KAAMA,EAAc,KAAK,KACzB,YAAaA,EAAc,KAAK,WAClC,EACA,iBAAkBA,EAAc,iBAChC,mBAAoB,CAAC,EACrB,uBAAwBA,EAAc,uBACtC,QAAS,GACX,EAEME,EAAa,MAAM,UAAU,YAAY,OAAO,CACpD,UAAWD,CACb,CAAC,EACD,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,4BAA4B,EAG9C,IAAMC,EAAmC,CACvC,GAAID,EAAW,GAAKA,EAAW,GAAK,KACpC,KAAMA,EAAW,KAAOA,EAAW,KAAO,KAC1C,MAAOA,EAAW,MAAQ,KAAK,wBAAwBA,EAAW,KAAK,EAAI,KAC3E,SAAU,CACR,kBAAmBA,EAAW,SAAS,kBAAoB,KAAK,wBAAwBA,EAAW,SAAS,iBAAiB,EAAI,KACjI,eAAgBA,EAAW,SAAS,eAAiB,KAAK,wBAAwBA,EAAW,SAAS,cAAc,EAAI,IAC1H,CACF,EAYA,GAAI,EAVuB,MAAM,OAAO,MAAM,2BAA4B,CACxE,OAAQ,OACR,KAAM,KAAK,UAAUC,CAAgC,EACrD,MAAO,WACP,QAAS,CACP,eAAgB,mBAChB,eAAgB,SAAS,cAAc,yBAAyB,EAAE,aAAa,SAAS,CAC1F,CACF,CAAC,GAEuB,GACtB,MAAM,IAAI,MAAM,0BAA0B,EAG5C,OAAO,SAAS,OAAO,CACzB,CAEA,MAAM,kBAAmB,CAKvB,OAAO,MAJU,MAAM,MAAM,2BAA4B,CACvD,OAAQ,KACV,CAAC,GAEqB,KAAK,CAC7B,CAEA,MAAM,OAAQ,CACZ,IAAMC,EAAY,MAAM,KAAK,aAAa,EAEpCC,EAAsB,MAAM,UAAU,YAAY,IAAI,CAC1D,UAAW,CACT,UAAW,KAAK,wBAAwBD,EAAU,SAAS,EAC3D,iBAAkBA,EAAU,iBAC5B,QAAS,GACX,CACF,CAAC,EAED,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,uBAAuB,EAGzC,IAAMF,EAAmC,CACvC,GAAIE,EAAoB,GAAKA,EAAoB,GAAK,GACtD,KAAMA,EAAoB,KAAOA,EAAoB,KAAO,GAC5D,MAAOA,EAAoB,MAAQ,KAAK,wBAAwBA,EAAoB,KAAK,EAAI,GAC7F,SAAU,CACR,kBAAmBA,EAAoB,SAAS,kBAAoB,KAAK,wBAAwBA,EAAoB,SAAS,iBAAiB,EAAI,GACnJ,eAAgBA,EAAoB,SAAS,eAAiB,KAAK,wBAAwBA,EAAoB,SAAS,cAAc,EAAI,GAC1I,UAAWA,EAAoB,SAAS,UAAY,KAAK,wBAAwBA,EAAoB,SAAS,SAAS,EAAI,GAC3H,WAAYA,EAAoB,SAAS,WAAa,KAAK,wBAAwBA,EAAoB,SAAS,UAAU,EAAI,EAChI,CACF,EAWA,GAAI,EATiB,MAAM,OAAO,MAAM,iBAAkB,CACxD,OAAQ,OACR,KAAM,KAAK,UAAUF,CAAgC,EACrD,QAAS,CACP,eAAgB,mBAChB,eAAgB,SAAS,cAAc,yBAAyB,EAAE,aAAa,SAAS,CAC1F,CACF,CAAC,GAEiB,GAChB,MAAM,IAAI,MAAM,cAAc,EAGhC,OAAO,SAAS,OAAO,QAAQ,CACjC,CAEA,MAAM,cAAe,CAKnB,OAAO,MAJU,MAAM,MAAM,iBAAkB,CAC7C,OAAQ,KACV,CAAC,GAEqB,KAAK,CAC7B,CAUA,wBAAwBG,EAAiB,CAEvC,IAAMC,EAASD,EAAgB,QAAQ,KAAM,GAAG,EAAE,QAAQ,KAAM,GAAG,EAQ7DE,GAAa,EAAKD,EAAO,OAAS,GAAM,EACxCE,EAASF,EAAO,OAAOA,EAAO,OAASC,EAAW,GAAG,EAErDE,EAAS,OAAO,KAAKD,CAAM,EAE3BE,EAAS,IAAI,YAAYD,EAAO,MAAM,EACtCE,EAAQ,IAAI,WAAWD,CAAM,EACnC,QAASE,EAAI,EAAGA,EAAIH,EAAO,OAAQG,IACjCD,EAAMC,CAAC,EAAIH,EAAO,WAAWG,CAAC,EAEhC,OAAOF,CACT,CAUA,wBAAwBA,EAAQ,CAC9B,IAAMC,EAAQ,IAAI,WAAWD,CAAM,EAC/BG,EAAM,GACV,QAAWC,KAAYH,EACrBE,GAAO,OAAO,aAAaC,CAAQ,EAGrC,OADqB,KAAKD,CAAG,EACT,QAAQ,MAAO,GAAG,EAAE,QAAQ,MAAO,GAAG,EAAE,QAAQ,KAAM,EAAE,CAC9E,CACF,ECpKA,IAAME,EAAN,KAAoB,CAClB,aAAc,CACZ,KAAK,OAAS,SAAS,cAAc,iBAAiB,CACxD,CAEA,qBAAsB,CACpB,KAAK,OAAO,iBAAiB,gCAAgC,EAAE,QAASC,GAAeA,EAAW,iBAAiB,QAAU,GAAM,CACjI,IAAIC,EAAQ,EAAE,OAAO,MAGrB,KAAK,OAAO,iBAAiB,aAAa,EAAE,QAASC,GAAQ,CACvDA,EAAI,UAAU,SAASD,CAAK,EAC9BC,EAAI,MAAM,QAAU,GAEpBA,EAAI,MAAM,QAAU,MAExB,CAAC,EAGD,IAAIC,EACJ,OAAQF,EAAO,CACb,IAAK,OACL,IAAK,QACHE,EAAgBF,EAChB,MACF,QACEE,EAAgB,YACpB,CAEA,IAAMC,EAAe,OAAO,YAAc,OAAO,WAAW,8BAA8B,EAAE,QAAW,OAAS,QAC1GC,EAAO,SAAS,cAAc,MAAM,EACtCC,EAAeD,EAAK,MAAM,iBAAiB,cAAc,EACzDC,IAAiB,KACnBA,EAAe,cAIjB,IAAIC,EAAe,GAEfJ,IAAkBG,IAChBH,IAAkB,aACpBI,EAAeD,IAAiBF,EACvBE,IAAiB,aAC1BC,EAAeJ,IAAkBC,EAEjCG,EAAe,IAInBF,EAAK,MAAM,mBAAqB,iBAC5BE,GAAgB,SAAS,oBAC3B,SAAS,oBAAoB,IAAM,CAEjC,SAAS,cAAc,0BAA0B,EAAE,cAAc,EAGjEF,EAAK,MAAM,YAAY,eAAgBF,CAAa,CACtD,CAAC,GAGD,SAAS,cAAc,0BAA0B,EAAE,cAAc,EAGjEE,EAAK,MAAM,YAAY,eAAgBF,CAAa,EAExD,CAAC,CAAC,CACJ,CACF,EChEA,IAAIK,EAAO,IAAIC,EACf,SAAS,iBAAiB,cAAc,EAAE,QAASC,GAAO,CACxDA,EAAG,iBAAiB,QAAS,IAAM,CACjCF,EAAK,SAAS,CAChB,CAAC,CACH,CAAC,EAED,SAAS,iBAAiB,gBAAgB,EAAE,QAASE,GAAO,CAC1DA,EAAG,iBAAiB,QAAS,IAAM,CACjCF,EAAK,MAAM,CACb,CAAC,CACH,CAAC,EAED,IAAIG,EAAgB,IAAIC,EACxBD,EAAc,oBAAoB",
- "names": ["Auth", "createOptions", "publicKeyCredentialCreationOptions", "credential", "authenticatorAttestationResponse", "loginData", "publicKeyCredential", "base64URLString", "base64", "padLength", "padded", "binary", "buffer", "bytes", "i", "str", "charCode", "ThemeSelector", "radioInput", "theme", "svg", "selectedTheme", "systemTheme", "html", "currentTheme", "doTransition", "auth", "Auth", "el", "themeSelector", "ThemeSelector"]
+ "sourcesContent": ["class Auth {\n constructor() {}\n\n async register() {\n const createOptions = await this.getCreateOptions();\n\n const publicKeyCredentialCreationOptions = {\n challenge: this.base64URLStringToBuffer(createOptions.challenge),\n rp: {\n id: createOptions.rp.id,\n name: createOptions.rp.name,\n },\n user: {\n id: new TextEncoder().encode(window.atob(createOptions.user.id)),\n name: createOptions.user.name,\n displayName: createOptions.user.displayName,\n },\n pubKeyCredParams: createOptions.pubKeyCredParams,\n excludeCredentials: [],\n authenticatorSelection: createOptions.authenticatorSelection,\n timeout: 60000,\n };\n\n const credential = await navigator.credentials.create({\n publicKey: publicKeyCredentialCreationOptions\n });\n if (!credential) {\n throw new Error('Error generating a passkey');\n }\n\n const authenticatorAttestationResponse = {\n id: credential.id ? credential.id : null,\n type: credential.type ? credential.type : null,\n rawId: credential.rawId ? this.bufferToBase64URLString(credential.rawId) : null,\n response: {\n attestationObject: credential.response.attestationObject ? this.bufferToBase64URLString(credential.response.attestationObject) : null,\n clientDataJSON: credential.response.clientDataJSON ? this.bufferToBase64URLString(credential.response.clientDataJSON) : null,\n }\n };\n\n const registerCredential = await window.fetch('/admin/passkeys/register', {\n method: 'POST',\n body: JSON.stringify(authenticatorAttestationResponse),\n cache: 'no-cache',\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRF-TOKEN': document.querySelector('meta[name=\"csrf-token\"]').getAttribute('content'),\n },\n });\n\n if (!registerCredential.ok) {\n throw new Error('Error saving the passkey');\n }\n\n window.location.reload();\n }\n\n async getCreateOptions() {\n const response = await fetch('/admin/passkeys/register', {\n method: 'GET',\n });\n\n return await response.json();\n }\n\n async login() {\n const loginData = await this.getLoginData();\n\n const publicKeyCredential = await navigator.credentials.get({\n publicKey: {\n challenge: this.base64URLStringToBuffer(loginData.challenge),\n userVerification: loginData.userVerification,\n timeout: 60000,\n }\n });\n\n if (!publicKeyCredential) {\n throw new Error('Authentication failed');\n }\n\n const authenticatorAttestationResponse = {\n id: publicKeyCredential.id ? publicKeyCredential.id : '',\n type: publicKeyCredential.type ? publicKeyCredential.type : '',\n rawId: publicKeyCredential.rawId ? this.bufferToBase64URLString(publicKeyCredential.rawId) : '',\n response: {\n authenticatorData: publicKeyCredential.response.authenticatorData ? this.bufferToBase64URLString(publicKeyCredential.response.authenticatorData) : '',\n clientDataJSON: publicKeyCredential.response.clientDataJSON ? this.bufferToBase64URLString(publicKeyCredential.response.clientDataJSON) : '',\n signature: publicKeyCredential.response.signature ? this.bufferToBase64URLString(publicKeyCredential.response.signature) : '',\n userHandle: publicKeyCredential.response.userHandle ? this.bufferToBase64URLString(publicKeyCredential.response.userHandle) : '',\n },\n };\n\n const loginAttempt = await window.fetch('/login/passkey', {\n method: 'POST',\n body: JSON.stringify(authenticatorAttestationResponse),\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRF-TOKEN': document.querySelector('meta[name=\"csrf-token\"]').getAttribute('content'),\n },\n });\n\n if (!loginAttempt.ok) {\n throw new Error('Login failed');\n }\n\n window.location.assign('/admin');\n }\n\n async getLoginData() {\n const response = await fetch('/login/passkey', {\n method: 'GET',\n });\n\n return await response.json();\n }\n\n /**\n * Convert a base64 URL string to a buffer.\n *\n * Sourced from https://github.com/MasterKale/SimpleWebAuthn/blob/master/packages/browser/src/helpers/base64URLStringToBuffer.ts#L8\n *\n * @param {string} base64URLString\n * @returns {ArrayBuffer}\n */\n base64URLStringToBuffer(base64URLString) {\n // Convert from Base64URL to Base64\n const base64 = base64URLString.replace(/-/g, '+').replace(/_/g, '/');\n /**\n * Pad with '=' until it's a multiple of four\n * (4 - (85 % 4 = 1) = 3) % 4 = 3 padding\n * (4 - (86 % 4 = 2) = 2) % 4 = 2 padding\n * (4 - (87 % 4 = 3) = 1) % 4 = 1 padding\n * (4 - (88 % 4 = 0) = 4) % 4 = 0 padding\n */\n const padLength = (4 - (base64.length % 4)) % 4;\n const padded = base64.padEnd(base64.length + padLength, '=');\n // Convert to a binary string\n const binary = window.atob(padded);\n // Convert binary string to buffer\n const buffer = new ArrayBuffer(binary.length);\n const bytes = new Uint8Array(buffer);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return buffer;\n }\n\n /**\n * Convert a buffer to a base64 URL string.\n *\n * Sourced from https://github.com/MasterKale/SimpleWebAuthn/blob/master/packages/browser/src/helpers/bufferToBase64URLString.ts#L7\n *\n * @param {ArrayBuffer} buffer\n * @returns {string}\n */\n bufferToBase64URLString(buffer) {\n const bytes = new Uint8Array(buffer);\n let str = '';\n for (const charCode of bytes) {\n str += String.fromCharCode(charCode);\n }\n const base64String = btoa(str);\n return base64String.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n }\n}\n\nexport { Auth };\n", "class ThemeSelector {\n constructor() {\n this.widget = document.querySelector('#theme-selector');\n this.btnLight = this.widget.querySelector('#btn-light');\n this.btnDark = this.widget.querySelector('#btn-dark');\n this.status = this.widget.querySelector('#theme-status');\n this.currentTheme = ThemeSelector.storedTheme();\n if (this.currentTheme !== 'system') {\n /* backstop in case theme-init.js didn't run, so the page always matches the buttons */\n document.documentElement.style.setProperty('color-scheme', this.currentTheme);\n }\n this.updateButtons();\n }\n\n static storedTheme() {\n try {\n const theme = localStorage.getItem('theme');\n return (theme === 'light' || theme === 'dark') ? theme : 'system';\n } catch {\n return 'system';\n }\n }\n\n static storeTheme(theme) {\n try {\n if (theme === 'system') {\n localStorage.removeItem('theme');\n } else {\n localStorage.setItem('theme', theme);\n }\n } catch {\n /* storage unavailable, the choice just won't persist */\n }\n }\n\n updateButtons() {\n this.btnLight.setAttribute('aria-pressed', String(this.currentTheme === 'light'));\n this.btnDark.setAttribute('aria-pressed', String(this.currentTheme === 'dark'));\n }\n\n setupEventListeners() {\n this.btnLight.addEventListener('click', () => {\n this.applyTheme(this.currentTheme === 'light' ? 'system' : 'light');\n });\n\n this.btnDark.addEventListener('click', () => {\n this.applyTheme(this.currentTheme === 'dark' ? 'system' : 'dark');\n });\n }\n\n applyTheme(theme) {\n const selectedTheme = (theme === 'light' || theme === 'dark') ? theme : 'light dark';\n\n const systemTheme = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light';\n const html = document.documentElement;\n let currentColorScheme = html.style.getPropertyValue('color-scheme');\n if (currentColorScheme === '') {\n currentColorScheme = 'light dark';\n }\n\n /* do we need to transition */\n let doTransition = false;\n\n if (selectedTheme !== currentColorScheme) {\n if (selectedTheme === 'light dark') {\n doTransition = currentColorScheme !== systemTheme;\n } else if (currentColorScheme === 'light dark') {\n doTransition = selectedTheme !== systemTheme;\n } else {\n doTransition = true;\n }\n }\n\n const applyChange = () => {\n this.currentTheme = theme;\n html.style.setProperty('color-scheme', selectedTheme);\n ThemeSelector.storeTheme(theme);\n\n this.updateButtons();\n this.status.textContent = theme === 'system' ? 'Theme set to system default' : '';\n };\n\n html.style.viewTransitionName = 'changing-theme';\n if (doTransition && document.startViewTransition) {\n document.startViewTransition(applyChange);\n } else {\n applyChange();\n }\n }\n}\n\nexport { ThemeSelector };\n", "import { Auth } from './auth.js';\nimport { ThemeSelector } from './theme-selector.js';\n\nlet auth = new Auth();\ndocument.querySelectorAll('.add-passkey').forEach((el) => {\n el.addEventListener('click', () => {\n auth.register();\n });\n});\n\ndocument.querySelectorAll('.login-passkey').forEach((el) => {\n el.addEventListener('click', () => {\n auth.login();\n });\n});\n\nlet themeSelector = new ThemeSelector();\nthemeSelector.setupEventListeners();\n"],
+ "mappings": "MAAA,IAAMA,EAAN,KAAW,CACT,aAAc,CAAC,CAEf,MAAM,UAAW,CACf,IAAMC,EAAgB,MAAM,KAAK,iBAAiB,EAE5CC,EAAqC,CACzC,UAAW,KAAK,wBAAwBD,EAAc,SAAS,EAC/D,GAAI,CACF,GAAIA,EAAc,GAAG,GACrB,KAAMA,EAAc,GAAG,IACzB,EACA,KAAM,CACJ,GAAI,IAAI,YAAY,EAAE,OAAO,OAAO,KAAKA,EAAc,KAAK,EAAE,CAAC,EAC/D,KAAMA,EAAc,KAAK,KACzB,YAAaA,EAAc,KAAK,WAClC,EACA,iBAAkBA,EAAc,iBAChC,mBAAoB,CAAC,EACrB,uBAAwBA,EAAc,uBACtC,QAAS,GACX,EAEME,EAAa,MAAM,UAAU,YAAY,OAAO,CACpD,UAAWD,CACb,CAAC,EACD,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,4BAA4B,EAG9C,IAAMC,EAAmC,CACvC,GAAID,EAAW,GAAKA,EAAW,GAAK,KACpC,KAAMA,EAAW,KAAOA,EAAW,KAAO,KAC1C,MAAOA,EAAW,MAAQ,KAAK,wBAAwBA,EAAW,KAAK,EAAI,KAC3E,SAAU,CACR,kBAAmBA,EAAW,SAAS,kBAAoB,KAAK,wBAAwBA,EAAW,SAAS,iBAAiB,EAAI,KACjI,eAAgBA,EAAW,SAAS,eAAiB,KAAK,wBAAwBA,EAAW,SAAS,cAAc,EAAI,IAC1H,CACF,EAYA,GAAI,EAVuB,MAAM,OAAO,MAAM,2BAA4B,CACxE,OAAQ,OACR,KAAM,KAAK,UAAUC,CAAgC,EACrD,MAAO,WACP,QAAS,CACP,eAAgB,mBAChB,eAAgB,SAAS,cAAc,yBAAyB,EAAE,aAAa,SAAS,CAC1F,CACF,CAAC,GAEuB,GACtB,MAAM,IAAI,MAAM,0BAA0B,EAG5C,OAAO,SAAS,OAAO,CACzB,CAEA,MAAM,kBAAmB,CAKvB,OAAO,MAJU,MAAM,MAAM,2BAA4B,CACvD,OAAQ,KACV,CAAC,GAEqB,KAAK,CAC7B,CAEA,MAAM,OAAQ,CACZ,IAAMC,EAAY,MAAM,KAAK,aAAa,EAEpCC,EAAsB,MAAM,UAAU,YAAY,IAAI,CAC1D,UAAW,CACT,UAAW,KAAK,wBAAwBD,EAAU,SAAS,EAC3D,iBAAkBA,EAAU,iBAC5B,QAAS,GACX,CACF,CAAC,EAED,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,uBAAuB,EAGzC,IAAMF,EAAmC,CACvC,GAAIE,EAAoB,GAAKA,EAAoB,GAAK,GACtD,KAAMA,EAAoB,KAAOA,EAAoB,KAAO,GAC5D,MAAOA,EAAoB,MAAQ,KAAK,wBAAwBA,EAAoB,KAAK,EAAI,GAC7F,SAAU,CACR,kBAAmBA,EAAoB,SAAS,kBAAoB,KAAK,wBAAwBA,EAAoB,SAAS,iBAAiB,EAAI,GACnJ,eAAgBA,EAAoB,SAAS,eAAiB,KAAK,wBAAwBA,EAAoB,SAAS,cAAc,EAAI,GAC1I,UAAWA,EAAoB,SAAS,UAAY,KAAK,wBAAwBA,EAAoB,SAAS,SAAS,EAAI,GAC3H,WAAYA,EAAoB,SAAS,WAAa,KAAK,wBAAwBA,EAAoB,SAAS,UAAU,EAAI,EAChI,CACF,EAWA,GAAI,EATiB,MAAM,OAAO,MAAM,iBAAkB,CACxD,OAAQ,OACR,KAAM,KAAK,UAAUF,CAAgC,EACrD,QAAS,CACP,eAAgB,mBAChB,eAAgB,SAAS,cAAc,yBAAyB,EAAE,aAAa,SAAS,CAC1F,CACF,CAAC,GAEiB,GAChB,MAAM,IAAI,MAAM,cAAc,EAGhC,OAAO,SAAS,OAAO,QAAQ,CACjC,CAEA,MAAM,cAAe,CAKnB,OAAO,MAJU,MAAM,MAAM,iBAAkB,CAC7C,OAAQ,KACV,CAAC,GAEqB,KAAK,CAC7B,CAUA,wBAAwBG,EAAiB,CAEvC,IAAMC,EAASD,EAAgB,QAAQ,KAAM,GAAG,EAAE,QAAQ,KAAM,GAAG,EAQ7DE,GAAa,EAAKD,EAAO,OAAS,GAAM,EACxCE,EAASF,EAAO,OAAOA,EAAO,OAASC,EAAW,GAAG,EAErDE,EAAS,OAAO,KAAKD,CAAM,EAE3BE,EAAS,IAAI,YAAYD,EAAO,MAAM,EACtCE,EAAQ,IAAI,WAAWD,CAAM,EACnC,QAASE,EAAI,EAAGA,EAAIH,EAAO,OAAQG,IACjCD,EAAMC,CAAC,EAAIH,EAAO,WAAWG,CAAC,EAEhC,OAAOF,CACT,CAUA,wBAAwBA,EAAQ,CAC9B,IAAMC,EAAQ,IAAI,WAAWD,CAAM,EAC/BG,EAAM,GACV,QAAWC,KAAYH,EACrBE,GAAO,OAAO,aAAaC,CAAQ,EAGrC,OADqB,KAAKD,CAAG,EACT,QAAQ,MAAO,GAAG,EAAE,QAAQ,MAAO,GAAG,EAAE,QAAQ,KAAM,EAAE,CAC9E,CACF,ECpKA,IAAME,EAAN,MAAMC,CAAc,CAClB,aAAc,CACZ,KAAK,OAAS,SAAS,cAAc,iBAAiB,EACtD,KAAK,SAAW,KAAK,OAAO,cAAc,YAAY,EACtD,KAAK,QAAU,KAAK,OAAO,cAAc,WAAW,EACpD,KAAK,OAAS,KAAK,OAAO,cAAc,eAAe,EACvD,KAAK,aAAeA,EAAc,YAAY,EAC1C,KAAK,eAAiB,UAExB,SAAS,gBAAgB,MAAM,YAAY,eAAgB,KAAK,YAAY,EAE9E,KAAK,cAAc,CACrB,CAEA,OAAO,aAAc,CACnB,GAAI,CACF,IAAMC,EAAQ,aAAa,QAAQ,OAAO,EAC1C,OAAQA,IAAU,SAAWA,IAAU,OAAUA,EAAQ,QAC3D,MAAQ,CACN,MAAO,QACT,CACF,CAEA,OAAO,WAAWA,EAAO,CACvB,GAAI,CACEA,IAAU,SACZ,aAAa,WAAW,OAAO,EAE/B,aAAa,QAAQ,QAASA,CAAK,CAEvC,MAAQ,CAER,CACF,CAEA,eAAgB,CACd,KAAK,SAAS,aAAa,eAAgB,OAAO,KAAK,eAAiB,OAAO,CAAC,EAChF,KAAK,QAAQ,aAAa,eAAgB,OAAO,KAAK,eAAiB,MAAM,CAAC,CAChF,CAEA,qBAAsB,CACpB,KAAK,SAAS,iBAAiB,QAAS,IAAM,CAC5C,KAAK,WAAW,KAAK,eAAiB,QAAU,SAAW,OAAO,CACpE,CAAC,EAED,KAAK,QAAQ,iBAAiB,QAAS,IAAM,CAC3C,KAAK,WAAW,KAAK,eAAiB,OAAS,SAAW,MAAM,CAClE,CAAC,CACH,CAEA,WAAWA,EAAO,CAChB,IAAMC,EAAiBD,IAAU,SAAWA,IAAU,OAAUA,EAAQ,aAElEE,EAAe,OAAO,YAAc,OAAO,WAAW,8BAA8B,EAAE,QAAW,OAAS,QAC1GC,EAAO,SAAS,gBAClBC,EAAqBD,EAAK,MAAM,iBAAiB,cAAc,EAC/DC,IAAuB,KACzBA,EAAqB,cAIvB,IAAIC,EAAe,GAEfJ,IAAkBG,IAChBH,IAAkB,aACpBI,EAAeD,IAAuBF,EAC7BE,IAAuB,aAChCC,EAAeJ,IAAkBC,EAEjCG,EAAe,IAInB,IAAMC,EAAc,IAAM,CACxB,KAAK,aAAeN,EACpBG,EAAK,MAAM,YAAY,eAAgBF,CAAa,EACpDF,EAAc,WAAWC,CAAK,EAE9B,KAAK,cAAc,EACnB,KAAK,OAAO,YAAcA,IAAU,SAAW,8BAAgC,EACjF,EAEAG,EAAK,MAAM,mBAAqB,iBAC5BE,GAAgB,SAAS,oBAC3B,SAAS,oBAAoBC,CAAW,EAExCA,EAAY,CAEhB,CACF,ECtFA,IAAIC,EAAO,IAAIC,EACf,SAAS,iBAAiB,cAAc,EAAE,QAASC,GAAO,CACxDA,EAAG,iBAAiB,QAAS,IAAM,CACjCF,EAAK,SAAS,CAChB,CAAC,CACH,CAAC,EAED,SAAS,iBAAiB,gBAAgB,EAAE,QAASE,GAAO,CAC1DA,EAAG,iBAAiB,QAAS,IAAM,CACjCF,EAAK,MAAM,CACb,CAAC,CACH,CAAC,EAED,IAAIG,EAAgB,IAAIC,EACxBD,EAAc,oBAAoB",
+ "names": ["Auth", "createOptions", "publicKeyCredentialCreationOptions", "credential", "authenticatorAttestationResponse", "loginData", "publicKeyCredential", "base64URLString", "base64", "padLength", "padded", "binary", "buffer", "bytes", "i", "str", "charCode", "ThemeSelector", "_ThemeSelector", "theme", "selectedTheme", "systemTheme", "html", "currentColorScheme", "doTransition", "applyChange", "auth", "Auth", "el", "themeSelector", "ThemeSelector"]
}
diff --git a/public/assets/js/app.js.zst b/public/assets/js/app.js.zst
index e9a5163a..641fc418 100644
Binary files a/public/assets/js/app.js.zst and b/public/assets/js/app.js.zst differ
diff --git a/public/assets/js/is-land.min.js b/public/assets/js/is-land.min.js
index 17203312..fa373a82 100644
--- a/public/assets/js/is-land.min.js
+++ b/public/assets/js/is-land.min.js
@@ -1,2 +1,2 @@
//!
-const e=window,t=e.document,a=e.navigator;function i(){let e,t;return{promise:new Promise((a,i)=>{e=a,t=i}),resolve:e,reject:t}}class r extends HTMLElement{static attributePrefix="on:";static attr={template:"data-island",ready:"ready",defer:"defer-hydration",type:"type",import:"import"};static _tagNames=new Set;static _once=new Map;static ctm(){return"undefined"!=typeof globalThis}static define(t=e.customElements){let a="is-land";this.ctm()&&!t.get(a)&&t.define(a,this)}static _initTypes={default:async e=>{await import(e.getAttribute(r.attr.import))}};static addInitType(e,t){this._initTypes[e]=t}static _fallback={};static addFallback(e,a){this._fallback[e]=a;let i=Array.from(this._tagNames);i.length&&t.querySelectorAll(i.map(e=>`${e}:defined`).join(",")).forEach(e=>{e.replaceFallbackContent()})}getFallback(){return Object.assign({[`:not(:defined):not(${this.localName}):not([${r.attr.defer}])`]:(e,t)=>{let a=r.renameNode(e,t+e.localName);return()=>{a.shadowRoot&&e.shadowRoot.append(...a.shadowRoot.childNodes),e.append(...a.childNodes),a.replaceWith(e)}}},r._fallback)}static renameNode(e,a){let i=t.createElement(a);for(let t of e.getAttributeNames())i.setAttribute(t,e.getAttribute(t));let r=e.shadowRoot;if(!r){let t=e.querySelector(":scope > template[shadowrootmode], :scope > template[shadowroot]");if(t){let a=t.getAttribute("shadowrootmode")||t.getAttribute("shadowroot")||"closed";r=e.attachShadow({mode:a}),r.appendChild(t.content.cloneNode(!0))}}return r&&i.attachShadow({mode:r.mode}).append(...r.childNodes),i.append(...e.childNodes),e.replaceWith(i),i}constructor(){super(),this._ready=i(),this._fallbackExec={},r._tagNames.add(this.localName)}getParents(e,a=!1){let i=[];for(;(e=e.parentNode)&&e&&e!==t.body;)if(e.matches&&e.matches(this.localName)){if(a&&e===a)break;s.hasConditions(e,r.attributePrefix)&&i.push(e)}return i}replaceTemplates(){let e=this.querySelectorAll(`template[${r.attr.template}]`);for(let t of e){if(this.getParents(t,this).length>0)continue;let e=t.getAttribute(r.attr.template);if("replace"===e){let e=Array.from(this.childNodes);for(let t of e)this.removeChild(t);this.appendChild(t.content);break}{let a=t.innerHTML;if("once"===e&&a){if(r._once.has(a))return void t.remove();r._once.set(a,!0)}t.replaceWith(t.content)}}}async beforeReady(){let e,t=this.getAttribute(r.attr.type);t?e=r._initTypes[t]:this.getAttribute(r.attr.import)&&(e=r._initTypes.default),e&&await e(this)}async ready(e,t){return Array.isArray(t)||(t=this.getParents(e)),Promise.all(t.map(e=>e.wait()))}replaceFallbackContent(){let e=`${this.localName}--`;for(let[t,a]of Object.entries(this.getFallback())){if(this._fallbackExec[t])continue;let i=Array.from(this.querySelectorAll(t)).reverse(),r=[];for(let t of i){if(!t.isConnected)continue;let i=this.getParents(t);if(i[0]===this){let s=a(t,e);r.push({node:t,parents:i,returned:s})}}for(let{node:e,parents:t,returned:a}of r.reverse())this.ready(e,t).then(a);this._fallbackExec[t]=!0}}wait(){return this._ready.promise}async connectedCallback(){s.hasConditions(this,r.attributePrefix)&&this.replaceFallbackContent(),await this.hydrate()}async hydrate(){let e=[],t=this.getParents(this);t.length&&e.push(t[0].wait()),e.push(...s.getConditions(this,r.attributePrefix)),await Promise.all(e),this.replaceTemplates(),await this.beforeReady(),this._ready.resolve();let{ready:a,defer:i}=r.attr;this.setAttribute(a,""),this.querySelectorAll(`[${i}]`).forEach(e=>e.removeAttribute(i))}}class s{static _media={};static map={visible:s.visible,idle:s.idle,load:s.pageLoad,interaction:s.interaction,media:s.media,"save-data":s.saveData};static getMap(e=""){return Object.keys(s.map).map(t=>e+t)}static hasConditions(e,t){for(let a of s.getMap(t))if(e.hasAttribute(a))return!0;return!1}static getConditions(e,t){let a=[];for(let i of s.getMap()){let r=t+i;if(e.hasAttribute(r)){let t=e.getAttribute(r);a.push(s.map[i](t,e))}}return a}static visible(t,a){let{promise:r,resolve:s}=i();if("IntersectionObserver"in e){let e=new IntersectionObserver(t=>{let[a]=t;a.isIntersecting&&(e.unobserve(a.target),s())});e.observe(a)}else s();return r}static pageLoad(){if(s._cacheLoad)return s._cacheLoad;let{promise:a,resolve:r}=i();return"complete"===t.readyState?r():e.addEventListener("load",()=>r(),{once:!0}),s._cacheLoad=a,a}static idle(){if(s._cacheIdle)return s._cacheIdle;let{promise:t,resolve:a}=i();return"requestIdleCallback"in e?requestIdleCallback(()=>a()):a(),s._cacheIdle=Promise.all([s.pageLoad(),t]),s._cacheIdle}static interaction(e,t){let a=(e||"click,touchstart").split(",").map(e=>e.trim()),{promise:r,resolve:s}=i();function o(e){s();for(let e of a)t.removeEventListener(e,o)}for(let e of a)t.addEventListener(e,o,{once:!0,passive:!0});return r}static media(t){if(s._media[t])return s._media[t];let{promise:a,resolve:r}=i(),o={matches:!0};return t&&"matchMedia"in e&&(o=e.matchMedia(t)),o.matches?r():o.addListener(e=>{e.matches&&r()}),s._media[t]=a,a}static saveData(e){let{promise:t,resolve:r}=i();return"connection"in a&&a.connection.saveData!==("false"!==e)||r(),t}}new URL(import.meta.url).searchParams.has("nodefine")||r.define(),e.Island=r;export{r as Island};
\ No newline at end of file
+const e=window,t=e.document,a=e.navigator;function r(){let e,t;return{promise:new Promise((a,r)=>{e=a,t=r}),resolve:e,reject:t}}class i extends HTMLElement{static attributePrefix="on:";static attr={template:"data-island",ready:"ready",defer:"defer-hydration",type:"type",import:"import",importMount:"import-mount"};static _tagNames=new Set;static _once=new Map;static ctm(){return"undefined"!=typeof globalThis}static define(t=e.customElements){let a="is-land";this.ctm()&&!t.get(a)&&t.define(a,this)}static _initTypes={default:async e=>{let t=e.getAttribute(i.attr.import),a=await(import(t));if(e.hasAttribute(i.attr.importMount)){if("function"!=typeof a.default)throw new Error(`[${i.attr.importMount}] expects a default export function: ${t}`);await a.default(e)}}};static addInitType(e,t){this._initTypes[e]=t}static setSwapBehavior(e){this._swapFn=e}static _fallback={};static addFallback(e,a){this._fallback[e]=a;let r=Array.from(this._tagNames);r.length&&t.querySelectorAll(r.map(e=>`${e}:defined`).join(",")).forEach(e=>{e.replaceFallbackContent()})}getFallback(){return Object.assign({[`:not(:defined):not(${this.localName}):not([${i.attr.defer}])`]:(e,t)=>{let a=i.renameNode(e,t+e.localName);return()=>{a.shadowRoot&&e.shadowRoot.append(...a.shadowRoot.childNodes),e.append(...a.childNodes),a.replaceWith(e)}}},i._fallback)}static renameNode(e,a){let r=t.createElement(a);for(let t of e.getAttributeNames())r.setAttribute(t,e.getAttribute(t));let i=e.shadowRoot;if(!i){let t=e.querySelector(":scope > template[shadowrootmode], :scope > template[shadowroot]");if(t){let a=t.getAttribute("shadowrootmode")||t.getAttribute("shadowroot")||"closed";i=e.attachShadow({mode:a}),i.appendChild(t.content.cloneNode(!0))}}return i&&r.attachShadow({mode:i.mode}).append(...i.childNodes),r.append(...e.childNodes),e.replaceWith(r),r}constructor(){super(),this._ready=r(),this._fallbackExec={},this._fallbackRestores=[],i._tagNames.add(this.localName)}getParents(e,a=!1){let r=[];for(;(e=e.parentNode)&&e&&e!==t.body;)if(e.matches&&e.matches(this.localName)){if(a&&e===a)break;s.hasConditions(e,i.attributePrefix)&&r.push(e)}return r}replaceTemplates(){let e=this.querySelectorAll(`template[${i.attr.template}]`);for(let t of e){if(this.getParents(t,this).length>0)continue;let e=t.getAttribute(i.attr.template);if("replace"===e){let e=Array.from(this.childNodes);for(let t of e)this.removeChild(t);this.appendChild(t.content);break}{let a=t.innerHTML;if("once"===e&&a){if(i._once.has(a))return void t.remove();i._once.set(a,!0)}t.replaceWith(t.content)}}}async beforeReady(){let e,t=this.getAttribute(i.attr.type);t?e=i._initTypes[t]:this.getAttribute(i.attr.import)&&(e=i._initTypes.default),e&&await e(this)}async ready(e,t){return Array.isArray(t)||(t=this.getParents(e)),Promise.all(t.map(e=>e.wait()))}replaceFallbackContent(){let e=`${this.localName}--`;for(let[t,a]of Object.entries(this.getFallback())){if(this._fallbackExec[t])continue;let r=Array.from(this.querySelectorAll(t)).reverse(),i=[];for(let t of r){if(!t.isConnected)continue;let r=this.getParents(t);if(r[0]===this){let s,o=a(t,e),l=()=>{!s&&o&&(s=!0,o())};this._fallbackRestores.push(l),i.push({node:t,parents:r,returned:l})}}for(let{node:e,parents:t,returned:a}of i.reverse())this.ready(e,t).then(a);this._fallbackExec[t]=!0}}wait(){return this._ready.promise}async connectedCallback(){s.hasConditions(this,i.attributePrefix)&&this.replaceFallbackContent(),await this.hydrate()}swap(){this.replaceTemplates();for(let e of this._fallbackRestores.reverse())e();this._fallbackRestores=[]}async hydrate(){let e=[],t=this.getParents(this);t.length&&e.push(t[0].wait()),e.push(...s.getConditions(this,i.attributePrefix)),await Promise.all(e);let a=i._swapFn;a?await new Promise(e=>a(()=>e(this.swap()),this)):this.swap(),await this.beforeReady(),this._ready.resolve();let{ready:r,defer:o}=i.attr;this.setAttribute(r,""),this.querySelectorAll(`[${o}]`).forEach(e=>e.removeAttribute(o))}}class s{static _cache={};static map={visible:s.visible,idle:s.idle,load:s.pageLoad,interaction:s.interaction,media:s.media,"save-data":s.saveData};static cached(e,t){let a=s._cache;return a[e]||(a[e]=t())}static hasConditions(e,t){return Object.keys(s.map).some(a=>e.hasAttribute(t+a))}static getConditions(e,t){let a=[];for(let[r,i]of Object.entries(s.map)){let s=t+r;e.hasAttribute(s)&&a.push(i(e.getAttribute(s),e))}return a}static visible(t,a){let{promise:i,resolve:s}=r();if("IntersectionObserver"in e){let e=new IntersectionObserver(t=>{let[a]=t;a.isIntersecting&&(e.unobserve(a.target),s())},t?{rootMargin:t}:void 0);e.observe(a)}else s();return i}static pageLoad(){return s.cached("load",()=>{let{promise:a,resolve:i}=r();return"complete"===t.readyState?i():e.addEventListener("load",()=>i(),{once:!0}),a})}static idle(t){let a=Number(t),i=a>0;return s.cached(i?"idle:"+a:"idle",()=>{let{promise:t,resolve:o}=r();return"requestIdleCallback"in e?requestIdleCallback(()=>o(),i?{timeout:a}:void 0):o(),Promise.all([s.pageLoad(),t])})}static interaction(e,t){let a=(e||"click,touchstart").split(",").map(e=>e.trim()),{promise:i,resolve:s}=r();function o(e){s();for(let e of a)t.removeEventListener(e,o)}for(let e of a)t.addEventListener(e,o,{once:!0,passive:!0});return i}static media(t){return s.cached("media:"+t,()=>{let a,{promise:i,resolve:s}=r();return t&&"matchMedia"in e&&!(a=e.matchMedia(t)).matches?a.addListener(e=>{e.matches&&s()}):s(),i})}static saveData(e){let{promise:t,resolve:i}=r();return"connection"in a&&a.connection.saveData!==("false"!==e)||i(),t}}for(let[e,t]of Object.entries(s.map))i["on"+e.replace("-","")]=(e,a)=>e instanceof Node?t(a,e):t(e,a);new URL(import.meta.url).searchParams.has("nodefine")||i.define(),e.Island=i;export{i as Island};
\ No newline at end of file
diff --git a/public/assets/js/is-land.min.js.br b/public/assets/js/is-land.min.js.br
index 34fe76f2..fffc5dc3 100644
Binary files a/public/assets/js/is-land.min.js.br and b/public/assets/js/is-land.min.js.br differ
diff --git a/public/assets/js/is-land.min.js.zst b/public/assets/js/is-land.min.js.zst
index f8784490..d3ab0c32 100644
Binary files a/public/assets/js/is-land.min.js.zst and b/public/assets/js/is-land.min.js.zst differ
diff --git a/public/assets/js/snow-fall.js.br b/public/assets/js/snow-fall.js.br
deleted file mode 100644
index b44b6670..00000000
Binary files a/public/assets/js/snow-fall.js.br and /dev/null differ
diff --git a/public/assets/js/snow-fall.js.zst b/public/assets/js/snow-fall.js.zst
deleted file mode 100644
index 6c26bd2a..00000000
Binary files a/public/assets/js/snow-fall.js.zst and /dev/null differ
diff --git a/public/assets/js/theme-init.js b/public/assets/js/theme-init.js
new file mode 100644
index 00000000..a8898291
--- /dev/null
+++ b/public/assets/js/theme-init.js
@@ -0,0 +1,2 @@
+(()=>{try{let e=localStorage.getItem("theme");(e==="light"||e==="dark")&&document.documentElement.style.setProperty("color-scheme",e)}catch{}})();
+//# sourceMappingURL=theme-init.js.map
diff --git a/public/assets/js/theme-init.js.br b/public/assets/js/theme-init.js.br
new file mode 100644
index 00000000..6446006b
Binary files /dev/null and b/public/assets/js/theme-init.js.br differ
diff --git a/public/assets/js/theme-init.js.map b/public/assets/js/theme-init.js.map
new file mode 100644
index 00000000..2bc745a0
--- /dev/null
+++ b/public/assets/js/theme-init.js.map
@@ -0,0 +1,7 @@
+{
+ "version": 3,
+ "sources": ["../../../resources/js/theme-init.js"],
+ "sourcesContent": ["/*\n * Apply a saved theme choice before first paint to avoid a flash of the system theme.\n * Loaded as a blocking external script (not inline) so it passes the site's CSP.\n */\ntry {\n const theme = localStorage.getItem('theme');\n if (theme === 'light' || theme === 'dark') {\n document.documentElement.style.setProperty('color-scheme', theme);\n }\n} catch {\n /* storage unavailable, fall back to the system theme */\n}\n"],
+ "mappings": "MAIA,GAAI,CACF,IAAMA,EAAQ,aAAa,QAAQ,OAAO,GACtCA,IAAU,SAAWA,IAAU,SACjC,SAAS,gBAAgB,MAAM,YAAY,eAAgBA,CAAK,CAEpE,MAAQ,CAER",
+ "names": ["theme"]
+}
diff --git a/public/assets/js/theme-init.js.zst b/public/assets/js/theme-init.js.zst
new file mode 100644
index 00000000..99aeb6ce
Binary files /dev/null and b/public/assets/js/theme-init.js.zst differ
diff --git a/resources/css/admin-tokens.css b/resources/css/admin-tokens.css
new file mode 100644
index 00000000..7bf0ad02
--- /dev/null
+++ b/resources/css/admin-tokens.css
@@ -0,0 +1,163 @@
+@layer components {
+ .token-list-wrapper {
+ margin-block-start: 1em;
+ border: 1px solid var(--clr-border);
+ border-radius: 16px;
+ overflow: auto hidden;
+ background: light-dark(
+ oklch(99% 0.02 var(--primary-hue)),
+ oklch(22% 0.05 var(--primary-hue))
+ );
+ }
+
+ .token-list {
+ width: 100%;
+ min-width: 640px;
+ table-layout: fixed;
+ border-collapse: collapse;
+
+ th,
+ td {
+ text-align: left;
+ padding: 0.9em 1.2em;
+ border-bottom: 1px solid var(--clr-border);
+ vertical-align: middle;
+ }
+
+ th {
+ font-size: 0.8em;
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.08em;
+ opacity: 0.7;
+ }
+
+ tr.is-revoked {
+ opacity: 0.6;
+ }
+
+ a {
+ word-break: break-all;
+ }
+
+ th:nth-child(1),
+ td:nth-child(1) {
+ width: 31%;
+ }
+
+ th:nth-child(2),
+ td:nth-child(2) {
+ width: 24%;
+ }
+
+ th:nth-child(3),
+ td:nth-child(3) {
+ width: 15%;
+ }
+
+ th:nth-child(4),
+ td:nth-child(4) {
+ width: 16%;
+ }
+
+ th:nth-child(5),
+ td:nth-child(5) {
+ width: 14%;
+ text-align: right;
+ }
+
+ tr:last-child td {
+ border-bottom: none;
+ }
+ }
+
+ .scope-chips {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.4em;
+ }
+
+ .scope-chip {
+ display: inline-block;
+ padding: 0.2em 0.7em;
+ border-radius: 999px;
+ background: light-dark(
+ oklch(92% 0.05 var(--primary-hue)),
+ oklch(35% 0.08 var(--primary-hue))
+ );
+ font-size: 0.85em;
+ white-space: nowrap;
+ }
+
+ .badge,
+ .token-list button.revoke {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4em;
+ padding: 0.3em 0.8em;
+ border-radius: 999px;
+ font-size: 0.85em;
+ font-weight: 600;
+ line-height: 1.5;
+ white-space: nowrap;
+ }
+
+ .badge {
+ background: transparent;
+ border: 1px solid currentcolor;
+ }
+
+ .badge-active {
+ color: light-dark(oklch(35% 0.16 145deg), oklch(75% 0.16 145deg));
+
+ .dot {
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background: currentcolor;
+ }
+ }
+
+ .badge-revoked {
+ color: var(--clr-text);
+ opacity: 0.7;
+ }
+
+ .token-list button.revoke {
+ background: light-dark(oklch(92% 0.15 25deg), oklch(30% 0.12 25deg));
+ color: light-dark(oklch(30% 0.15 25deg), oklch(92% 0.12 25deg));
+ border: 1px solid transparent;
+ cursor: pointer;
+ transition: background-color 150ms ease;
+ }
+
+ .token-list button.revoke:hover {
+ background: light-dark(oklch(80% 0.2 25deg), oklch(45% 0.18 25deg));
+ }
+
+ .token-reveal {
+ margin-block-end: 1em;
+ padding: 1em 1.2em;
+ border: 1px solid var(--clr-border);
+ border-radius: 16px;
+ background: light-dark(
+ oklch(96% 0.08 145deg),
+ oklch(28% 0.08 145deg)
+ );
+
+ input {
+ width: 100%;
+ font-family: monospace;
+ padding: 0.5em 0.7em;
+ border-radius: 8px;
+ border: 1px solid var(--clr-border);
+ }
+ }
+
+ .scope-checkboxes {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 1em;
+ }
+}
diff --git a/resources/css/app.css b/resources/css/app.css
index f25e47e3..f02fbd58 100644
--- a/resources/css/app.css
+++ b/resources/css/app.css
@@ -2,9 +2,11 @@
@layer reset, base, components;
@import url('reset.css');
+@import url('fonts.css');
@import url('colours.css');
@import url('layout.css');
@import url('header.css');
@import url('notes.css');
@import url('pagination.css');
@import url('theme-selector.css');
+@import url('admin-tokens.css');
diff --git a/resources/css/fonts.css b/resources/css/fonts.css
new file mode 100644
index 00000000..b6cc66d3
--- /dev/null
+++ b/resources/css/fonts.css
@@ -0,0 +1,61 @@
+/*
+ * Libron (serif, body text) and Cal Sans (sans, headings), both SIL OFL 1.1
+ * Libron v0.31: https://github.com/nicoverbruggen/libron/releases
+ * Cal Sans v2.011: https://github.com/calcom/sans/releases
+ */
+@font-face {
+ font-family: Libron;
+ src: url('/assets/fonts/libron/Libron-Regular.woff2') format('woff2');
+ font-weight: 400;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: Libron;
+ src: url('/assets/fonts/libron/Libron-Italic.woff2') format('woff2');
+ font-weight: 400;
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: Libron;
+ src: url('/assets/fonts/libron/Libron-Bold.woff2') format('woff2');
+ font-weight: 700;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: Libron;
+ src: url('/assets/fonts/libron/Libron-BoldItalic.woff2') format('woff2');
+ font-weight: 700;
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Cal Sans';
+ src: url('/assets/fonts/cal-sans/CalSansVF.woff2') format('woff2');
+ font-weight: 400 700;
+ font-style: normal;
+ font-display: swap;
+}
+
+@layer base {
+ :root {
+ --font-serif: libron, georgia, serif;
+ --font-sans: 'Cal Sans', system-ui, sans-serif;
+ }
+
+ body {
+ font-family: var(--font-serif);
+ }
+
+ h1, h2, h3,
+ h4, h5, h6,
+ body > header nav {
+ font-family: var(--font-sans);
+ }
+}
diff --git a/resources/css/layout.css b/resources/css/layout.css
index dc5f753f..e87cb76d 100644
--- a/resources/css/layout.css
+++ b/resources/css/layout.css
@@ -18,7 +18,17 @@
}
> main {
- grid-column: 2/3;
+ grid-column: 1/-1;
+ display: grid;
+ grid-template-columns: subgrid;
+
+ > * {
+ grid-column: 2/3;
+ }
+
+ > .full-bleed {
+ grid-column: 1/-1;
+ }
}
> footer {
@@ -50,6 +60,23 @@
pre {
padding: 1rem;
}
+
+ .post-info {
+ font-size: 85%;
+ }
}
}
+
+@layer components {
+ .draft-notice {
+ margin-block-end: 2ex;
+ padding: 1ex 1em;
+ border: 2px dashed var(--clr-border);
+ border-radius: 8px;
+ background: light-dark(
+ oklch(95% 0.08 85deg),
+ oklch(30% 0.08 85deg)
+ );
+ }
+}
diff --git a/resources/css/notes.css b/resources/css/notes.css
index 8b4726c5..f93b6c40 100644
--- a/resources/css/notes.css
+++ b/resources/css/notes.css
@@ -7,6 +7,8 @@
padding: 1ex 2ex;
.e-content {
+ font-size: 110%;
+
> p:first-child {
margin-block-start: 0;
}
@@ -17,6 +19,10 @@
}
}
+ .note-metadata {
+ font-size: 85%;
+ }
+
.syndication-links {
display: flex;
flex-direction: row;
diff --git a/resources/css/theme-selector.css b/resources/css/theme-selector.css
index 333639a4..f718b4b0 100644
--- a/resources/css/theme-selector.css
+++ b/resources/css/theme-selector.css
@@ -1,72 +1,68 @@
@layer components {
#theme-selector {
+ display: flex;
+ justify-self: start;
+ align-items: center;
+ gap: .25rem;
+ padding: .25rem;
+ border-radius: 999px;
+ background-color: color-mix(in oklch, var(--clr-border) 40%, transparent);
+
button {
+ display: grid;
+ place-items: center;
appearance: none;
border: none;
- background: none;
+ border-radius: 999px;
+ padding: .375rem;
+ background: transparent;
+ color: inherit;
+ transition: background-color .2s, color .2s;
&:hover {
cursor: pointer;
}
- }
- /* This is the element with the [popover] attribute */
- #theme-selector-dropdown {
- position: absolute;
- position-area: block-end span-inline-start;
- margin: 0;
- border: 2px solid var(--clr-border);
- background-color: var(--clr-background);
- color: var(--clr-text);
-
- fieldset {
- border: 0;
- display: flex;
- flex-direction: row;
- gap: 1ch;
-
- input {
- display: none;
- }
+ &:focus-visible {
+ outline: 2px solid var(--clr-text);
+ outline-offset: 2px;
}
- }
- /*
- * This is the element with the [popover] attribute
- * Here we are styling the open and closing animations
- */
- @media (prefers-reduced-motion: no-preference) {
- #theme-selector-dropdown {
- &:popover-open {
- transform: translateY(0) scale(1);
- opacity: 1;
+ svg {
+ width: 1.5rem;
+ height: 1.5rem;
+ fill: currentcolor;
+ }
- /*
- * Start styles for the opening transition.
- * Added to :popover-open, but after the opened styles.
- */
- @starting-style {
- transform: translateY(30px) scale(0);
- opacity: 0;
- }
+ @media (hover: hover) {
+ &:hover {
+ background-color: color-mix(in oklch, var(--clr-border) 70%, transparent);
}
- /*
- * End styles for the closing transition.
- */
- transform: translateY(0) scale(0);
- opacity: 0;
+ &[aria-pressed="true"]:hover {
+ background-color: var(--clr-text);
+ }
+ }
- /*
- * Enumerate transitioning properties, including display and overlay.
- */
- transition: transform, opacity, display allow-discrete, overlay allow-discrete;
- transition-duration: 0.5s;
- transform-origin: top right;
+ &[aria-pressed="true"] {
+ background-color: var(--clr-text);
+ color: var(--clr-background);
}
}
}
+ .sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip-path: inset(50%);
+ white-space: nowrap;
+ border: 0;
+ }
+
::view-transition-group(changing-theme) {
animation-duration: 1.25s;
}
diff --git a/resources/js/theme-init.js b/resources/js/theme-init.js
new file mode 100644
index 00000000..cba54c8e
--- /dev/null
+++ b/resources/js/theme-init.js
@@ -0,0 +1,12 @@
+/*
+ * Apply a saved theme choice before first paint to avoid a flash of the system theme.
+ * Loaded as a blocking external script (not inline) so it passes the site's CSP.
+ */
+try {
+ const theme = localStorage.getItem('theme');
+ if (theme === 'light' || theme === 'dark') {
+ document.documentElement.style.setProperty('color-scheme', theme);
+ }
+} catch {
+ /* storage unavailable, fall back to the system theme */
+}
diff --git a/resources/js/theme-selector.js b/resources/js/theme-selector.js
index 3248b9bf..ee738872 100644
--- a/resources/js/theme-selector.js
+++ b/resources/js/theme-selector.js
@@ -1,69 +1,91 @@
class ThemeSelector {
constructor() {
this.widget = document.querySelector('#theme-selector');
+ this.btnLight = this.widget.querySelector('#btn-light');
+ this.btnDark = this.widget.querySelector('#btn-dark');
+ this.status = this.widget.querySelector('#theme-status');
+ this.currentTheme = ThemeSelector.storedTheme();
+ if (this.currentTheme !== 'system') {
+ /* backstop in case theme-init.js didn't run, so the page always matches the buttons */
+ document.documentElement.style.setProperty('color-scheme', this.currentTheme);
+ }
+ this.updateButtons();
+ }
+
+ static storedTheme() {
+ try {
+ const theme = localStorage.getItem('theme');
+ return (theme === 'light' || theme === 'dark') ? theme : 'system';
+ } catch {
+ return 'system';
+ }
+ }
+
+ static storeTheme(theme) {
+ try {
+ if (theme === 'system') {
+ localStorage.removeItem('theme');
+ } else {
+ localStorage.setItem('theme', theme);
+ }
+ } catch {
+ /* storage unavailable, the choice just won't persist */
+ }
+ }
+
+ updateButtons() {
+ this.btnLight.setAttribute('aria-pressed', String(this.currentTheme === 'light'));
+ this.btnDark.setAttribute('aria-pressed', String(this.currentTheme === 'dark'));
}
setupEventListeners() {
- this.widget.querySelectorAll('#theme-selector-dropdown input').forEach((radioInput) => radioInput.addEventListener('input', (e) => {
- let theme = e.target.value;
+ this.btnLight.addEventListener('click', () => {
+ this.applyTheme(this.currentTheme === 'light' ? 'system' : 'light');
+ });
- // Update current icon
- this.widget.querySelectorAll('.toggle svg').forEach((svg) => {
- if (svg.classList.contains(theme)) {
- svg.style.display = '';
- } else {
- svg.style.display = 'none';
- }
- });
+ this.btnDark.addEventListener('click', () => {
+ this.applyTheme(this.currentTheme === 'dark' ? 'system' : 'dark');
+ });
+ }
- // Set the theme
- let selectedTheme;
- switch (theme) {
- case 'dark':
- case 'light':
- selectedTheme = theme;
- break;
- default:
- selectedTheme = 'light dark';
- }
+ applyTheme(theme) {
+ const selectedTheme = (theme === 'light' || theme === 'dark') ? theme : 'light dark';
- const systemTheme = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light';
- const html = document.querySelector('html');
- let currentTheme = html.style.getPropertyValue('color-scheme');
- if (currentTheme === '') {
- currentTheme = 'light dark';
- }
+ const systemTheme = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light';
+ const html = document.documentElement;
+ let currentColorScheme = html.style.getPropertyValue('color-scheme');
+ if (currentColorScheme === '') {
+ currentColorScheme = 'light dark';
+ }
- /* do we need to transition */
- let doTransition = false;
+ /* do we need to transition */
+ let doTransition = false;
- if (selectedTheme !== currentTheme) {
- if (selectedTheme === 'light dark') {
- doTransition = currentTheme !== systemTheme;
- } else if (currentTheme === 'light dark') {
- doTransition = selectedTheme !== systemTheme;
- } else {
- doTransition = true;
- }
- }
-
- html.style.viewTransitionName = 'changing-theme';
- if (doTransition && document.startViewTransition) {
- document.startViewTransition(() => {
- // Close the popover
- document.querySelector('#theme-selector-dropdown').togglePopover();
-
- // Set the colour theme
- html.style.setProperty('color-scheme', selectedTheme);
- });
+ if (selectedTheme !== currentColorScheme) {
+ if (selectedTheme === 'light dark') {
+ doTransition = currentColorScheme !== systemTheme;
+ } else if (currentColorScheme === 'light dark') {
+ doTransition = selectedTheme !== systemTheme;
} else {
- // Close the popover
- document.querySelector('#theme-selector-dropdown').togglePopover();
-
- // Set the colour theme
- html.style.setProperty('color-scheme', selectedTheme);
+ doTransition = true;
}
- }));
+ }
+
+ const applyChange = () => {
+ this.currentTheme = theme;
+ html.style.setProperty('color-scheme', selectedTheme);
+ ThemeSelector.storeTheme(theme);
+
+ this.updateButtons();
+ this.status.textContent = theme === 'system' ? 'Theme set to system default' : '';
+ };
+
+ html.style.viewTransitionName = 'changing-theme';
+ if (doTransition && document.startViewTransition) {
+ document.startViewTransition(applyChange);
+ } else {
+ applyChange();
+ }
}
}
diff --git a/resources/views/about.blade.php b/resources/views/about.blade.php
new file mode 100644
index 00000000..e73c933a
--- /dev/null
+++ b/resources/views/about.blade.php
@@ -0,0 +1,9 @@
+@extends('master')
+@section('title')About « @stop
+
+@section('content')
+ About
+
+ {!! $about !!}
+
+@stop
diff --git a/resources/views/admin/about/show.blade.php b/resources/views/admin/about/show.blade.php
new file mode 100644
index 00000000..59c6a433
--- /dev/null
+++ b/resources/views/admin/about/show.blade.php
@@ -0,0 +1,19 @@
+@extends('master')
+
+@section('title')Edit About « Admin CP « @stop
+
+@section('content')
+ Edit About
+
+@stop
diff --git a/resources/views/admin/settings/show.blade.php b/resources/views/admin/settings/show.blade.php
new file mode 100644
index 00000000..801171e1
--- /dev/null
+++ b/resources/views/admin/settings/show.blade.php
@@ -0,0 +1,26 @@
+@extends('master')
+
+@section('title')Site Settings « Admin CP « @stop
+
+@section('content')
+ Site settings
+
+ {{ csrf_field() }}
+ {{ method_field('PUT') }}
+
+
+ winter_effect_enabled))
+ >
+ Show winter snow effect
+
+
+
+ Save
+
+
+@stop
diff --git a/resources/views/admin/tokens/create.blade.php b/resources/views/admin/tokens/create.blade.php
new file mode 100644
index 00000000..d4847d1e
--- /dev/null
+++ b/resources/views/admin/tokens/create.blade.php
@@ -0,0 +1,52 @@
+@extends('master')
+
+@section('title')New Token « Admin CP « @stop
+
+@section('content')
+ Generate a new token
+ Use this for clients that can't complete the IndieAuth authorization flow (e.g. they don't support PKCE) and instead let you paste in a token directly.
+
+
+ {{ csrf_field() }}
+
+
+ Client
+
+
+
+
+ Scope
+
+
+ create
+
+
+
+ update
+
+
+
+
+ Generate token
+
+
+@stop
diff --git a/resources/views/admin/tokens/index.blade.php b/resources/views/admin/tokens/index.blade.php
new file mode 100644
index 00000000..33806cdd
--- /dev/null
+++ b/resources/views/admin/tokens/index.blade.php
@@ -0,0 +1,64 @@
+@extends('master')
+
+@section('title')List Tokens « Admin CP « @stop
+
+@section('content')
+ Micropub Tokens
+ Generate new token
+
+ @if(session('new_token'))
+
+
Here's your new token. Copy it now — it won't be shown again.
+
+
+ @endif
+
+ @if($tokens->isEmpty())
+ No tokens have been issued.
+ @else
+
+
+
+
+ Client
+ Scope
+ Issued
+ Status
+ Action
+
+
+
+ @foreach($tokens as $token)
+
+ {{ $token->client_id }}
+
+
+ @foreach(explode(' ', $token->scope) as $scope)
+ {{ $scope }}
+ @endforeach
+
+
+ {{ $token->created_at->diffForHumans() }}
+
+ @if($token->isRevoked)
+ Revoked {{ $token->revoked_at->diffForHumans() }}
+ @else
+ Active
+ @endif
+
+
+ @unless($token->isRevoked)
+
+ {{ csrf_field() }}
+ {{ method_field('PUT') }}
+ Revoke
+
+ @endunless
+
+
+ @endforeach
+
+
+
+ @endif
+@stop
diff --git a/resources/views/admin/welcome.blade.php b/resources/views/admin/welcome.blade.php
index 269ccdc5..132da7cc 100644
--- a/resources/views/admin/welcome.blade.php
+++ b/resources/views/admin/welcome.blade.php
@@ -47,13 +47,28 @@
or edit them.
+ Tokens
+
+ View and revoke issued Micropub tokens.
+
+
Bio
Edit your bio .
+ About
+
+ Edit your about page .
+
+
Passkeys
Manager your passkeys .
+
+ Settings
+
+ Edit site settings .
+
@stop
diff --git a/resources/views/articles/atom.blade.php b/resources/views/articles/atom.blade.php
deleted file mode 100644
index 9892bcfb..00000000
--- a/resources/views/articles/atom.blade.php
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
- Atom feed for {{ config('user.display_name') }}’s blog
-
- {{ config('app.url')}}/blog
- {{ $articles[0]->updated_at->toAtomString() }}
-
-@foreach($articles as $article)
-
- {{ $article->title }}
-
- {{ config('app.url') }}{{ $article->link }}
- {{ $article->updated_at->toAtomString() }}
- {{ $article->main }}
-
- {{ config('user.display_name') }}
-
-
-@endforeach
-
diff --git a/resources/views/articles/rss.blade.php b/resources/views/articles/rss.blade.php
deleted file mode 100644
index 00268681..00000000
--- a/resources/views/articles/rss.blade.php
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
- {{ config('user.display_name') }}
-
- An RSS feed of the blog posts found on {{ config('app.url') }}
- {{ config('app.url') }}/blog
- {{ $buildDate }}
- 1800
-
-@foreach($articles as $article)
- -
-
{{ strip_tags($article->title) }}
-
- main }}
- @if($article->url)Permalink
@endif
- ]]>
-
- @if($article->url != ''){{ $article->url }}@else{{ config('app.url') }}{{ $article->link }}@endif
- {{ config('app.url') }}{{ $article->link }}
- {{ $article->pubdate }}
-
-@endforeach
-
-
diff --git a/resources/views/articles/show.blade.php b/resources/views/articles/show.blade.php
index dddc6ba2..17af11b1 100644
--- a/resources/views/articles/show.blade.php
+++ b/resources/views/articles/show.blade.php
@@ -1,7 +1,18 @@
@extends('master')
-@section('title'){{ strip_tags($article->title) }} « @stop
+@section('title'){{ $article->published ? '' : '[Draft] ' }}{{ strip_tags($article->title) }} « @stop
+
+@if (! $article->published)
+ @push('head')
+
+ @endpush
+@endif
@section('content')
+ @unless ($article->published)
+
+ Draft — this post hasn’t been published yet. It isn’t listed on the site or in feeds, so only people with this link can see it.
+
+ @endunless
@include('templates.article', ['article' => $article])
@stop
diff --git a/resources/views/icons/json-feed.blade.php b/resources/views/icons/json-feed.blade.php
new file mode 100644
index 00000000..7b8df856
--- /dev/null
+++ b/resources/views/icons/json-feed.blade.php
@@ -0,0 +1,11 @@
+@php
+if (isset($title)) {
+ $uniqueId = bin2hex(random_bytes(6));
+}
+@endphp
+
+ @if($title){{ $title }} @endif
+
+
diff --git a/resources/views/master.blade.php b/resources/views/master.blade.php
index 2e5c6b5a..0af7f507 100644
--- a/resources/views/master.blade.php
+++ b/resources/views/master.blade.php
@@ -5,15 +5,13 @@
@yield('title'){{ config('app.name') }}
+
+
-
-
-
+
-
-
-
+
@@ -26,6 +24,9 @@
@if (File::exists(public_path('gpg.key')))
@endif
+ @stack('head')
+ {{-- Blocking on purpose: applies a saved theme before first paint. Must stay external to satisfy the CSP --}}
+
@@ -40,37 +41,17 @@
Likes
Contacts
Projects
-
+ About
+
-
-
-
-
-
+
+
+
-
-
- Select theme:
-
-
-
-
-
+
+
+
+
@@ -106,14 +87,16 @@
@section('scripts')
-
-
-
-
-
+ @if($winterEffectEnabled ?? false)
+
+
+
+
+
+ @endif
@show