From cb61d9d543e9fb4e787ba4c84216a66cacaaab6c Mon Sep 17 00:00:00 2001 From: BT Date: Sat, 2 May 2026 17:17:13 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A5=20Add=20initial=20database=20migra?= =?UTF-8?q?tions,=20seeders,=20and=20factories=20=F0=9F=8E=A8=20Refactor?= =?UTF-8?q?=20`Lecturer`=20model=20to=20include=20new=20fields=20and=20fac?= =?UTF-8?q?tory=20usage=20=F0=9F=94=A7=20Update=20`DatabaseSeeder`=20to=20?= =?UTF-8?q?handle=20default=20seeds=20=F0=9F=9B=A0=EF=B8=8F=20Enhance=20`e?= =?UTF-8?q?inundzwanzig`=20database=20configuration=20for=20SQLite=20compa?= =?UTF-8?q?tibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .ai/mcp/mcp.json | 6 +- app/Models/Category.php | 3 + app/Models/City.php | 8 + app/Models/Country.php | 5 + app/Models/Course.php | 5 + app/Models/CourseEvent.php | 6 + app/Models/Event.php | 3 + app/Models/Lecturer.php | 8 + app/Models/Meetup.php | 9 + app/Models/MeetupEvent.php | 11 + app/Models/Profile.php | 3 + app/Models/RenderedEvent.php | 3 + app/Models/SecurityAttempt.php | 3 + app/Models/Venue.php | 7 + app/Models/Vote.php | 3 + composer.lock | 869 ++++++++++-------- config/database.php | 10 +- database/factories/CategoryFactory.php | 32 + database/factories/CityFactory.php | 64 ++ database/factories/CountryFactory.php | 51 + database/factories/CourseEventFactory.php | 42 + database/factories/CourseFactory.php | 45 + database/factories/EventFactory.php | 62 ++ database/factories/LecturerFactory.php | 43 + database/factories/MeetupEventFactory.php | 47 + database/factories/MeetupFactory.php | 53 ++ database/factories/ProfileFactory.php | 50 + database/factories/RenderedEventFactory.php | 26 + database/factories/SecurityAttemptFactory.php | 49 + database/factories/VenueFactory.php | 37 + database/factories/VoteFactory.php | 37 + ...26_05_02_155301_create_countries_table.php | 24 + .../2026_05_02_155302_create_cities_table.php | 29 + ...26_05_02_155303_create_lecturers_table.php | 29 + ...6_05_02_155304_create_categories_table.php | 22 + ...2026_05_02_155305_create_meetups_table.php | 30 + ...5_02_155306_create_meetup_events_table.php | 30 + .../2026_05_02_155307_create_venues_table.php | 28 + ...2026_05_02_155308_create_courses_table.php | 27 + ...5_02_155309_create_course_events_table.php | 26 + ...02_155310_create_category_course_table.php | 22 + ..._05_02_155311_create_meetup_user_table.php | 22 + database/seeders/CourseSeeder.php | 55 ++ database/seeders/DatabaseSeeder.php | 21 +- database/seeders/ElectionSeeder.php | 38 + database/seeders/MeetupSeeder.php | 40 + database/seeders/NostrSeeder.php | 64 ++ database/seeders/NotificationSeeder.php | 57 ++ database/seeders/PlebSeeder.php | 111 +++ database/seeders/ProjectProposalSeeder.php | 91 ++ database/seeders/SecuritySeeder.php | 16 + .../association/election/show.blade.php | 2 +- .../association/members/admin.blade.php | 2 +- .../project-support/index.blade.php | 6 +- 54 files changed, 1975 insertions(+), 417 deletions(-) create mode 100644 database/factories/CategoryFactory.php create mode 100644 database/factories/CityFactory.php create mode 100644 database/factories/CountryFactory.php create mode 100644 database/factories/CourseEventFactory.php create mode 100644 database/factories/CourseFactory.php create mode 100644 database/factories/EventFactory.php create mode 100644 database/factories/LecturerFactory.php create mode 100644 database/factories/MeetupEventFactory.php create mode 100644 database/factories/MeetupFactory.php create mode 100644 database/factories/ProfileFactory.php create mode 100644 database/factories/RenderedEventFactory.php create mode 100644 database/factories/SecurityAttemptFactory.php create mode 100644 database/factories/VenueFactory.php create mode 100644 database/factories/VoteFactory.php create mode 100644 database/migrations/2026_05_02_155301_create_countries_table.php create mode 100644 database/migrations/2026_05_02_155302_create_cities_table.php create mode 100644 database/migrations/2026_05_02_155303_create_lecturers_table.php create mode 100644 database/migrations/2026_05_02_155304_create_categories_table.php create mode 100644 database/migrations/2026_05_02_155305_create_meetups_table.php create mode 100644 database/migrations/2026_05_02_155306_create_meetup_events_table.php create mode 100644 database/migrations/2026_05_02_155307_create_venues_table.php create mode 100644 database/migrations/2026_05_02_155308_create_courses_table.php create mode 100644 database/migrations/2026_05_02_155309_create_course_events_table.php create mode 100644 database/migrations/2026_05_02_155310_create_category_course_table.php create mode 100644 database/migrations/2026_05_02_155311_create_meetup_user_table.php create mode 100644 database/seeders/CourseSeeder.php create mode 100644 database/seeders/ElectionSeeder.php create mode 100644 database/seeders/MeetupSeeder.php create mode 100644 database/seeders/NostrSeeder.php create mode 100644 database/seeders/NotificationSeeder.php create mode 100644 database/seeders/PlebSeeder.php create mode 100644 database/seeders/ProjectProposalSeeder.php create mode 100644 database/seeders/SecuritySeeder.php diff --git a/.ai/mcp/mcp.json b/.ai/mcp/mcp.json index 4b9bacd..ff5b8d2 100644 --- a/.ai/mcp/mcp.json +++ b/.ai/mcp/mcp.json @@ -1,11 +1,11 @@ { "mcpServers": { "laravel-boost": { - "command": "php", + "command": "/usr/bin/php", "args": [ - "artisan", + "/var/home/user/Code/einundzwanzig-verein/artisan", "boost:mcp" ] } } -} +} \ No newline at end of file diff --git a/app/Models/Category.php b/app/Models/Category.php index e72c179..2a2cc38 100644 --- a/app/Models/Category.php +++ b/app/Models/Category.php @@ -2,11 +2,14 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsToMany; class Category extends Model { + use HasFactory; + protected $connection = 'einundzwanzig'; /** @var list */ diff --git a/app/Models/City.php b/app/Models/City.php index 9fe5ad7..44e3d9d 100644 --- a/app/Models/City.php +++ b/app/Models/City.php @@ -3,6 +3,7 @@ namespace App\Models; use Akuechler\Geoly; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -13,6 +14,7 @@ use Spatie\Sluggable\SlugOptions; class City extends Model { use Geoly; + use HasFactory; use HasSlug; protected $connection = 'einundzwanzig'; @@ -20,6 +22,12 @@ class City extends Model /** @var list */ protected $fillable = [ 'name', + 'country_id', + 'latitude', + 'longitude', + 'osm_relation', + 'simplified_geojson', + 'created_by', ]; /** diff --git a/app/Models/Country.php b/app/Models/Country.php index 4ea5af0..e7a8205 100644 --- a/app/Models/Country.php +++ b/app/Models/Country.php @@ -2,16 +2,21 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; class Country extends Model { + use HasFactory; + protected $connection = 'einundzwanzig'; /** @var list */ protected $fillable = [ 'name', + 'code', + 'language_codes', ]; /** diff --git a/app/Models/Course.php b/app/Models/Course.php index e9205c2..4aefa06 100644 --- a/app/Models/Course.php +++ b/app/Models/Course.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; @@ -14,6 +15,7 @@ use Spatie\Tags\HasTags; class Course extends Model implements HasMedia { + use HasFactory; use HasTags; use InteractsWithMedia; @@ -23,6 +25,9 @@ class Course extends Model implements HasMedia protected $fillable = [ 'name', 'description', + 'lecturer_id', + 'duration_minutes', + 'created_by', ]; /** diff --git a/app/Models/CourseEvent.php b/app/Models/CourseEvent.php index 668b501..4c57af7 100644 --- a/app/Models/CourseEvent.php +++ b/app/Models/CourseEvent.php @@ -2,17 +2,23 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class CourseEvent extends Model { + use HasFactory; + protected $connection = 'einundzwanzig'; /** @var list */ protected $fillable = [ 'from', 'to', + 'course_id', + 'venue_id', + 'created_by', ]; /** diff --git a/app/Models/Event.php b/app/Models/Event.php index 72cb13c..f4c56c2 100644 --- a/app/Models/Event.php +++ b/app/Models/Event.php @@ -2,10 +2,13 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Event extends Model { + use HasFactory; + /** @var list */ protected $fillable = [ 'event_id', diff --git a/app/Models/Lecturer.php b/app/Models/Lecturer.php index f333ea6..6fe006c 100644 --- a/app/Models/Lecturer.php +++ b/app/Models/Lecturer.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -16,6 +17,7 @@ use Spatie\Sluggable\SlugOptions; class Lecturer extends Model implements HasMedia { + use HasFactory; use HasSlug; use InteractsWithMedia; @@ -24,6 +26,12 @@ class Lecturer extends Model implements HasMedia /** @var list */ protected $fillable = [ 'name', + 'bio', + 'npub', + 'pubkey', + 'website', + 'active', + 'created_by', ]; /** diff --git a/app/Models/Meetup.php b/app/Models/Meetup.php index e8f5ef8..d569599 100644 --- a/app/Models/Meetup.php +++ b/app/Models/Meetup.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Casts\Attribute; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -16,6 +17,7 @@ use Spatie\Sluggable\SlugOptions; class Meetup extends Model implements HasMedia { + use HasFactory; use HasSlug; use InteractsWithMedia; @@ -24,6 +26,13 @@ class Meetup extends Model implements HasMedia /** @var list */ protected $fillable = [ 'name', + 'city_id', + 'description', + 'website', + 'nostr_pubkey', + 'github_data', + 'simplified_geojson', + 'created_by', ]; /** diff --git a/app/Models/MeetupEvent.php b/app/Models/MeetupEvent.php index 888b44d..38114e9 100644 --- a/app/Models/MeetupEvent.php +++ b/app/Models/MeetupEvent.php @@ -2,16 +2,27 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class MeetupEvent extends Model { + use HasFactory; + protected $connection = 'einundzwanzig'; /** @var list */ protected $fillable = [ 'start', + 'meetup_id', + 'location', + 'description', + 'link', + 'attendees', + 'might_attendees', + 'nostr_status', + 'created_by', ]; /** diff --git a/app/Models/Profile.php b/app/Models/Profile.php index 26321ee..8a3a0ad 100644 --- a/app/Models/Profile.php +++ b/app/Models/Profile.php @@ -2,10 +2,13 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Profile extends Model { + use HasFactory; + /** @var list */ protected $fillable = [ 'pubkey', diff --git a/app/Models/RenderedEvent.php b/app/Models/RenderedEvent.php index 21be49c..8c4744f 100644 --- a/app/Models/RenderedEvent.php +++ b/app/Models/RenderedEvent.php @@ -2,10 +2,13 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class RenderedEvent extends Model { + use HasFactory; + /** @var list */ protected $fillable = [ 'event_id', diff --git a/app/Models/SecurityAttempt.php b/app/Models/SecurityAttempt.php index 1dc8592..9dca70c 100644 --- a/app/Models/SecurityAttempt.php +++ b/app/Models/SecurityAttempt.php @@ -3,10 +3,13 @@ namespace App\Models; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class SecurityAttempt extends Model { + use HasFactory; + protected $fillable = [ 'ip_address', 'user_agent', diff --git a/app/Models/Venue.php b/app/Models/Venue.php index aadf1a7..285cf0a 100644 --- a/app/Models/Venue.php +++ b/app/Models/Venue.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -16,6 +17,7 @@ use Staudenmeir\EloquentHasManyDeep\HasRelationships; class Venue extends Model implements HasMedia { + use HasFactory; use HasRelationships; use HasSlug; use InteractsWithMedia; @@ -25,6 +27,11 @@ class Venue extends Model implements HasMedia /** @var list */ protected $fillable = [ 'name', + 'city_id', + 'description', + 'address', + 'website', + 'created_by', ]; /** diff --git a/app/Models/Vote.php b/app/Models/Vote.php index 7cd8576..ea9d983 100644 --- a/app/Models/Vote.php +++ b/app/Models/Vote.php @@ -2,11 +2,14 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class Vote extends Model { + use HasFactory; + /** @var list */ protected $fillable = [ 'einundzwanzig_pleb_id', diff --git a/composer.lock b/composer.lock index cbbaf63..3affde9 100644 --- a/composer.lock +++ b/composer.lock @@ -1822,16 +1822,16 @@ }, { "name": "laravel/framework", - "version": "v13.2.0", + "version": "v13.7.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "9e48d1fe933e89de628dafa167d2c5778566d4cf" + "reference": "f13b85b2cce7ef5e8f3bcdf2b6c6364bbdedae0b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/9e48d1fe933e89de628dafa167d2c5778566d4cf", - "reference": "9e48d1fe933e89de628dafa167d2c5778566d4cf", + "url": "https://api.github.com/repos/laravel/framework/zipball/f13b85b2cce7ef5e8f3bcdf2b6c6364bbdedae0b", + "reference": "f13b85b2cce7ef5e8f3bcdf2b6c6364bbdedae0b", "shasum": "" }, "require": { @@ -1874,6 +1874,7 @@ "symfony/mime": "^7.4.0 || ^8.0.0", "symfony/polyfill-php84": "^1.33", "symfony/polyfill-php85": "^1.33", + "symfony/polyfill-php86": "^1.36", "symfony/process": "^7.4.5 || ^8.0.5", "symfony/routing": "^7.4.0 || ^8.0.0", "symfony/uid": "^7.4.0 || ^8.0.0", @@ -1949,6 +1950,7 @@ "phpstan/phpstan": "^2.0", "phpunit/phpunit": "^11.5.50 || ^12.5.8 || ^13.0.3", "predis/predis": "^2.3 || ^3.0", + "rector/rector": "^2.3", "resend/resend-php": "^1.0", "symfony/cache": "^7.4.0 || ^8.0.0", "symfony/http-client": "^7.4.0 || ^8.0.0", @@ -1984,6 +1986,7 @@ "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0 || ^7.0).", "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0 || ^1.0).", + "spatie/fork": "Required to use the 'fork' concurrency driver (^1.2).", "symfony/cache": "Required to PSR-6 cache bridge (^7.4 || ^8.0).", "symfony/filesystem": "Required to enable support for relative symbolic links (^7.4 || ^8.0).", "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.4 || ^8.0).", @@ -2039,20 +2042,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-03-24T18:42:09+00:00" + "time": "2026-04-28T17:18:25+00:00" }, { "name": "laravel/nightwatch", - "version": "v1.24.4", + "version": "1.26.1", "source": { "type": "git", "url": "https://github.com/laravel/nightwatch.git", - "reference": "127e9bb9928f0fcf69b52b244053b393c90347c8" + "reference": "9212390822f80e6e3e4f399ad7818c551d94af71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/nightwatch/zipball/127e9bb9928f0fcf69b52b244053b393c90347c8", - "reference": "127e9bb9928f0fcf69b52b244053b393c90347c8", + "url": "https://api.github.com/repos/laravel/nightwatch/zipball/9212390822f80e6e3e4f399ad7818c551d94af71", + "reference": "9212390822f80e6e3e4f399ad7818c551d94af71", "shasum": "" }, "require": { @@ -2081,9 +2084,9 @@ "livewire/livewire": "^2.0|^3.0", "mockery/mockery": "^1.0", "mongodb/laravel-mongodb": "^4.0|^5.0", - "orchestra/testbench": "^8.0|^9.0|^10.0", - "orchestra/testbench-core": "^8.0|^9.0|^10.0", - "orchestra/workbench": "^8.0|^9.0|^10.0", + "orchestra/testbench": "^8.0|^9.0|^10.0|^11.0", + "orchestra/testbench-core": "^8.0|^9.0|^10.0|^11.0", + "orchestra/workbench": "^8.0|^9.0|^10.0|^11.0", "phpstan/phpstan": "^1.0", "phpunit/phpunit": "^10.0|^11.0|^12.0", "singlestoredb/singlestoredb-laravel": "^1.0|^2.0", @@ -2133,20 +2136,20 @@ "issues": "https://github.com/laravel/nightwatch/issues", "source": "https://github.com/laravel/nightwatch" }, - "time": "2026-03-18T23:25:05+00:00" + "time": "2026-04-13T03:38:38+00:00" }, { "name": "laravel/prompts", - "version": "v0.3.16", + "version": "v0.3.17", "source": { "type": "git", "url": "https://github.com/laravel/prompts.git", - "reference": "11e7d5f93803a2190b00e145142cb00a33d17ad2" + "reference": "6a82ac19a28b916ae0885828795dbd4c59d9a818" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/11e7d5f93803a2190b00e145142cb00a33d17ad2", - "reference": "11e7d5f93803a2190b00e145142cb00a33d17ad2", + "url": "https://api.github.com/repos/laravel/prompts/zipball/6a82ac19a28b916ae0885828795dbd4c59d9a818", + "reference": "6a82ac19a28b916ae0885828795dbd4c59d9a818", "shasum": "" }, "require": { @@ -2190,22 +2193,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.16" + "source": "https://github.com/laravel/prompts/tree/v0.3.17" }, - "time": "2026-03-23T14:35:33+00:00" + "time": "2026-04-20T16:07:33+00:00" }, { "name": "laravel/reverb", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/laravel/reverb.git", - "reference": "7a1ef2235cfe085cdf3190d0dcfaed4f7d251734" + "reference": "a9c2b24ba455d0b2c22bb2851c15ba1adcb75240" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/reverb/zipball/7a1ef2235cfe085cdf3190d0dcfaed4f7d251734", - "reference": "7a1ef2235cfe085cdf3190d0dcfaed4f7d251734", + "url": "https://api.github.com/repos/laravel/reverb/zipball/a9c2b24ba455d0b2c22bb2851c15ba1adcb75240", + "reference": "a9c2b24ba455d0b2c22bb2851c15ba1adcb75240", "shasum": "" }, "require": { @@ -2269,22 +2272,22 @@ ], "support": { "issues": "https://github.com/laravel/reverb/issues", - "source": "https://github.com/laravel/reverb/tree/v1.9.0" + "source": "https://github.com/laravel/reverb/tree/v1.10.0" }, - "time": "2026-03-20T20:16:59+00:00" + "time": "2026-03-29T14:51:57+00:00" }, { "name": "laravel/serializable-closure", - "version": "v2.0.10", + "version": "v2.0.13", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "870fc81d2f879903dfc5b60bf8a0f94a1609e669" + "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/870fc81d2f879903dfc5b60bf8a0f94a1609e669", - "reference": "870fc81d2f879903dfc5b60bf8a0f94a1609e669", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/b566ee0dd251f3c4078bed003a7ce015f5ea6dce", + "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce", "shasum": "" }, "require": { @@ -2332,20 +2335,20 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2026-02-20T19:59:49+00:00" + "time": "2026-04-16T14:03:50+00:00" }, { "name": "laravel/tinker", - "version": "v3.0.0", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/laravel/tinker.git", - "reference": "cc74081282ba2e3dae1f0068ccb330370d24634e" + "reference": "4faba77764bd33411735936acdf30446d058c78b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/cc74081282ba2e3dae1f0068ccb330370d24634e", - "reference": "cc74081282ba2e3dae1f0068ccb330370d24634e", + "url": "https://api.github.com/repos/laravel/tinker/zipball/4faba77764bd33411735936acdf30446d058c78b", + "reference": "4faba77764bd33411735936acdf30446d058c78b", "shasum": "" }, "require": { @@ -2399,9 +2402,9 @@ ], "support": { "issues": "https://github.com/laravel/tinker/issues", - "source": "https://github.com/laravel/tinker/tree/v3.0.0" + "source": "https://github.com/laravel/tinker/tree/v3.0.2" }, - "time": "2026-03-17T14:53:17+00:00" + "time": "2026-03-17T14:54:13+00:00" }, { "name": "league/commonmark", @@ -2964,16 +2967,16 @@ }, { "name": "livewire/flux", - "version": "v2.13.1", + "version": "v2.14.1", "source": { "type": "git", "url": "https://github.com/livewire/flux.git", - "reference": "5bee3d50ea8382e178d2b10a3412a82e6ecfb4a3" + "reference": "44f240efd186b5629d5e4c4a4cc7bbba0111fb48" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/flux/zipball/5bee3d50ea8382e178d2b10a3412a82e6ecfb4a3", - "reference": "5bee3d50ea8382e178d2b10a3412a82e6ecfb4a3", + "url": "https://api.github.com/repos/livewire/flux/zipball/44f240efd186b5629d5e4c4a4cc7bbba0111fb48", + "reference": "44f240efd186b5629d5e4c4a4cc7bbba0111fb48", "shasum": "" }, "require": { @@ -3024,25 +3027,25 @@ ], "support": { "issues": "https://github.com/livewire/flux/issues", - "source": "https://github.com/livewire/flux/tree/v2.13.1" + "source": "https://github.com/livewire/flux/tree/v2.14.1" }, - "time": "2026-03-26T00:02:01+00:00" + "time": "2026-04-23T23:00:08+00:00" }, { "name": "livewire/flux-pro", - "version": "2.13.1", + "version": "2.14.1", "dist": { "type": "zip", - "url": "https://composer.fluxui.dev/download/a16373f8-0de4-4b5e-b741-1ca11754c32b/flux-pro-2.13.1.zip", - "reference": "3a764f5bfc8733a4cb43459ae2cb797377725165", - "shasum": "40cd2207c66885e856315a258990443329e6e7a3" + "url": "https://composer.fluxui.dev/download/a19daa53-2ce1-4180-8867-7bf8cf84639a/flux-pro-2.14.1.zip", + "reference": "61404a28ab2271b5381a784c9c6727a4a38124de", + "shasum": "eb709ab3bb9493ecc4bad3c084dd951fe3247ce3" }, "require": { "illuminate/console": "^10.0|^11.0|^12.0|^13.0", "illuminate/support": "^10.0|^11.0|^12.0|^13.0", "illuminate/view": "^10.0|^11.0|^12.0|^13.0", "laravel/prompts": "^0.1.24|^0.2|^0.3", - "livewire/flux": "2.13.1|dev-main", + "livewire/flux": "2.14.1|dev-main", "livewire/livewire": "^3.7.4|^4.0", "php": "^8.1", "symfony/console": "^6.0|^7.0|^8.0" @@ -3099,20 +3102,20 @@ "livewire", "ui" ], - "time": "2026-03-26T00:33:15+00:00" + "time": "2026-04-23T23:03:15+00:00" }, { "name": "livewire/livewire", - "version": "v4.2.2", + "version": "v4.3.0", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "71c28888f99b4bfdaad89a07a104adbc3f98c04b" + "reference": "19ebb1ee4d057debceccf70ff01950e6a6114edc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/71c28888f99b4bfdaad89a07a104adbc3f98c04b", - "reference": "71c28888f99b4bfdaad89a07a104adbc3f98c04b", + "url": "https://api.github.com/repos/livewire/livewire/zipball/19ebb1ee4d057debceccf70ff01950e6a6114edc", + "reference": "19ebb1ee4d057debceccf70ff01950e6a6114edc", "shasum": "" }, "require": { @@ -3167,7 +3170,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v4.2.2" + "source": "https://github.com/livewire/livewire/tree/v4.3.0" }, "funding": [ { @@ -3175,7 +3178,7 @@ "type": "github" } ], - "time": "2026-03-25T23:19:23+00:00" + "time": "2026-05-01T00:46:07+00:00" }, { "name": "livewire/volt", @@ -3250,16 +3253,16 @@ }, { "name": "maennchen/zipstream-php", - "version": "3.2.1", + "version": "3.2.2", "source": { "type": "git", "url": "https://github.com/maennchen/ZipStream-PHP.git", - "reference": "682f1098a8fddbaf43edac2306a691c7ad508ec5" + "reference": "77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/682f1098a8fddbaf43edac2306a691c7ad508ec5", - "reference": "682f1098a8fddbaf43edac2306a691c7ad508ec5", + "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e", + "reference": "77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e", "shasum": "" }, "require": { @@ -3316,7 +3319,7 @@ ], "support": { "issues": "https://github.com/maennchen/ZipStream-PHP/issues", - "source": "https://github.com/maennchen/ZipStream-PHP/tree/3.2.1" + "source": "https://github.com/maennchen/ZipStream-PHP/tree/3.2.2" }, "funding": [ { @@ -3324,7 +3327,7 @@ "type": "github" } ], - "time": "2025-12-10T09:58:31+00:00" + "time": "2026-04-11T18:38:28+00:00" }, { "name": "monolog/monolog", @@ -3431,16 +3434,16 @@ }, { "name": "nesbot/carbon", - "version": "3.11.3", + "version": "3.11.4", "source": { "type": "git", "url": "https://github.com/CarbonPHP/carbon.git", - "reference": "6a7e652845bb018c668220c2a545aded8594fbbf" + "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/6a7e652845bb018c668220c2a545aded8594fbbf", - "reference": "6a7e652845bb018c668220c2a545aded8594fbbf", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/e890471a3494740f7d9326d72ce6a8c559ffee60", + "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60", "shasum": "" }, "require": { @@ -3532,7 +3535,7 @@ "type": "tidelift" } ], - "time": "2026-03-11T17:23:39+00:00" + "time": "2026-04-07T09:57:54+00:00" }, { "name": "nette/schema", @@ -4857,35 +4860,36 @@ }, { "name": "phrity/websocket", - "version": "3.6.2", + "version": "3.7.0", "source": { "type": "git", "url": "https://github.com/sirn-se/websocket-php.git", - "reference": "b9816ed2b4a10c8c42bd0b6398044ab506869756" + "reference": "01f15374987d8281dba0ca511f322a0e18229330" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sirn-se/websocket-php/zipball/b9816ed2b4a10c8c42bd0b6398044ab506869756", - "reference": "b9816ed2b4a10c8c42bd0b6398044ab506869756", + "url": "https://api.github.com/repos/sirn-se/websocket-php/zipball/01f15374987d8281dba0ca511f322a0e18229330", + "reference": "01f15374987d8281dba0ca511f322a0e18229330", "shasum": "" }, "require": { + "nyholm/psr7": "^1.4", "php": "^8.1", - "phrity/http": "^1.0", - "phrity/net-stream": "^2.3", + "phrity/http": "^1.1", + "phrity/net-stream": "^2.4", "phrity/net-uri": "^2.1", - "psr/http-message": "^1.1 | ^2.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", "psr/log": "^1.0 || ^2.0 || ^3.0" }, "require-dev": { - "guzzlehttp/psr7": "^2.0", "phpstan/phpstan": "^2.0", - "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0 || ^13.0", "phrity/logger-console": "^1.0", - "phrity/net-mock": "^2.3", + "phrity/net-mock": "^2.4", "phrity/util-errorhandler": "^1.1", "robiningelbrecht/phpunit-coverage-tools": "^1.9", - "squizlabs/php_codesniffer": "^3.5 || ^4.0" + "squizlabs/php_codesniffer": "^4.0" }, "type": "library", "autoload": { @@ -4916,22 +4920,22 @@ ], "support": { "issues": "https://github.com/sirn-se/websocket-php/issues", - "source": "https://github.com/sirn-se/websocket-php/tree/3.6.2" + "source": "https://github.com/sirn-se/websocket-php/tree/3.7.0" }, - "time": "2025-12-21T09:58:16+00:00" + "time": "2026-04-06T18:18:14+00:00" }, { "name": "power-components/livewire-powergrid", - "version": "v6.9.2", + "version": "v6.10.0", "source": { "type": "git", "url": "https://github.com/Power-Components/livewire-powergrid.git", - "reference": "2a0adb116e0e20b0e0cacadeca1b77194883d337" + "reference": "01737362c6f5384c1725d0f6f6fbbd1c30c1be72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Power-Components/livewire-powergrid/zipball/2a0adb116e0e20b0e0cacadeca1b77194883d337", - "reference": "2a0adb116e0e20b0e0cacadeca1b77194883d337", + "url": "https://api.github.com/repos/Power-Components/livewire-powergrid/zipball/01737362c6f5384c1725d0f6f6fbbd1c30c1be72", + "reference": "01737362c6f5384c1725d0f6f6fbbd1c30c1be72", "shasum": "" }, "require": { @@ -4988,7 +4992,7 @@ "homepage": "https://github.com/power-components/livewire-powergrid", "support": { "issues": "https://github.com/Power-Components/livewire-powergrid/issues", - "source": "https://github.com/Power-Components/livewire-powergrid/tree/v6.9.2" + "source": "https://github.com/Power-Components/livewire-powergrid/tree/v6.10.0" }, "funding": [ { @@ -4996,7 +5000,7 @@ "type": "github" } ], - "time": "2026-03-04T12:47:30+00:00" + "time": "2026-04-25T15:21:23+00:00" }, { "name": "psr/clock", @@ -6491,16 +6495,16 @@ }, { "name": "sentry/sentry", - "version": "4.23.0", + "version": "4.25.0", "source": { "type": "git", "url": "https://github.com/getsentry/sentry-php.git", - "reference": "121a674d5fffcdb8e414b75c1b76edba8e592b66" + "reference": "bfee3381e1f6dea8a5f3a18adba6419fe81c5f54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/121a674d5fffcdb8e414b75c1b76edba8e592b66", - "reference": "121a674d5fffcdb8e414b75c1b76edba8e592b66", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/bfee3381e1f6dea8a5f3a18adba6419fe81c5f54", + "reference": "bfee3381e1f6dea8a5f3a18adba6419fe81c5f54", "shasum": "" }, "require": { @@ -6532,6 +6536,7 @@ "spiral/roadrunner-worker": "^3.6" }, "suggest": { + "ext-excimer": "Enable Sentry profiling with the Excimer PHP extension.", "monolog/monolog": "Allow sending log messages to Sentry by using the included Monolog handler." }, "type": "library", @@ -6568,7 +6573,7 @@ ], "support": { "issues": "https://github.com/getsentry/sentry-php/issues", - "source": "https://github.com/getsentry/sentry-php/tree/4.23.0" + "source": "https://github.com/getsentry/sentry-php/tree/4.25.0" }, "funding": [ { @@ -6580,20 +6585,20 @@ "type": "custom" } ], - "time": "2026-03-23T13:15:52+00:00" + "time": "2026-04-23T12:50:03+00:00" }, { "name": "sentry/sentry-laravel", - "version": "4.24.0", + "version": "4.25.0", "source": { "type": "git", "url": "https://github.com/getsentry/sentry-laravel.git", - "reference": "f823bd85e38e06cb4f1b7a82d48a2fc95320b31d" + "reference": "6699c9465df6bee07d82279f7a209db941913456" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/f823bd85e38e06cb4f1b7a82d48a2fc95320b31d", - "reference": "f823bd85e38e06cb4f1b7a82d48a2fc95320b31d", + "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/6699c9465df6bee07d82279f7a209db941913456", + "reference": "6699c9465df6bee07d82279f7a209db941913456", "shasum": "" }, "require": { @@ -6659,7 +6664,7 @@ ], "support": { "issues": "https://github.com/getsentry/sentry-laravel/issues", - "source": "https://github.com/getsentry/sentry-laravel/tree/4.24.0" + "source": "https://github.com/getsentry/sentry-laravel/tree/4.25.0" }, "funding": [ { @@ -6671,7 +6676,7 @@ "type": "custom" } ], - "time": "2026-03-24T10:33:54+00:00" + "time": "2026-04-07T12:55:27+00:00" }, { "name": "simplesoftwareio/simple-qrcode", @@ -7387,16 +7392,16 @@ }, { "name": "spatie/laravel-google-fonts", - "version": "1.5.0", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-google-fonts.git", - "reference": "d68f49d35532ec16eade427ca12c00136350bcfd" + "reference": "aaac1cedd48c4c8436b4eb51d9b5e30bd4bd914a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-google-fonts/zipball/d68f49d35532ec16eade427ca12c00136350bcfd", - "reference": "d68f49d35532ec16eade427ca12c00136350bcfd", + "url": "https://api.github.com/repos/spatie/laravel-google-fonts/zipball/aaac1cedd48c4c8436b4eb51d9b5e30bd4bd914a", + "reference": "aaac1cedd48c4c8436b4eb51d9b5e30bd4bd914a", "shasum": "" }, "require": { @@ -7457,7 +7462,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-google-fonts/issues", - "source": "https://github.com/spatie/laravel-google-fonts/tree/1.5.0" + "source": "https://github.com/spatie/laravel-google-fonts/tree/1.6.0" }, "funding": [ { @@ -7465,7 +7470,7 @@ "type": "github" } ], - "time": "2026-02-22T18:45:01+00:00" + "time": "2026-04-27T16:38:35+00:00" }, { "name": "spatie/laravel-markdown", @@ -7545,16 +7550,16 @@ }, { "name": "spatie/laravel-medialibrary", - "version": "11.21.0", + "version": "11.22.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-medialibrary.git", - "reference": "d6e2595033ffd130d4dd5d124510ab3304794c44" + "reference": "a80f584d93bad370ca7a0efa52c16a1a81e6e9fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-medialibrary/zipball/d6e2595033ffd130d4dd5d124510ab3304794c44", - "reference": "d6e2595033ffd130d4dd5d124510ab3304794c44", + "url": "https://api.github.com/repos/spatie/laravel-medialibrary/zipball/a80f584d93bad370ca7a0efa52c16a1a81e6e9fe", + "reference": "a80f584d93bad370ca7a0efa52c16a1a81e6e9fe", "shasum": "" }, "require": { @@ -7639,7 +7644,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-medialibrary/issues", - "source": "https://github.com/spatie/laravel-medialibrary/tree/11.21.0" + "source": "https://github.com/spatie/laravel-medialibrary/tree/11.22.0" }, "funding": [ { @@ -7651,7 +7656,7 @@ "type": "github" } ], - "time": "2026-02-21T15:58:56+00:00" + "time": "2026-04-28T09:18:56+00:00" }, { "name": "spatie/laravel-package-tools", @@ -7920,16 +7925,16 @@ }, { "name": "spatie/laravel-translatable", - "version": "6.13.0", + "version": "6.14.1", "source": { "type": "git", "url": "https://github.com/spatie/laravel-translatable.git", - "reference": "f2c5b8805a2dd22799c9aa8ce66cd98ce3170dcb" + "reference": "d120a925cf413b2427f886264bb6eb102ac23d42" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-translatable/zipball/f2c5b8805a2dd22799c9aa8ce66cd98ce3170dcb", - "reference": "f2c5b8805a2dd22799c9aa8ce66cd98ce3170dcb", + "url": "https://api.github.com/repos/spatie/laravel-translatable/zipball/d120a925cf413b2427f886264bb6eb102ac23d42", + "reference": "d120a925cf413b2427f886264bb6eb102ac23d42", "shasum": "" }, "require": { @@ -7991,7 +7996,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-translatable/issues", - "source": "https://github.com/spatie/laravel-translatable/tree/6.13.0" + "source": "https://github.com/spatie/laravel-translatable/tree/6.14.1" }, "funding": [ { @@ -7999,20 +8004,20 @@ "type": "github" } ], - "time": "2026-02-21T14:20:19+00:00" + "time": "2026-04-23T08:26:29+00:00" }, { "name": "spatie/shiki-php", - "version": "2.3.3", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/spatie/shiki-php.git", - "reference": "9d50ff4d9825d87d3283a6695c65ae9c3c3caa6b" + "reference": "b8b0ca32d3a82bc5c533e68ffab96c5d4ec1b9ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/shiki-php/zipball/9d50ff4d9825d87d3283a6695c65ae9c3c3caa6b", - "reference": "9d50ff4d9825d87d3283a6695c65ae9c3c3caa6b", + "url": "https://api.github.com/repos/spatie/shiki-php/zipball/b8b0ca32d3a82bc5c533e68ffab96c5d4ec1b9ba", + "reference": "b8b0ca32d3a82bc5c533e68ffab96c5d4ec1b9ba", "shasum": "" }, "require": { @@ -8056,7 +8061,7 @@ "spatie" ], "support": { - "source": "https://github.com/spatie/shiki-php/tree/2.3.3" + "source": "https://github.com/spatie/shiki-php/tree/2.4.0" }, "funding": [ { @@ -8064,7 +8069,7 @@ "type": "github" } ], - "time": "2026-02-01T09:30:04+00:00" + "time": "2026-04-27T14:27:52+00:00" }, { "name": "spatie/temporary-directory", @@ -8301,16 +8306,16 @@ }, { "name": "symfony/clock", - "version": "v8.0.0", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/clock.git", - "reference": "832119f9b8dbc6c8e6f65f30c5969eca1e88764f" + "reference": "b55a638b189a6faa875e0ccdb00908fb87af95b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/832119f9b8dbc6c8e6f65f30c5969eca1e88764f", - "reference": "832119f9b8dbc6c8e6f65f30c5969eca1e88764f", + "url": "https://api.github.com/repos/symfony/clock/zipball/b55a638b189a6faa875e0ccdb00908fb87af95b3", + "reference": "b55a638b189a6faa875e0ccdb00908fb87af95b3", "shasum": "" }, "require": { @@ -8354,7 +8359,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v8.0.0" + "source": "https://github.com/symfony/clock/tree/v8.0.8" }, "funding": [ { @@ -8374,20 +8379,20 @@ "type": "tidelift" } ], - "time": "2025-11-12T15:46:48+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/console", - "version": "v8.0.7", + "version": "v8.0.9", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "15ed9008a4ebe2d6a78e4937f74e0c13ef2e618a" + "reference": "7113778e2e91f4709cb3194a75dfa9c0d028d94d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/15ed9008a4ebe2d6a78e4937f74e0c13ef2e618a", - "reference": "15ed9008a4ebe2d6a78e4937f74e0c13ef2e618a", + "url": "https://api.github.com/repos/symfony/console/zipball/7113778e2e91f4709cb3194a75dfa9c0d028d94d", + "reference": "7113778e2e91f4709cb3194a75dfa9c0d028d94d", "shasum": "" }, "require": { @@ -8444,7 +8449,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v8.0.7" + "source": "https://github.com/symfony/console/tree/v8.0.9" }, "funding": [ { @@ -8464,20 +8469,20 @@ "type": "tidelift" } ], - "time": "2026-03-06T14:06:22+00:00" + "time": "2026-04-29T15:02:55+00:00" }, { "name": "symfony/css-selector", - "version": "v8.0.6", + "version": "v8.0.9", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "2a178bf80f05dbbe469a337730eba79d61315262" + "reference": "3665cfade90565430909b906394c73c8739e57d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/2a178bf80f05dbbe469a337730eba79d61315262", - "reference": "2a178bf80f05dbbe469a337730eba79d61315262", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/3665cfade90565430909b906394c73c8739e57d0", + "reference": "3665cfade90565430909b906394c73c8739e57d0", "shasum": "" }, "require": { @@ -8513,7 +8518,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v8.0.6" + "source": "https://github.com/symfony/css-selector/tree/v8.0.9" }, "funding": [ { @@ -8533,7 +8538,7 @@ "type": "tidelift" } ], - "time": "2026-02-17T13:07:04+00:00" + "time": "2026-04-18T13:51:42+00:00" }, { "name": "symfony/deprecation-contracts", @@ -8604,16 +8609,16 @@ }, { "name": "symfony/error-handler", - "version": "v8.0.4", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "7620b97ec0ab1d2d6c7fb737aa55da411bea776a" + "reference": "c1119fe8dcfc3825ec74ec061b96ef0c8f281517" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/7620b97ec0ab1d2d6c7fb737aa55da411bea776a", - "reference": "7620b97ec0ab1d2d6c7fb737aa55da411bea776a", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/c1119fe8dcfc3825ec74ec061b96ef0c8f281517", + "reference": "c1119fe8dcfc3825ec74ec061b96ef0c8f281517", "shasum": "" }, "require": { @@ -8661,7 +8666,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.0.4" + "source": "https://github.com/symfony/error-handler/tree/v8.0.8" }, "funding": [ { @@ -8681,20 +8686,20 @@ "type": "tidelift" } ], - "time": "2026-01-23T11:07:10+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v8.0.4", + "version": "v8.0.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "99301401da182b6cfaa4700dbe9987bb75474b47" + "reference": "0c3c1a17604c4dbbec4b93fe162c538482096e1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/99301401da182b6cfaa4700dbe9987bb75474b47", - "reference": "99301401da182b6cfaa4700dbe9987bb75474b47", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/0c3c1a17604c4dbbec4b93fe162c538482096e1f", + "reference": "0c3c1a17604c4dbbec4b93fe162c538482096e1f", "shasum": "" }, "require": { @@ -8746,7 +8751,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.0.4" + "source": "https://github.com/symfony/event-dispatcher/tree/v8.0.9" }, "funding": [ { @@ -8766,7 +8771,7 @@ "type": "tidelift" } ], - "time": "2026-01-05T11:45:55+00:00" + "time": "2026-04-18T13:51:42+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -8846,16 +8851,16 @@ }, { "name": "symfony/finder", - "version": "v8.0.6", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "441404f09a54de6d1bd6ad219e088cdf4c91f97c" + "reference": "8da41214757b87d97f181e3d14a4179286151007" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/441404f09a54de6d1bd6ad219e088cdf4c91f97c", - "reference": "441404f09a54de6d1bd6ad219e088cdf4c91f97c", + "url": "https://api.github.com/repos/symfony/finder/zipball/8da41214757b87d97f181e3d14a4179286151007", + "reference": "8da41214757b87d97f181e3d14a4179286151007", "shasum": "" }, "require": { @@ -8890,7 +8895,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v8.0.6" + "source": "https://github.com/symfony/finder/tree/v8.0.8" }, "funding": [ { @@ -8910,20 +8915,20 @@ "type": "tidelift" } ], - "time": "2026-01-29T09:41:02+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/http-foundation", - "version": "v8.0.7", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "c5ecf7b07408dbc4a87482634307654190954ae8" + "reference": "02656f7ebeae5c155d659e946f6b3a33df24051b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/c5ecf7b07408dbc4a87482634307654190954ae8", - "reference": "c5ecf7b07408dbc4a87482634307654190954ae8", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/02656f7ebeae5c155d659e946f6b3a33df24051b", + "reference": "02656f7ebeae5c155d659e946f6b3a33df24051b", "shasum": "" }, "require": { @@ -8970,7 +8975,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.0.7" + "source": "https://github.com/symfony/http-foundation/tree/v8.0.8" }, "funding": [ { @@ -8990,20 +8995,20 @@ "type": "tidelift" } ], - "time": "2026-03-06T13:17:40+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/http-kernel", - "version": "v8.0.7", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "c04721f45723d8ce049fa3eee378b5a505272ac7" + "reference": "1770f6818d83b2fddc12185025b93f39a90cb628" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/c04721f45723d8ce049fa3eee378b5a505272ac7", - "reference": "c04721f45723d8ce049fa3eee378b5a505272ac7", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/1770f6818d83b2fddc12185025b93f39a90cb628", + "reference": "1770f6818d83b2fddc12185025b93f39a90cb628", "shasum": "" }, "require": { @@ -9074,7 +9079,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.0.7" + "source": "https://github.com/symfony/http-kernel/tree/v8.0.8" }, "funding": [ { @@ -9094,20 +9099,20 @@ "type": "tidelift" } ], - "time": "2026-03-06T16:58:46+00:00" + "time": "2026-03-31T21:14:05+00:00" }, { "name": "symfony/mailer", - "version": "v8.0.6", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "a8971c86b25ff8557e844f08c1f6207d9b3e614c" + "reference": "ca5f6edaf8780ece814404b58a4482b22b509c56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/a8971c86b25ff8557e844f08c1f6207d9b3e614c", - "reference": "a8971c86b25ff8557e844f08c1f6207d9b3e614c", + "url": "https://api.github.com/repos/symfony/mailer/zipball/ca5f6edaf8780ece814404b58a4482b22b509c56", + "reference": "ca5f6edaf8780ece814404b58a4482b22b509c56", "shasum": "" }, "require": { @@ -9154,7 +9159,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v8.0.6" + "source": "https://github.com/symfony/mailer/tree/v8.0.8" }, "funding": [ { @@ -9174,20 +9179,20 @@ "type": "tidelift" } ], - "time": "2026-02-25T16:59:43+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/mime", - "version": "v8.0.7", + "version": "v8.0.9", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "5d26d1958aeeba2ace8cc64a3a93d4f5d8f8022b" + "reference": "a9fcb293650c054b62a5b406f4e92e7b711ea333" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/5d26d1958aeeba2ace8cc64a3a93d4f5d8f8022b", - "reference": "5d26d1958aeeba2ace8cc64a3a93d4f5d8f8022b", + "url": "https://api.github.com/repos/symfony/mime/zipball/a9fcb293650c054b62a5b406f4e92e7b711ea333", + "reference": "a9fcb293650c054b62a5b406f4e92e7b711ea333", "shasum": "" }, "require": { @@ -9240,7 +9245,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v8.0.7" + "source": "https://github.com/symfony/mime/tree/v8.0.9" }, "funding": [ { @@ -9260,20 +9265,20 @@ "type": "tidelift" } ], - "time": "2026-03-06T13:17:40+00:00" + "time": "2026-04-29T15:02:55+00:00" }, { "name": "symfony/options-resolver", - "version": "v8.0.0", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "d2b592535ffa6600c265a3893a7f7fd2bad82dd7" + "reference": "b48bce0a70b914f6953dafbd10474df232ed4de8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/d2b592535ffa6600c265a3893a7f7fd2bad82dd7", - "reference": "d2b592535ffa6600c265a3893a7f7fd2bad82dd7", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/b48bce0a70b914f6953dafbd10474df232ed4de8", + "reference": "b48bce0a70b914f6953dafbd10474df232ed4de8", "shasum": "" }, "require": { @@ -9311,7 +9316,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v8.0.0" + "source": "https://github.com/symfony/options-resolver/tree/v8.0.8" }, "funding": [ { @@ -9331,20 +9336,20 @@ "type": "tidelift" } ], - "time": "2025-11-12T15:55:31+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", "shasum": "" }, "require": { @@ -9394,7 +9399,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" }, "funding": [ { @@ -9414,20 +9419,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" + "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/4864388bfbd3001ce88e234fab652acd91fdc57e", + "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e", "shasum": "" }, "require": { @@ -9476,7 +9481,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.37.0" }, "funding": [ { @@ -9496,11 +9501,11 @@ "type": "tidelift" } ], - "time": "2025-06-27T09:58:17+00:00" + "time": "2026-04-26T13:13:48+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", @@ -9563,7 +9568,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.37.0" }, "funding": [ { @@ -9587,7 +9592,7 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -9648,7 +9653,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.37.0" }, "funding": [ { @@ -9672,16 +9677,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", "shasum": "" }, "require": { @@ -9733,7 +9738,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.37.0" }, "funding": [ { @@ -9753,20 +9758,20 @@ "type": "tidelift" } ], - "time": "2024-12-23T08:48:59+00:00" + "time": "2026-04-10T17:25:58+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", - "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", "shasum": "" }, "require": { @@ -9817,7 +9822,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0" }, "funding": [ { @@ -9837,20 +9842,20 @@ "type": "tidelift" } ], - "time": "2025-01-02T08:10:11+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-php84", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", - "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06", + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06", "shasum": "" }, "require": { @@ -9897,7 +9902,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.37.0" }, "funding": [ { @@ -9917,20 +9922,20 @@ "type": "tidelift" } ], - "time": "2025-06-24T13:30:11+00:00" + "time": "2026-04-10T18:47:49+00:00" }, { "name": "symfony/polyfill-php85", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91" + "reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", - "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/fcfa4973a9917cef23f2e38774da74a2b7d115ee", + "reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee", "shasum": "" }, "require": { @@ -9977,7 +9982,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.37.0" }, "funding": [ { @@ -9997,20 +10002,100 @@ "type": "tidelift" } ], - "time": "2025-06-23T16:12:55+00:00" + "time": "2026-04-26T13:10:57+00:00" }, { - "name": "symfony/polyfill-uuid", - "version": "v1.33.0", + "name": "symfony/polyfill-php86", + "version": "v1.37.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-uuid.git", - "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2" + "url": "https://github.com/symfony/polyfill-php86.git", + "reference": "33d8fc5a705481e21fe3a81212b26f9b1f61749c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2", - "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "url": "https://api.github.com/repos/symfony/polyfill-php86/zipball/33d8fc5a705481e21fe3a81212b26f9b1f61749c", + "reference": "33d8fc5a705481e21fe3a81212b26f9b1f61749c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php86\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.6+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php86/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-26T13:13:48+00:00" + }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/26dfec253c4cf3e51b541b52ddf7e42cb0908e94", + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94", "shasum": "" }, "require": { @@ -10060,7 +10145,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.37.0" }, "funding": [ { @@ -10080,20 +10165,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/process", - "version": "v8.0.5", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674" + "reference": "cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674", - "reference": "b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674", + "url": "https://api.github.com/repos/symfony/process/zipball/cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc", + "reference": "cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc", "shasum": "" }, "require": { @@ -10125,7 +10210,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v8.0.5" + "source": "https://github.com/symfony/process/tree/v8.0.8" }, "funding": [ { @@ -10145,20 +10230,20 @@ "type": "tidelift" } ], - "time": "2026-01-26T15:08:38+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/psr-http-message-bridge", - "version": "v8.0.4", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "d6edf266746dd0b8e81e754a79da77b08dc00531" + "reference": "94facc221260c1d5f20e31ee43cd6c6a824b4a19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/d6edf266746dd0b8e81e754a79da77b08dc00531", - "reference": "d6edf266746dd0b8e81e754a79da77b08dc00531", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/94facc221260c1d5f20e31ee43cd6c6a824b4a19", + "reference": "94facc221260c1d5f20e31ee43cd6c6a824b4a19", "shasum": "" }, "require": { @@ -10212,7 +10297,7 @@ "psr-7" ], "support": { - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v8.0.4" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v8.0.8" }, "funding": [ { @@ -10232,20 +10317,20 @@ "type": "tidelift" } ], - "time": "2026-01-03T23:40:55+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/routing", - "version": "v8.0.6", + "version": "v8.0.9", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "053c40fd46e1d19c5c5a94cada93ce6c3facdd55" + "reference": "75d1bd8e5da3424e4db2fc3ff0222cb4d0c73038" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/053c40fd46e1d19c5c5a94cada93ce6c3facdd55", - "reference": "053c40fd46e1d19c5c5a94cada93ce6c3facdd55", + "url": "https://api.github.com/repos/symfony/routing/zipball/75d1bd8e5da3424e4db2fc3ff0222cb4d0c73038", + "reference": "75d1bd8e5da3424e4db2fc3ff0222cb4d0c73038", "shasum": "" }, "require": { @@ -10292,7 +10377,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v8.0.6" + "source": "https://github.com/symfony/routing/tree/v8.0.9" }, "funding": [ { @@ -10312,7 +10397,7 @@ "type": "tidelift" } ], - "time": "2026-02-25T16:59:43+00:00" + "time": "2026-04-29T15:02:55+00:00" }, { "name": "symfony/service-contracts", @@ -10403,16 +10488,16 @@ }, { "name": "symfony/string", - "version": "v8.0.6", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "6c9e1108041b5dce21a9a4984b531c4923aa9ec4" + "reference": "ae9488f874d7603f9d2dfbf120203882b645d963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/6c9e1108041b5dce21a9a4984b531c4923aa9ec4", - "reference": "6c9e1108041b5dce21a9a4984b531c4923aa9ec4", + "url": "https://api.github.com/repos/symfony/string/zipball/ae9488f874d7603f9d2dfbf120203882b645d963", + "reference": "ae9488f874d7603f9d2dfbf120203882b645d963", "shasum": "" }, "require": { @@ -10469,7 +10554,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v8.0.6" + "source": "https://github.com/symfony/string/tree/v8.0.8" }, "funding": [ { @@ -10489,20 +10574,20 @@ "type": "tidelift" } ], - "time": "2026-02-09T10:14:57+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/translation", - "version": "v8.0.6", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "13ff19bcf2bea492d3c2fbeaa194dd6f4599ce1b" + "reference": "27c03ae3940de24ba2f71cfdbac824f2aa1fdf2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/13ff19bcf2bea492d3c2fbeaa194dd6f4599ce1b", - "reference": "13ff19bcf2bea492d3c2fbeaa194dd6f4599ce1b", + "url": "https://api.github.com/repos/symfony/translation/zipball/27c03ae3940de24ba2f71cfdbac824f2aa1fdf2f", + "reference": "27c03ae3940de24ba2f71cfdbac824f2aa1fdf2f", "shasum": "" }, "require": { @@ -10562,7 +10647,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v8.0.6" + "source": "https://github.com/symfony/translation/tree/v8.0.8" }, "funding": [ { @@ -10582,7 +10667,7 @@ "type": "tidelift" } ], - "time": "2026-02-17T13:07:04+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/translation-contracts", @@ -10668,16 +10753,16 @@ }, { "name": "symfony/uid", - "version": "v8.0.4", + "version": "v8.0.9", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "8b81bd3700f5c1913c22a3266a647aa1bb974435" + "reference": "4d9d6510bbe88ebb4608b7200d18606cdf80825c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/8b81bd3700f5c1913c22a3266a647aa1bb974435", - "reference": "8b81bd3700f5c1913c22a3266a647aa1bb974435", + "url": "https://api.github.com/repos/symfony/uid/zipball/4d9d6510bbe88ebb4608b7200d18606cdf80825c", + "reference": "4d9d6510bbe88ebb4608b7200d18606cdf80825c", "shasum": "" }, "require": { @@ -10722,7 +10807,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v8.0.4" + "source": "https://github.com/symfony/uid/tree/v8.0.9" }, "funding": [ { @@ -10742,20 +10827,20 @@ "type": "tidelift" } ], - "time": "2026-01-03T23:40:55+00:00" + "time": "2026-04-30T16:10:06+00:00" }, { "name": "symfony/var-dumper", - "version": "v8.0.6", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "2e14f7e0bf5ff02c6e63bd31cb8e4855a13d6209" + "reference": "cfb7badd53bf4177f6e9416cfbbccc13c0e773a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/2e14f7e0bf5ff02c6e63bd31cb8e4855a13d6209", - "reference": "2e14f7e0bf5ff02c6e63bd31cb8e4855a13d6209", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/cfb7badd53bf4177f6e9416cfbbccc13c0e773a1", + "reference": "cfb7badd53bf4177f6e9416cfbbccc13c0e773a1", "shasum": "" }, "require": { @@ -10809,7 +10894,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v8.0.6" + "source": "https://github.com/symfony/var-dumper/tree/v8.0.8" }, "funding": [ { @@ -10829,7 +10914,7 @@ "type": "tidelift" } ], - "time": "2026-02-15T10:53:29+00:00" + "time": "2026-03-31T07:15:36+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -10972,23 +11057,23 @@ }, { "name": "voku/portable-ascii", - "version": "2.0.3", + "version": "2.1.1", "source": { "type": "git", "url": "https://github.com/voku/portable-ascii.git", - "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d" + "reference": "8e1051fe39379367aecf014f41744ce7539a856f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", - "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/8e1051fe39379367aecf014f41744ce7539a856f", + "reference": "8e1051fe39379367aecf014f41744ce7539a856f", "shasum": "" }, "require": { - "php": ">=7.0.0" + "php": ">=7.1.0" }, "require-dev": { - "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + "phpunit/phpunit": "~8.5 || ~9.6 || ~10.5 || ~11.5" }, "suggest": { "ext-intl": "Use Intl for transliterator_transliterate() support" @@ -11018,7 +11103,7 @@ ], "support": { "issues": "https://github.com/voku/portable-ascii/issues", - "source": "https://github.com/voku/portable-ascii/tree/2.0.3" + "source": "https://github.com/voku/portable-ascii/tree/2.1.1" }, "funding": [ { @@ -11042,7 +11127,7 @@ "type": "tidelift" } ], - "time": "2024-11-21T01:49:47+00:00" + "time": "2026-04-26T05:33:54+00:00" } ], "packages-dev": [ @@ -11435,16 +11520,16 @@ }, { "name": "laravel/boost", - "version": "v2.4.1", + "version": "v2.4.6", "source": { "type": "git", "url": "https://github.com/laravel/boost.git", - "reference": "f6241df9fd81a86d79a051851177d4ffe3e28506" + "reference": "c9ea6368c66f7c0e6a9b26706b401de900cdb9ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/boost/zipball/f6241df9fd81a86d79a051851177d4ffe3e28506", - "reference": "f6241df9fd81a86d79a051851177d4ffe3e28506", + "url": "https://api.github.com/repos/laravel/boost/zipball/c9ea6368c66f7c0e6a9b26706b401de900cdb9ac", + "reference": "c9ea6368c66f7c0e6a9b26706b401de900cdb9ac", "shasum": "" }, "require": { @@ -11453,7 +11538,7 @@ "illuminate/contracts": "^11.45.3|^12.41.1|^13.0", "illuminate/routing": "^11.45.3|^12.41.1|^13.0", "illuminate/support": "^11.45.3|^12.41.1|^13.0", - "laravel/mcp": "^0.5.1|^0.6.0", + "laravel/mcp": "^0.5.1|^0.6.0|^0.7.0", "laravel/prompts": "^0.3.10", "laravel/roster": "^0.5.0", "php": "^8.2" @@ -11497,20 +11582,20 @@ "issues": "https://github.com/laravel/boost/issues", "source": "https://github.com/laravel/boost" }, - "time": "2026-03-25T16:37:40+00:00" + "time": "2026-04-28T11:52:01+00:00" }, { "name": "laravel/mcp", - "version": "v0.6.4", + "version": "v0.7.0", "source": { "type": "git", "url": "https://github.com/laravel/mcp.git", - "reference": "f822c5eb5beed19adb2e5bfe2f46f8c977ecea42" + "reference": "3513b4feca5f1678be4d2261dcfa8e456436d02a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/mcp/zipball/f822c5eb5beed19adb2e5bfe2f46f8c977ecea42", - "reference": "f822c5eb5beed19adb2e5bfe2f46f8c977ecea42", + "url": "https://api.github.com/repos/laravel/mcp/zipball/3513b4feca5f1678be4d2261dcfa8e456436d02a", + "reference": "3513b4feca5f1678be4d2261dcfa8e456436d02a", "shasum": "" }, "require": { @@ -11570,7 +11655,7 @@ "issues": "https://github.com/laravel/mcp/issues", "source": "https://github.com/laravel/mcp" }, - "time": "2026-03-19T12:37:13+00:00" + "time": "2026-04-21T10:23:03+00:00" }, { "name": "laravel/pail", @@ -11654,16 +11739,16 @@ }, { "name": "laravel/pint", - "version": "v1.29.0", + "version": "v1.29.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "bdec963f53172c5e36330f3a400604c69bf02d39" + "reference": "0770e9b7fafd50d4586881d456d6eb41c9247a80" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/bdec963f53172c5e36330f3a400604c69bf02d39", - "reference": "bdec963f53172c5e36330f3a400604c69bf02d39", + "url": "https://api.github.com/repos/laravel/pint/zipball/0770e9b7fafd50d4586881d456d6eb41c9247a80", + "reference": "0770e9b7fafd50d4586881d456d6eb41c9247a80", "shasum": "" }, "require": { @@ -11674,14 +11759,14 @@ "php": "^8.2.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.94.2", - "illuminate/view": "^12.54.1", - "larastan/larastan": "^3.9.3", - "laravel-zero/framework": "^12.0.5", + "friendsofphp/php-cs-fixer": "^3.95.1", + "illuminate/view": "^12.56.0", + "larastan/larastan": "^3.9.6", + "laravel-zero/framework": "^12.1.0", "mockery/mockery": "^1.6.12", "nunomaduro/termwind": "^2.4.0", "pestphp/pest": "^3.8.6", - "shipfastlabs/agent-detector": "^1.1.0" + "shipfastlabs/agent-detector": "^1.1.3" }, "bin": [ "builds/pint" @@ -11718,7 +11803,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2026-03-12T15:51:39+00:00" + "time": "2026-04-20T15:26:14+00:00" }, { "name": "laravel/roster", @@ -11926,23 +12011,23 @@ }, { "name": "nunomaduro/collision", - "version": "v8.9.1", + "version": "v8.9.4", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "a1ed3fa530fd60bc515f9303e8520fcb7d4bd935" + "reference": "716af8f95a470e9094cfca09ed897b023be191a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/a1ed3fa530fd60bc515f9303e8520fcb7d4bd935", - "reference": "a1ed3fa530fd60bc515f9303e8520fcb7d4bd935", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/716af8f95a470e9094cfca09ed897b023be191a5", + "reference": "716af8f95a470e9094cfca09ed897b023be191a5", "shasum": "" }, "require": { "filp/whoops": "^2.18.4", "nunomaduro/termwind": "^2.4.0", "php": "^8.2.0", - "symfony/console": "^7.4.4 || ^8.0.4" + "symfony/console": "^7.4.8 || ^8.0.8" }, "conflict": { "laravel/framework": "<11.48.0 || >=14.0.0", @@ -11950,12 +12035,12 @@ }, "require-dev": { "brianium/paratest": "^7.8.5", - "larastan/larastan": "^3.9.2", - "laravel/framework": "^11.48.0 || ^12.52.0", - "laravel/pint": "^1.27.1", - "orchestra/testbench-core": "^9.12.0 || ^10.9.0", - "pestphp/pest": "^3.8.5 || ^4.4.1 || ^5.0.0", - "sebastian/environment": "^7.2.1 || ^8.0.3 || ^9.0.0" + "larastan/larastan": "^3.9.6", + "laravel/framework": "^11.48.0 || ^12.56.0 || ^13.5.0", + "laravel/pint": "^1.29.1", + "orchestra/testbench-core": "^9.12.0 || ^10.12.1 || ^11.2.1", + "pestphp/pest": "^3.8.5 || ^4.4.3 || ^5.0.0", + "sebastian/environment": "^7.2.1 || ^8.0.4 || ^9.3.0" }, "type": "library", "extra": { @@ -12018,45 +12103,46 @@ "type": "patreon" } ], - "time": "2026-02-17T17:33:08+00:00" + "time": "2026-04-21T14:04:20+00:00" }, { "name": "pestphp/pest", - "version": "v4.4.3", + "version": "v4.6.3", "source": { "type": "git", "url": "https://github.com/pestphp/pest.git", - "reference": "e6ab897594312728ef2e32d586cb4f6780b1b495" + "reference": "bff44562a99d30aa37573995566051b0344f9f8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/e6ab897594312728ef2e32d586cb4f6780b1b495", - "reference": "e6ab897594312728ef2e32d586cb4f6780b1b495", + "url": "https://api.github.com/repos/pestphp/pest/zipball/bff44562a99d30aa37573995566051b0344f9f8e", + "reference": "bff44562a99d30aa37573995566051b0344f9f8e", "shasum": "" }, "require": { - "brianium/paratest": "^7.19.2", - "nunomaduro/collision": "^8.9.1", + "brianium/paratest": "^7.20.0", + "nunomaduro/collision": "^8.9.3", "nunomaduro/termwind": "^2.4.0", "pestphp/pest-plugin": "^4.0.0", - "pestphp/pest-plugin-arch": "^4.0.0", + "pestphp/pest-plugin-arch": "^4.0.2", "pestphp/pest-plugin-mutate": "^4.0.1", "pestphp/pest-plugin-profanity": "^4.2.1", "php": "^8.3.0", - "phpunit/phpunit": "^12.5.14", - "symfony/process": "^7.4.5|^8.0.5" + "phpunit/phpunit": "^12.5.23", + "symfony/process": "^7.4.8|^8.0.8" }, "conflict": { "filp/whoops": "<2.18.3", - "phpunit/phpunit": ">12.5.14", + "phpunit/phpunit": ">12.5.23", "sebastian/exporter": "<7.0.0", "webmozart/assert": "<1.11.0" }, "require-dev": { + "mrpunyapal/peststan": "^0.2.5", "pestphp/pest-dev-tools": "^4.1.0", - "pestphp/pest-plugin-browser": "^4.3.0", - "pestphp/pest-plugin-type-coverage": "^4.0.3", - "psy/psysh": "^0.12.21" + "pestphp/pest-plugin-browser": "^4.3.1", + "pestphp/pest-plugin-type-coverage": "^4.0.4", + "psy/psysh": "^0.12.22" }, "bin": [ "bin/pest" @@ -12122,7 +12208,7 @@ ], "support": { "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v4.4.3" + "source": "https://github.com/pestphp/pest/tree/v4.6.3" }, "funding": [ { @@ -12134,7 +12220,7 @@ "type": "github" } ], - "time": "2026-03-21T13:14:39+00:00" + "time": "2026-04-18T13:51:25+00:00" }, { "name": "pestphp/pest-plugin", @@ -12208,26 +12294,26 @@ }, { "name": "pestphp/pest-plugin-arch", - "version": "v4.0.0", + "version": "v4.0.2", "source": { "type": "git", "url": "https://github.com/pestphp/pest-plugin-arch.git", - "reference": "25bb17e37920ccc35cbbcda3b00d596aadf3e58d" + "reference": "3fb0d02a91b9da504b139dc7ab2a31efb7c3215c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/25bb17e37920ccc35cbbcda3b00d596aadf3e58d", - "reference": "25bb17e37920ccc35cbbcda3b00d596aadf3e58d", + "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/3fb0d02a91b9da504b139dc7ab2a31efb7c3215c", + "reference": "3fb0d02a91b9da504b139dc7ab2a31efb7c3215c", "shasum": "" }, "require": { "pestphp/pest-plugin": "^4.0.0", "php": "^8.3", - "ta-tikoma/phpunit-architecture-test": "^0.8.5" + "ta-tikoma/phpunit-architecture-test": "^0.8.7" }, "require-dev": { - "pestphp/pest": "^4.0.0", - "pestphp/pest-dev-tools": "^4.0.0" + "pestphp/pest": "^4.4.6", + "pestphp/pest-dev-tools": "^4.1.0" }, "type": "library", "extra": { @@ -12262,7 +12348,7 @@ "unit" ], "support": { - "source": "https://github.com/pestphp/pest-plugin-arch/tree/v4.0.0" + "source": "https://github.com/pestphp/pest-plugin-arch/tree/v4.0.2" }, "funding": [ { @@ -12274,7 +12360,7 @@ "type": "github" } ], - "time": "2025-08-20T13:10:51+00:00" + "time": "2026-04-10T17:20:19+00:00" }, { "name": "pestphp/pest-plugin-laravel", @@ -12825,16 +12911,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "12.5.3", + "version": "12.5.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "b015312f28dd75b75d3422ca37dff2cd1a565e8d" + "reference": "876099a072646c7745f673d7aeab5382c4439691" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/b015312f28dd75b75d3422ca37dff2cd1a565e8d", - "reference": "b015312f28dd75b75d3422ca37dff2cd1a565e8d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/876099a072646c7745f673d7aeab5382c4439691", + "reference": "876099a072646c7745f673d7aeab5382c4439691", "shasum": "" }, "require": { @@ -12843,7 +12929,6 @@ "ext-xmlwriter": "*", "nikic/php-parser": "^5.7.0", "php": ">=8.3", - "phpunit/php-file-iterator": "^6.0", "phpunit/php-text-template": "^5.0", "sebastian/complexity": "^5.0", "sebastian/environment": "^8.0.3", @@ -12890,7 +12975,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.3" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.6" }, "funding": [ { @@ -12910,7 +12995,7 @@ "type": "tidelift" } ], - "time": "2026-02-06T06:01:44+00:00" + "time": "2026-04-15T08:23:17+00:00" }, { "name": "phpunit/php-file-iterator", @@ -13171,16 +13256,16 @@ }, { "name": "phpunit/phpunit", - "version": "12.5.14", + "version": "12.5.23", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "47283cfd98d553edcb1353591f4e255dc1bb61f0" + "reference": "c54fcf3d6bcb6e96ac2f7e40097dc37b5f139969" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/47283cfd98d553edcb1353591f4e255dc1bb61f0", - "reference": "47283cfd98d553edcb1353591f4e255dc1bb61f0", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c54fcf3d6bcb6e96ac2f7e40097dc37b5f139969", + "reference": "c54fcf3d6bcb6e96ac2f7e40097dc37b5f139969", "shasum": "" }, "require": { @@ -13194,15 +13279,15 @@ "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.3", - "phpunit/php-code-coverage": "^12.5.3", + "phpunit/php-code-coverage": "^12.5.6", "phpunit/php-file-iterator": "^6.0.1", "phpunit/php-invoker": "^6.0.0", "phpunit/php-text-template": "^5.0.0", "phpunit/php-timer": "^8.0.0", "sebastian/cli-parser": "^4.2.0", - "sebastian/comparator": "^7.1.4", + "sebastian/comparator": "^7.1.6", "sebastian/diff": "^7.0.0", - "sebastian/environment": "^8.0.3", + "sebastian/environment": "^8.1.0", "sebastian/exporter": "^7.0.2", "sebastian/global-state": "^8.0.2", "sebastian/object-enumerator": "^7.0.0", @@ -13249,31 +13334,15 @@ "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.14" + "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.23" }, "funding": [ { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "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/phpunit", - "type": "tidelift" + "url": "https://phpunit.de/sponsoring.html", + "type": "other" } ], - "time": "2026-02-18T12:38:40+00:00" + "time": "2026-04-18T06:12:49+00:00" }, { "name": "sebastian/cli-parser", @@ -13346,16 +13415,16 @@ }, { "name": "sebastian/comparator", - "version": "7.1.4", + "version": "7.1.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "6a7de5df2e094f9a80b40a522391a7e6022df5f6" + "reference": "c769009dee98f494e0edc3fd4f4087501688f11e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a7de5df2e094f9a80b40a522391a7e6022df5f6", - "reference": "6a7de5df2e094f9a80b40a522391a7e6022df5f6", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c769009dee98f494e0edc3fd4f4087501688f11e", + "reference": "c769009dee98f494e0edc3fd4f4087501688f11e", "shasum": "" }, "require": { @@ -13414,7 +13483,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.4" + "source": "https://github.com/sebastianbergmann/comparator/tree/7.1.6" }, "funding": [ { @@ -13434,7 +13503,7 @@ "type": "tidelift" } ], - "time": "2026-01-24T09:28:48+00:00" + "time": "2026-04-14T08:23:15+00:00" }, { "name": "sebastian/complexity", @@ -13563,16 +13632,16 @@ }, { "name": "sebastian/environment", - "version": "8.0.4", + "version": "8.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "7b8842c2d8e85d0c3a5831236bf5869af6ab2a11" + "reference": "b121608b28a13f721e76ffbbd386d08eff58f3f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/7b8842c2d8e85d0c3a5831236bf5869af6ab2a11", - "reference": "7b8842c2d8e85d0c3a5831236bf5869af6ab2a11", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/b121608b28a13f721e76ffbbd386d08eff58f3f6", + "reference": "b121608b28a13f721e76ffbbd386d08eff58f3f6", "shasum": "" }, "require": { @@ -13587,7 +13656,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "8.0-dev" + "dev-main": "8.1-dev" } }, "autoload": { @@ -13615,7 +13684,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.0.4" + "source": "https://github.com/sebastianbergmann/environment/tree/8.1.0" }, "funding": [ { @@ -13635,7 +13704,7 @@ "type": "tidelift" } ], - "time": "2026-03-15T07:05:40+00:00" + "time": "2026-04-15T12:13:01+00:00" }, { "name": "sebastian/exporter", @@ -14226,16 +14295,16 @@ }, { "name": "symfony/yaml", - "version": "v8.0.6", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "5f006c50a981e1630bbb70ad409c5d85f9a716e0" + "reference": "54174ab48c0c0f9e21512b304be17f8150ccf8f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/5f006c50a981e1630bbb70ad409c5d85f9a716e0", - "reference": "5f006c50a981e1630bbb70ad409c5d85f9a716e0", + "url": "https://api.github.com/repos/symfony/yaml/zipball/54174ab48c0c0f9e21512b304be17f8150ccf8f1", + "reference": "54174ab48c0c0f9e21512b304be17f8150ccf8f1", "shasum": "" }, "require": { @@ -14277,7 +14346,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v8.0.6" + "source": "https://github.com/symfony/yaml/tree/v8.0.8" }, "funding": [ { @@ -14297,7 +14366,7 @@ "type": "tidelift" } ], - "time": "2026-02-09T10:14:57+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "ta-tikoma/phpunit-architecture-test", @@ -14410,16 +14479,16 @@ }, { "name": "webmozart/assert", - "version": "2.1.6", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "ff31ad6efc62e66e518fbab1cde3453d389bcdc8" + "reference": "eb0d790f735ba6cff25c683a85a1da0eadeff9e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/ff31ad6efc62e66e518fbab1cde3453d389bcdc8", - "reference": "ff31ad6efc62e66e518fbab1cde3453d389bcdc8", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/eb0d790f735ba6cff25c683a85a1da0eadeff9e4", + "reference": "eb0d790f735ba6cff25c683a85a1da0eadeff9e4", "shasum": "" }, "require": { @@ -14466,9 +14535,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/2.1.6" + "source": "https://github.com/webmozarts/assert/tree/2.3.0" }, - "time": "2026-02-27T10:28:38+00:00" + "time": "2026-04-11T10:33:05+00:00" } ], "aliases": [], diff --git a/config/database.php b/config/database.php index a20af3a..d75f686 100644 --- a/config/database.php +++ b/config/database.php @@ -97,7 +97,15 @@ return [ 'sslmode' => 'prefer', ], - 'einundzwanzig' => [ + 'einundzwanzig' => env('DB_CONNECTION', 'sqlite') === 'sqlite' ? [ + 'driver' => 'sqlite', + 'database' => env('DB_DATABASE', database_path('database.sqlite')), + 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), + 'busy_timeout' => null, + 'journal_mode' => null, + 'synchronous' => null, + ] : [ 'driver' => 'pgsql', 'url' => env('DB_URL_EINUNDZANZIG'), 'host' => env('DB_HOST_EINUNDZANZIG', '127.0.0.1'), diff --git a/database/factories/CategoryFactory.php b/database/factories/CategoryFactory.php new file mode 100644 index 0000000..7235902 --- /dev/null +++ b/database/factories/CategoryFactory.php @@ -0,0 +1,32 @@ + + */ +class CategoryFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + return [ + 'name' => fake()->unique()->randomElement([ + 'Grundlagen', + 'Self Custody', + 'Lightning', + 'Nostr', + 'Privacy', + 'Mining', + 'Wirtschaft', + 'Recht', + 'Technik', + ]), + ]; + } +} diff --git a/database/factories/CityFactory.php b/database/factories/CityFactory.php new file mode 100644 index 0000000..c9db644 --- /dev/null +++ b/database/factories/CityFactory.php @@ -0,0 +1,64 @@ + + */ +class CityFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + return [ + 'country_id' => Country::factory(), + 'name' => fake()->city(), + 'latitude' => fake()->latitude(47, 55), + 'longitude' => fake()->longitude(6, 16), + 'osm_relation' => null, + 'simplified_geojson' => null, + ]; + } + + public function vienna(): static + { + return $this->state(fn () => [ + 'name' => 'Wien', + 'latitude' => 48.2082, + 'longitude' => 16.3738, + ]); + } + + public function berlin(): static + { + return $this->state(fn () => [ + 'name' => 'Berlin', + 'latitude' => 52.5200, + 'longitude' => 13.4050, + ]); + } + + public function munich(): static + { + return $this->state(fn () => [ + 'name' => 'München', + 'latitude' => 48.1351, + 'longitude' => 11.5820, + ]); + } + + public function zurich(): static + { + return $this->state(fn () => [ + 'name' => 'Zürich', + 'latitude' => 47.3769, + 'longitude' => 8.5417, + ]); + } +} diff --git a/database/factories/CountryFactory.php b/database/factories/CountryFactory.php new file mode 100644 index 0000000..45e39ce --- /dev/null +++ b/database/factories/CountryFactory.php @@ -0,0 +1,51 @@ + + */ +class CountryFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + return [ + 'name' => fake()->unique()->country(), + 'code' => strtoupper(fake()->unique()->lexify('??')), + 'language_codes' => ['de'], + ]; + } + + public function germany(): static + { + return $this->state(fn () => [ + 'name' => 'Deutschland', + 'code' => 'DE', + 'language_codes' => ['de'], + ]); + } + + public function austria(): static + { + return $this->state(fn () => [ + 'name' => 'Österreich', + 'code' => 'AT', + 'language_codes' => ['de'], + ]); + } + + public function switzerland(): static + { + return $this->state(fn () => [ + 'name' => 'Schweiz', + 'code' => 'CH', + 'language_codes' => ['de', 'fr', 'it'], + ]); + } +} diff --git a/database/factories/CourseEventFactory.php b/database/factories/CourseEventFactory.php new file mode 100644 index 0000000..a6a2dc9 --- /dev/null +++ b/database/factories/CourseEventFactory.php @@ -0,0 +1,42 @@ + + */ +class CourseEventFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + $from = fake()->dateTimeBetween('+1 day', '+90 days'); + $to = (clone $from)->modify('+2 hours'); + + return [ + 'course_id' => Course::factory(), + 'venue_id' => Venue::factory(), + 'from' => $from, + 'to' => $to, + ]; + } + + public function past(): static + { + return $this->state(function () { + $from = fake()->dateTimeBetween('-90 days', '-1 day'); + + return [ + 'from' => $from, + 'to' => (clone $from)->modify('+2 hours'), + ]; + }); + } +} diff --git a/database/factories/CourseFactory.php b/database/factories/CourseFactory.php new file mode 100644 index 0000000..9345711 --- /dev/null +++ b/database/factories/CourseFactory.php @@ -0,0 +1,45 @@ + + */ +class CourseFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + $titles = [ + 'Bitcoin Basics', + 'Self Custody und Hardware Wallets', + 'Lightning Network 101', + 'Nostr Einführung', + 'Bitcoin für Unternehmer', + 'Privacy & Coinjoin', + 'Running Your Own Node', + ]; + + return [ + 'lecturer_id' => Lecturer::factory(), + 'name' => fake()->randomElement($titles), + 'description' => fake()->paragraphs(2, true), + 'duration_minutes' => fake()->randomElement([60, 90, 120, 180]), + ]; + } + + public function bitcoinBasics(): static + { + return $this->state(fn () => [ + 'name' => 'Bitcoin Basics', + 'description' => 'Eine umfassende Einführung in Bitcoin: Was ist Bitcoin, wie funktioniert die Blockchain, warum ist es revolutionär. Perfekt für Einsteiger.', + 'duration_minutes' => 90, + ]); + } +} diff --git a/database/factories/EventFactory.php b/database/factories/EventFactory.php new file mode 100644 index 0000000..aed0bdb --- /dev/null +++ b/database/factories/EventFactory.php @@ -0,0 +1,62 @@ + + */ +class EventFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + $eventId = bin2hex(random_bytes(32)); + $pubkey = bin2hex(random_bytes(32)); + $createdAt = fake()->dateTimeBetween('-1 year')->getTimestamp(); + + return [ + 'event_id' => $eventId, + 'parent_event_id' => null, + 'pubkey' => $pubkey, + 'type' => fake()->randomElement(['note', 'long-form', 'reaction']), + 'json' => json_encode([ + 'id' => $eventId, + 'pubkey' => $pubkey, + 'created_at' => $createdAt, + 'kind' => 1, + 'tags' => [], + 'content' => fake()->paragraph(), + 'sig' => bin2hex(random_bytes(64)), + ], JSON_THROW_ON_ERROR), + ]; + } + + public function fromMarkusTurm(): static + { + return $this->state(function () { + $eventId = bin2hex(random_bytes(32)); + $pubkey = 'f240be2b684f85cc81566f2081386af81d7427ea86250c8bde6b7a8500c761ba'; + $createdAt = fake()->dateTimeBetween('-30 days')->getTimestamp(); + + return [ + 'event_id' => $eventId, + 'pubkey' => $pubkey, + 'type' => 'note', + 'json' => json_encode([ + 'id' => $eventId, + 'pubkey' => $pubkey, + 'created_at' => $createdAt, + 'kind' => 1, + 'tags' => [['t', 'bitcoin'], ['t', 'einundzwanzig']], + 'content' => 'Bitcoin fixes this. #bitcoin #einundzwanzig', + 'sig' => bin2hex(random_bytes(64)), + ], JSON_THROW_ON_ERROR), + ]; + }); + } +} diff --git a/database/factories/LecturerFactory.php b/database/factories/LecturerFactory.php new file mode 100644 index 0000000..8015ef1 --- /dev/null +++ b/database/factories/LecturerFactory.php @@ -0,0 +1,43 @@ + + */ +class LecturerFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + return [ + 'name' => fake()->name(), + 'bio' => fake()->paragraph(), + 'pubkey' => bin2hex(random_bytes(32)), + 'website' => fake()->url(), + 'active' => true, + ]; + } + + public function markusTurm(): static + { + return $this->state(fn () => [ + 'name' => 'Markus Turm', + 'bio' => 'Hobby Hedge Fund Manager. Bitcoin, Austrian Economics, Laissez-Faire Radical.', + 'npub' => 'npub17fqtu2mgf7zueq2kdusgzwr2lqwhgfl2scjsez77ddag2qx8vxaq3vnr8y', + 'pubkey' => 'f240be2b684f85cc81566f2081386af81d7427ea86250c8bde6b7a8500c761ba', + 'website' => 'https://einundzwanzig.space', + 'active' => true, + ]); + } + + public function inactive(): static + { + return $this->state(fn () => ['active' => false]); + } +} diff --git a/database/factories/MeetupEventFactory.php b/database/factories/MeetupEventFactory.php new file mode 100644 index 0000000..adbfd5b --- /dev/null +++ b/database/factories/MeetupEventFactory.php @@ -0,0 +1,47 @@ + + */ +class MeetupEventFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + return [ + 'meetup_id' => Meetup::factory(), + 'start' => fake()->dateTimeBetween('+1 day', '+90 days'), + 'location' => fake()->company().', '.fake()->streetAddress(), + 'description' => fake()->paragraph(), + 'link' => fake()->url(), + 'attendees' => [ + 'f240be2b684f85cc81566f2081386af81d7427ea86250c8bde6b7a8500c761ba', + bin2hex(random_bytes(32)), + ], + 'might_attendees' => [bin2hex(random_bytes(32))], + 'nostr_status' => 'Sent event '.bin2hex(random_bytes(8)).' to wss://simple-relay.codingarena.top', + ]; + } + + public function past(): static + { + return $this->state(fn () => [ + 'start' => fake()->dateTimeBetween('-90 days', '-1 day'), + ]); + } + + public function upcoming(): static + { + return $this->state(fn () => [ + 'start' => fake()->dateTimeBetween('+1 day', '+30 days'), + ]); + } +} diff --git a/database/factories/MeetupFactory.php b/database/factories/MeetupFactory.php new file mode 100644 index 0000000..f5baead --- /dev/null +++ b/database/factories/MeetupFactory.php @@ -0,0 +1,53 @@ + + */ +class MeetupFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + $name = 'Einundzwanzig '.fake()->city(); + + return [ + 'city_id' => City::factory(), + 'name' => $name, + 'description' => fake()->paragraph(), + 'website' => 'https://einundzwanzig.space/meetups/'.str()->slug($name), + 'nostr_pubkey' => bin2hex(random_bytes(32)), + 'github_data' => [ + 'repo' => 'einundzwanzig-portal', + 'path' => 'meetups/'.str()->slug($name).'.json', + ], + 'simplified_geojson' => null, + ]; + } + + public function vienna(): static + { + return $this->state(fn () => [ + 'name' => 'Einundzwanzig Wien', + 'description' => 'Das Bitcoin-only Meetup in Wien. Jeden ersten Donnerstag im Monat.', + 'website' => 'https://einundzwanzig.space/meetups/wien', + 'nostr_pubkey' => 'f240be2b684f85cc81566f2081386af81d7427ea86250c8bde6b7a8500c761ba', + ]); + } + + public function berlin(): static + { + return $this->state(fn () => [ + 'name' => 'Einundzwanzig Berlin', + 'description' => 'Bitcoin Meetup in der Hauptstadt. Plebs willkommen.', + 'website' => 'https://einundzwanzig.space/meetups/berlin', + ]); + } +} diff --git a/database/factories/ProfileFactory.php b/database/factories/ProfileFactory.php new file mode 100644 index 0000000..43b4044 --- /dev/null +++ b/database/factories/ProfileFactory.php @@ -0,0 +1,50 @@ + + */ +class ProfileFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + $name = fake()->userName(); + + return [ + 'pubkey' => bin2hex(random_bytes(32)), + 'name' => $name, + 'display_name' => fake()->name(), + 'picture' => 'https://image.nostr.build/'.fake()->uuid().'.jpg', + 'banner' => null, + 'website' => fake()->url(), + 'about' => fake()->sentence(12), + 'nip05' => $name.'@einundzwanzig.space', + 'lud16' => $name.'@walletofsatoshi.com', + 'lud06' => null, + 'deleted' => false, + ]; + } + + public function markusTurm(): static + { + return $this->state(fn (array $attributes) => [ + 'pubkey' => 'f240be2b684f85cc81566f2081386af81d7427ea86250c8bde6b7a8500c761ba', + 'name' => 'markusturm', + 'display_name' => 'Markus Turm', + 'picture' => 'https://m.primal.net/HQqf.jpg', + 'banner' => 'https://m.primal.net/HQqg.jpg', + 'website' => 'https://einundzwanzig.space', + 'about' => '#Bitcoin | Austrian Economics | Laissez-Faire Radical | @_einundzwanzig_', + 'nip05' => 'markusturm@einundzwanzig.space', + 'lud16' => 'markusturm@walletofsatoshi.com', + 'deleted' => false, + ]); + } +} diff --git a/database/factories/RenderedEventFactory.php b/database/factories/RenderedEventFactory.php new file mode 100644 index 0000000..2246251 --- /dev/null +++ b/database/factories/RenderedEventFactory.php @@ -0,0 +1,26 @@ + + */ +class RenderedEventFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + return [ + 'event_id' => Event::factory()->create()->event_id, + 'html' => '

'.fake()->paragraph().'

', + 'profile_image' => 'https://m.primal.net/'.fake()->uuid().'.jpg', + 'profile_name' => fake()->userName(), + ]; + } +} diff --git a/database/factories/SecurityAttemptFactory.php b/database/factories/SecurityAttemptFactory.php new file mode 100644 index 0000000..9e85169 --- /dev/null +++ b/database/factories/SecurityAttemptFactory.php @@ -0,0 +1,49 @@ + + */ +class SecurityAttemptFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + return [ + 'ip_address' => fake()->ipv4(), + 'user_agent' => fake()->userAgent(), + 'method' => fake()->randomElement(['GET', 'POST']), + 'url' => fake()->url(), + 'route_name' => fake()->randomElement(['association.profile', 'association.elections', 'association.projectSupport']), + 'exception_class' => fake()->randomElement([ + ValidationException::class, + AuthenticationException::class, + AuthorizationException::class, + ]), + 'exception_message' => fake()->sentence(), + 'component_name' => fake()->randomElement(['association.profile', 'association.election.show']), + 'target_property' => fake()->randomElement(['name', 'email', 'npub']), + 'payload' => ['attempt' => fake()->word()], + 'severity' => fake()->randomElement(['low', 'medium', 'high', 'critical']), + ]; + } + + public function high(): static + { + return $this->state(fn () => ['severity' => 'high']); + } + + public function critical(): static + { + return $this->state(fn () => ['severity' => 'critical']); + } +} diff --git a/database/factories/VenueFactory.php b/database/factories/VenueFactory.php new file mode 100644 index 0000000..06200b4 --- /dev/null +++ b/database/factories/VenueFactory.php @@ -0,0 +1,37 @@ + + */ +class VenueFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + return [ + 'city_id' => City::factory(), + 'name' => fake()->randomElement(['Bitcoin Bar', 'Plebsfreundlicher Coworking', 'Hodler Hangout', 'Lightning Lounge']).' '.fake()->lastName(), + 'description' => fake()->paragraph(), + 'address' => fake()->streetAddress(), + 'website' => fake()->url(), + ]; + } + + public function bitcoinBarVienna(): static + { + return $this->state(fn () => [ + 'name' => 'Bitcoin Bar Wien', + 'description' => 'Die erste Bitcoin-only Bar im 7. Bezirk.', + 'address' => 'Neubaugasse 21, 1070 Wien', + 'website' => 'https://bitcoin-bar.at', + ]); + } +} diff --git a/database/factories/VoteFactory.php b/database/factories/VoteFactory.php new file mode 100644 index 0000000..8c83c93 --- /dev/null +++ b/database/factories/VoteFactory.php @@ -0,0 +1,37 @@ + + */ +class VoteFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + return [ + 'einundzwanzig_pleb_id' => EinundzwanzigPleb::factory(), + 'project_proposal_id' => ProjectProposal::factory(), + 'value' => fake()->boolean(70), + 'reason' => fake()->optional(0.3)->sentence(), + ]; + } + + public function approve(): static + { + return $this->state(fn () => ['value' => true]); + } + + public function reject(): static + { + return $this->state(fn () => ['value' => false]); + } +} diff --git a/database/migrations/2026_05_02_155301_create_countries_table.php b/database/migrations/2026_05_02_155301_create_countries_table.php new file mode 100644 index 0000000..ef89729 --- /dev/null +++ b/database/migrations/2026_05_02_155301_create_countries_table.php @@ -0,0 +1,24 @@ +id(); + $table->string('name'); + $table->string('code', 8)->unique(); + $table->json('language_codes')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('countries'); + } +}; diff --git a/database/migrations/2026_05_02_155302_create_cities_table.php b/database/migrations/2026_05_02_155302_create_cities_table.php new file mode 100644 index 0000000..73dec8a --- /dev/null +++ b/database/migrations/2026_05_02_155302_create_cities_table.php @@ -0,0 +1,29 @@ +id(); + $table->foreignId('country_id')->constrained()->cascadeOnDelete(); + $table->string('name'); + $table->string('slug')->nullable()->index(); + $table->decimal('latitude', 10, 7)->nullable(); + $table->decimal('longitude', 10, 7)->nullable(); + $table->json('osm_relation')->nullable(); + $table->json('simplified_geojson')->nullable(); + $table->unsignedBigInteger('created_by')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('cities'); + } +}; diff --git a/database/migrations/2026_05_02_155303_create_lecturers_table.php b/database/migrations/2026_05_02_155303_create_lecturers_table.php new file mode 100644 index 0000000..aa557fe --- /dev/null +++ b/database/migrations/2026_05_02_155303_create_lecturers_table.php @@ -0,0 +1,29 @@ +id(); + $table->string('name'); + $table->string('slug')->nullable()->index(); + $table->text('bio')->nullable(); + $table->string('npub', 63)->nullable()->index(); + $table->string('pubkey', 64)->nullable()->index(); + $table->string('website')->nullable(); + $table->boolean('active')->default(true); + $table->unsignedBigInteger('created_by')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('lecturers'); + } +}; diff --git a/database/migrations/2026_05_02_155304_create_categories_table.php b/database/migrations/2026_05_02_155304_create_categories_table.php new file mode 100644 index 0000000..9ba03d4 --- /dev/null +++ b/database/migrations/2026_05_02_155304_create_categories_table.php @@ -0,0 +1,22 @@ +id(); + $table->string('name')->unique(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('categories'); + } +}; diff --git a/database/migrations/2026_05_02_155305_create_meetups_table.php b/database/migrations/2026_05_02_155305_create_meetups_table.php new file mode 100644 index 0000000..af0f76d --- /dev/null +++ b/database/migrations/2026_05_02_155305_create_meetups_table.php @@ -0,0 +1,30 @@ +id(); + $table->foreignId('city_id')->constrained()->cascadeOnDelete(); + $table->string('name'); + $table->string('slug')->nullable()->index(); + $table->text('description')->nullable(); + $table->string('website')->nullable(); + $table->string('nostr_pubkey', 64)->nullable(); + $table->json('github_data')->nullable(); + $table->json('simplified_geojson')->nullable(); + $table->unsignedBigInteger('created_by')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('meetups'); + } +}; diff --git a/database/migrations/2026_05_02_155306_create_meetup_events_table.php b/database/migrations/2026_05_02_155306_create_meetup_events_table.php new file mode 100644 index 0000000..825fd53 --- /dev/null +++ b/database/migrations/2026_05_02_155306_create_meetup_events_table.php @@ -0,0 +1,30 @@ +id(); + $table->foreignId('meetup_id')->constrained()->cascadeOnDelete(); + $table->timestamp('start'); + $table->string('location')->nullable(); + $table->text('description')->nullable(); + $table->string('link')->nullable(); + $table->json('attendees')->nullable(); + $table->json('might_attendees')->nullable(); + $table->string('nostr_status')->nullable(); + $table->unsignedBigInteger('created_by')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('meetup_events'); + } +}; diff --git a/database/migrations/2026_05_02_155307_create_venues_table.php b/database/migrations/2026_05_02_155307_create_venues_table.php new file mode 100644 index 0000000..6a980fe --- /dev/null +++ b/database/migrations/2026_05_02_155307_create_venues_table.php @@ -0,0 +1,28 @@ +id(); + $table->foreignId('city_id')->constrained()->cascadeOnDelete(); + $table->string('name'); + $table->string('slug')->nullable()->index(); + $table->text('description')->nullable(); + $table->string('address')->nullable(); + $table->string('website')->nullable(); + $table->unsignedBigInteger('created_by')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('venues'); + } +}; diff --git a/database/migrations/2026_05_02_155308_create_courses_table.php b/database/migrations/2026_05_02_155308_create_courses_table.php new file mode 100644 index 0000000..a623c41 --- /dev/null +++ b/database/migrations/2026_05_02_155308_create_courses_table.php @@ -0,0 +1,27 @@ +id(); + $table->foreignId('lecturer_id')->nullable()->constrained()->nullOnDelete(); + $table->string('name'); + $table->string('slug')->nullable()->index(); + $table->text('description')->nullable(); + $table->unsignedInteger('duration_minutes')->nullable(); + $table->unsignedBigInteger('created_by')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('courses'); + } +}; diff --git a/database/migrations/2026_05_02_155309_create_course_events_table.php b/database/migrations/2026_05_02_155309_create_course_events_table.php new file mode 100644 index 0000000..1f05271 --- /dev/null +++ b/database/migrations/2026_05_02_155309_create_course_events_table.php @@ -0,0 +1,26 @@ +id(); + $table->foreignId('course_id')->constrained()->cascadeOnDelete(); + $table->foreignId('venue_id')->nullable()->constrained()->nullOnDelete(); + $table->timestamp('from'); + $table->timestamp('to')->nullable(); + $table->unsignedBigInteger('created_by')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('course_events'); + } +}; diff --git a/database/migrations/2026_05_02_155310_create_category_course_table.php b/database/migrations/2026_05_02_155310_create_category_course_table.php new file mode 100644 index 0000000..91f6701 --- /dev/null +++ b/database/migrations/2026_05_02_155310_create_category_course_table.php @@ -0,0 +1,22 @@ +foreignId('category_id')->constrained()->cascadeOnDelete(); + $table->foreignId('course_id')->constrained()->cascadeOnDelete(); + $table->primary(['category_id', 'course_id']); + }); + } + + public function down(): void + { + Schema::dropIfExists('category_course'); + } +}; diff --git a/database/migrations/2026_05_02_155311_create_meetup_user_table.php b/database/migrations/2026_05_02_155311_create_meetup_user_table.php new file mode 100644 index 0000000..50f6d35 --- /dev/null +++ b/database/migrations/2026_05_02_155311_create_meetup_user_table.php @@ -0,0 +1,22 @@ +foreignId('meetup_id')->constrained()->cascadeOnDelete(); + $table->foreignId('user_id')->constrained()->cascadeOnDelete(); + $table->primary(['meetup_id', 'user_id']); + }); + } + + public function down(): void + { + Schema::dropIfExists('meetup_user'); + } +}; diff --git a/database/seeders/CourseSeeder.php b/database/seeders/CourseSeeder.php new file mode 100644 index 0000000..8bdfb8f --- /dev/null +++ b/database/seeders/CourseSeeder.php @@ -0,0 +1,55 @@ +map(fn (string $name) => Category::query()->create(['name' => $name])); + + $markus = Lecturer::factory()->markusTurm()->create(); + $otherLecturers = Lecturer::factory()->count(3)->create(); + + $bitcoinBasics = Course::factory()->bitcoinBasics()->for($markus)->create(); + $bitcoinBasics->categories()->attach([ + $categories->firstWhere('name', 'Grundlagen')->id, + $categories->firstWhere('name', 'Wirtschaft')->id, + ]); + + $lightningCourse = Course::factory() + ->state(['name' => 'Lightning Network 101']) + ->for($markus) + ->create(); + $lightningCourse->categories()->attach($categories->firstWhere('name', 'Lightning')->id); + + foreach ($otherLecturers as $lecturer) { + $course = Course::factory()->for($lecturer)->create(); + $course->categories()->attach($categories->random(rand(1, 3))->pluck('id')); + } + + $venues = Venue::query()->take(3)->get(); + if ($venues->isEmpty()) { + return; + } + + foreach (Course::query()->get() as $course) { + CourseEvent::factory()->for($course)->for($venues->random())->past()->create(); + CourseEvent::factory()->for($course)->for($venues->random())->create(); + } + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index d01a0ef..1e974f4 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -3,21 +3,26 @@ namespace Database\Seeders; use App\Models\User; -// use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { - /** - * Seed the application's database. - */ public function run(): void { - // User::factory(10)->create(); + User::query()->updateOrCreate( + ['email' => 'test@example.com'], + ['name' => 'Test User', 'password' => bcrypt('password')] + ); - User::factory()->create([ - 'name' => 'Test User', - 'email' => 'test@example.com', + $this->call([ + PlebSeeder::class, + ProjectProposalSeeder::class, + ElectionSeeder::class, + NostrSeeder::class, + MeetupSeeder::class, + CourseSeeder::class, + NotificationSeeder::class, + SecuritySeeder::class, ]); } } diff --git a/database/seeders/ElectionSeeder.php b/database/seeders/ElectionSeeder.php new file mode 100644 index 0000000..5538c8a --- /dev/null +++ b/database/seeders/ElectionSeeder.php @@ -0,0 +1,38 @@ +updateOrCreate( + ['year' => 2025], + [ + 'candidates' => $candidates, + 'end_time' => now()->setDate(2025, 4, 15), + ] + ); + + Election::query()->updateOrCreate( + ['year' => 2026], + [ + 'candidates' => $candidates, + 'end_time' => now()->addMonths(2), + ] + ); + + Election::query()->updateOrCreate( + ['year' => 2027], + [ + 'candidates' => [], + 'end_time' => now()->addYear()->addMonths(3), + ] + ); + } +} diff --git a/database/seeders/MeetupSeeder.php b/database/seeders/MeetupSeeder.php new file mode 100644 index 0000000..4f200dd --- /dev/null +++ b/database/seeders/MeetupSeeder.php @@ -0,0 +1,40 @@ +germany()->create(); + $at = Country::factory()->austria()->create(); + $ch = Country::factory()->switzerland()->create(); + + $vienna = City::factory()->vienna()->for($at)->create(); + $berlin = City::factory()->berlin()->for($de)->create(); + $munich = City::factory()->munich()->for($de)->create(); + $zurich = City::factory()->zurich()->for($ch)->create(); + + $viennaMeetup = Meetup::factory()->vienna()->for($vienna)->create(); + $berlinMeetup = Meetup::factory()->berlin()->for($berlin)->create(); + $munichMeetup = Meetup::factory()->state(['name' => 'Einundzwanzig München'])->for($munich)->create(); + $zurichMeetup = Meetup::factory()->state(['name' => 'Einundzwanzig Zürich'])->for($zurich)->create(); + + Venue::factory()->bitcoinBarVienna()->for($vienna)->create(); + Venue::factory()->count(2)->for($berlin)->create(); + Venue::factory()->count(2)->for($munich)->create(); + Venue::factory()->count(1)->for($zurich)->create(); + + foreach ([$viennaMeetup, $berlinMeetup, $munichMeetup, $zurichMeetup] as $meetup) { + MeetupEvent::factory()->past()->for($meetup)->count(2)->create(); + MeetupEvent::factory()->upcoming()->for($meetup)->count(2)->create(); + } + } +} diff --git a/database/seeders/NostrSeeder.php b/database/seeders/NostrSeeder.php new file mode 100644 index 0000000..147ba9d --- /dev/null +++ b/database/seeders/NostrSeeder.php @@ -0,0 +1,64 @@ +markusTurm()->create(); + + $boardProfiles = [ + [ + 'pubkey' => '0adf67475ccc5ca456fd3022e46f5d526eb0af6284bf85494c0dd7847f3e5033', + 'name' => 'pleb1', + 'display_name' => 'Vorstandsmitglied 1', + ], + [ + 'pubkey' => '430169631f2f0682c60cebb4f902d68f0c71c498fd1711fd982f052cf1fd4279', + 'name' => 'pleb2', + 'display_name' => 'Vorstandsmitglied 2', + ], + [ + 'pubkey' => '7acf30cf60b85c62b8f654556cc21e4016df8f5604b3b6892794f88bb80d7a1d', + 'name' => 'pleb3', + 'display_name' => 'Vorstandsmitglied 3', + ], + [ + 'pubkey' => '19e358b8011f5f4fc653c565c6d4c2f33f32661f4f90982c9eedc292a8774ec3', + 'name' => 'pleb4', + 'display_name' => 'Vorstandsmitglied 4', + ], + ]; + + foreach ($boardProfiles as $data) { + Profile::query()->create([ + ...$data, + 'about' => 'Vorstand bei Einundzwanzig. Bitcoin only.', + 'nip05' => $data['name'].'@einundzwanzig.space', + 'lud16' => $data['name'].'@walletofsatoshi.com', + 'website' => 'https://einundzwanzig.space', + 'picture' => 'https://m.primal.net/'.fake()->uuid().'.jpg', + 'deleted' => false, + ]); + } + + Event::factory() + ->fromMarkusTurm() + ->count(5) + ->create() + ->each(function (Event $event): void { + RenderedEvent::query()->create([ + 'event_id' => $event->event_id, + 'html' => '

'.fake()->paragraph().'

', + 'profile_image' => 'https://m.primal.net/HQqf.jpg', + 'profile_name' => 'markusturm', + ]); + }); + } +} diff --git a/database/seeders/NotificationSeeder.php b/database/seeders/NotificationSeeder.php new file mode 100644 index 0000000..261b751 --- /dev/null +++ b/database/seeders/NotificationSeeder.php @@ -0,0 +1,57 @@ +where('npub', 'npub17fqtu2mgf7zueq2kdusgzwr2lqwhgfl2scjsez77ddag2qx8vxaq3vnr8y') + ->first() ?? EinundzwanzigPleb::query()->first(); + + if (! $markus) { + return; + } + + $news = [ + [ + 'name' => 'Generalversammlung 2026 - Save the Date', + 'description' => "Die nächste Generalversammlung findet am 21. Juni 2026 in Wien statt. Alle Mitglieder sind herzlich eingeladen.\n\nAgenda:\n- Bericht des Vorstands\n- Wahl des neuen Vorstands\n- Project Support Abstimmungen", + 'category' => NewsCategory::Veranstaltungen, + ], + [ + 'name' => 'Neuer Lightning Watchtower verfügbar', + 'description' => 'Mitglieder können ab sofort unseren Watchtower nutzen. Details zur Konfiguration im Mitgliederbereich.', + 'category' => NewsCategory::Bitcoin, + ], + [ + 'name' => 'Meetup-Welle im Sommer 2026', + 'description' => 'Über 30 Einundzwanzig Meetups im DACH-Raum geplant. Termine im Portal.', + 'category' => NewsCategory::Meetups, + ], + [ + 'name' => 'Q1 2026 Finanzbericht', + 'description' => 'Der Finanzbericht für das erste Quartal 2026 ist im Mitgliederbereich abrufbar.', + 'category' => NewsCategory::Finanzen, + ], + [ + 'name' => 'Neue Bildungsinitiative gestartet', + 'description' => 'Die Einundzwanzig Bitcoin Schule startet im September. Anmeldung ab sofort möglich.', + 'category' => NewsCategory::Bildung, + ], + ]; + + foreach ($news as $item) { + Notification::query()->create([ + ...$item, + 'einundzwanzig_pleb_id' => $markus->id, + ]); + } + } +} diff --git a/database/seeders/PlebSeeder.php b/database/seeders/PlebSeeder.php new file mode 100644 index 0000000..0a51341 --- /dev/null +++ b/database/seeders/PlebSeeder.php @@ -0,0 +1,111 @@ +}> + */ + private array $boardMembers = [ + [ + 'npub' => 'npub17fqtu2mgf7zueq2kdusgzwr2lqwhgfl2scjsez77ddag2qx8vxaq3vnr8y', + 'pubkey' => 'f240be2b684f85cc81566f2081386af81d7427ea86250c8bde6b7a8500c761ba', + 'email' => 'markus@einundzwanzig.space', + 'nip05' => 'markusturm', + 'status' => AssociationStatus::HONORARY, + 'paid_years' => [2024, 2025, 2026], + 'name' => 'Markus Turm', + ], + [ + 'npub' => 'npub1pt0kw36ue3w2g4haxq3wgm6a2fhtptmzsjlc2j2vphtcgle72qesgpjyc6', + 'pubkey' => '0adf67475ccc5ca456fd3022e46f5d526eb0af6284bf85494c0dd7847f3e5033', + 'email' => 'board1@einundzwanzig.space', + 'nip05' => 'pleb1', + 'status' => AssociationStatus::HONORARY, + 'paid_years' => [2024, 2025, 2026], + 'name' => 'Vorstand 1', + ], + [ + 'npub' => 'npub1gvqkjccl9urg93svaw60jqkk3ux8r3ycl5t3rlvc9uzjeu0agfuss8x8qy', + 'pubkey' => '430169631f2f0682c60cebb4f902d68f0c71c498fd1711fd982f052cf1fd4279', + 'email' => 'board2@einundzwanzig.space', + 'nip05' => 'pleb2', + 'status' => AssociationStatus::HONORARY, + 'paid_years' => [2025, 2026], + 'name' => 'Vorstand 2', + ], + [ + 'npub' => 'npub10t8npnmqhpwx9w8k232kess7gqtdlr6kqjemdzf8jnughwqd0gwsez0924', + 'pubkey' => '7acf30cf60b85c62b8f654556cc21e4016df8f5604b3b6892794f88bb80d7a1d', + 'email' => 'board3@einundzwanzig.space', + 'nip05' => 'pleb3', + 'status' => AssociationStatus::HONORARY, + 'paid_years' => [2025, 2026], + 'name' => 'Vorstand 3', + ], + [ + 'npub' => 'npub1r8343wqpra05l3jnc4jud4xz7vlnyeslf7gfsty7ahpf92rhfmpsmqwym8', + 'pubkey' => '19e358b8011f5f4fc653c565c6d4c2f33f32661f4f90982c9eedc292a8774ec3', + 'email' => 'board4@einundzwanzig.space', + 'nip05' => 'pleb4', + 'status' => AssociationStatus::HONORARY, + 'paid_years' => [2026], + 'name' => 'Vorstand 4', + ], + ]; + + public function run(): void + { + foreach ($this->boardMembers as $member) { + $pleb = EinundzwanzigPleb::query()->create([ + 'npub' => $member['npub'], + 'pubkey' => $member['pubkey'], + 'email' => $member['email'], + 'nip05_handle' => $member['nip05'], + 'association_status' => $member['status'], + 'application_text' => 'Ich bin Teil des Einundzwanzig Vorstands und unterstütze die Mission, Bitcoin in den deutschsprachigen Raum zu bringen.', + ]); + + foreach ($member['paid_years'] as $year) { + PaymentEvent::query()->create([ + 'einundzwanzig_pleb_id' => $pleb->id, + 'year' => $year, + 'amount' => 21000, + 'paid' => true, + 'event_id' => 'seed_'.bin2hex(random_bytes(16)), + ]); + } + } + + EinundzwanzigPleb::factory() + ->count(8) + ->active() + ->create() + ->each(function (EinundzwanzigPleb $pleb): void { + PaymentEvent::factory() + ->paid() + ->withYear((int) date('Y')) + ->for($pleb, 'pleb') + ->create(); + }); + + EinundzwanzigPleb::factory() + ->count(5) + ->state(['association_status' => AssociationStatus::PASSIVE]) + ->create(); + + EinundzwanzigPleb::factory() + ->count(3) + ->state([ + 'association_status' => AssociationStatus::DEFAULT, + 'application_text' => 'Ich möchte Mitglied bei Einundzwanzig werden und die Bitcoin-Community im deutschsprachigen Raum mitgestalten.', + ]) + ->create(); + } +} diff --git a/database/seeders/ProjectProposalSeeder.php b/database/seeders/ProjectProposalSeeder.php new file mode 100644 index 0000000..c19fdda --- /dev/null +++ b/database/seeders/ProjectProposalSeeder.php @@ -0,0 +1,91 @@ + + */ + private array $proposals = [ + [ + 'name' => 'Einundzwanzig Portal Refactoring', + 'description' => "Das Einundzwanzig Portal benötigt ein größeres Refactoring, um die Performance zu verbessern und neue Features wie Meetup-Anmeldung über Nostr DMs zu ermöglichen.\n\n**Geplante Änderungen:**\n- Migration auf Livewire 4\n- Nostr Login per NIP-46\n- Meetup Kalender als ICS-Feed\n- API für externe Tools", + 'support_in_sats' => 2_100_000, + 'website' => 'https://github.com/einundzwanzig-portal/einundzwanzig-portal', + 'accepted' => true, + ], + [ + 'name' => 'Bitcoin Schule für Plebs', + 'description' => "Curriculum für eine deutschsprachige Bitcoin-Schule mit modular aufgebauten Kursen für Einsteiger und Fortgeschrittene.\n\n- Onboarding für totale Beginner\n- Self Custody Workshops\n- Lightning Network Hands-on\n- Privacy & Coinjoin Module", + 'support_in_sats' => 1_500_000, + 'website' => 'https://einundzwanzig.school', + 'accepted' => true, + ], + [ + 'name' => 'Lightning Watchtower für Mitglieder', + 'description' => 'Hosting eines Lightning Watchtower Service exklusiv für Einundzwanzig Mitglieder, um Channel-Verlust durch böswillige Counterparties zu verhindern.', + 'support_in_sats' => 500_000, + 'website' => 'https://einundzwanzig.space/benefits', + 'accepted' => false, + ], + [ + 'name' => 'Nostr Relay Hosting', + 'description' => 'Betrieb eines schnellen Nostr Relay (`wss://simple-relay.codingarena.top`) für die Einundzwanzig Community. Optimiert für deutschsprachige Inhalte und Meetup-Events.', + 'support_in_sats' => 800_000, + 'website' => 'https://simple-relay.codingarena.top', + 'accepted' => true, + ], + [ + 'name' => 'Meetup Sticker Druck Q3 2026', + 'description' => 'Bestellung von 5000 Einundzwanzig Stickern für die Meetups im DACH-Raum. Verteilung über die lokalen Meetup Organisatoren.', + 'support_in_sats' => 210_000, + 'website' => 'https://einundzwanzig.space', + 'accepted' => false, + ], + ]; + + public function run(): void + { + $plebs = EinundzwanzigPleb::query()->get(); + if ($plebs->isEmpty()) { + return; + } + + $markus = EinundzwanzigPleb::query() + ->where('npub', 'npub17fqtu2mgf7zueq2kdusgzwr2lqwhgfl2scjsez77ddag2qx8vxaq3vnr8y') + ->first(); + + foreach ($this->proposals as $index => $data) { + $pleb = $markus && $index < 2 ? $markus : $plebs->random(); + + $proposal = ProjectProposal::query()->create([ + 'einundzwanzig_pleb_id' => $pleb->id, + 'name' => $data['name'], + 'description' => $data['description'], + 'support_in_sats' => $data['support_in_sats'], + 'website' => $data['website'], + 'accepted' => $data['accepted'], + 'sats_paid' => $data['accepted'] ? $data['support_in_sats'] : null, + ]); + + foreach ($plebs->random(min($plebs->count(), 6)) as $voter) { + Vote::query()->updateOrCreate( + [ + 'einundzwanzig_pleb_id' => $voter->id, + 'project_proposal_id' => $proposal->id, + ], + [ + 'value' => fake()->boolean(70), + 'reason' => fake()->optional(0.4)->sentence(), + ] + ); + } + } + } +} diff --git a/database/seeders/SecuritySeeder.php b/database/seeders/SecuritySeeder.php new file mode 100644 index 0000000..6671064 --- /dev/null +++ b/database/seeders/SecuritySeeder.php @@ -0,0 +1,16 @@ +count(15)->create(); + SecurityAttempt::factory()->high()->count(4)->create(); + SecurityAttempt::factory()->critical()->count(1)->create(); + } +} diff --git a/resources/views/livewire/association/election/show.blade.php b/resources/views/livewire/association/election/show.blade.php index 3843b5d..c13737b 100644 --- a/resources/views/livewire/association/election/show.blade.php +++ b/resources/views/livewire/association/election/show.blade.php @@ -243,7 +243,7 @@ new class extends Component { ->whereIn('association_status', [3, 4]) ->where(fn ($query) => $query ->where('pubkey', 'like', "%$value%") - ->orWhereHas('profile', fn ($query) => $query->where('name', 'ilike', "%$value%"))) + ->orWhereHas('profile', fn ($query) => $query->whereLike('name', "%$value%"))) ->orderBy('association_status', 'desc') ->get() ->toArray(); diff --git a/resources/views/livewire/association/members/admin.blade.php b/resources/views/livewire/association/members/admin.blade.php index c3de70d..e6f36e3 100644 --- a/resources/views/livewire/association/members/admin.blade.php +++ b/resources/views/livewire/association/members/admin.blade.php @@ -107,7 +107,7 @@ new class extends Component if ($this->search) { $query->where(function ($query) { $query->whereHas('profile', function ($query) { - $query->where('name', 'ilike', '%'.$this->search.'%'); + $query->whereLike('name', '%'.$this->search.'%'); })->orWhere('npub', 'like', '%'.$this->search.'%'); }); } diff --git a/resources/views/livewire/association/project-support/index.blade.php b/resources/views/livewire/association/project-support/index.blade.php index 3a209a1..ae20b64 100644 --- a/resources/views/livewire/association/project-support/index.blade.php +++ b/resources/views/livewire/association/project-support/index.blade.php @@ -54,10 +54,10 @@ new class extends Component { ]) ->where(function ($query) { $query - ->where('name', 'ilike', '%'.$this->search.'%') - ->orWhere('description', 'ilike', '%'.$this->search.'%') + ->whereLike('name', '%'.$this->search.'%') + ->orWhereLike('description', '%'.$this->search.'%') ->orWhereHas('einundzwanzigPleb.profile', function ($q) { - $q->where('name', 'ilike', '%'.$this->search.'%'); + $q->whereLike('name', '%'.$this->search.'%'); }); }) ->orderBy('created_at', 'desc')