From ac0c5410c1ca0bb727aba1a69b5b9192a0849cf8 Mon Sep 17 00:00:00 2001 From: Mark Gregory Date: Mon, 19 Oct 2026 14:11:28 +0100 Subject: [PATCH] updates --- rsync-studio-licensing/.editorconfig | 0 rsync-studio-licensing/.env.example | 10 + rsync-studio-licensing/.gitattributes | 0 rsync-studio-licensing/.gitignore | 0 rsync-studio-licensing/.npmrc | 0 rsync-studio-licensing/AGENTS.md | 0 rsync-studio-licensing/CLAUDE.md | 0 rsync-studio-licensing/README.md | 0 .../Commands/RsyncStudioAdminCreate.php | 32 +- .../Commands/RsyncStudioLicenseIssue.php | 23 +- .../Commands/RsyncStudioLicenseRevoke.php | 17 +- .../Commands/RsyncStudioProductCreate.php | 17 +- .../Controllers/Admin/AdminController.php | 49 +- .../Admin/SupportTicketController.php | 59 + .../Api/LicenseActivationController.php | 157 +- .../Api/PaymentWebhookController.php | 75 +- .../Auth/AuthenticatedSessionController.php | 37 +- .../Auth/EmailVerificationController.php | 29 +- .../Controllers/Auth/PasswordController.php | 38 +- .../Auth/RegisteredUserController.php | 26 +- .../Http/Controllers/CheckoutController.php | 38 + .../app/Http/Controllers/Controller.php | 0 .../Controllers/Portal/PortalController.php | 139 +- .../Controllers/Support/SupportController.php | 92 + .../app/Http/Middleware/AdminOnly.php | 10 +- rsync-studio-licensing/app/Models/License.php | 27 +- .../app/Models/LicenseActivation.php | 9 +- .../app/Models/LicenseDeliveryOutbox.php | 9 +- .../app/Models/LicenseProduct.php | 6 +- .../app/Models/LicenseWebhookEvent.php | 8 +- .../app/Models/SupportTicket.php | 46 + rsync-studio-licensing/app/Models/User.php | 13 +- .../app/Notifications/NewSupportTicket.php | 43 + .../RsyncStudioLicensingServiceProvider.php | 0 .../Licensing/LicenseDeliveryService.php | 40 + .../app/Services/Licensing/LicenseIssuer.php | 40 +- .../app/Services/Licensing/LicenseKey.php | 6 +- .../app/Services/Licensing/LicenseSigner.php | 12 +- .../Licensing/LicenseTokenVerifier.php | 20 +- .../Payments/LemonSqueezyWebhookVerifier.php | 11 +- .../app/Services/Payments/PaddleClient.php | 82 + .../Payments/PaddleWebhookVerifier.php | 26 +- .../Services/Payments/PurchaseProvisioner.php | 247 +- .../app/Services/Payments/WebhookVerifier.php | 8 +- rsync-studio-licensing/bootstrap/app.php | 0 .../bootstrap/cache/.gitignore | 0 .../bootstrap/providers.php | 4 +- rsync-studio-licensing/composer.json | 3 +- rsync-studio-licensing/composer.lock | 65 +- rsync-studio-licensing/composer.stage4.json | 7 - .../config/rsync-studio.php | 26 + .../database/database.sqlite | Bin 143360 -> 184320 bytes ...026_09_08_193343_create_sessions_table.php | 0 ...0_create_rsync_studio_licensing_tables.php | 3 +- .../2026_09_08_200758_create_cache_table.php | 0 ...205000_create_rsync_studio_auth_tables.php | 0 ..._210000_add_rsync_studio_portal_fields.php | 0 ..._100000_add_paddle_subscription_fields.php | 34 + ...eate_support_tickets_and_notifications.php | 47 + .../database/seeders/PaddleCatalogSeeder.php | 29 + rsync-studio-licensing/deploy.php | 24 +- .../docs/PADDLE_SUBSCRIPTIONS.md | 71 + .../docs/PORTAL_LAUNCH_FRONTEND.md | 24 + .../docs/rsync-studio-paddle-ids.env | 7 + rsync-studio-licensing/package-lock.json | 2354 +++++++++++++++++ rsync-studio-licensing/package.json | 0 rsync-studio-licensing/phpunit.xml | 0 rsync-studio-licensing/public/.htaccess | 0 .../public/browserconfig.xml | 9 + rsync-studio-licensing/public/favicon.ico | Bin 0 -> 11471 bytes .../public/icons/android-chrome-192x192.png | Bin 0 -> 24499 bytes .../public/icons/android-chrome-512x512.png | Bin 0 -> 86623 bytes .../public/icons/apple-touch-icon.png | Bin 0 -> 22309 bytes .../public/icons/favicon-16x16.png | Bin 0 -> 669 bytes .../public/icons/favicon-32x32.png | Bin 0 -> 1865 bytes .../public/icons/favicon-48x48.png | Bin 0 -> 3476 bytes .../public/icons/mstile-150x150.png | Bin 0 -> 17485 bytes .../public/icons/og-rsync-studio.png | Bin 0 -> 86623 bytes .../public/icons/rsync-studio-icon-128.png | Bin 0 -> 14049 bytes .../public/icons/rsync-studio-icon-64.png | Bin 0 -> 5299 bytes .../public/icons/safari-pinned-tab.svg | 3 + rsync-studio-licensing/public/index.php | 0 rsync-studio-licensing/public/robots.txt | 0 .../public/site.webmanifest | 13 + rsync-studio-licensing/resources/css/app.css | 0 rsync-studio-licensing/resources/js/app.js | 0 .../resources/views/admin/index.blade.php | 7 +- .../resources/views/admin/license.blade.php | 0 .../resources/views/admin/licenses.blade.php | 0 .../views/admin/support/index.blade.php | 24 + .../views/admin/support/show.blade.php | 14 + .../views/auth/forgot-password.blade.php | 0 .../resources/views/auth/login.blade.php | 0 .../resources/views/auth/register.blade.php | 0 .../views/auth/reset-password.blade.php | 0 .../views/auth/verify-email.blade.php | 0 .../resources/views/checkout/buy.blade.php | 91 + .../resources/views/layouts/app.blade.php | 316 ++- .../resources/views/legal/cookies.blade.php | 16 + .../resources/views/legal/privacy.blade.php | 39 + .../resources/views/legal/terms.blade.php | 19 + .../resources/views/portal/index.blade.php | 114 +- .../resources/views/portal/show.blade.php | 81 +- .../resources/views/portal/welcome.blade.php | 148 +- .../resources/views/support.blade.php | 100 + .../resources/views/welcome.blade.php | 0 rsync-studio-licensing/routes/api.php | 11 +- rsync-studio-licensing/routes/api.stage4.php | 11 - rsync-studio-licensing/routes/console.php | 6 + rsync-studio-licensing/routes/web.php | 54 +- rsync-studio-licensing/routes/web.stage5.php | 14 - .../scripts/create-rsync-studio-catalog.sh | 247 ++ .../{ => scripts}/install-overlay.sh | 0 rsync-studio-licensing/storage/app/.gitignore | 0 .../storage/app/private/.gitignore | 0 .../storage/app/public/.gitignore | 0 .../storage/framework/.gitignore | 0 .../storage/framework/cache/.gitignore | 0 .../storage/framework/cache/data/.gitignore | 0 .../storage/framework/sessions/.gitignore | 0 .../storage/framework/testing/.gitignore | 0 .../storage/framework/views/.gitignore | 0 .../storage/logs/.gitignore | 0 .../tests/Feature/CheckoutPageTest.php | 27 + .../tests/Feature/LicenseActivationTest.php | 76 +- .../PaddleSubscriptionProvisioningTest.php | 105 + .../PortalSubscriptionManagementTest.php | 66 + rsync-studio-licensing/vite.config.js | 0 128 files changed, 5593 insertions(+), 217 deletions(-) mode change 100644 => 100755 rsync-studio-licensing/.editorconfig mode change 100644 => 100755 rsync-studio-licensing/.env.example mode change 100644 => 100755 rsync-studio-licensing/.gitattributes mode change 100644 => 100755 rsync-studio-licensing/.gitignore mode change 100644 => 100755 rsync-studio-licensing/.npmrc mode change 100644 => 100755 rsync-studio-licensing/AGENTS.md mode change 100644 => 100755 rsync-studio-licensing/CLAUDE.md mode change 100644 => 100755 rsync-studio-licensing/README.md mode change 100644 => 100755 rsync-studio-licensing/app/Console/Commands/RsyncStudioAdminCreate.php mode change 100644 => 100755 rsync-studio-licensing/app/Console/Commands/RsyncStudioLicenseIssue.php mode change 100644 => 100755 rsync-studio-licensing/app/Console/Commands/RsyncStudioLicenseRevoke.php mode change 100644 => 100755 rsync-studio-licensing/app/Console/Commands/RsyncStudioProductCreate.php mode change 100644 => 100755 rsync-studio-licensing/app/Http/Controllers/Admin/AdminController.php create mode 100755 rsync-studio-licensing/app/Http/Controllers/Admin/SupportTicketController.php mode change 100644 => 100755 rsync-studio-licensing/app/Http/Controllers/Api/LicenseActivationController.php mode change 100644 => 100755 rsync-studio-licensing/app/Http/Controllers/Api/PaymentWebhookController.php mode change 100644 => 100755 rsync-studio-licensing/app/Http/Controllers/Auth/AuthenticatedSessionController.php mode change 100644 => 100755 rsync-studio-licensing/app/Http/Controllers/Auth/EmailVerificationController.php mode change 100644 => 100755 rsync-studio-licensing/app/Http/Controllers/Auth/PasswordController.php mode change 100644 => 100755 rsync-studio-licensing/app/Http/Controllers/Auth/RegisteredUserController.php create mode 100755 rsync-studio-licensing/app/Http/Controllers/CheckoutController.php mode change 100644 => 100755 rsync-studio-licensing/app/Http/Controllers/Controller.php mode change 100644 => 100755 rsync-studio-licensing/app/Http/Controllers/Portal/PortalController.php create mode 100755 rsync-studio-licensing/app/Http/Controllers/Support/SupportController.php mode change 100644 => 100755 rsync-studio-licensing/app/Http/Middleware/AdminOnly.php mode change 100644 => 100755 rsync-studio-licensing/app/Models/License.php mode change 100644 => 100755 rsync-studio-licensing/app/Models/LicenseActivation.php mode change 100644 => 100755 rsync-studio-licensing/app/Models/LicenseDeliveryOutbox.php mode change 100644 => 100755 rsync-studio-licensing/app/Models/LicenseProduct.php mode change 100644 => 100755 rsync-studio-licensing/app/Models/LicenseWebhookEvent.php create mode 100755 rsync-studio-licensing/app/Models/SupportTicket.php mode change 100644 => 100755 rsync-studio-licensing/app/Models/User.php create mode 100755 rsync-studio-licensing/app/Notifications/NewSupportTicket.php mode change 100644 => 100755 rsync-studio-licensing/app/Providers/RsyncStudioLicensingServiceProvider.php create mode 100755 rsync-studio-licensing/app/Services/Licensing/LicenseDeliveryService.php mode change 100644 => 100755 rsync-studio-licensing/app/Services/Licensing/LicenseIssuer.php mode change 100644 => 100755 rsync-studio-licensing/app/Services/Licensing/LicenseKey.php mode change 100644 => 100755 rsync-studio-licensing/app/Services/Licensing/LicenseSigner.php mode change 100644 => 100755 rsync-studio-licensing/app/Services/Licensing/LicenseTokenVerifier.php mode change 100644 => 100755 rsync-studio-licensing/app/Services/Payments/LemonSqueezyWebhookVerifier.php create mode 100755 rsync-studio-licensing/app/Services/Payments/PaddleClient.php mode change 100644 => 100755 rsync-studio-licensing/app/Services/Payments/PaddleWebhookVerifier.php mode change 100644 => 100755 rsync-studio-licensing/app/Services/Payments/PurchaseProvisioner.php mode change 100644 => 100755 rsync-studio-licensing/app/Services/Payments/WebhookVerifier.php mode change 100644 => 100755 rsync-studio-licensing/bootstrap/app.php mode change 100644 => 100755 rsync-studio-licensing/bootstrap/cache/.gitignore mode change 100644 => 100755 rsync-studio-licensing/bootstrap/providers.php mode change 100644 => 100755 rsync-studio-licensing/composer.json mode change 100644 => 100755 rsync-studio-licensing/composer.lock delete mode 100644 rsync-studio-licensing/composer.stage4.json mode change 100644 => 100755 rsync-studio-licensing/config/rsync-studio.php mode change 100644 => 100755 rsync-studio-licensing/database/database.sqlite mode change 100644 => 100755 rsync-studio-licensing/database/migrations/2026_09_08_193343_create_sessions_table.php mode change 100644 => 100755 rsync-studio-licensing/database/migrations/2026_09_08_200000_create_rsync_studio_licensing_tables.php mode change 100644 => 100755 rsync-studio-licensing/database/migrations/2026_09_08_200758_create_cache_table.php mode change 100644 => 100755 rsync-studio-licensing/database/migrations/2026_09_08_205000_create_rsync_studio_auth_tables.php mode change 100644 => 100755 rsync-studio-licensing/database/migrations/2026_09_08_210000_add_rsync_studio_portal_fields.php create mode 100755 rsync-studio-licensing/database/migrations/2026_09_09_100000_add_paddle_subscription_fields.php create mode 100755 rsync-studio-licensing/database/migrations/2026_09_09_160000_create_support_tickets_and_notifications.php create mode 100755 rsync-studio-licensing/database/seeders/PaddleCatalogSeeder.php mode change 100644 => 100755 rsync-studio-licensing/deploy.php create mode 100755 rsync-studio-licensing/docs/PADDLE_SUBSCRIPTIONS.md create mode 100755 rsync-studio-licensing/docs/PORTAL_LAUNCH_FRONTEND.md create mode 100755 rsync-studio-licensing/docs/rsync-studio-paddle-ids.env create mode 100755 rsync-studio-licensing/package-lock.json mode change 100644 => 100755 rsync-studio-licensing/package.json mode change 100644 => 100755 rsync-studio-licensing/phpunit.xml mode change 100644 => 100755 rsync-studio-licensing/public/.htaccess create mode 100755 rsync-studio-licensing/public/browserconfig.xml mode change 100644 => 100755 rsync-studio-licensing/public/favicon.ico create mode 100755 rsync-studio-licensing/public/icons/android-chrome-192x192.png create mode 100755 rsync-studio-licensing/public/icons/android-chrome-512x512.png create mode 100755 rsync-studio-licensing/public/icons/apple-touch-icon.png create mode 100755 rsync-studio-licensing/public/icons/favicon-16x16.png create mode 100755 rsync-studio-licensing/public/icons/favicon-32x32.png create mode 100755 rsync-studio-licensing/public/icons/favicon-48x48.png create mode 100755 rsync-studio-licensing/public/icons/mstile-150x150.png create mode 100755 rsync-studio-licensing/public/icons/og-rsync-studio.png create mode 100755 rsync-studio-licensing/public/icons/rsync-studio-icon-128.png create mode 100755 rsync-studio-licensing/public/icons/rsync-studio-icon-64.png create mode 100755 rsync-studio-licensing/public/icons/safari-pinned-tab.svg mode change 100644 => 100755 rsync-studio-licensing/public/index.php mode change 100644 => 100755 rsync-studio-licensing/public/robots.txt create mode 100755 rsync-studio-licensing/public/site.webmanifest mode change 100644 => 100755 rsync-studio-licensing/resources/css/app.css mode change 100644 => 100755 rsync-studio-licensing/resources/js/app.js mode change 100644 => 100755 rsync-studio-licensing/resources/views/admin/index.blade.php mode change 100644 => 100755 rsync-studio-licensing/resources/views/admin/license.blade.php mode change 100644 => 100755 rsync-studio-licensing/resources/views/admin/licenses.blade.php create mode 100755 rsync-studio-licensing/resources/views/admin/support/index.blade.php create mode 100755 rsync-studio-licensing/resources/views/admin/support/show.blade.php mode change 100644 => 100755 rsync-studio-licensing/resources/views/auth/forgot-password.blade.php mode change 100644 => 100755 rsync-studio-licensing/resources/views/auth/login.blade.php mode change 100644 => 100755 rsync-studio-licensing/resources/views/auth/register.blade.php mode change 100644 => 100755 rsync-studio-licensing/resources/views/auth/reset-password.blade.php mode change 100644 => 100755 rsync-studio-licensing/resources/views/auth/verify-email.blade.php create mode 100755 rsync-studio-licensing/resources/views/checkout/buy.blade.php mode change 100644 => 100755 rsync-studio-licensing/resources/views/layouts/app.blade.php create mode 100755 rsync-studio-licensing/resources/views/legal/cookies.blade.php create mode 100755 rsync-studio-licensing/resources/views/legal/privacy.blade.php create mode 100755 rsync-studio-licensing/resources/views/legal/terms.blade.php mode change 100644 => 100755 rsync-studio-licensing/resources/views/portal/index.blade.php mode change 100644 => 100755 rsync-studio-licensing/resources/views/portal/show.blade.php mode change 100644 => 100755 rsync-studio-licensing/resources/views/portal/welcome.blade.php create mode 100755 rsync-studio-licensing/resources/views/support.blade.php mode change 100644 => 100755 rsync-studio-licensing/resources/views/welcome.blade.php mode change 100644 => 100755 rsync-studio-licensing/routes/api.php delete mode 100644 rsync-studio-licensing/routes/api.stage4.php create mode 100755 rsync-studio-licensing/routes/console.php mode change 100644 => 100755 rsync-studio-licensing/routes/web.php delete mode 100644 rsync-studio-licensing/routes/web.stage5.php create mode 100755 rsync-studio-licensing/scripts/create-rsync-studio-catalog.sh rename rsync-studio-licensing/{ => scripts}/install-overlay.sh (100%) mode change 100644 => 100755 rsync-studio-licensing/storage/app/.gitignore mode change 100644 => 100755 rsync-studio-licensing/storage/app/private/.gitignore mode change 100644 => 100755 rsync-studio-licensing/storage/app/public/.gitignore mode change 100644 => 100755 rsync-studio-licensing/storage/framework/.gitignore mode change 100644 => 100755 rsync-studio-licensing/storage/framework/cache/.gitignore mode change 100644 => 100755 rsync-studio-licensing/storage/framework/cache/data/.gitignore mode change 100644 => 100755 rsync-studio-licensing/storage/framework/sessions/.gitignore mode change 100644 => 100755 rsync-studio-licensing/storage/framework/testing/.gitignore mode change 100644 => 100755 rsync-studio-licensing/storage/framework/views/.gitignore mode change 100644 => 100755 rsync-studio-licensing/storage/logs/.gitignore create mode 100755 rsync-studio-licensing/tests/Feature/CheckoutPageTest.php mode change 100644 => 100755 rsync-studio-licensing/tests/Feature/LicenseActivationTest.php create mode 100755 rsync-studio-licensing/tests/Feature/PaddleSubscriptionProvisioningTest.php create mode 100755 rsync-studio-licensing/tests/Feature/PortalSubscriptionManagementTest.php mode change 100644 => 100755 rsync-studio-licensing/vite.config.js diff --git a/rsync-studio-licensing/.editorconfig b/rsync-studio-licensing/.editorconfig old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/.env.example b/rsync-studio-licensing/.env.example old mode 100644 new mode 100755 index ed05089..6b9ff41 --- a/rsync-studio-licensing/.env.example +++ b/rsync-studio-licensing/.env.example @@ -72,6 +72,16 @@ RSYNC_STUDIO_DEFAULT_MAX_MAJOR_VERSION=1 RSYNC_STUDIO_PURCHASE_URL= RSYNC_STUDIO_PORTAL_URL= RSYNC_STUDIO_SUPPORT_URL= +PADDLE_API_KEY= +PADDLE_API_URL=https://sandbox-api.paddle.com +PADDLE_CLIENT_SIDE_TOKEN= +PADDLE_ENVIRONMENT=sandbox PADDLE_WEBHOOK_SECRET= PADDLE_WEBHOOK_TOLERANCE=300 +PADDLE_PERSONAL_PRODUCT_ID= +PADDLE_PERSONAL_MONTHLY_PRICE_ID= +PADDLE_PERSONAL_ANNUAL_PRICE_ID= +PADDLE_PROFESSIONAL_PRODUCT_ID= +PADDLE_PROFESSIONAL_MONTHLY_PRICE_ID= +PADDLE_PROFESSIONAL_ANNUAL_PRICE_ID= LEMON_SQUEEZY_WEBHOOK_SECRET= diff --git a/rsync-studio-licensing/.gitattributes b/rsync-studio-licensing/.gitattributes old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/.gitignore b/rsync-studio-licensing/.gitignore old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/.npmrc b/rsync-studio-licensing/.npmrc old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/AGENTS.md b/rsync-studio-licensing/AGENTS.md old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/CLAUDE.md b/rsync-studio-licensing/CLAUDE.md old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/README.md b/rsync-studio-licensing/README.md old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/app/Console/Commands/RsyncStudioAdminCreate.php b/rsync-studio-licensing/app/Console/Commands/RsyncStudioAdminCreate.php old mode 100644 new mode 100755 index 6671411..ee52644 --- a/rsync-studio-licensing/app/Console/Commands/RsyncStudioAdminCreate.php +++ b/rsync-studio-licensing/app/Console/Commands/RsyncStudioAdminCreate.php @@ -1,10 +1,36 @@ argument('email'))); $password=Str::password(24,true,true,false,false); $u=User::firstOrNew(['email'=>$email]); $u->name=$this->option('name'); $u->is_admin=true; $u->email_verified_at=now(); if(!$u->exists){$u->password=Hash::make($password);} $u->save(); $this->info("Administrator ready: {$email}"); if(!$u->wasRecentlyCreated){$this->line('Existing password retained.');}else{$this->warn("Temporary password (shown once): {$password}");} return self::SUCCESS; } + +final class RsyncStudioAdminCreate extends Command +{ + protected $signature = 'rsync-studio:admin {email} {--name=Administrator}'; + + protected $description = 'Create or promote an Rsync Studio licensing administrator'; + + public function handle(): int + { + $email = strtolower(trim($this->argument('email'))); + $password = Str::password(24, true, true, false, false); + $u = User::firstOrNew(['email' => $email]); + $u->name = $this->option('name'); + $u->is_admin = true; + $u->email_verified_at = now(); + if (! $u->exists) { + $u->password = Hash::make($password); + } $u->save(); + $this->info("Administrator ready: {$email}"); + if (! $u->wasRecentlyCreated) { + $this->line('Existing password retained.'); + } else { + $this->warn("Temporary password (shown once): {$password}"); + } + +return self::SUCCESS; + } } diff --git a/rsync-studio-licensing/app/Console/Commands/RsyncStudioLicenseIssue.php b/rsync-studio-licensing/app/Console/Commands/RsyncStudioLicenseIssue.php old mode 100644 new mode 100755 index 886cefd..aa5d895 --- a/rsync-studio-licensing/app/Console/Commands/RsyncStudioLicenseIssue.php +++ b/rsync-studio-licensing/app/Console/Commands/RsyncStudioLicenseIssue.php @@ -1,10 +1,29 @@ argument('product'))->firstOrFail(); [$l,$key]=$issuer->issue($p,$this->option('name')?:null,$this->option('email')?:null); if(!$key){$this->warn('Licence already existed; plaintext key is intentionally not recoverable.');return self::FAILURE;} $this->line('Licence ID: '.$l->id);$this->line('Licence key: '.$key);$this->warn('This is the only time the plaintext key is shown.');return self::SUCCESS; } + protected $signature = 'rsync-studio:license:issue {product} {--name=} {--email=}'; + + protected $description = 'Issue a manual Rsync Studio licence key'; + + public function handle(LicenseIssuer $issuer): int + { + $p = LicenseProduct::where('code', $this->argument('product'))->firstOrFail(); + [$l,$key] = $issuer->issue($p, $this->option('name') ?: null, $this->option('email') ?: null); + if (! $key) { + $this->warn('Licence already existed; plaintext key is intentionally not recoverable.'); + + return self::FAILURE; + } $this->line('Licence ID: '.$l->id); + $this->line('Licence key: '.$key); + $this->warn('This is the only time the plaintext key is shown.'); + + return self::SUCCESS; + } } diff --git a/rsync-studio-licensing/app/Console/Commands/RsyncStudioLicenseRevoke.php b/rsync-studio-licensing/app/Console/Commands/RsyncStudioLicenseRevoke.php old mode 100644 new mode 100755 index c608df3..f48204f --- a/rsync-studio-licensing/app/Console/Commands/RsyncStudioLicenseRevoke.php +++ b/rsync-studio-licensing/app/Console/Commands/RsyncStudioLicenseRevoke.php @@ -1,9 +1,22 @@ argument('id'));$l->update(['revoked_at'=>now(),'revoke_reason'=>$this->option('reason')]);$this->info('Licence revoked.');return self::SUCCESS; } + protected $signature = 'rsync-studio:license:revoke {id} {--reason=Administrative revocation}'; + + protected $description = 'Revoke a Rsync Studio licence'; + + public function handle(): int + { + $l = License::findOrFail($this->argument('id')); + $l->update(['revoked_at' => now(), 'revoke_reason' => $this->option('reason')]); + $this->info('Licence revoked.'); + + return self::SUCCESS; + } } diff --git a/rsync-studio-licensing/app/Console/Commands/RsyncStudioProductCreate.php b/rsync-studio-licensing/app/Console/Commands/RsyncStudioProductCreate.php old mode 100644 new mode 100755 index 098b20d..6191cb4 --- a/rsync-studio-licensing/app/Console/Commands/RsyncStudioProductCreate.php +++ b/rsync-studio-licensing/app/Console/Commands/RsyncStudioProductCreate.php @@ -1,10 +1,21 @@ $this->argument('code')],['name'=>$this->option('name'),'edition'=>$this->option('edition'),'activation_limit'=>(int)$this->option('activations'),'max_major_version'=>$this->option('max-major')!==''?(int)$this->option('max-major'):null,'payment_provider'=>$this->option('provider')?:null,'external_product_id'=>$this->option('product-id')?:null,'external_price_id'=>$this->option('price-id')?:null,'active'=>true]); $this->info("Product {$p->code} ready."); return self::SUCCESS; } + protected $signature = 'rsync-studio:product {code} {--name=Rsync Studio} {--edition=Professional} {--activations=1} {--max-major=1} {--provider=} {--product-id=} {--price-id=}'; + + protected $description = 'Create or update a Rsync Studio licensing product'; + + public function handle(): int + { + $p = LicenseProduct::updateOrCreate(['code' => $this->argument('code')], ['name' => $this->option('name'), 'edition' => $this->option('edition'), 'activation_limit' => (int) $this->option('activations'), 'max_major_version' => $this->option('max-major') !== '' ? (int) $this->option('max-major') : null, 'payment_provider' => $this->option('provider') ?: null, 'external_product_id' => $this->option('product-id') ?: null, 'external_price_id' => $this->option('price-id') ?: null, 'active' => true]); + $this->info("Product {$p->code} ready."); + + return self::SUCCESS; + } } diff --git a/rsync-studio-licensing/app/Http/Controllers/Admin/AdminController.php b/rsync-studio-licensing/app/Http/Controllers/Admin/AdminController.php old mode 100644 new mode 100755 index 1d87ddc..6c2bb25 --- a/rsync-studio-licensing/app/Http/Controllers/Admin/AdminController.php +++ b/rsync-studio-licensing/app/Http/Controllers/Admin/AdminController.php @@ -1,14 +1,49 @@ License::count(),'activeCount'=>License::whereNull('revoked_at')->count(),'activationCount'=>\App\Models\LicenseActivation::whereNull('deactivated_at')->count(),'userCount'=>User::count()]); } - public function licenses(Request $r){ $q=License::with('product')->latest(); if($s=trim((string)$r->query('q'))) $q->where(fn($x)=>$x->where('customer_email','like',"%{$s}%")->orWhere('customer_name','like',"%{$s}%")->orWhere('license_key_last4','like',"%{$s}%")); return view('admin.licenses',['licenses'=>$q->paginate(50)->withQueryString()]); } - public function show(License $license){$license->load(['product','activations']); return view('admin.license',compact('license'));} - public function revoke(Request $request,License $license){$data=$request->validate(['reason'=>['nullable','string','max:255']]);$license->update(['revoked_at'=>now(),'revoke_reason'=>$data['reason']?:'Revoked by administrator']);return back()->with('status','Licence revoked.');} - public function restore(License $license){$license->update(['revoked_at'=>null,'revoke_reason'=>null]);return back()->with('status','Licence restored.');} + +final class AdminController extends Controller +{ + public function index() + { + return view('admin.index', ['licenseCount' => License::count(), 'activeCount' => License::whereNull('revoked_at')->count(), 'activationCount' => LicenseActivation::whereNull('deactivated_at')->count(), 'userCount' => User::count()]); + } + + public function licenses(Request $r) + { + $q = License::with('product')->latest(); + if ($s = trim((string) $r->query('q'))) { + $q->where(fn ($x) => $x->where('customer_email', 'like', "%{$s}%")->orWhere('customer_name', 'like', "%{$s}%")->orWhere('license_key_last4', 'like', "%{$s}%")); + } + +return view('admin.licenses', ['licenses' => $q->paginate(50)->withQueryString()]); + } + + public function show(License $license) + { + $license->load(['product', 'activations']); + + return view('admin.license', compact('license')); + } + + public function revoke(Request $request, License $license) + { + $data = $request->validate(['reason' => ['nullable', 'string', 'max:255']]); + $license->update(['revoked_at' => now(), 'revoke_reason' => $data['reason'] ?: 'Revoked by administrator']); + + return back()->with('status', 'Licence revoked.'); + } + + public function restore(License $license) + { + $license->update(['revoked_at' => null, 'revoke_reason' => null]); + + return back()->with('status','Licence restored.'); + } } diff --git a/rsync-studio-licensing/app/Http/Controllers/Admin/SupportTicketController.php b/rsync-studio-licensing/app/Http/Controllers/Admin/SupportTicketController.php new file mode 100755 index 0000000..99484af --- /dev/null +++ b/rsync-studio-licensing/app/Http/Controllers/Admin/SupportTicketController.php @@ -0,0 +1,59 @@ +with('assignee') + ->when($request->filled('status'), fn ($q) => $q->where('status', $request->string('status'))) + ->latest() + ->paginate(50) + ->withQueryString(); + + return view('admin.support.index', compact('tickets')); + } + + public function show(SupportTicket $ticket) + { + $ticket->load(['user', 'assignee']); + if (auth()->user()) { + auth()->user()->unreadNotifications()->get() + ->filter(fn ($notification) => (int) ($notification->data['support_ticket_id'] ?? 0) === $ticket->id) + ->each->markAsRead(); + } + + return view('admin.support.show', [ + 'ticket' => $ticket, + 'admins' => User::query()->where('is_admin', true)->orderBy('name')->get(['id', 'name', 'email']), + ]); + } + + public function update(Request $request, SupportTicket $ticket): RedirectResponse + { + $data = $request->validate([ + 'status' => ['required', 'in:new,open,waiting,resolved,closed'], + 'priority' => ['required', 'in:low,normal,high,urgent'], + 'assigned_to' => ['nullable', 'integer', 'exists:users,id'], + ]); + + if ($data['assigned_to'] ?? null) { + abort_unless(User::whereKey($data['assigned_to'])->where('is_admin', true)->exists(), 422); + } + + $data['resolved_at'] = in_array($data['status'], ['resolved', 'closed'], true) + ? ($ticket->resolved_at ?? now()) + : null; + $ticket->update($data); + + return back()->with('status', 'Support ticket updated.'); + } +} diff --git a/rsync-studio-licensing/app/Http/Controllers/Api/LicenseActivationController.php b/rsync-studio-licensing/app/Http/Controllers/Api/LicenseActivationController.php old mode 100644 new mode 100755 index 4bd5b7d..d4e1aba --- a/rsync-studio-licensing/app/Http/Controllers/Api/LicenseActivationController.php +++ b/rsync-studio-licensing/app/Http/Controllers/Api/LicenseActivationController.php @@ -1,4 +1,5 @@ validate([ - 'licenseKey'=>['required','string','max:128'], - 'installationID'=>['required','uuid'], - 'appVersion'=>['required','string','max:32'], - 'platform'=>['required','string','max:32'], + 'licenseKey' => ['required', 'string', 'max:128'], + 'installationID' => ['required', 'uuid'], + 'appVersion' => ['required', 'string', 'max:32'], + 'platform' => ['required', 'string', 'max:32'], ]); - return DB::transaction(function () use ($data,$signer) { - $license = License::where('license_key_hash', LicenseKey::hash($data['licenseKey']))->lockForUpdate()->first(); - if (!$license) throw ValidationException::withMessages(['licenseKey'=>'The licence key is not valid.']); - if (!$license->is_usable) return response()->json(['message'=>'This licence is expired or has been revoked.'], 403); + return DB::transaction(function () use ($data, $signer) { + $license = License::where('license_key_hash', LicenseKey::hash($data['licenseKey'])) + ->lockForUpdate() + ->first(); - $activation = LicenseActivation::where('license_id',$license->id)->where('installation_id',strtolower($data['installationID']))->first(); - if ($activation && $activation->deactivated_at === null) { - $activation->update(['last_seen_at'=>now(),'platform'=>$data['platform'],'app_version'=>$data['appVersion']]); - } else { - $activeCount = LicenseActivation::where('license_id',$license->id)->whereNull('deactivated_at')->count(); - if ($activeCount >= $license->activation_limit) return response()->json(['message'=>'This licence has reached its activation limit. Deactivate another Mac first.'], 409); - if ($activation) $activation->update(['deactivated_at'=>null,'activated_at'=>now(),'last_seen_at'=>now(),'platform'=>$data['platform'],'app_version'=>$data['appVersion']]); - else LicenseActivation::create(['license_id'=>$license->id,'installation_id'=>strtolower($data['installationID']),'platform'=>$data['platform'],'app_version'=>$data['appVersion'],'activated_at'=>now(),'last_seen_at'=>now()]); + if (! $license) { + throw ValidationException::withMessages(['licenseKey' => 'The licence key is not valid.']); } - return response()->json(['licenseToken'=>$signer->sign($license, $data['installationID'])]); + + if (! $license->is_usable) { + return response()->json(['message' => 'This licence is expired or has been revoked.'], 403); + } + + $installationID = strtolower($data['installationID']); + $activation = LicenseActivation::where('license_id', $license->id) + ->where('installation_id', $installationID) + ->first(); + + if ($activation && $activation->deactivated_at === null) { + $activation->update([ + 'last_seen_at' => now(), + 'platform' => $data['platform'], + 'app_version' => $data['appVersion'], + ]); + } else { + $activeCount = LicenseActivation::where('license_id', $license->id) + ->whereNull('deactivated_at') + ->count(); + + if ($activeCount >= $license->activation_limit) { + return response()->json(['message' => 'This licence has reached its activation limit. Deactivate another Mac first.'], 409); + } + + if ($activation) { + $activation->update([ + 'deactivated_at' => null, + 'activated_at' => now(), + 'last_seen_at' => now(), + 'platform' => $data['platform'], + 'app_version' => $data['appVersion'], + ]); + } else { + LicenseActivation::create([ + 'license_id' => $license->id, + 'installation_id' => $installationID, + 'platform' => $data['platform'], + 'app_version' => $data['appVersion'], + 'activated_at' => now(), + 'last_seen_at' => now(), + ]); + } + } + + return response()->json([ + 'licenseToken' => $signer->sign($license, $data['installationID']), + ]); + }); + } + + public function validateInstallation( + Request $request, + LicenseTokenVerifier $verifier, + LicenseSigner $signer, + ): JsonResponse { + $data = $request->validate([ + 'licenseToken' => ['required', 'string', 'max:8192'], + 'installationID' => ['required', 'uuid'], + 'appVersion' => ['required', 'string', 'max:32'], + 'platform' => ['required', 'string', 'max:32'], + ]); + + try { + $payload = $verifier->verify($data['licenseToken']); + } catch (\Throwable) { + return response()->json(['message' => 'The licence token is invalid.'], 400); + } + + if (strcasecmp((string) ($payload['installationID'] ?? ''), $data['installationID']) !== 0) { + return response()->json(['message' => 'The installation does not match this licence token.'], 400); + } + + return DB::transaction(function () use ($data, $payload, $signer) { + $license = License::whereKey((string) ($payload['licenseID'] ?? '')) + ->lockForUpdate() + ->first(); + + if (! $license || ! $license->is_usable) { + return response()->json(['message' => 'This licence is expired or has been revoked.'], 403); + } + + $activation = LicenseActivation::where('license_id', $license->id) + ->where('installation_id', strtolower($data['installationID'])) + ->first(); + + if (! $activation || $activation->deactivated_at !== null) { + return response()->json(['message' => 'This Mac has been deactivated from the licence portal.'], 403); + } + + $activation->update([ + 'last_seen_at' => now(), + 'platform' => $data['platform'], + 'app_version' => $data['appVersion'], + ]); + + return response()->json([ + 'active' => true, + // Refreshing the signed token also applies subscription edition/expiry changes + // without requiring the user to reactivate manually. + 'licenseToken' => $signer->sign($license, $data['installationID']), + ]); }); } public function deactivate(Request $request, LicenseTokenVerifier $verifier): JsonResponse { - $data = $request->validate(['licenseToken'=>['required','string','max:8192'],'installationID'=>['required','uuid']]); - try { $payload = $verifier->verify($data['licenseToken']); } - catch (\Throwable) { return response()->json(['message'=>'The licence token is invalid.'], 400); } - if (strcasecmp((string)($payload['installationID'] ?? ''), $data['installationID']) !== 0) return response()->json(['message'=>'The installation does not match this licence token.'], 400); - LicenseActivation::where('license_id',(string)($payload['licenseID'] ?? ''))->where('installation_id',strtolower($data['installationID']))->whereNull('deactivated_at')->update(['deactivated_at'=>now(),'last_seen_at'=>now()]); - return response()->json((object)[]); + $data = $request->validate([ + 'licenseToken' => ['required', 'string', 'max:8192'], + 'installationID' => ['required', 'uuid'], + ]); + + try { + $payload = $verifier->verify($data['licenseToken']); + } catch (\Throwable) { + return response()->json(['message' => 'The licence token is invalid.'], 400); + } + + if (strcasecmp((string) ($payload['installationID'] ?? ''), $data['installationID']) !== 0) { + return response()->json(['message' => 'The installation does not match this licence token.'], 400); + } + + LicenseActivation::where('license_id', (string) ($payload['licenseID'] ?? '')) + ->where('installation_id', strtolower($data['installationID'])) + ->whereNull('deactivated_at') + ->update(['deactivated_at' => now(), 'last_seen_at' => now()]); + + return response()->json((object) []); } } diff --git a/rsync-studio-licensing/app/Http/Controllers/Api/PaymentWebhookController.php b/rsync-studio-licensing/app/Http/Controllers/Api/PaymentWebhookController.php old mode 100644 new mode 100755 index 867d9ef..e4c8036 --- a/rsync-studio-licensing/app/Http/Controllers/Api/PaymentWebhookController.php +++ b/rsync-studio-licensing/app/Http/Controllers/Api/PaymentWebhookController.php @@ -1,8 +1,10 @@ getContent(); - $verifier=match($provider){'paddle'=>app(PaddleWebhookVerifier::class),'lemon-squeezy'=>app(LemonSqueezyWebhookVerifier::class),default=>null}; - if (!$verifier) return response()->json(['message'=>'Unknown webhook provider.'],404); - try { $verifier->verify($request,$raw); } catch (\Throwable $e) { report($e); return response()->json(['message'=>'Invalid webhook signature.'],400); } - try { $payload=json_decode($raw,true,flags:JSON_THROW_ON_ERROR); } catch (\Throwable) { return response()->json(['message'=>'Invalid JSON.'],400); } - $externalID=(string)($provider==='paddle'?($payload['event_id']??''):($payload['meta']['event_name']??'').':'.($payload['data']['id']??'')); - $eventType=(string)($provider==='paddle'?($payload['event_type']??'unknown'):($payload['meta']['event_name']??'unknown')); - if ($externalID==='') return response()->json(['message'=>'Webhook event has no stable identifier.'],400); + $raw = (string) $request->getContent(); + $verifier = match ($provider) { + 'paddle' => app(PaddleWebhookVerifier::class),'lemon-squeezy' => app(LemonSqueezyWebhookVerifier::class),default => null + }; + if (! $verifier) { + return response()->json(['message' => 'Unknown webhook provider.'], 404); + } + try { + $verifier->verify($request, $raw); + } catch (\Throwable $e) { + report($e); + + return response()->json(['message' => 'Invalid webhook signature.'], 400); + } + try { + $payload = json_decode($raw, true, flags: JSON_THROW_ON_ERROR); + } catch (\Throwable) { + return response()->json(['message' => 'Invalid JSON.'], 400); + } + $externalID = (string) ($provider === 'paddle' ? ($payload['event_id'] ?? '') : ($payload['meta']['event_name'] ?? '').':'.($payload['data']['id'] ?? '')); + $eventType = (string) ($provider === 'paddle' ? ($payload['event_type'] ?? 'unknown') : ($payload['meta']['event_name'] ?? 'unknown')); + if ($externalID === '') { + return response()->json(['message' => 'Webhook event has no stable identifier.'], 400); + } try { - DB::transaction(function() use($provider,$externalID,$eventType,$payload,$raw,$provisioner){ - $event=LicenseWebhookEvent::firstOrCreate(['provider'=>$provider,'external_event_id'=>$externalID],['event_type'=>$eventType,'payload_sha256'=>hash('sha256',$raw),'payload'=>$payload]); - if ($event->processed_at) return; - if (!hash_equals($event->payload_sha256,hash('sha256',$raw))) throw new \RuntimeException('Webhook ID was reused with a different payload.'); - try { $provisioner->provision($provider,$payload); $event->update(['processed_at'=>now(),'processing_error'=>null]); } - catch (\Throwable $e) { $event->update(['processing_error'=>mb_substr($e->getMessage(),0,4000)]); throw $e; } + DB::transaction(function () use ($provider, $externalID, $eventType, $payload, $raw, $provisioner) { + $event = LicenseWebhookEvent::firstOrCreate(['provider' => $provider, 'external_event_id' => $externalID], ['event_type' => $eventType, 'payload_sha256' => hash('sha256', $raw), 'payload' => $payload]); + if ($event->processed_at) { + return; + } + if (! hash_equals($event->payload_sha256, hash('sha256', $raw))) { + throw new \RuntimeException('Webhook ID was reused with a different payload.'); + } + try { + $provisioner->provision($provider, $payload); + $event->update(['processed_at' => now(), 'processing_error' => null]); + } catch (\Throwable $e) { + $event->update(['processing_error' => mb_substr($e->getMessage(), 0, 4000)]); + throw $e; + } }); - } catch (\Throwable $e) { report($e); return response()->json(['message'=>'Webhook could not be processed.'],500); } - return response()->json(['ok'=>true]); + } catch (\Throwable $e) { + report($e); + + return response()->json(['message' => 'Webhook could not be processed.'], 500); + } + + // Delivery is intentionally outside the webhook transaction. A temporary mail + // outage must not roll back an otherwise valid Paddle event. Pending outbox + // rows remain available for portal resend or a later webhook delivery attempt. + try { + $delivery->deliverPending(10); + } catch (\Throwable $e) { + report($e); + } + + return response()->json(['ok' => true]); } } diff --git a/rsync-studio-licensing/app/Http/Controllers/Auth/AuthenticatedSessionController.php b/rsync-studio-licensing/app/Http/Controllers/Auth/AuthenticatedSessionController.php old mode 100644 new mode 100755 index 7622bce..d63878e --- a/rsync-studio-licensing/app/Http/Controllers/Auth/AuthenticatedSessionController.php +++ b/rsync-studio-licensing/app/Http/Controllers/Auth/AuthenticatedSessionController.php @@ -1,14 +1,35 @@ validate(['email'=>['required','email'],'password'=>['required','string']]); - if(!Auth::attempt(['email'=>strtolower($credentials['email']),'password'=>$credentials['password']], $request->boolean('remember'))){ return back()->withErrors(['email'=>'The supplied credentials are invalid.'])->onlyInput('email'); } - $request->session()->regenerate(); return redirect()->intended(route('portal.index')); - } - public function destroy(Request $request){ Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return redirect()->route('login'); } + +final class AuthenticatedSessionController extends Controller +{ + public function create() + { + return view('auth.login'); + } + + public function store(Request $request) + { + $credentials = $request->validate(['email' => ['required', 'email'], 'password' => ['required', 'string']]); + if (! Auth::attempt(['email' => strtolower($credentials['email']), 'password' => $credentials['password']], $request->boolean('remember'))) { + return back()->withErrors(['email' => 'The supplied credentials are invalid.'])->onlyInput('email'); + } + $request->session()->regenerate(); + + return redirect()->intended(route('portal.index')); + } + + public function destroy(Request $request) + { + Auth::logout(); + $request->session()->invalidate(); + $request->session()->regenerateToken(); + + return redirect()->route('login'); + } } diff --git a/rsync-studio-licensing/app/Http/Controllers/Auth/EmailVerificationController.php b/rsync-studio-licensing/app/Http/Controllers/Auth/EmailVerificationController.php old mode 100644 new mode 100755 index 1f020dc..2f38de1 --- a/rsync-studio-licensing/app/Http/Controllers/Auth/EmailVerificationController.php +++ b/rsync-studio-licensing/app/Http/Controllers/Auth/EmailVerificationController.php @@ -1,10 +1,31 @@ fulfill(); return redirect()->route('portal.index')->with('status','Email verified.'); } - public function resend(Request $request){ if(!$request->user()->hasVerifiedEmail()) $request->user()->sendEmailVerificationNotification(); return back()->with('status','Verification link sent.'); } + +final class EmailVerificationController extends Controller +{ + public function notice() + { + return view('auth.verify-email'); + } + + public function verify(EmailVerificationRequest $request) + { + $request->fulfill(); + + return redirect()->route('portal.index')->with('status', 'Email verified.'); + } + + public function resend(Request $request) + { + if (! $request->user()->hasVerifiedEmail()) { + $request->user()->sendEmailVerificationNotification(); + } + +return back()->with('status', 'Verification link sent.'); + } } diff --git a/rsync-studio-licensing/app/Http/Controllers/Auth/PasswordController.php b/rsync-studio-licensing/app/Http/Controllers/Auth/PasswordController.php old mode 100644 new mode 100755 index 7a416a9..4eb6694 --- a/rsync-studio-licensing/app/Http/Controllers/Auth/PasswordController.php +++ b/rsync-studio-licensing/app/Http/Controllers/Auth/PasswordController.php @@ -1,5 +1,7 @@ validate(['email'=>['required','email']]); $status=Password::sendResetLink(['email'=>strtolower($request->email)]); return $status===Password::RESET_LINK_SENT?back()->with('status',__($status)):back()->withErrors(['email'=>__($status)]); } - public function resetForm(Request $request,string $token){ return view('auth.reset-password',['token'=>$token,'email'=>$request->query('email')]); } - public function reset(Request $request){ $data=$request->validate(['token'=>['required'],'email'=>['required','email'],'password'=>['required','confirmed',PasswordRule::min(12)->letters()->mixedCase()->numbers()]]); $status=Password::reset($data,function(User $user,string $password){$user->forceFill(['password'=>$password,'remember_token'=>Str::random(60)])->save();event(new PasswordReset($user));}); return $status===Password::PASSWORD_RESET?redirect()->route('login')->with('status',__($status)):back()->withErrors(['email'=>__($status)]); } + +final class PasswordController extends Controller +{ + public function requestForm() + { + return view('auth.forgot-password'); + } + + public function email(Request $request) + { + $request->validate(['email' => ['required', 'email']]); + $status = Password::sendResetLink(['email' => strtolower($request->email)]); + + return $status === Password::RESET_LINK_SENT ? back()->with('status', __($status)) : back()->withErrors(['email' => __($status)]); + } + + public function resetForm(Request $request, string $token) + { + return view('auth.reset-password', ['token' => $token, 'email' => $request->query('email')]); + } + + public function reset(Request $request) + { + $data = $request->validate(['token' => ['required'], 'email' => ['required', 'email'], 'password' => ['required', 'confirmed', PasswordRule::min(12)->letters()->mixedCase()->numbers()]]); + $status = Password::reset($data, function (User $user, string $password) { + $user->forceFill(['password' => $password, 'remember_token' => Str::random(60)])->save(); + event(new PasswordReset($user)); + }); + + return $status === Password::PASSWORD_RESET ? redirect()->route('login')->with('status', __($status)) : back()->withErrors(['email' => __($status)]); + } } diff --git a/rsync-studio-licensing/app/Http/Controllers/Auth/RegisteredUserController.php b/rsync-studio-licensing/app/Http/Controllers/Auth/RegisteredUserController.php old mode 100644 new mode 100755 index 035e0ef..3b5c073 --- a/rsync-studio-licensing/app/Http/Controllers/Auth/RegisteredUserController.php +++ b/rsync-studio-licensing/app/Http/Controllers/Auth/RegisteredUserController.php @@ -1,15 +1,29 @@ validate(['name'=>['required','string','max:120'],'email'=>['required','email','max:255','unique:users,email'],'password'=>['required','confirmed',Password::min(12)->letters()->mixedCase()->numbers()]]); - $user=User::create(['name'=>$data['name'],'email'=>strtolower($data['email']),'password'=>$data['password']]); event(new Registered($user)); Auth::login($user); $request->session()->regenerate(); return redirect()->route('verification.notice'); - } + +final class RegisteredUserController extends Controller +{ + public function create() + { + return view('auth.register'); + } + + public function store(Request $request) + { + $data = $request->validate(['name' => ['required', 'string', 'max:120'], 'email' => ['required', 'email', 'max:255', 'unique:users,email'], 'password' => ['required', 'confirmed', Password::min(12)->letters()->mixedCase()->numbers()]]); + $user = User::create(['name' => $data['name'], 'email' => strtolower($data['email']), 'password' => $data['password']]); + event(new Registered($user)); + Auth::login($user); + $request->session()->regenerate(); + + return redirect()->route('verification.notice'); + } } diff --git a/rsync-studio-licensing/app/Http/Controllers/CheckoutController.php b/rsync-studio-licensing/app/Http/Controllers/CheckoutController.php new file mode 100755 index 0000000..bdfff2b --- /dev/null +++ b/rsync-studio-licensing/app/Http/Controllers/CheckoutController.php @@ -0,0 +1,38 @@ + ['name' => 'Personal', 'billing' => 'Monthly', 'display_price' => '£1.99 / month', 'price_id' => $paddle['personal_monthly_price_id'], 'activation_limit' => 1], + 'personal-annual' => ['name' => 'Personal', 'billing' => 'Annual', 'display_price' => '£14.99 / year', 'price_id' => $paddle['personal_annual_price_id'], 'activation_limit' => 1], + 'professional-monthly' => ['name' => 'Professional', 'billing' => 'Monthly', 'display_price' => '£3.99 / month', 'price_id' => $paddle['professional_monthly_price_id'], 'activation_limit' => 3], + 'professional-annual' => ['name' => 'Professional', 'billing' => 'Annual', 'display_price' => '£29.99 / year', 'price_id' => $paddle['professional_annual_price_id'], 'activation_limit' => 3], + ]; + + foreach ($plans as $plan) { + if (trim((string) $plan['price_id']) === '') { + throw new RuntimeException('One or more Paddle price IDs are not configured.'); + } + } + + return view('checkout.buy', [ + 'plans' => $plans, + 'paddleToken' => $token, + 'paddleEnvironment' => (string) ($paddle['environment'] ?? 'sandbox'), + ]); + } +} diff --git a/rsync-studio-licensing/app/Http/Controllers/Controller.php b/rsync-studio-licensing/app/Http/Controllers/Controller.php old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/app/Http/Controllers/Portal/PortalController.php b/rsync-studio-licensing/app/Http/Controllers/Portal/PortalController.php old mode 100644 new mode 100755 index 429263d..d76d20f --- a/rsync-studio-licensing/app/Http/Controllers/Portal/PortalController.php +++ b/rsync-studio-licensing/app/Http/Controllers/Portal/PortalController.php @@ -1,15 +1,142 @@ whereRaw('lower(customer_email) = ?', [strtolower($request->user()->email)]); } - public function index(Request $request){ return view('portal.index',['licenses'=>$this->owned($request)->latest()->get()]); } - public function show(Request $request,License $license){ abort_unless(strtolower((string)$license->customer_email)===strtolower($request->user()->email),404); $license->load(['product','activations']); return view('portal.show',compact('license')); } - public function deactivate(Request $request,License $license,int $activation){ abort_unless(strtolower((string)$license->customer_email)===strtolower($request->user()->email),404); $item=$license->activations()->whereKey($activation)->firstOrFail(); if(!$item->deactivated_at){$item->update(['deactivated_at'=>now()]);} return back()->with('status','Activation released.'); } - public function resend(Request $request,License $license){ abort_unless(strtolower((string)$license->customer_email)===strtolower($request->user()->email),404); $out=LicenseDeliveryOutbox::where('license_id',$license->id)->first(); if(!$out) return back()->withErrors(['licence'=>'This licence was issued manually and its full key is not recoverable. Contact support.']); $plain=Crypt::decryptString($out->encrypted_license_key); Mail::raw("Your Rsync Studio licence key is:\n\n{$plain}\n\nKeep this key private.",fn($m)=>$m->to($request->user()->email)->subject('Your Rsync Studio licence key')); $out->update(['delivered_at'=>now()]); return back()->with('status','Licence key sent to your verified email address.'); } +use RuntimeException; + +final class PortalController extends Controller +{ + public function __construct(private PaddleClient $paddle) {} + + private function owned(Request $request) + { + return License::with(['product', 'activations']) + ->whereRaw('lower(customer_email) = ?', [strtolower($request->user()->email)]); + } + + public function index(Request $request) + { + $licenses = $this->owned($request)->latest()->get(); + $hasProfessional = $licenses->contains(fn (License $license) => $license->is_usable && $license->edition === 'Professional'); + + return view('portal.index', compact('licenses', 'hasProfessional')); + } + + public function show(Request $request, License $license) + { + $this->authorise($request, $license); + $license->load(['product', 'activations']); + + return view('portal.show', compact('license')); + } + + public function upgrade(Request $request, License $license): RedirectResponse + { + $this->authorise($request, $license); + abort_unless($license->payment_provider === 'paddle' && $license->external_subscription_id, 422); + abort_unless($license->edition === 'Personal' && $license->is_usable, 422); + + $targetPriceID = $this->professionalPriceFor($license); + $targetProduct = LicenseProduct::query() + ->where('payment_provider', 'paddle') + ->where('external_price_id', $targetPriceID) + ->where('active', true) + ->firstOrFail(); + + try { + $subscription = $this->paddle->updateSubscriptionPrice($license->external_subscription_id, $targetPriceID); + } catch (RuntimeException $exception) { + return back()->withErrors(['licence' => $exception->getMessage()]); + } + + // Apply the entitlement immediately. Paddle webhooks remain authoritative and + // will reconcile subscription status/current-period details afterwards. + $license->update([ + 'license_product_id' => $targetProduct->id, + 'edition' => $targetProduct->edition, + 'activation_limit' => $targetProduct->activation_limit, + 'max_major_version' => $targetProduct->max_major_version, + 'external_price_id' => $targetPriceID, + 'subscription_status' => (string) ($subscription['status'] ?? $license->subscription_status), + 'revoked_at' => null, + 'revoke_reason' => null, + ]); + + return redirect()->route('portal.show', $license)->with('status', 'Upgraded to Professional. Your existing Paddle subscription was changed; no second subscription was created.'); + } + + public function cancel(Request $request, License $license): RedirectResponse + { + $this->authorise($request, $license); + abort_unless($license->payment_provider === 'paddle' && $license->external_subscription_id, 422); + abort_unless(! in_array($license->subscription_status, ['canceled'], true), 422); + + try { + $this->paddle->cancelSubscriptionImmediately($license->external_subscription_id); + } catch (RuntimeException $exception) { + return back()->withErrors(['licence' => $exception->getMessage()]); + } + + $license->update([ + 'subscription_status' => 'canceled', + 'expires_at' => now(), + 'revoked_at' => now(), + 'revoke_reason' => 'Subscription canceled from licence portal', + 'cancel_scheduled_at' => null, + ]); + + return redirect()->route('portal.index')->with('status', 'Subscription canceled in Paddle and the licence is no longer active.'); + } + + public function deactivate(Request $request, License $license, int $activation) + { + $this->authorise($request, $license); + $item = $license->activations()->whereKey($activation)->firstOrFail(); + if (! $item->deactivated_at) { + $item->update(['deactivated_at' => now()]); + } + + return back()->with('status', 'Mac deactivated. Rsync Studio will detect this through the licensing API.'); + } + + public function resend(Request $request, License $license) + { + $this->authorise($request, $license); + $out = LicenseDeliveryOutbox::where('license_id', $license->id)->first(); + if (! $out) { + return back()->withErrors(['licence' => 'This licence was issued manually and its full key is not recoverable. Contact support.']); + } + + $plain = Crypt::decryptString($out->encrypted_license_key); + Mail::raw("Your Rsync Studio licence key is:\n\n{$plain}\n\nKeep this key private.", fn ($m) => $m->to($request->user()->email)->subject('Your Rsync Studio licence key')); + $out->update(['delivered_at' => now()]); + + return back()->with('status', 'Licence key sent to your verified email address.'); + } + + private function authorise(Request $request, License $license): void + { + abort_unless(strtolower((string) $license->customer_email) === strtolower($request->user()->email), 404); + } + + private function professionalPriceFor(License $license): string + { + $paddle = config('rsync-studio.paddle'); + $current = (string) $license->external_price_id; + + if ($current === (string) ($paddle['personal_annual_price_id'] ?? '')) { + return (string) ($paddle['professional_annual_price_id'] ?? ''); + } + + return (string) ($paddle['professional_monthly_price_id'] ?? ''); + } } diff --git a/rsync-studio-licensing/app/Http/Controllers/Support/SupportController.php b/rsync-studio-licensing/app/Http/Controllers/Support/SupportController.php new file mode 100755 index 0000000..13e9bec --- /dev/null +++ b/rsync-studio-licensing/app/Http/Controllers/Support/SupportController.php @@ -0,0 +1,92 @@ + [ + 'technical' => 'Technical support', + 'licensing' => 'Licence & activation', + 'billing' => 'Billing & subscription', + 'feature' => 'Feature request', + 'privacy' => 'Privacy / data request', + 'general' => 'General enquiry', + ], + ]); + } + + public function store(Request $request): RedirectResponse + { + // Honeypot: bots tend to fill hidden fields. Return success without retaining spam. + if (filled($request->input('company_website'))) { + return back()->with('status', 'Your support request has been received.'); + } + + $data = $request->validate([ + 'name' => ['required', 'string', 'max:120'], + 'email' => ['required', 'email:rfc', 'max:254'], + 'category' => ['required', 'in:technical,licensing,billing,feature,privacy,general'], + 'subject' => ['required', 'string', 'max:180'], + 'message' => ['required', 'string', 'min:10', 'max:10000'], + 'privacy_notice' => ['accepted'], + ]); + + $ticket = SupportTicket::create([ + 'user_id' => $request->user()?->id, + 'reference' => $this->reference(), + 'name' => $data['name'], + 'email' => strtolower($data['email']), + 'category' => $data['category'], + 'subject' => $data['subject'], + 'message' => $data['message'], + 'privacy_notice_accepted_at' => now(), + ]); + + $this->notifyTeam($ticket); + + Mail::raw( + "We received your Rsync Studio support request.\n\nReference: {$ticket->reference}\nSubject: {$ticket->subject}\n\nWe will reply to this email address. Please keep the reference in any follow-up.", + fn ($mail) => $mail->to($ticket->email)->subject("Rsync Studio support request {$ticket->reference}") + ); + + return redirect()->route('support')->with('status', "Support request {$ticket->reference} received. A confirmation has been emailed to you."); + } + + private function notifyTeam(SupportTicket $ticket): void + { + if (config('rsync-studio.support.notify_admin_users', true)) { + User::query()->where('is_admin', true)->get()->each->notify(new NewSupportTicket($ticket)); + } + + $emails = collect(config('rsync-studio.support.alert_emails', [])) + ->filter(fn ($email) => filter_var($email, FILTER_VALIDATE_EMAIL)) + ->unique() + ->values(); + + if ($emails->isNotEmpty()) { + Notification::route('mail', $emails->all())->notify(new NewSupportTicket($ticket)); + } + } + + private function reference(): string + { + do { + $reference = 'RS-'.now()->format('ymd').'-'.Str::upper(Str::random(6)); + } while (SupportTicket::where('reference', $reference)->exists()); + + return $reference; + } +} diff --git a/rsync-studio-licensing/app/Http/Middleware/AdminOnly.php b/rsync-studio-licensing/app/Http/Middleware/AdminOnly.php old mode 100644 new mode 100755 index 6de2fcd..e7cd3a6 --- a/rsync-studio-licensing/app/Http/Middleware/AdminOnly.php +++ b/rsync-studio-licensing/app/Http/Middleware/AdminOnly.php @@ -1,11 +1,17 @@ user()?->is_admin === true, 403); + return $next($request); } } diff --git a/rsync-studio-licensing/app/Models/License.php b/rsync-studio-licensing/app/Models/License.php old mode 100644 new mode 100755 index e42d8b0..c3dcc56 --- a/rsync-studio-licensing/app/Models/License.php +++ b/rsync-studio-licensing/app/Models/License.php @@ -1,4 +1,5 @@ 'datetime','revoked_at'=>'datetime','activation_limit'=>'integer','max_major_version'=>'integer']; - public function product(): BelongsTo { return $this->belongsTo(LicenseProduct::class, 'license_product_id'); } - public function activations(): HasMany { return $this->hasMany(LicenseActivation::class); } - public function getIsUsableAttribute(): bool { return $this->revoked_at === null && ($this->expires_at === null || $this->expires_at->isFuture()); } + + protected $fillable = ['license_product_id', 'license_key_hash', 'license_key_last4', 'customer_name', 'customer_email', 'edition', 'activation_limit', 'max_major_version', 'expires_at', 'revoked_at', 'revoke_reason', 'payment_provider', 'external_order_id', 'external_customer_id', 'external_subscription_id', 'external_price_id', 'subscription_status', 'current_period_ends_at', 'cancel_scheduled_at']; + + protected $casts = ['expires_at' => 'datetime', 'revoked_at' => 'datetime', 'activation_limit' => 'integer', 'max_major_version' => 'integer', 'current_period_ends_at' => 'datetime', 'cancel_scheduled_at' => 'datetime']; + + public function product(): BelongsTo + { + return $this->belongsTo(LicenseProduct::class, 'license_product_id'); + } + + public function activations(): HasMany + { + return $this->hasMany(LicenseActivation::class); + } + + public function getIsUsableAttribute(): bool + { + return $this->revoked_at === null && ($this->expires_at === null || $this->expires_at->isFuture()); + } } diff --git a/rsync-studio-licensing/app/Models/LicenseActivation.php b/rsync-studio-licensing/app/Models/LicenseActivation.php old mode 100644 new mode 100755 index 8139a60..8562d4b --- a/rsync-studio-licensing/app/Models/LicenseActivation.php +++ b/rsync-studio-licensing/app/Models/LicenseActivation.php @@ -1,9 +1,14 @@ 'datetime','last_seen_at'=>'datetime','deactivated_at'=>'datetime']; + + protected $fillable = ['license_id', 'installation_id', 'installation_name', 'platform', 'app_version', 'activated_at', 'last_seen_at', 'deactivated_at']; + + protected $casts = ['activated_at' => 'datetime', 'last_seen_at' => 'datetime', 'deactivated_at' => 'datetime']; } diff --git a/rsync-studio-licensing/app/Models/LicenseDeliveryOutbox.php b/rsync-studio-licensing/app/Models/LicenseDeliveryOutbox.php old mode 100644 new mode 100755 index 63ae8ce..e0af182 --- a/rsync-studio-licensing/app/Models/LicenseDeliveryOutbox.php +++ b/rsync-studio-licensing/app/Models/LicenseDeliveryOutbox.php @@ -1,9 +1,14 @@ 'datetime']; + + protected $fillable = ['license_id', 'encrypted_license_key', 'recipient_email', 'delivered_at']; + + protected $casts = ['delivered_at' => 'datetime']; } diff --git a/rsync-studio-licensing/app/Models/LicenseProduct.php b/rsync-studio-licensing/app/Models/LicenseProduct.php old mode 100644 new mode 100755 index 28cf89c..85ac9f5 --- a/rsync-studio-licensing/app/Models/LicenseProduct.php +++ b/rsync-studio-licensing/app/Models/LicenseProduct.php @@ -1,10 +1,12 @@ 'boolean','activation_limit'=>'integer','max_major_version'=>'integer']; + protected $fillable = ['code', 'name', 'edition', 'activation_limit', 'max_major_version', 'payment_provider', 'external_product_id', 'external_price_id', 'active']; + + protected $casts = ['active' => 'boolean', 'activation_limit' => 'integer', 'max_major_version' => 'integer']; } diff --git a/rsync-studio-licensing/app/Models/LicenseWebhookEvent.php b/rsync-studio-licensing/app/Models/LicenseWebhookEvent.php old mode 100644 new mode 100755 index ac1c2a2..38fea30 --- a/rsync-studio-licensing/app/Models/LicenseWebhookEvent.php +++ b/rsync-studio-licensing/app/Models/LicenseWebhookEvent.php @@ -1,8 +1,12 @@ 'array','processed_at'=>'datetime']; + protected $fillable = ['provider', 'external_event_id', 'event_type', 'payload_sha256', 'payload', 'processed_at', 'processing_error']; + + protected $casts = ['payload' => 'array', 'processed_at' => 'datetime']; } diff --git a/rsync-studio-licensing/app/Models/SupportTicket.php b/rsync-studio-licensing/app/Models/SupportTicket.php new file mode 100755 index 0000000..6fa73ef --- /dev/null +++ b/rsync-studio-licensing/app/Models/SupportTicket.php @@ -0,0 +1,46 @@ + 'datetime', + 'resolved_at' => 'datetime', + ]; + } + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + public function assignee(): BelongsTo + { + return $this->belongsTo(User::class, 'assigned_to'); + } + + public function prunable(): Builder + { + $days = max(30, (int) config('rsync-studio.privacy.support_retention_days', 730)); + + return static::query() + ->whereNotNull('resolved_at') + ->where('resolved_at', '<=', now()->subDays($days)); + } +} diff --git a/rsync-studio-licensing/app/Models/User.php b/rsync-studio-licensing/app/Models/User.php old mode 100644 new mode 100755 index 2c45b19..ff6872c --- a/rsync-studio-licensing/app/Models/User.php +++ b/rsync-studio-licensing/app/Models/User.php @@ -1,4 +1,5 @@ 'datetime','password'=>'hashed','is_admin'=>'boolean']; } + + protected $fillable = ['name', 'email', 'password', 'is_admin']; + + protected $hidden = ['password', 'remember_token']; + + protected function casts(): array + { + return ['email_verified_at' => 'datetime', 'password' => 'hashed', 'is_admin' => 'boolean']; + } } diff --git a/rsync-studio-licensing/app/Notifications/NewSupportTicket.php b/rsync-studio-licensing/app/Notifications/NewSupportTicket.php new file mode 100755 index 0000000..a1528ae --- /dev/null +++ b/rsync-studio-licensing/app/Notifications/NewSupportTicket.php @@ -0,0 +1,43 @@ +subject("New Rsync Studio support request {$this->ticket->reference}") + ->greeting('New support request') + ->line("{$this->ticket->name} <{$this->ticket->email}>") + ->line("Category: {$this->ticket->category}") + ->line("Subject: {$this->ticket->subject}") + ->line($this->ticket->message) + ->action('Open support ticket', route('admin.support.show', $this->ticket)); + } + + public function toArray(object $notifiable): array + { + return [ + 'support_ticket_id' => $this->ticket->id, + 'reference' => $this->ticket->reference, + 'subject' => $this->ticket->subject, + 'email' => $this->ticket->email, + ]; + } +} diff --git a/rsync-studio-licensing/app/Providers/RsyncStudioLicensingServiceProvider.php b/rsync-studio-licensing/app/Providers/RsyncStudioLicensingServiceProvider.php old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/app/Services/Licensing/LicenseDeliveryService.php b/rsync-studio-licensing/app/Services/Licensing/LicenseDeliveryService.php new file mode 100755 index 0000000..94e804c --- /dev/null +++ b/rsync-studio-licensing/app/Services/Licensing/LicenseDeliveryService.php @@ -0,0 +1,40 @@ +whereNull('delivered_at') + ->whereNotNull('recipient_email') + ->where('recipient_email', '!=', '') + ->oldest() + ->limit(max(1, min($limit, 100))) + ->get(); + + foreach ($pending as $outbox) { + $plain = Crypt::decryptString($outbox->encrypted_license_key); + $recipient = strtolower(trim((string) $outbox->recipient_email)); + if ($recipient === '') { + continue; + } + + Mail::raw( + "Thank you for choosing Rsync Studio.\n\nYour licence key is:\n\n{$plain}\n\nOpen Rsync Studio → Settings → Licence and enter this key to activate your Mac.\n\nKeep this key private. You can manage activations from the Rsync Studio licence portal.", + fn ($message) => $message->to($recipient)->subject('Your Rsync Studio licence key') + ); + + $outbox->update(['delivered_at' => now()]); + $delivered++; + } + + return $delivered; + } +} diff --git a/rsync-studio-licensing/app/Services/Licensing/LicenseIssuer.php b/rsync-studio-licensing/app/Services/Licensing/LicenseIssuer.php old mode 100644 new mode 100755 index 6702788..ec51713 --- a/rsync-studio-licensing/app/Services/Licensing/LicenseIssuer.php +++ b/rsync-studio-licensing/app/Services/Licensing/LicenseIssuer.php @@ -1,41 +1,45 @@ where('external_order_id',$orderID)->first(); - if ($existing) return [$existing, null]; + $existing = License::where('payment_provider', $provider)->where('external_order_id', $orderID)->first(); + if ($existing) { + return [$existing, null]; + } } $plain = LicenseKey::generate(); $license = License::create([ - 'license_product_id'=>$product->id, - 'license_key_hash'=>LicenseKey::hash($plain), - 'license_key_last4'=>substr(LicenseKey::normalize($plain), -4), - 'customer_name'=>$name, - 'customer_email'=>$email ? strtolower(trim($email)) : null, - 'edition'=>$product->edition, - 'activation_limit'=>$product->activation_limit, - 'max_major_version'=>$product->max_major_version, - 'payment_provider'=>$provider, - 'external_order_id'=>$orderID, - 'external_customer_id'=>$customerID, + 'license_product_id' => $product->id, + 'license_key_hash' => LicenseKey::hash($plain), + 'license_key_last4' => substr(LicenseKey::normalize($plain), -4), + 'customer_name' => $name, + 'customer_email' => $email ? strtolower(trim($email)) : null, + 'edition' => $product->edition, + 'activation_limit' => $product->activation_limit, + 'max_major_version' => $product->max_major_version, + 'payment_provider' => $provider, + 'external_order_id' => $orderID, + 'external_customer_id' => $customerID, ]); if ($queueDelivery) { LicenseDeliveryOutbox::updateOrCreate( - ['license_id'=>$license->id], - ['encrypted_license_key'=>Crypt::encryptString($plain),'recipient_email'=>$license->customer_email,'delivered_at'=>null] + ['license_id' => $license->id], + ['encrypted_license_key' => Crypt::encryptString($plain), 'recipient_email' => $license->customer_email, 'delivered_at' => null] ); } + return [$license, $plain]; }); } diff --git a/rsync-studio-licensing/app/Services/Licensing/LicenseKey.php b/rsync-studio-licensing/app/Services/Licensing/LicenseKey.php old mode 100644 new mode 100755 index c1104ae..3e42361 --- a/rsync-studio-licensing/app/Services/Licensing/LicenseKey.php +++ b/rsync-studio-licensing/app/Services/Licensing/LicenseKey.php @@ -1,4 +1,5 @@ privateSeed()); + return base64_encode(sodium_crypto_sign_publickey($pair)); } private function privateSeed(): string { $path = config('rsync-studio.private_key_path'); - if (!$path || !is_file($path)) throw new RuntimeException('RSYNC_STUDIO_LICENSE_PRIVATE_KEY_PATH is not configured or does not exist.'); + if (! $path || ! is_file($path)) { + throw new RuntimeException('RSYNC_STUDIO_LICENSE_PRIVATE_KEY_PATH is not configured or does not exist.'); + } $decoded = base64_decode(trim((string) file_get_contents($path)), true); - if ($decoded === false || strlen($decoded) !== SODIUM_CRYPTO_SIGN_SEEDBYTES) throw new RuntimeException('The Rsync Studio private key must be a Base64-encoded 32-byte Ed25519 seed.'); + if ($decoded === false || strlen($decoded) !== SODIUM_CRYPTO_SIGN_SEEDBYTES) { + throw new RuntimeException('The Rsync Studio private key must be a Base64-encoded 32-byte Ed25519 seed.'); + } + return $decoded; } diff --git a/rsync-studio-licensing/app/Services/Licensing/LicenseTokenVerifier.php b/rsync-studio-licensing/app/Services/Licensing/LicenseTokenVerifier.php old mode 100644 new mode 100755 index b461cbf..90b7b3b --- a/rsync-studio-licensing/app/Services/Licensing/LicenseTokenVerifier.php +++ b/rsync-studio-licensing/app/Services/Licensing/LicenseTokenVerifier.php @@ -1,4 +1,5 @@ decode($parts[1]); $signature = $this->decode($parts[2]); $public = base64_decode((string) config('rsync-studio.public_key'), true); - if ($public === false || strlen($public) !== SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES) throw new RuntimeException('Server licence public key is invalid.'); - if (!sodium_crypto_sign_verify_detached($signature, $payload, $public)) throw new RuntimeException('Licence token signature is invalid.'); + if ($public === false || strlen($public) !== SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES) { + throw new RuntimeException('Server licence public key is invalid.'); + } + if (! sodium_crypto_sign_verify_detached($signature, $payload, $public)) { + throw new RuntimeException('Licence token signature is invalid.'); + } $decoded = json_decode($payload, true, flags: JSON_THROW_ON_ERROR); + return is_array($decoded) ? $decoded : throw new RuntimeException('Licence token payload is invalid.'); } + private function decode(string $value): string { $value = strtr($value, '-_', '+/'); $value .= str_repeat('=', (4 - strlen($value) % 4) % 4); $out = base64_decode($value, true); - if ($out === false) throw new RuntimeException('Invalid Base64URL value.'); + if ($out === false) { + throw new RuntimeException('Invalid Base64URL value.'); + } + return $out; } } diff --git a/rsync-studio-licensing/app/Services/Payments/LemonSqueezyWebhookVerifier.php b/rsync-studio-licensing/app/Services/Payments/LemonSqueezyWebhookVerifier.php old mode 100644 new mode 100755 index d94d56a..3d7a49b --- a/rsync-studio-licensing/app/Services/Payments/LemonSqueezyWebhookVerifier.php +++ b/rsync-studio-licensing/app/Services/Payments/LemonSqueezyWebhookVerifier.php @@ -1,4 +1,5 @@ header('X-Signature'); - if ($secret === '' || $signature === '') throw new RuntimeException('Lemon Squeezy webhook verification is not configured.'); - $expected = hash_hmac('sha256',$rawBody,$secret); - if (!hash_equals($expected,$signature)) throw new RuntimeException('Lemon Squeezy webhook signature is invalid.'); + if ($secret === '' || $signature === '') { + throw new RuntimeException('Lemon Squeezy webhook verification is not configured.'); + } + $expected = hash_hmac('sha256', $rawBody, $secret); + if (! hash_equals($expected, $signature)) { + throw new RuntimeException('Lemon Squeezy webhook signature is invalid.'); + } } } diff --git a/rsync-studio-licensing/app/Services/Payments/PaddleClient.php b/rsync-studio-licensing/app/Services/Payments/PaddleClient.php new file mode 100755 index 0000000..6dd5d35 --- /dev/null +++ b/rsync-studio-licensing/app/Services/Payments/PaddleClient.php @@ -0,0 +1,82 @@ +request()->get('/customers/'.$customerID); + + if (! $response->successful()) { + return null; + } + $data = $response->json('data'); + + return is_array($data) ? $data : null; + } + + public function updateSubscriptionPrice(string $subscriptionID, string $priceID): array + { + $this->requireWritableConfiguration(); + + $response = $this->request()->patch('/subscriptions/'.$subscriptionID, [ + 'proration_billing_mode' => 'prorated_immediately', + 'items' => [[ + 'price_id' => $priceID, + 'quantity' => 1, + ]], + ]); + + return $this->subscriptionData($response, 'Paddle could not update the subscription.'); + } + + public function cancelSubscriptionImmediately(string $subscriptionID): array + { + $this->requireWritableConfiguration(); + + $response = $this->request()->post('/subscriptions/'.$subscriptionID.'/cancel', [ + 'effective_from' => 'immediately', + ]); + + return $this->subscriptionData($response, 'Paddle could not cancel the subscription.'); + } + + private function request() + { + return Http::baseUrl((string) config('rsync-studio.paddle.api_url')) + ->withToken((string) config('rsync-studio.paddle.api_key')) + ->acceptJson() + ->timeout(15); + } + + private function requireWritableConfiguration(): void + { + if (trim((string) config('rsync-studio.paddle.api_key')) === '') { + throw new RuntimeException('Paddle subscription management is not configured.'); + } + } + + private function subscriptionData(Response $response, string $fallback): array + { + if (! $response->successful()) { + $detail = trim((string) ($response->json('error.detail') ?? '')); + throw new RuntimeException($detail !== '' ? $detail : $fallback); + } + + $data = $response->json('data'); + if (! is_array($data)) { + throw new RuntimeException($fallback); + } + + return $data; + } +} diff --git a/rsync-studio-licensing/app/Services/Payments/PaddleWebhookVerifier.php b/rsync-studio-licensing/app/Services/Payments/PaddleWebhookVerifier.php old mode 100644 new mode 100755 index bce9424..813827d --- a/rsync-studio-licensing/app/Services/Payments/PaddleWebhookVerifier.php +++ b/rsync-studio-licensing/app/Services/Payments/PaddleWebhookVerifier.php @@ -1,4 +1,5 @@ header('Paddle-Signature'); - if ($secret === '' || $header === '') throw new RuntimeException('Paddle webhook verification is not configured.'); + if ($secret === '' || $header === '') { + throw new RuntimeException('Paddle webhook verification is not configured.'); + } $parts = []; - foreach (explode(';', $header) as $part) { [$k,$v] = array_pad(explode('=',trim($part),2),2,null); if ($k && $v) $parts[$k][]=$v; } - $ts = isset($parts['ts'][0]) ? (int)$parts['ts'][0] : 0; + foreach (explode(';', $header) as $part) { + [$k,$v] = array_pad(explode('=', trim($part), 2), 2, null); + if ($k && $v) { + $parts[$k][] = $v; + } + } + $ts = isset($parts['ts'][0]) ? (int) $parts['ts'][0] : 0; $signatures = $parts['h1'] ?? []; - $tolerance = max(1,(int)config('rsync-studio.paddle.timestamp_tolerance',300)); - if (!$ts || abs(time()-$ts)>$tolerance) throw new RuntimeException('Paddle webhook timestamp is outside the allowed tolerance.'); + $tolerance = max(1, (int) config('rsync-studio.paddle.timestamp_tolerance', 300)); + if (! $ts || abs(time() - $ts) > $tolerance) { + throw new RuntimeException('Paddle webhook timestamp is outside the allowed tolerance.'); + } $expected = hash_hmac('sha256', $ts.':'.$rawBody, $secret); - foreach ($signatures as $signature) if (hash_equals($expected,$signature)) return; + foreach ($signatures as $signature) { + if (hash_equals($expected, $signature)) { + return; + } + } throw new RuntimeException('Paddle webhook signature is invalid.'); } } diff --git a/rsync-studio-licensing/app/Services/Payments/PurchaseProvisioner.php b/rsync-studio-licensing/app/Services/Payments/PurchaseProvisioner.php old mode 100644 new mode 100755 index 7cb0c4c..2cc9680 --- a/rsync-studio-licensing/app/Services/Payments/PurchaseProvisioner.php +++ b/rsync-studio-licensing/app/Services/Payments/PurchaseProvisioner.php @@ -1,47 +1,246 @@ $this->fromPaddle($event), - 'lemon-squeezy' => $this->fromLemonSqueezy($event), - default => throw new RuntimeException('Unsupported payment provider.'), - }; - if ($normalized['action'] === 'ignore') return; - if ($normalized['action'] === 'revoke') { - License::where('payment_provider',$provider)->where('external_order_id',$normalized['orderID'])->whereNull('revoked_at')->update(['revoked_at'=>now(),'revoke_reason'=>'Payment refunded or reversed']); + if ($provider === 'paddle') { + $this->provisionPaddle($event); + return; } - $product = LicenseProduct::where('payment_provider',$provider)->where(function($q) use($normalized){ $q->where('external_price_id',$normalized['priceID'])->orWhere('external_product_id',$normalized['productID']); })->where('active',true)->first(); - if (!$product) throw new RuntimeException('No active licence product maps to this payment item.'); - $this->issuer->issue($product,$normalized['name'],$normalized['email'],$provider,$normalized['orderID'],$normalized['customerID'], true); + + if ($provider === 'lemon-squeezy') { + $this->provisionLemonSqueezy($event); + + return; + } + + throw new RuntimeException('Unsupported payment provider.'); } - private function fromPaddle(array $e): array + private function provisionPaddle(array $event): void { - $type=(string)($e['event_type']??''); $d=$e['data']??[]; - if (in_array($type,['transaction.refunded','transaction.canceled'],true)) return ['action'=>'revoke','orderID'=>(string)($d['id']??''),'priceID'=>'','productID'=>'','name'=>null,'email'=>null,'customerID'=>null]; - if ($type!=='transaction.completed') return ['action'=>'ignore']; - $item=$d['items'][0]??[]; $price=$item['price']??[]; $product=$price['product_id']??($item['product_id']??null); - return ['action'=>'issue','orderID'=>(string)($d['id']??''),'priceID'=>(string)($price['id']??($item['price_id']??'')),'productID'=>(string)($product??''),'name'=>$d['custom_data']['customer_name']??null,'email'=>$d['custom_data']['customer_email']??null,'customerID'=>isset($d['customer_id'])?(string)$d['customer_id']:null]; + $type = (string) ($event['event_type'] ?? ''); + $data = $event['data'] ?? []; + + if (str_starts_with($type, 'subscription.')) { + $this->syncPaddleSubscription($type, $data); + + return; + } + + if ($type === 'transaction.completed') { + $this->syncPaddleTransaction($data); + + return; + } + + if ($type === 'transaction.refunded') { + $transactionID = (string) ($data['id'] ?? ''); + if ($transactionID !== '') { + License::where('payment_provider', 'paddle') + ->where('external_order_id', $transactionID) + ->whereNull('external_subscription_id') + ->whereNull('revoked_at') + ->update(['revoked_at' => now(), 'revoke_reason' => 'Payment refunded']); + } + } } - private function fromLemonSqueezy(array $e): array + private function syncPaddleSubscription(string $type, array $data): void { - $type=(string)($e['meta']['event_name']??''); $a=$e['data']['attributes']??[]; - $order=(string)($e['data']['id']??($a['order_id']??'')); - if (in_array($type,['order_refunded','subscription_expired'],true)) return ['action'=>'revoke','orderID'=>$order,'priceID'=>'','productID'=>'','name'=>null,'email'=>null,'customerID'=>null]; - if (!in_array($type,['order_created','subscription_created'],true)) return ['action'=>'ignore']; - return ['action'=>'issue','orderID'=>$order,'priceID'=>(string)($a['variant_id']??''),'productID'=>(string)($a['product_id']??''),'name'=>$a['user_name']??null,'email'=>$a['user_email']??null,'customerID'=>isset($a['customer_id'])?(string)$a['customer_id']:null]; + $subscriptionID = (string) ($data['id'] ?? ''); + if ($subscriptionID === '') { + throw new RuntimeException('Paddle subscription webhook has no subscription ID.'); + } + + $status = (string) ($data['status'] ?? ''); + $item = $this->firstRecurringItem($data['items'] ?? []); + $price = $item['price'] ?? []; + $priceID = (string) ($price['id'] ?? $item['price_id'] ?? ''); + $productID = (string) ($price['product_id'] ?? $item['product_id'] ?? ''); + + $license = License::where('payment_provider', 'paddle') + ->where('external_subscription_id', $subscriptionID) + ->first(); + + if (! $license) { + $product = $this->mappedProduct('paddle', $priceID, $productID); + $custom = is_array($data['custom_data'] ?? null) ? $data['custom_data'] : []; + $customer = $this->paddle->customer($this->nullableString($data['customer_id'] ?? null)); + [$license] = $this->issuer->issue( + $product, + $this->nullableString($custom['customer_name'] ?? $custom['name'] ?? $customer['name'] ?? null), + $this->nullableString($custom['customer_email'] ?? $custom['email'] ?? $customer['email'] ?? null), + 'paddle', + $this->nullableString($data['transaction_id'] ?? null), + $this->nullableString($data['customer_id'] ?? null), + true, + ); + $license->external_subscription_id = $subscriptionID; + } elseif ($priceID !== '' && $priceID !== $license->external_price_id) { + // Upgrades/downgrades change the entitlement attached to the existing key. + $product = $this->mappedProduct('paddle', $priceID, $productID); + $license->license_product_id = $product->id; + $license->edition = $product->edition; + $license->activation_limit = $product->activation_limit; + $license->max_major_version = $product->max_major_version; + } + + $periodEnd = $data['current_billing_period']['ends_at'] ?? null; + $scheduled = $data['scheduled_change'] ?? null; + $cancelAt = is_array($scheduled) && ($scheduled['action'] ?? null) === 'cancel' + ? ($scheduled['effective_at'] ?? null) + : null; + + $license->external_customer_id = $this->nullableString($data['customer_id'] ?? null) ?? $license->external_customer_id; + $license->external_price_id = $priceID !== '' ? $priceID : $license->external_price_id; + $license->subscription_status = $status !== '' ? $status : $license->subscription_status; + $license->current_period_ends_at = $periodEnd ? Carbon::parse($periodEnd) : $license->current_period_ends_at; + $license->cancel_scheduled_at = $cancelAt ? Carbon::parse($cancelAt) : null; + + if (in_array($status, ['active', 'trialing'], true)) { + $license->revoked_at = null; + $license->revoke_reason = null; + // Trialing/active subscriptions remain valid through the current period. + $license->expires_at = $periodEnd ? Carbon::parse($periodEnd) : null; + } elseif ($status === 'past_due') { + // Do not instantly kill a licence on the first failed renewal. Preserve the + // period Paddle says is current; a later canceled event ends entitlement. + $license->expires_at = $periodEnd ? Carbon::parse($periodEnd) : ($license->expires_at ?? now()->addDays(7)); + } elseif (in_array($status, ['canceled', 'paused'], true)) { + $license->expires_at = now(); + $license->revoked_at = now(); + $license->revoke_reason = $status === 'paused' ? 'Subscription paused' : 'Subscription canceled'; + } + + $license->save(); + } + + private function syncPaddleTransaction(array $data): void + { + $subscriptionID = $this->nullableString($data['subscription_id'] ?? null); + $transactionID = (string) ($data['id'] ?? ''); + + // Recurring purchases are provisioned from subscription events because those + // events contain the authoritative trial/status/current-period state. + if ($subscriptionID) { + License::where('payment_provider', 'paddle') + ->where('external_subscription_id', $subscriptionID) + ->whereNull('external_order_id') + ->update(['external_order_id' => $transactionID ?: null]); + + return; + } + + // Keep support for any future one-time Paddle licence product. + $item = $data['items'][0] ?? []; + $price = $item['price'] ?? []; + $priceID = (string) ($price['id'] ?? $item['price_id'] ?? ''); + $productID = (string) ($price['product_id'] ?? $item['product_id'] ?? ''); + $product = $this->mappedProduct('paddle', $priceID, $productID); + $custom = is_array($data['custom_data'] ?? null) ? $data['custom_data'] : []; + $customer = $this->paddle->customer($this->nullableString($data['customer_id'] ?? null)); + + $this->issuer->issue( + $product, + $this->nullableString($custom['customer_name'] ?? $custom['name'] ?? $customer['name'] ?? null), + $this->nullableString($custom['customer_email'] ?? $custom['email'] ?? $customer['email'] ?? null), + 'paddle', + $transactionID, + $this->nullableString($data['customer_id'] ?? null), + true, + ); + } + + private function provisionLemonSqueezy(array $event): void + { + $type = (string) ($event['meta']['event_name'] ?? ''); + $attributes = $event['data']['attributes'] ?? []; + $order = (string) ($event['data']['id'] ?? $attributes['order_id'] ?? ''); + + if (in_array($type, ['order_refunded', 'subscription_expired'], true)) { + License::where('payment_provider', 'lemon-squeezy') + ->where('external_order_id', $order) + ->whereNull('revoked_at') + ->update(['revoked_at' => now(), 'revoke_reason' => 'Payment refunded or subscription expired']); + + return; + } + + if (! in_array($type, ['order_created', 'subscription_created'], true)) { + return; + } + + $product = $this->mappedProduct( + 'lemon-squeezy', + (string) ($attributes['variant_id'] ?? ''), + (string) ($attributes['product_id'] ?? ''), + ); + + $this->issuer->issue( + $product, + $this->nullableString($attributes['user_name'] ?? null), + $this->nullableString($attributes['user_email'] ?? null), + 'lemon-squeezy', + $order, + $this->nullableString($attributes['customer_id'] ?? null), + true, + ); + } + + private function mappedProduct(string $provider, string $priceID, string $productID): LicenseProduct + { + // Price IDs are the authoritative mapping because monthly and annual prices + // intentionally share the same Paddle product ID. + if ($priceID !== '') { + $product = LicenseProduct::where('payment_provider', $provider) + ->where('external_price_id', $priceID) + ->where('active', true) + ->first(); + } else { + $product = LicenseProduct::where('payment_provider', $provider) + ->where('external_product_id', $productID) + ->where('active', true) + ->first(); + } + + if (! $product) { + throw new RuntimeException("No active licence product maps to {$provider} price {$priceID} / product {$productID}."); + } + + return $product; + } + + private function firstRecurringItem(array $items): array + { + foreach ($items as $item) { + if (($item['recurring'] ?? true) === true) { + return $item; + } + } + + return $items[0] ?? []; + } + + private function nullableString(mixed $value): ?string + { + if (! is_scalar($value)) { + return null; + } + $value = trim((string) $value); + + return $value === '' ? null : $value; } } diff --git a/rsync-studio-licensing/app/Services/Payments/WebhookVerifier.php b/rsync-studio-licensing/app/Services/Payments/WebhookVerifier.php old mode 100644 new mode 100755 index 5f31a79..984c28e --- a/rsync-studio-licensing/app/Services/Payments/WebhookVerifier.php +++ b/rsync-studio-licensing/app/Services/Payments/WebhookVerifier.php @@ -1,4 +1,10 @@ =0.6.2)" + }, + "type": "library", + "autoload": { + "psr-4": { + "Predis\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Till Krüss", + "homepage": "https://till.im", + "role": "Maintainer" + } + ], + "description": "A flexible and feature-complete Redis/Valkey client for PHP.", + "homepage": "http://github.com/predis/predis", + "keywords": [ + "nosql", + "predis", + "redis" + ], + "support": { + "issues": "https://github.com/predis/predis/issues", + "source": "https://github.com/predis/predis/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/tillkruss", + "type": "github" + } + ], + "time": "2026-08-14T23:07:56+00:00" + }, { "name": "psr/clock", "version": "1.0.0", diff --git a/rsync-studio-licensing/composer.stage4.json b/rsync-studio-licensing/composer.stage4.json deleted file mode 100644 index 9442786..0000000 --- a/rsync-studio-licensing/composer.stage4.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "require": { - "php": "^8.3", - "ext-sodium": "*", - "laravel/framework": "^13.0" - } -} diff --git a/rsync-studio-licensing/config/rsync-studio.php b/rsync-studio-licensing/config/rsync-studio.php old mode 100644 new mode 100755 index d500f47..54c5b73 --- a/rsync-studio-licensing/config/rsync-studio.php +++ b/rsync-studio-licensing/config/rsync-studio.php @@ -10,9 +10,35 @@ return [ 'purchase_url' => env('RSYNC_STUDIO_PURCHASE_URL'), 'portal_url' => env('RSYNC_STUDIO_PORTAL_URL'), 'support_url' => env('RSYNC_STUDIO_SUPPORT_URL'), + + 'legal' => [ + 'controller_name' => env('RSYNC_STUDIO_LEGAL_NAME', 'Rsync Studio'), + 'privacy_email' => env('RSYNC_STUDIO_PRIVACY_EMAIL', env('MAIL_FROM_ADDRESS')), + 'support_email' => env('RSYNC_STUDIO_SUPPORT_EMAIL', env('MAIL_FROM_ADDRESS')), + 'country' => env('RSYNC_STUDIO_LEGAL_COUNTRY', 'United Kingdom'), + ], + 'privacy' => [ + 'policy_version' => env('RSYNC_STUDIO_PRIVACY_VERSION', '2026-09-09'), + 'cookie_version' => env('RSYNC_STUDIO_COOKIE_VERSION', '1'), + 'support_retention_days' => (int) env('RSYNC_STUDIO_SUPPORT_RETENTION_DAYS', 730), + ], + 'support' => [ + 'alert_emails' => array_values(array_filter(array_map('trim', explode(',', (string) env('RSYNC_STUDIO_SUPPORT_ALERT_EMAILS', ''))))), + 'notify_admin_users' => filter_var(env('RSYNC_STUDIO_SUPPORT_NOTIFY_ADMINS', true), FILTER_VALIDATE_BOOL), + ], 'paddle' => [ + 'api_key' => env('PADDLE_API_KEY'), + 'client_side_token' => env('PADDLE_CLIENT_SIDE_TOKEN'), + 'environment' => env('PADDLE_ENVIRONMENT', env('APP_ENV') === 'production' ? 'production' : 'sandbox'), + 'api_url' => env('PADDLE_API_URL', env('APP_ENV') === 'production' ? 'https://api.paddle.com' : 'https://sandbox-api.paddle.com'), 'webhook_secret' => env('PADDLE_WEBHOOK_SECRET'), 'timestamp_tolerance' => (int) env('PADDLE_WEBHOOK_TOLERANCE', 300), + 'personal_product_id' => env('PADDLE_PERSONAL_PRODUCT_ID'), + 'personal_monthly_price_id' => env('PADDLE_PERSONAL_MONTHLY_PRICE_ID'), + 'personal_annual_price_id' => env('PADDLE_PERSONAL_ANNUAL_PRICE_ID'), + 'professional_product_id' => env('PADDLE_PROFESSIONAL_PRODUCT_ID'), + 'professional_monthly_price_id' => env('PADDLE_PROFESSIONAL_MONTHLY_PRICE_ID'), + 'professional_annual_price_id' => env('PADDLE_PROFESSIONAL_ANNUAL_PRICE_ID'), ], 'lemon_squeezy' => [ 'webhook_secret' => env('LEMON_SQUEEZY_WEBHOOK_SECRET'), diff --git a/rsync-studio-licensing/database/database.sqlite b/rsync-studio-licensing/database/database.sqlite old mode 100644 new mode 100755 index 63f9d499c18a283cd23ca0a07279c380e0327e93..379c23df544e74dcd7fe058bb3c1440bb3fded99 GIT binary patch delta 3597 zcmds3U2Gdw7M|;w*s&e^CP3?5nvlr=vE8J|iEF1;R3JZY;!-inu@n9STH2v}+1fyZ45@diW{0tBhLckIO2Aq^lF zt+e*|%5&~L=Y02^d%kne{j2fZ^Uli$TAn2c;t>9AfBaXvgZrK(?pc1k0gEi~8*`!? z{s6xzHV43gSD##fG?wgd#lvmTg-4tFA^|^!Mfear=)U28*L|_n(VTS`?zc4%YXI~H zdc$lWVm>|L0RFJNiZ~syS}vPaRGrmDehKLs%gF*OE4nx@@|-RzvPOlh6p^VjVCn~0 zP7v5E9wgJqoW`qS)>L5UMI;Ft>2IKj2~cWi|GpX8OoXJvN4Ty!zjpXAvfCYpFT_au z8KV9Ct&g@*V}r*AqmnqVJiR&@Oons0&`{6noVKD39?#Dn4k_{2@xbaIj(5ssad2J_t1 z(05Ec0?AG?$6zgiJsj3&z8Vlp^w( zNRKcwQF$L$L~bOa&z_3)%}?X`v?5OT&T2E$2_=@+7st}EFv5EAyn>yqELCI!Sk{vt zOUJRVkR+_e`Y`gdW3nEZ@1G7FO}}&_d?9A31|*~_Q!~9$VZJ9lEQHm8SSA+>45vpU zeJG9QMk0MjPRjAKixLjVlb{@cP<$%!Kzu1XIwi%=B580$2t<3wrOD9Lv~&VV<5P1z zv&q@Ou@kAuv!mGM-5d}+@3qQB>Vy?>jz{}(d;($%BG76%FQ1bh+Z;U}dQT7nOD zlV`v$JszaF_?L#x(nX%J8y_6?J(Z-e*J}j)7G8s!rIzGpu$3YSK$?SvB<*&Gd3@pL z1pE$u1wY3tK83e5k`yqrMwb6z_?FUliv4Pr`vw6mn*^M}r~YgAN3KgQhqKesZ-3c( z*~&IN(?C%dESr`A;t4{za%HHf1i&5Z*Jl7}bzD5)uzA|rz@P1O8cDDuoq4DTIDoV!^!_jG)`B`;_R%CNop^nxV+Q-y*V*G35-8N4Yqq=i9 zr)(vpy8`m<4QN}lU~YCB%uldvrOdxZ+-36&VHoYZ!ax~Lly*ho-5UkUELJsd3ZiTs zhhpEIHcuR5xNlbsDw;?5F!6}Z$>PH~v?BwZMQ|GIE9{W6JGE{KqPmdrKNe(co~|zN zr#79NlXg1V;odzjR&p$ zxEub_T38$M+dPUFtUXfBLR|~qYRG0#Sba5%YTrenaz5%54%MHIy182AAB`2nvh{6i zm2}nVnI%*aRBt>l1GDy?71@zMj+G<$acZ_Or{m6_mI%`_X;v0u5>U)x? ztf(1I+FHHL@vCJ{!X2i8<9U=d;+9rxr67#IQYQ*I4XLbIwRDxVHJUM{8slTi6S(IK zNJ2WIHB_POZhBr(5oUgR39b5=+Ai>`?D*I0r#oz(LK`^mFG3dh+UxFKm@q4CQ4)D1 nYe>7x?1!z!U#zW7wF`}RtdW*lL3u;#ktBE*07nUI+<^Z9Lz2LJ delta 812 zcmb7COKTHR7`-={w4KD{Hu%_B+lW|-^)Zu4qN%i^#=Oj(NzyUt3>Hl$g-J4#379s` zfLM#~l`)IBQ*hx$Xu6s**#D6YNmUB2%e4(EgOE!=f1yzjfY z-F+1Ru*h|wx%bBA>H~oHV|M{R^uY`Q7&55XUbJEr&PHd zU2R}*O<^-^fDg;DLRhJ06;Z=f*`L!fT`0CD4pSFmKCT$o3ej|3(zUq+6W3?5{!*eM z*34d!ycsGnbxf8RmdP{ma>9!#F;r$){e&0mn8I1C3p{QJ*%Nh^Pf;u%F0p#N%<+XH zRz+FhWm)6}Mo{B27m{c(q?FhY_KTsTem0V#@dY)ku%+?=F-yz2Y(1FIh8wwtzapub zifQPN^QpR!jq740<4vf3rEolU&|H)@mu}>l3?)wfp6A(+R+J)PU1ADzlA4+|^}0Bf zDsl|1b0r}VQ-W&VYO zA!){WWv2CVe7DgZ4_SI3dI!)u!<~GAh*9e_*?KiTaw|!6h%Q`1cKgOfpjCiY4fo1t zWUOjrca%I2?7bF%1k~&N=2~`MbJ`ul_QT|ZUJH4?=aB8bZPstring('external_subscription_id')->nullable()->after('external_customer_id'); + $table->string('external_price_id')->nullable()->after('external_subscription_id'); + $table->string('subscription_status')->nullable()->after('external_price_id'); + $table->timestamp('current_period_ends_at')->nullable()->after('subscription_status'); + $table->timestamp('cancel_scheduled_at')->nullable()->after('current_period_ends_at'); + $table->unique(['payment_provider', 'external_subscription_id']); + }); + } + + public function down(): void + { + Schema::table('licenses', function (Blueprint $table) { + $table->dropUnique(['payment_provider', 'external_subscription_id']); + $table->dropColumn([ + 'external_subscription_id', + 'external_price_id', + 'subscription_status', + 'current_period_ends_at', + 'cancel_scheduled_at', + ]); + }); + } +}; diff --git a/rsync-studio-licensing/database/migrations/2026_09_09_160000_create_support_tickets_and_notifications.php b/rsync-studio-licensing/database/migrations/2026_09_09_160000_create_support_tickets_and_notifications.php new file mode 100755 index 0000000..a6223e3 --- /dev/null +++ b/rsync-studio-licensing/database/migrations/2026_09_09_160000_create_support_tickets_and_notifications.php @@ -0,0 +1,47 @@ +id(); + $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete(); + $table->foreignId('assigned_to')->nullable()->constrained('users')->nullOnDelete(); + $table->string('reference', 24)->unique(); + $table->string('name', 120); + $table->string('email', 254)->index(); + $table->string('category', 40)->default('general'); + $table->string('subject', 180); + $table->text('message'); + $table->string('status', 20)->default('new')->index(); + $table->string('priority', 20)->default('normal'); + $table->timestamp('privacy_notice_accepted_at'); + $table->timestamp('resolved_at')->nullable()->index(); + $table->timestamps(); + }); + } + + if (! Schema::hasTable('notifications')) { + Schema::create('notifications', function (Blueprint $table): void { + $table->uuid('id')->primary(); + $table->string('type'); + $table->morphs('notifiable'); + $table->text('data'); + $table->timestamp('read_at')->nullable(); + $table->timestamps(); + }); + } + } + + public function down(): void + { + Schema::dropIfExists('support_tickets'); + Schema::dropIfExists('notifications'); + } +}; diff --git a/rsync-studio-licensing/database/seeders/PaddleCatalogSeeder.php b/rsync-studio-licensing/database/seeders/PaddleCatalogSeeder.php new file mode 100755 index 0000000..23b0091 --- /dev/null +++ b/rsync-studio-licensing/database/seeders/PaddleCatalogSeeder.php @@ -0,0 +1,29 @@ + 'personal-monthly', 'name' => 'Rsync Studio Personal Monthly', 'edition' => 'Personal', 'activation_limit' => 1, 'external_product_id' => config('rsync-studio.paddle.personal_product_id'), 'external_price_id' => config('rsync-studio.paddle.personal_monthly_price_id')], + ['code' => 'personal-annual', 'name' => 'Rsync Studio Personal Annual', 'edition' => 'Personal', 'activation_limit' => 1, 'external_product_id' => config('rsync-studio.paddle.personal_product_id'), 'external_price_id' => config('rsync-studio.paddle.personal_annual_price_id')], + ['code' => 'professional-monthly', 'name' => 'Rsync Studio Professional Monthly', 'edition' => 'Professional', 'activation_limit' => 3, 'external_product_id' => config('rsync-studio.paddle.professional_product_id'), 'external_price_id' => config('rsync-studio.paddle.professional_monthly_price_id')], + ['code' => 'professional-annual', 'name' => 'Rsync Studio Professional Annual', 'edition' => 'Professional', 'activation_limit' => 3, 'external_product_id' => config('rsync-studio.paddle.professional_product_id'), 'external_price_id' => config('rsync-studio.paddle.professional_annual_price_id')], + ]; + + foreach ($products as $data) { + if (! $data['external_product_id'] || ! $data['external_price_id']) { + continue; + } + LicenseProduct::updateOrCreate( + ['code' => $data['code']], + $data + ['payment_provider' => 'paddle', 'max_major_version' => config('rsync-studio.default_max_major_version'), 'active' => true] + ); + } + } +} diff --git a/rsync-studio-licensing/deploy.php b/rsync-studio-licensing/deploy.php old mode 100644 new mode 100755 index ea60122..ebbfe7f --- a/rsync-studio-licensing/deploy.php +++ b/rsync-studio-licensing/deploy.php @@ -9,7 +9,7 @@ set('writable_use_sudo', true); set('clear_use_sudo', true); set('cleanup_use_sudo', true); set('keep_releases', 1); -set('repository', 'git@git.absdev.net:admin/RSync-Studio.git'); +set('repository', 'git@git.absdev.net:mag/rsync_licensing_server.git'); set('node_version', '22.12.0'); set('allow_anonymous_stats', false); @@ -18,8 +18,8 @@ add('shared_dirs', ['storage']); add('writable_dirs', ['storage', 'bootstrap/cache']); // Host Definitions -host('main') - ->set('hostname', 'rsyncstudio.absdev.net') +host('prod') + ->set('hostname', 'rsyncs.absdev.net') ->set('remote_user', 'mag') ->set('branch', 'main') ->set('deploy_path', '/var/www/rsyncstudio'); @@ -28,7 +28,7 @@ host('stage') ->set('hostname', 'pegasus.absdev.net') ->set('remote_user', 'mag') ->set('branch', 'stage') - ->set('deploy_path', '/var/www/rsyncstudio'); + ->set('deploy_path', '/var/www/rsyncstudio_dev'); task('build', function (): void { run('export NVM_DIR="$HOME/.nvm" && [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && nvm use {{node_version}} && cd {{release_path}} && npm ci --no-audit --no-fund'); @@ -50,7 +50,21 @@ task('artisan:clear', function (): void { task('services:restart', function (): void { run('sudo -n nginx -t'); run('sudo -n systemctl reload nginx'); - run('sudo -n systemctl restart php8.3-fpm'); + $phpFpm = run(<<<'BASH' + if systemctl list-unit-files php8.5-fpm.service --no-legend | grep -q '^php8.5-fpm.service'; then + echo php8.5-fpm + elif systemctl list-unit-files php8.3-fpm.service --no-legend | grep -q '^php8.3-fpm.service'; then + echo php8.3-fpm + else + exit 1 + fi + BASH); + $phpFpm = trim($phpFpm); + if ($phpFpm === '') { + throw new \RuntimeException('No supported PHP-FPM service found (8.5 or 8.3).'); + } + writeln("Restarting {$phpFpm}..."); + run("sudo -n systemctl restart {$phpFpm}"); }); after('deploy:update_code', 'deploy:write_revision_file'); diff --git a/rsync-studio-licensing/docs/PADDLE_SUBSCRIPTIONS.md b/rsync-studio-licensing/docs/PADDLE_SUBSCRIPTIONS.md new file mode 100755 index 0000000..bb6826d --- /dev/null +++ b/rsync-studio-licensing/docs/PADDLE_SUBSCRIPTIONS.md @@ -0,0 +1,71 @@ +# Paddle subscription integration + +## Sandbox configuration + +Keep the Paddle API key and webhook secret server-side only. Do not put either value in the macOS application or commit them to Git. + +Required environment variables: + +```dotenv +PADDLE_API_KEY=pdl_sdbx_apikey_... +PADDLE_API_URL=https://sandbox-api.paddle.com +PADDLE_WEBHOOK_SECRET=... + +PADDLE_PERSONAL_PRODUCT_ID=pro_01m22q4c3vt7yvtv3h3zw1jbn0 +PADDLE_PERSONAL_MONTHLY_PRICE_ID=pri_01m22q4cjx177krcpvdph7e2vy +PADDLE_PERSONAL_ANNUAL_PRICE_ID=pri_01m22q4cs9sr5gshxp6j56nvmh +PADDLE_PROFESSIONAL_PRODUCT_ID=pro_01m22q4d0s6y1557wsq9s7xw8n +PADDLE_PROFESSIONAL_MONTHLY_PRICE_ID=pri_01m22q4d6h1yvr1frawtx51gy8 +PADDLE_PROFESSIONAL_ANNUAL_PRICE_ID=pri_01m22q4dcndcdbzc20txadaz52 +``` + +Then run: + +```bash +php artisan migrate +php artisan db:seed --class=Database\\Seeders\\PaddleCatalogSeeder +php artisan config:clear +``` + +The seeder maps the four Paddle price IDs to licensing entitlements. Personal permits one active Mac; Professional permits three. + +## Paddle notification destination + +Configure the sandbox notification destination to POST to: + +`https://YOUR-HOST/api/v1/webhooks/paddle` + +Copy the destination endpoint secret into `PADDLE_WEBHOOK_SECRET`. + +Subscribe to at least: + +- `subscription.created` +- `subscription.updated` +- `subscription.activated` +- `subscription.trialing` +- `subscription.canceled` +- `subscription.paused` +- `subscription.resumed` +- `subscription.past_due` +- `transaction.completed` +- `transaction.refunded` + +## Entitlement behavior + +- Trialing and active subscriptions are usable. +- A scheduled end-of-period cancellation stays usable until Paddle changes the subscription to canceled. +- Upgrades/downgrades update the entitlement on the existing licence key. +- Canceled or paused subscriptions revoke the licence. +- Past-due subscriptions retain access through Paddle's current billing period rather than being revoked on the first failed payment. +- Paddle customer details are fetched server-side when the webhook does not carry customer email/name in custom data. + +## Important + +The API key is required only on the licensing server. Use a sandbox key with the sandbox API URL. Live Paddle products/prices have different IDs and should be configured separately when moving to production. + + +## Hosted sandbox checkout + +The licensing site exposes `/buy`, which initializes Paddle.js with `PADDLE_CLIENT_SIDE_TOKEN` and opens an overlay checkout for the four configured price IDs. Set `PADDLE_ENVIRONMENT=sandbox` while testing and use a `test_...` client-side token. The token is intentionally browser-visible; never use `PADDLE_API_KEY` in frontend code. + +After a subscription webhook provisions a licence, the webhook controller makes a best-effort attempt to deliver pending licence keys by email. Delivery failures do not roll back the verified Paddle event; the encrypted outbox remains available for portal resend. diff --git a/rsync-studio-licensing/docs/PORTAL_LAUNCH_FRONTEND.md b/rsync-studio-licensing/docs/PORTAL_LAUNCH_FRONTEND.md new file mode 100755 index 0000000..bdd65ec --- /dev/null +++ b/rsync-studio-licensing/docs/PORTAL_LAUNCH_FRONTEND.md @@ -0,0 +1,24 @@ +# Rsync Studio launch frontend + +The public `/` page is now a product-launch landing page using the same shared Laravel layout as checkout, support, authentication and the licence portal. + +## Favicon/device assets + +The website uses the existing Rsync Studio app icon as the web brand source and includes: + +- multi-resolution `public/favicon.ico` +- 16x16, 32x32 and 48x48 browser favicons +- 180x180 Apple touch icon +- 192x192 and 512x512 Android/PWA icons +- Windows 150x150 tile icon and `browserconfig.xml` +- Safari pinned-tab mask icon +- `site.webmanifest` +- Open Graph/Twitter image metadata + +The shared `resources/views/layouts/app.blade.php` loads these assets on every website page. + +## Launch page + +`resources/views/portal/welcome.blade.php` contains the public product page: hero, native app preview, features, workflow, security positioning, Personal/Professional plan summary and trial calls-to-action. + +Non-production environments automatically emit `noindex,nofollow`; production emits normal index/follow metadata. diff --git a/rsync-studio-licensing/docs/rsync-studio-paddle-ids.env b/rsync-studio-licensing/docs/rsync-studio-paddle-ids.env new file mode 100755 index 0000000..87b3c5f --- /dev/null +++ b/rsync-studio-licensing/docs/rsync-studio-paddle-ids.env @@ -0,0 +1,7 @@ +PADDLE_PERSONAL_PRODUCT_ID=pro_01m22q4c3vt7yvtv3h3zw1jbn0 +PADDLE_PERSONAL_MONTHLY_PRICE_ID=pri_01m22q4cjx177krcpvdph7e2vy +PADDLE_PERSONAL_ANNUAL_PRICE_ID=pri_01m22q4cs9sr5gshxp6j56nvmh + +PADDLE_PROFESSIONAL_PRODUCT_ID=pro_01m22q4d0s6y1557wsq9s7xw8n +PADDLE_PROFESSIONAL_MONTHLY_PRICE_ID=pri_01m22q4d6h1yvr1frawtx51gy8 +PADDLE_PROFESSIONAL_ANNUAL_PRICE_ID=pri_01m22q4dcndcdbzc20txadaz52 diff --git a/rsync-studio-licensing/package-lock.json b/rsync-studio-licensing/package-lock.json new file mode 100755 index 0000000..b211042 --- /dev/null +++ b/rsync-studio-licensing/package-lock.json @@ -0,0 +1,2354 @@ +{ + "name": "rsync-studio-licensing", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "@tailwindcss/vite": "^4.0.0", + "concurrently": "^10.0.3", + "laravel-vite-plugin": "^3.1", + "tailwindcss": "^4.0.0", + "vite": "^8.0.0" + }, + "optionalDependencies": { + "@laravel/multiplex": "^0.4.1" + } + }, + "node_modules/@alcalzone/ansi-tokenize": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.3.0.tgz", + "integrity": "sha512-p+CMKJ93HFmLkjXKlXiVGlMQEuRb6H0MokBSwUsX+S6BRX8eV5naFZpQJFfJHjRZY0Hmnqy1/r6UWl3x+19zYA==", + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@laravel/multiplex": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@laravel/multiplex/-/multiplex-0.4.3.tgz", + "integrity": "sha512-jJTZGgKl6sK0ETYmqiPqeAwmErvqjxgDRLfzqsmqiWiupc5dfjaoVVrrdXZwb6eGylSg99WwHLibCPJs8F0bGw==", + "license": "MIT", + "optional": true, + "os": [ + "darwin", + "linux" + ], + "dependencies": { + "ansi-styles": "^6.2.3", + "commander": "^15.0.0", + "ink": "^7.1.0", + "react": "^19.2.7", + "string-width": "^8.2.2", + "wrap-ansi": "^10.0.0" + }, + "bin": { + "multiplex": "dist/cli.js" + }, + "engines": { + "node": ">=22.13.0" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.148.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.148.0.tgz", + "integrity": "sha512-Nm4s/jB+4FpFsPhWGEC4h7rzksesmtnMXomo6rCMcg/b8zLQuOziRgkCS1fxDCXOlJB/6Q8oABOZ/OP6RIPj9A==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.7.tgz", + "integrity": "sha512-EypzgnYCwyVY4NDHKzGmNJT5b+XaQEBniHxsMdeIQLB/tcCzZnhqrzHpZFbX9iaxx+5RiB8caATBtfvZP7zVxQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.7.tgz", + "integrity": "sha512-l17HE9EweWaqJZhuUuNBN/FzM62xw+DECVnJyvMsxn8vJFAGLy5QfLDoYAcronkAN8VxKZHezDpulHDPx95vFw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.7.tgz", + "integrity": "sha512-8ED8ELFvHXc6OCETIn4gXObPiaR6bckM/ipXtbzlPVDRMBfEGjCKgO90F9YtfdpDatVx/ZQw7aZ1vUMf/+T3Mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.7.tgz", + "integrity": "sha512-/WPripjtiAIZ2tWY7ddijORT0Ujg87wxWW/qcoFVCKAWVDPhtY0xr7Dj0M3GyNGz60jGwTElhro/mkF9dT7dDQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.7.tgz", + "integrity": "sha512-14DI4NcqpvbICxSnGLx3PmtDaWqRP/KGSGb6C+JLLVPeZRl6dKdHba3pGsqT3vpdTqhEYIPG0MMQ8c0xYqoJxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.7.tgz", + "integrity": "sha512-bxrWIRvHWQvbJwi+VIie/kDJmQxcNE6xxWwZdqF/ExVAigtHkv54WTLQPb+QsZdnFy18fg7JPfWGL0RH6vwIlQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.7.tgz", + "integrity": "sha512-toOY2BChBZyuxU7OYX6Tn389di4IzAqPTycVcci0O7FSfBqzRB3RZn+K5Is6ANf4tmgRd/K1yZTsNTXbkXsnLg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.7.tgz", + "integrity": "sha512-lAIXTH/aiLRLxsTgQvfhjo4K1ydWIp00+V0voOr9beb/9ZmkUFrSIb03dXNFRgMNvkE6oGsF10ioQ6UsI+vS5Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.7.tgz", + "integrity": "sha512-kdnwS28Pkenp/mZMRwjXXXwxQ7pIsm+bF919LUK93BOyhcLsrVKdP2p9fxpiPNPAbNuch8ypQt0pm2P2LYCAGg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.7.tgz", + "integrity": "sha512-516OdsyLdr5E65paF3yBF55t8mfm9+gmtCsK3xI7XKXIT7EfRlHhxL8K/NR6Hu8BWSgF5+1w74lTL0+nxcc8Qw==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.7.tgz", + "integrity": "sha512-r8/z8n7GFaYRln3xmP1Cxy0HH/HLM0uBUPkEuSVEfKGDA89M0FsZRZJRSwe/tJjRx+fpH/gjorfhB8tmEbSFLA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.7.tgz", + "integrity": "sha512-pAsE8iiDxUg1xBqdhrTfg45AVDVpirjz00sblEYClGNNcMnDb+e8beQgqIAw6LvauX/APvgxUnwrgun/YYGBhw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.7.tgz", + "integrity": "sha512-lTcIYmmnQQA8Or/2DatS6oSqcdLHvendjS+zLu+FwgToynWMRSmQdpM65fTANJgIS4mjbMOo5KT2lnT9SAb96w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.7.tgz", + "integrity": "sha512-e3Gu3WxbNk/UqQhxqU7YIYO+9ZBvWNz3U+h/qRFosscMFzdRPbXYSaSWgSnklv2fz1TgzBTcti2z35c/7irsHw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.7.tgz", + "integrity": "sha512-W/jg5qoRSqjsEv0+dZi4e687mcHqmVuU0P4fK6qS/xjetW2Gmc1W8j//z5nAeNcC8Ttm0hV46IjcYeuVwYhuiw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tailwindcss/node": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", + "integrity": "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.24.1", + "jiti": "^2.7.0", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.3.3" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.3.tgz", + "integrity": "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-x64": "4.3.3", + "@tailwindcss/oxide-freebsd-x64": "4.3.3", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-x64-musl": "4.3.3", + "@tailwindcss/oxide-wasm32-wasi": "4.3.3", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.3.tgz", + "integrity": "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.3.tgz", + "integrity": "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.3.tgz", + "integrity": "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.3.tgz", + "integrity": "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.3.tgz", + "integrity": "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.3.tgz", + "integrity": "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.3.tgz", + "integrity": "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.3.tgz", + "integrity": "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.3.tgz", + "integrity": "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.3.tgz", + "integrity": "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.11.1", + "@emnapi/runtime": "^1.11.1", + "@emnapi/wasi-threads": "^1.2.2", + "@napi-rs/wasm-runtime": "^1.1.4", + "@tybys/wasm-util": "^0.10.2", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz", + "integrity": "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.3.tgz", + "integrity": "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.3.tgz", + "integrity": "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.3.3", + "@tailwindcss/oxide": "4.3.3", + "tailwindcss": "4.3.3" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" + } + }, + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "license": "MIT", + "optional": true, + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/auto-bind": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-5.0.1.tgz", + "integrity": "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cli-boxes": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-4.0.1.tgz", + "integrity": "sha512-5IOn+jcCEHEraYolBPs/sT4BxYCe2nHg374OPiItB1O96KZFseS2gthU4twyYzeDcFew4DaUM/xwc5BQf08JJw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18.20 <19 || >=20.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "license": "MIT", + "optional": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-6.1.1.tgz", + "integrity": "sha512-06p9vyLahLa4zkGcgsGxU6iEkSOiuI4fhCH6Emhe2lPAcoUv73n72DnODsnHA+5wwXGnV0n9M9/qOQJSjYhFhw==", + "license": "MIT", + "optional": true, + "dependencies": { + "slice-ansi": "^9.0.0", + "string-width": "^8.2.0" + }, + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/code-excerpt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", + "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", + "license": "MIT", + "optional": true, + "dependencies": { + "convert-to-spaces": "^2.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/commander": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", + "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/concurrently": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-10.0.5.tgz", + "integrity": "sha512-JaP/CoftUrCcAFW/g//RbgEGwlelnEae6cfBLgH6ZdO6s8jPkn6p9SB9u6pdVxYXoiSnFqseOlHfrEfF82TVOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "5.6.2", + "rxjs": "7.8.2", + "shell-quote": "1.9.0", + "supports-color": "10.2.2", + "tree-kill": "1.2.2", + "yargs": "18.0.0" + }, + "bin": { + "conc": "dist/bin/index.js", + "concurrently": "dist/bin/index.js" + }, + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/convert-to-spaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", + "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.24.5", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", + "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/es-toolkit": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.52.0.tgz", + "integrity": "sha512-XTNEJQh1tY1ZJVcf6ayP/2n4ZPyaHlW2FWs7xvw5ddPuhUVjLD3olQVQS7kf58JbAB48iL0uL/jerTrjtV3lDA==", + "license": "MIT", + "optional": true, + "workspaces": [ + "docs", + "benchmarks", + "tests/types", + "tests/browser-compat" + ] + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/ink/-/ink-7.1.1.tgz", + "integrity": "sha512-Y43xxa1ZSPvpmfLHcN5o+OdP8Rf8ykkNJEuKYOUNZKT8wXVNLFTtEm1nSDMQkfBH+YANF4Xuu0hhZ4ejqAtN2w==", + "license": "MIT", + "optional": true, + "dependencies": { + "@alcalzone/ansi-tokenize": "^0.3.0", + "ansi-escapes": "^7.3.0", + "ansi-styles": "^6.2.3", + "auto-bind": "^5.0.1", + "chalk": "^5.6.2", + "cli-boxes": "^4.0.1", + "cli-cursor": "^4.0.0", + "cli-truncate": "^6.0.0", + "code-excerpt": "^4.0.0", + "es-toolkit": "^1.45.1", + "indent-string": "^5.0.0", + "is-in-ci": "^2.0.0", + "patch-console": "^2.0.0", + "react-reconciler": "^0.33.0", + "scheduler": "^0.27.0", + "signal-exit": "^3.0.7", + "slice-ansi": "^9.0.0", + "stack-utils": "^2.0.6", + "string-width": "^8.2.0", + "terminal-size": "^4.0.1", + "type-fest": "^5.5.0", + "widest-line": "^6.0.0", + "wrap-ansi": "^10.0.0", + "ws": "^8.20.0", + "yoga-layout": "~3.2.1" + }, + "engines": { + "node": ">=22" + }, + "peerDependencies": { + "@types/react": ">=19.2.0", + "react": ">=19.2.0", + "react-devtools-core": ">=6.1.2" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react-devtools-core": { + "optional": true + } + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-in-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-2.0.0.tgz", + "integrity": "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w==", + "license": "MIT", + "optional": true, + "bin": { + "is-in-ci": "cli.js" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/laravel-vite-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-3.2.0.tgz", + "integrity": "sha512-xSxY9Gzeb/eancd8WeK09piAFP+a6i5QIBqNCKNv9L0Eq6wziwzSem7F1GvMSrtjMh5F/QVKFxn8t9naGOA66A==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "tinyglobby": "^0.2.12", + "vite-plugin-full-reload": "^1.1.0" + }, + "bin": { + "clean-orphaned-assets": "bin/clean.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "fontaine": "^0.8.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "fontaine": { + "optional": true + } + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/nanoid": { + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/patch-console": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/patch-console/-/patch-console-2.0.0.tgz", + "integrity": "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.18", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", + "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-reconciler": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.33.0.tgz", + "integrity": "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA==", + "license": "MIT", + "optional": true, + "dependencies": { + "scheduler": "^0.27.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^19.2.0" + } + }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "license": "MIT", + "optional": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rolldown": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.7.tgz", + "integrity": "sha512-g0EtLvBjTUB7jhyV0S/TCup3v/XSVl45vUIGbOGU4QPiyjTenCe4mKuFvW9fEgYmS2Fo42AUssRmNuMziXdrig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.148.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm-eabi": "1.2.7", + "@rolldown/binding-android-arm64": "1.2.7", + "@rolldown/binding-darwin-arm64": "1.2.7", + "@rolldown/binding-darwin-x64": "1.2.7", + "@rolldown/binding-freebsd-x64": "1.2.7", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.7", + "@rolldown/binding-linux-arm64-gnu": "1.2.7", + "@rolldown/binding-linux-arm64-musl": "1.2.7", + "@rolldown/binding-linux-ppc64-gnu": "1.2.7", + "@rolldown/binding-linux-s390x-gnu": "1.2.7", + "@rolldown/binding-linux-x64-gnu": "1.2.7", + "@rolldown/binding-linux-x64-musl": "1.2.7", + "@rolldown/binding-openharmony-arm64": "1.2.7", + "@rolldown/binding-win32-arm64-msvc": "1.2.7", + "@rolldown/binding-win32-x64-msvc": "1.2.7" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT", + "optional": true + }, + "node_modules/shell-quote": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.9.0.tgz", + "integrity": "sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC", + "optional": true + }, + "node_modules/slice-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-9.0.0.tgz", + "integrity": "sha512-SO/3iYL5S3W57LLEniscOGPZgOqZUPCx6d3dB+52B80yJ0XstzsC/eV8gnA4tM3MHDrKz+OCFSLNjswdSC+/bA==", + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-styles": "^6.2.3", + "is-fullwidth-code-point": "^5.1.0" + }, + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", + "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", + "license": "MIT", + "optional": true, + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tagged-tag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", + "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tailwindcss": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz", + "integrity": "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terminal-size": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/terminal-size/-/terminal-size-4.0.1.tgz", + "integrity": "sha512-avMLDQpUI9I5XFrklECw1ZEUPJhqzcwSWsyyI8blhRLT+8N1jLJWLWWYQpB2q2xthq8xDvjZPISVh53T/+CLYQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.9.0.tgz", + "integrity": "sha512-yANm3Jr3GiJ1qgJlxGAVxTOIcEOk1rhQHamlXtnrCK7EHP4HeM9OGxtMg/W7HFdrVzw/ZWJKGVIJusVH85sLtw==", + "license": "(MIT OR CC0-1.0)", + "optional": true, + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vite": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz", + "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.33.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.26", + "rolldown": "~1.2.4", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.4.0 || ^0.5.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-plugin-full-reload": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.2.0.tgz", + "integrity": "sha512-kz18NW79x0IHbxRSHm0jttP4zoO9P9gXh+n6UTwlNKnviTTEpOlum6oS9SmecrTtSr+muHEn5TUuC75UovQzcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "picomatch": "^2.3.1" + } + }, + "node_modules/vite-plugin-full-reload/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vite/node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/vite/node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/widest-line": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-6.0.0.tgz", + "integrity": "sha512-U89AsyEeAsyoF0zVJBkG9zBgekjgjK7yk9sje3F4IQpXBJ10TF6ByLlIfjMhcmHMJgHZI4KHt4rdNfktzxIAMA==", + "license": "MIT", + "optional": true, + "dependencies": { + "string-width": "^8.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-10.0.1.tgz", + "integrity": "sha512-M0N4xzyzosiIok3svYlEo1sdLZts/8FPgYH/GPC3wvlmPoRvnoManGMrE54waYj3tISA8w6lsdesfVv67qSr8Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-styles": "^6.2.3", + "string-width": "^8.2.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/ws": { + "version": "8.21.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", + "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoga-layout": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz", + "integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==", + "license": "MIT", + "optional": true + } + } +} diff --git a/rsync-studio-licensing/package.json b/rsync-studio-licensing/package.json old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/phpunit.xml b/rsync-studio-licensing/phpunit.xml old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/public/.htaccess b/rsync-studio-licensing/public/.htaccess old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/public/browserconfig.xml b/rsync-studio-licensing/public/browserconfig.xml new file mode 100755 index 0000000..6492abb --- /dev/null +++ b/rsync-studio-licensing/public/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #2563eb + + + diff --git a/rsync-studio-licensing/public/favicon.ico b/rsync-studio-licensing/public/favicon.ico old mode 100644 new mode 100755 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..439dd30e491b86ccd01e53482a32680c13f350d8 GIT binary patch literal 11471 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%0Aog3Rh7aO~}<;}bkZ|Bxi%dm8E6B=P>Y zU%Rnit~00QKpvFDt|aK_x};O!3M72nWqqpkw}u;W5>|tT>XXY4cMuPxT2}G^m0eQ_LU#9m546`Wf`i|i=Px9`aCnj z*cY5x6>-uf*b~XMeuj7Ry#LwhHoHe<*GuS>0B-e1HXJr!8Z*&j69&j)8tVl8(Rpg_T5V9bn@A9X; zOE$Yhf)Y6uOIw1`j{*$ueDB*uB5W~BGS;2{MSvuz{Y0FOb;eN5-IgkqDd9vK+ZuE< z9}Zex?%LlIr$XaG>FPwGafh@iqvO#|wBurJdYC%9j@|$YnWtxE^E=0Y`xMbX{Q6&atm*!?HFWgJ7n6$@+E$ErmjH0&{(VvT z`sP6q8N3-K7(qAm0ZV54x10Bu0bx3zbUJ5H(r%He=;=V6JK{TKa*RA4g#O@s+?i3F zEHj?$YqDDXU^O}B@y#ktH|&G|o|vubhlE=9oYVauplmV5#2KewOH@}ad)jpmo}Cor z(Fb{`%h@cq;|sOHpLN^vXPWNy7Pfp2PH6|N^D&kFv{vGhSeedmSjuXsUS zX23TV&!(ErAv62&;%At}%oc$N@p?6jkqutFH})q9)A@)bxHmA!g!ZD=|Hqt{c{3rs zkdv#S+if@-Iy_SVXms+A_cC6y7ov_?=(+&U2o2puv`~ux<=HzQwWFRe%=QZiwF-x>a%w*lTJ9+%J&TwG%)h6(O5f75VL(18s~<9 z3v@*fBGQdANQTlln=ZFm9t?(Q*VY!&w^zi52Go2CxFR6{(}=F(*Z-TAU6Es?*MCHb zMeHwZ#OkuVBRi*JTIR?QwlC<#dwB6l%X^RndM5-5o4#Za{V#rdd_}fKj1HqX^D^7R zZS*-+i05dQ9zH|)GLlB~e}AuREx>X{1hmxtZhTp2=2A|8c^ZekHL4L?hakjQ<1o*- zu}(-JcX#%EK-mGJCrdj0WP|M&^|aM|@h>kl{`V&w!6z*}%~G^{^W>Ft zqgUF}&_pZ6OXvZF{1>y|5Adwm)LP_~`s=R`P$40i*#z&a4cAjl>`7A(`I-E_UE*|O zEoNCO2X#6UYRtEcOGbE^z@Os+NJWU}qJLK9;L8X5z7M+5OTJM^lKW z1m^{*2+OOr|N8!MrEs9>;E>;ihBWI9AE@46`4O7*TUlauj+CFq7+M{X0TWw9!1>|6 zrr3mM;|KOxqC^ADRzAl)Kbeyu56YdU_YpUQ&@+1w{ST~CnOI1vN!v;52X_7{!UL!| z$*?RrCUZ`GzCa3KY=&+W;r9JkA0T5H;PVX<68;;8uw^9!Wl;w$4_a^D=6W0jPb$v3C{m9}K4sf!Pr-OS%SnHOW*>Xb@eOkO z%NUnqLx1_59O|m9S&QW;=7d7&XpNEf-pgy2vJd3I8k+XsNX&$Yz&>eRQ_80+|5JyQNC(oDWV4G;@y)8X6j^f?5QN;$w z!0rd!I%8Vxuh(20IS%TEl(ilPa%KPIe8^uZJTby6mw0S`-Vs>fs3RcyT@}aCXLf%E z7n6Ypc<{tv|J?CVF`C{FGQd+eJ!-6lBxeaKC@8;HjQYrhSuiqkLW;%)vxx*(Uv}C` zhQ59wzhG@f6Tossj4{rL$E7Qn%{i1922@v3SDbB@64kXVc~4e|MtD1Cy6uKn7*uZ+ z{6!T8=~f%x-evaAeA5Ebj!F+>LFlPoHBgdkJ}%@<*y>G_YJ7HG6*pod_Y`xFTG_`X zW<`)tM(xzh&*rCRgvs@UDhDO<#9KZv?_?fiF&r|}*TVHSvBrRQjORk2z_<=_uymGl z^iltnm$tu(-gGuG`a%{5?JpBj5|RG9l>G<)K_b~#CqX+s7ekt!>B_9{uY!yh#8yq(FI)#6UAwaR3QJXRn|vhVL{Prx_U_1)fR&M2+219p z^WE~ZbHTF=CwTHw4CNZTV|t8vG|+Yg1L@75n7n)MuSfIqB>j$f!{3boh#D+0Ks(Pf zJdx~b7D1<|x6Nc}BSP@52VWI`J!&WVE<68rC8hJz4L(6rWh#T&i(;%ptjE&dqZUv{ z1o;Y*DTa1jLWa|BMD*}nfl2vlh1fxTNb2j@U=A1w#!lTpfk~8RYp+PREXpsDNr z)%mz2f@M{>?U=?lXl-bTs)MV}Yf@O<>~OR3l{lf*s90(LLFp=8jKWUzHxj<=9I+U% znHYr8VpXnu`|HY06Enj0?#Z-E+WpRt4GEHsYt+GCsOJ zdp*mxE^4Pq&5^^EX|VrlinGbS({8V}dbV9FchdN~$F@qHz{li!V_!47x;cQ24KR#= z;Zt4b-&u782iLfm`3$GZ{!7G!GAji|C;Xmn{Oy$LkOY-9>YRJG>_XAabm~ns21$+D z5^HYivm8by>lne(uD!ZQrWH8e+b;7~s7U`l2Xc3r zD&Q9KO<+)5nW@+@@_$tJWT1+J8e?;QD}pj3m9_ zkSl;x^M&T;1Q)+#?<(zFd&CX-1>@2zHCmknE+ve{*Bkko8|`jEZejk%4R7KJZLq-y zf|YRgC0TSrx`du-Q|OWWa9PVO(C}5U_s3KiRQy9~C*jJSz`}h12Pm`4S2ViMH2<@T zGfd8yDQs}vr|0_tS1c>Ye8fD)CIY=DAbp+uS-7LY$>C<~`~-{!Ocd`aJyt47nw|EU zw;pcxtvvk{&iPC8-t=4?19BmZ?aO|r48sdR3(X6t6Yp8Ajz*mwGh7=!AIB>N#wpiL z<6+`pa}r~q4O#?alOlhD*Za=}yTZ77ci^cz^mbHFdq>#6nvq8&MVf(aL!A>yLy{u* zQ|%r9)-?ro>B9W8V9wg?FKm~p>I4iIVXwSy+oY@~HQ~0l=bLMOk<4`hQ11ZbCbBu7 zO^BW{-a4A$!FMxRf>H~>R=(2>JmgZy1o(&o{W&1+12j6+Q)3@IzCui8QJO+^SmeS9 z-`z_7f%S(9CT~AqS$B{Y6KK-U@7?tMxXG#+DUqmObb!wg>AVvY3k8Jmcu-yT@)Yy1 zdDY+{xqID*XLHwkdxxa2{L%@#<>!?`XGc-_VUak}fXE1X z^HZ|xjZi;%K~Tl_q&c>`S~}!-!VtO!%*EY<-7Rnoy;XgioV(n0I5GLu^Htr3reIs& zMB4F`ovSCi%nB?+Z}t~{btPY`DZesq*XS#8uJ1ofX8Dg!VE%7qUT&(Bgf%N!NTEo@ zkE->G5i4I>JzFr%qVA>r8$Z>eTwURGOzlawN*o zi4m|wxKBY_fz%eh9RL_30Dm7AWS=13RX7wM3#Zy}-o%Mz?FGza8x!?B^0<3`0o~X+ z0@m2|#0A;9P6RGE-5*Hd&2w3xZHa$T!uYwCF@hVEI< zw9vWX90gO5E_lQo$SdERsFWr`ZA!OTBKrN+ZS94^;O!o47~7mrf~vZGJ1-=3Qj>7V z4YE{o`{Q-T?d7YShu@UEIp+BZnX1k8OM$y2vJjHd-VhJ`(Uawu-s3yDP z={^XiBLb$rF0SYPgvxr^)eZ0N`_VL%sTd+%4Y7Q`W8dxg$ZT*)1$ZSdeM|ZFKD1?VpR|bAF^C1SSi-={*r&nz*UPIaxS@ydytk*| zDTgpqAEEXevO0W+$l%I1?;5b~ajfZQWKw61@JSMS@edAyYrcwJWSOtww5R`L^_|k_ z6w8AF@kp4QAS>(62>eR}D4IyRziV75hwLhnOo^$8W!Jk>h$~R4*@3rrm?oW&m3plC zE{wtCC~@1s`r6F71udJ9SbLt~9_dlKth46eI*IE5`!HlZ6-@mTl>#{zoMsMeEVLi}2|Q9JG(M|7IZ?(Z;w& zy8Fy3ZzPxaICy0E)$islu8{Wvef|2L!;|ShJX%ew4#>nd4vA&?>6DrG56|l~-~4C` zHX1Em3^5u!8YRsvUq0u)3gp;X9>?@7kd1Y`-qSIs&VpVgll;zH$pVvOyK?6&qOlib z7!?ZCk{aSYk6VkW>Cs^*wuTJwSBvy=w`98;r$Bl!vW>0K$MC(SCCw!F7k$C@@aOho z$YSX9hevjl-Gn3r4j)WMOISrfu^G=EjDF96*Atlq*|Ei)yzV|9i%UQHPkJW6W;j&< z2PlB9n_O*tywtxk3gI1U=mIc%CEXD3&!c1B45d*AV9d{q1MNP!NANz0=xXJYiBN2I z8bb&ZKQLsc&d4bGlWsEChiQphqdywgQIdYN9iwo}Z!@v_?MeH^XV711@BP0fhbs23 zBcSKD!-*7ogo;D8pP6mum|}&;($lW<|DH1n0%W7jYiU8+$tc>0`hx5|028C%M8uCN zo6Oz#l&IMPEI}}4Yqg-=XduojrGa|40o0)?22zL1RpLK_}~pa0wB8Vrt1LDOdaLa^^&9hUT1N|FhpP*4W{@2)kXS&B&zIOr)`iBvx1V z%_#}9n_y>oDC8u{{0<-yuS7wQvHYPsA;g$jj>Gj5ND*RKPD=N;6?HsmwZaOaGv_Ay z+BQtIyN%5zFh{kBA-j#M*YC~nd|{42)e)bN;n)LLeeNZr@_~BPM5AL_+Mj^+ihgSg z^=xvkoLigirQxo>PNN=Ig^UJZOAa|#qnJfDu#@kUvL3qy&BK2l`oe-b?!Mu%dnZ5#Nh9xB3L!Fm7FDh4zC>LM07dxN{H&kwB}YU6Ko6(v z(vklLMgt~R;V3q0z&DqHg-H0ac^&gFM2$(&ksuDM@u%tsj7eg8UV!$zYj$}e@9 zkIcp_jXhPE>APt@(NY7!_Ne1nMGCttE3k9#N5dzmK5NPQ<_auuoys?YspJ3SBHr3i zg8?FP1CH4HNGRZ)0X?7`L|xSBBKJ;szt`tjt{XFSbC2f=6`!tC?5ufJ_36ZCz!9u-FA0 zQfE!TZgU3EU_5X&Au`1wpyv7+!EfM#8mOX$-8w`mqzIttH>o0v_u~7NXr)jEs*=dsX(&n9h@TvWL067HGo=#4Q6n=|{l)7230(pHLfuk2$Fs^qh2l?&Q0hj-Ym0qy5Z+J~`P*U}|a_P9=17oNn zO#7i+eCW4}K|t+s7wxnN^=Ro`b*s@zH>|A1PQYP;@@V`cIaQzA-+EW~*6l8nT$$vW z?{7F?b;p`#TMF8u!lSes}l?8O`jGK{n5lcF{$GTi8C z#-QL8fEqhqq>V(@;C^DdqD9V9N(qkOR{Tc~n9UHk5PX>x82Zlgzq{gnG$&5@*)gLa zt|cyF_c-x%Siv#$avQHCy{?;%z8P5E9ng6s%5+1w! zM*_ph)9NEfvksOEMHYjMg(UIY?e~@$|84H4k_YrkAI(6{z)l6^N61QA1vVRXzm`&r zE;AaGf7FNgG2`BG9bHh+sKC<^A_Ie%u^BGGpF9a~3nt*O$&Q^ViYRa|o~jVkvq;49OY_Lp zFF$)mS^6f{zU}cQHOnJIH_(@d=;N%&p(86rjUe&f-j)IWML;q`p=T4|i%>%{Szv_> z-+Y^fxJ;97)>s`$GXTY6g~^_FXN$F1WTQ~AR^}><@FLoE^cN@4Ql3KQ$BTmBT-QgP zZJ=anD5Y@1qofsbhDv7FW7*I8T8|84$ZW{w-R&(Q>35Q@-@)7yxY<&}hIlb(**fKn z>Egspi;?h7CFL29{d)jfU^KZ#_=Sv?kE~;H_|%WF0j>9JrQ0wGM?LVwzfunSEftu3 z1VS9i;8WB@+f#cc&M-C+Y_rh+hITgJDY*JN1K&Qi^`kH0uR&x*6%{iHrQ~?Nup|%- zxe3XWY_P$lG*b&xtaY?m_xjIaV(bPzrtP*BRV2cmN?fu*`BxL*$u}yQEP~84fOABY z?N;!G7unj!l?(v{lMZN6?}p`*PJWaA+!zU%*4TPPO$ZSE+2Lcox+`Y$z05gYlT}7d zjUMpD*6eUWa%r+x2Il?)wnQQRZfpDV(wumcW280wuFL1<{==}wjBR&Ib^BFKzD27X zAel%j*QL=P`_6d5#EVnw?{H_sGBGL%}>YQb3{ge zEA?hMky#W@=ii*gqITlBS1o({HC*0aF-I}R>)YS^LEW#+b z^>zutG?pLnf6+!$0j8J=5H#7)4b zXw9>7IMQ_iy{iwAB zkemJ_p1mV;dL@Yb{W*OUEN~7aS#|&t;vaKw`^@QH61n2hY+=3$wwuog2DnSJH4}-mXDhP0)wWI)(mc8hrt4CWIIVRkx;!{82)pW8DP*{ zK(A>{y2|2ew2!EF%kFSv=emw12KJg;wT}%1wVMR^T!4#Dyrq4)2LK6g29)MY3bbst zP2AitL#b*&U~~ax9v{M9o4)y3P5jhH(R(p>bN)KtN8k=QeD(sFsBJq=Gn|km;r=n7 zft-)3?dY&3Ck!WPH$tQC|roDq~g9rWUGqG5#T!d2s zf~@N#Aj26Yn(pIH&3K=lfMrXQ2)You<1-WKH zKzBQ5yfeXu>#;SkE-TH+eEzwOFiWvm-<;dnH$ud< zc!OZG_p}{$LwvL}&vl-)Gz&dhm;F=9Q1Cc?urhR~Z>F4^@Af}H+uTB;=FFGHsXgtg z(tCn4Hv%lQPcIYR43BKJvbU?@o_p;T+kHEa_-d!PIOW^$t1901?7XQ6R7%azpdc82 z+RmQBez*2hMixMvjn5^V+&152V^ zSNI(r4TD@=oHUq!Ef;dL57iL{*Aw}Zq`grmv+YV~PwM(N+?8DR@5YVE&N#^g z*H3Bj`S)G{hi(OK<}pPWK`|qCAsJ7;qOr~R#M;xUt!H)75l8CgW5Tnx_z^!57go`3 zxEDlfk?zrm417OhfEBx88kajNk-!m<0N|muKX|tlBOcocdPwR@LW+WxgEV?b8)RX_&*?sEW*qsHVHPU@ zm0NK4rxq@mLS`mqx;}*5F4&=lk&OI9+r#{JYtp+}&T7&!&-wo5{(iWyMztw z1ALhd&zt<6hn^>9I#TlpdGm4!fu7FS32o+b--zs$lQ-Ai+!_s7|B@0#rrVNx91niw z*GWbty8?wNP9LI)j;xXAB4ur2gW@%%Wo+7-U99d|Sv#EgkPtM?`6szAf~?9w6cV?A znY3R#ruz9S>YXIn`A|tr|0=GciFi+%xz&LqZ=>i&7c6>s@H#V5sf+vMy4{_hOgkB) z6hwz#ek0E@e}Dacd8bX_df~@n&&$F^K;M#hqw{$t1G9Hho-$evS@yRzFO@P2ke3V^ ziX1=MSU-&5D$x=_kR&JvOIUrU4JEWTXtBIIZ?WX6NCY>mF$1 z=-0GwDfBb)4&d>tok11*TF}Vd$)(NRrg$HW-*-$WbA-)xinG9yml&VVJ`t0Se!FQm zV{E~YM5b|8{b+lCvxFE_h2_t1UePI*dwkp`@$VkRgXht55nc%&)nL@}mNkH5;Y$lB z@8FfQa&wV~8k@3l#tX*1JPY*4r!!cp#2n5zOMungZ)1-ir$o*1HX3l+6CfWG-x1r+ zjIqlzjHztqF}rX4pU~_)%AC4`u8l@~^?9|#&coF;3P+~H(i1Ozq;?QH->(7?r$45) z>Z@Lf+BF*8YXL`|cfUqH`l=njrnKvN&oHGgnPIgOi&qaNeI3n`CWY}`Jl908ta=+F z|L*^${$t|RtkdO3$)I>&P;{*#Oke82=hKD3yP*^XK{Y)oWRDIv3$6*n;~4bI-k?R4 z%~!XRP+qZKbPanZUucrzC~y^-t*7)Cvlo;fN}9YvEC-ZP;I{v=K|`DO2<_b~ht2vG z@cV$gen$q!-!INOm+Fu^exwpS&{4Q zlAZF-<=~dJsFZhizPBAi>2qqUN3uTA{L}E}_4?b(u=}mMrZI(vpBfvo=z+V!iRSz-0|1X~v-Ch_=Z;tgJyuV}Q@t6YB;R-Ja zCQo5axk%;#X%i8aa!|Ss|HMT218KL?* zVTH(+)I8w>vsHp;iQN>hLEjaHl%;#+FjEqWOg7+F3zHRb=?k0L>zuubL_bYtE*G6? z&^fB4>A3cx)n0RS{0a2r$DN7ZcT@Sb-_uk8vsJ=zRP)t|>v;^EXa=*9gQ~$#+|0h) zmT(ZAY90{N`cVQHxN>v@=h`tHBQszUO$s7g0YZb%xZ&=-Ve{QE)}Ly56o|ubRUReD z6pKab^7CpM%SS6Erh?m?f|`Yl55gwiw`${Tw&v$7HqSSA3-l+TZY$@P0JqAHfg@L+ z<^(3{jpSRLBV0&)rs7+jva9{!`O@=oI^A9*^LEh#u-=-BUSBTHqQ*WP3Ay+q^h|Ac zp5NC`)IP(I;;Kh{{Z(%UBB66MlY$g-YM(Vilo{|N&67Q67AO6R7=lS&NZ%W;__0J@ z@%tRzeb!F_pF&A7KkrC#Q0?im%ay;G&#B;|QDHmEjbYM_aB&(>p1U5Zs1~988`|~F zycpi)lXLxW|M-C-Y=QQ7hTzM4a-p2?sLbS~@S89d0f3yX+`&#dpQHJ)vIsisE#UXU zVl=GYs)=ldd%?>Ve87VHSEgjkUAXaBHU&Ga3F=^Xha*;a-oVoru*Cdrf)aW_G%wNm z5UN|GrKZ#1*i{&VM0m2($92NQ{JB1-m-pk@pYTz~@yCc|j~PP6>%n_}D{27#)r^uR z5jQ!3TAc7^10(R{o6_%NhP1WR82n|u*-Jv}&PU`3QS=RbKm)XOReCv^bQQ1ENg4;> zW?Mc5pMHP(((}Unq$8j_>fq)kYpjQ$mc@rdq7^hFhKJeCE0q-LHvZL zI|Ld5z8cF1AGM@j`~Ym#4^hL^?4<&kyya8Bwv3tsD-qH!p|1-?jm8|gps+jJE&{lZ zs#WK}ULdw73JoLtc^`uBl!uRu(Q?xHhAQT3UNoZ-Ad)c_%nXm0%f)5aqkJP5bBJYV z@DZ`>9y0Or))<#|Sy|#w&{;CW(0az)tx)fsDyE5`-Mx}^!eoyQXh-_ti|0xr5#G%C z3fCqO*TyFai5t$JDgn*cgx^x-P=LRyC)s(Dgx=&YhzqgcmJBL_adSN4y`OG|Jido4 zg{v%D(E+^fu_cOww(Cu#Wxn}u^w!4$o>p>D15P&AooG|{MF-r0RN zlmXATSJsjLQhn!6rd1n=#Pk}%;MY2Q868yOfR&SGJIa^X#1V%5it77`{hs8ihGyev zL~;70D{Wbswb=d-cg16iPMDPUJOzI1!=*sSPin8fuhO-cnd3rhatobwEZq?=Q4nll zU?!N3+KkG9%G>g)|L&ITZAH^uTfjIL7Bmcbn>VuL|4f+6HJY%<%5?dBd z+&C#2@Mr4W^+i~yMhClC z(c&iIeuKEKFGy%;C+$Q>NzGt1%?mKPVp*kIeP6Z#qRGoo+%0JXs8ga>H}B)OXIzI1 zVA=Egl(3m(^RIuMr_SMQ-do?mOjr#0g!;mem@JOFjaBI^7&mH8=`yTQf3#zd!mpu*YO?x!-2+a6q)lB$O~mtkM94Uz;Nwiue(kTXh) zQ%1t;^L3JTLA4)%9>3H`fb_mRYtmVK@aHTguvcn(x(??R@EGD(F z9&951w**S5p6wa#z&5+hsXb3qBJg zufpyteB4kn8$H;nsIDbFbRe(vThzoP)5^789`7}9=g6=5kVzL}+9ZqB>R-z4M(lhz_xfGmgKo^Xn zf)JzpW_ekgs#iz+uPjE^A!+vc*XQ4tUKcGL?Ee|#blc;sC#{N}tgZ}pkf@SEA3unV zb}7ONi(=U^;Po41@-aTLoLZEeA&pabicwaGtkz#z%5+2mu_c|(F(ttmZlA7RL!zs* zS~)x3;Tn-|6i(WE@0h}%8%hC74U%odDCuALyoTj|26wDb`ABEkUQbj$QA0r+kA9@_ z<`OHPEM2w`tz}F*a!$K|e=N&~=Jc38=5{pC|jY-|T7oxlkHwdJB9t)*&Ai^)xU68iM043DF36j@}Xh zCcAb*K+CT-0g#g@I^xvAT|nx!3`&i+c@kr>jEl5r=%a}3dOq6aaPlvRn&QJy-%~MC z|EOjWkc2xjP|fR6x0k*`Y{Xn&Cw9wzY-9(0A&`@Z<_GupE+k~3=`RF-9TM|Te?%8b zOfRcU)rcx`SIU<-kRC_dX~1rklo~u3OR=>zVXb|O&hzP+f6E?mCHz{-c&EIW1M^qT znBO`yH_@cJu)DY|=68dQ%4b`zFtnWK!N-W zW-I;Rg3E^3&qEDEW~>hZa6vHDeoVM$8b7ncbQH|+B0UPR(){%<;jS9-d^7JDO^Cns zHr`eNTN$G{_wMmK*xjuawvH@IAX|Q@9;r*s84W&<{;3;hRyRzQ{o<`j8hxoovGq^W zr`&G})*Ru%K6mg{LHo}ivG{#$e~Q{bjwS@7JPleSW$b~jw-c`?+*<-(cetN_S`m#P zCF=2+z88oMFSv*7Ss*{N4_ULNgs@CUTniJQ<;hq4+J;Mni+>X@WL&gIBLGA~l|9KC zYj?(hs{zk7!&6h{TJ)K{H>UPVf9&My zCw}q}G9Fth>Wv7sg!75jU55|P7~yAMw+CY<+~y1xTc}r_#R78%3`Ei1xXjC|1G@Ix z`Db^LJ`s*du%mBN;qXZ#3P9#=uqtKR2C^Nhj9kG-+2LoO-c^O%s!lecdUfcL`2$&S zH{0hL-UdiIaqM1wgw0W>#togBVKWdJ9zt z{ZeR?NIh#Q(D4r;wd7s3fvRb{-FLs_*L8wlAa2;YRR8B0_x^S6Dktt+b8)pp6i)t| z7!CTiK#0wsf!|)4A!p(*nA6{&u3wqV*w_`A2AOnR&@9UjFe994;w=;?Uubxi3s46~ zBKjJZAC>0(`!VoM#v`16wFyL5Iwak?$9F)|3{MI3;X%JUV^p|d!Ptua`YG_n{;Dr^ z5icd=0!a&wT%tvsk4S1=jPS@pxpvbMUPd{K|5RD{BP31;k_(A zolV+0dSBs9{5wIPw|jZ8>5!n9*N*mzzp{y9UmlB6e8~v{=V=s35W*s7-tWqVtd$t( zlxC}xL)a+M^-kY!uvhpT44PlQ)R%=ePA?Oudc+H#7#p9n1m9J>!N$mMv-{2`MF=GR zUDaa8%`U9&_n-JWzuLDl6@HT?BsmyXBQSpB4d}w)a}S`NXZ7NZ{#7qAZHn4ug>MbD zS9cEhaF->jedEURQW@9%iuZMUK6t2v$t#uT{5MkAUi$8uSyw;|16im2c($Ofi~nZR zqiG;s5{;SXO3wI6oC?POZ*>Q+P(jX#3d@03QCo}fKQ_DnxGwT@#rH`V#Dji97zL?W zIG2uS?n0>fNb<)(=yuDYJMU!|PS^M*?~^(dV8RYzzlq%GB^;ekqD+fn16&{WC}$lM z`r@g^MJ$|~ETJz_K0;X7RErsi6Evd^L3j8@*5wv>sj*ARa+2nY6Dxd{TF6E;jEEEZ zNzeF~S{PW{VNpnn|D8lz1TJhlrfK?}Fw^zjYeDc0v~7h($o-7)bR+#ob+ofKWwabW zeVPj=7O?`vcPRWJQsb=NH=-b#gNP8PxTisLyg1Kw;^-?!R0?40tC-lF!hMrZX(M*y zKst7K;dwD4)oeQk@u`M4OOzARI}N($aVbjo8kUj3@q%mSL~N5=N;WD!HC{OTRu39v zIC??bpt9mGJAk+*9(yI$?KV6)fNr>>YZb{og$Y~Y#vp>C%c?4;`-B;>8|`te&hf#k zW5HXg`IP=vcfZy>kV*V}fyoE7>!H_I3f3^%*vyso&4|Ddv%O>1D0h7-VjrbQ_)4cp z_*$c6*J*fSd~t!}lLD%dem_%F{Ld_Ml_$&}JY3>ET+QoDm#KaG1}LaRLhIEE?Mg^k zRLhe0ouRV1YW{tuxJx7K3O@z2rsm+vPJ>$Jv->3p?1YXgzQ6|J&+-M~S(HQ z4l;Dla~+HJi2GjjwIe8SQT*VYQH#aiWo5J17`cf?vRd0g z<+cXOxKvJz0eVXds;z%+k$JW=z1RN9sp$&*iYm)TFXpv6)8KwYi2N6W(_o}>D1END z)I5n?uKWRg^S$4^1WMd)%*R=kD##Br)Y>_dw)H+>BOG6n@-lfqFmi~u-q-t=Tfeb) zCpJ0sApSebaNG3x&tkt|($qG8%5{L}8UC|bNG7Mh-0PeNUM~Ivy#UFx!Lgp?(%@k~ zvp(f26PdcO;{bDhM)tzx8uA{Nb3m4u{q%HW4*IHFADGW z)wa3DbBw{C0wXUj;r}fknyCA+O{NsvcL3JP>`y8wAjfynv6S5s;1UNIJ$WziJkz*2 z^g8oB9XrSGuxBjMnN-9J1Q(}=nUS9vjpbERo5I1UIzz|BCyKKra?O2#emC{;a->bj zYt!cB=W#FUL)I| z0Yw4Iay-^m6qE&HKfs6;!9QRGET&#lWf0tDzSfv~KYZ_;t?4$lr%Q+`xh{$Fn!U|# z^21ey^5{-!0mu!j5)IW`m!u6lKRd{A9BW`aGVGZq@`k!?7s|#x0kuYi(jhSvBr}M@ zph@P)Yeb(0$$k;>v+ZH6T(kYHF9PKeQhSV9_LKYr#L^Xs53i>4XK)64$rB}e+`Q%g zS`Qs0YBEv~T39nH;QSo%^w{0%2BZmN27QGjo~idhV3pUd{dwY*j1<}nb98h8c!C?Uli9@GS;eq^V09!ad__8$ zYPK3#OO+;#iqrrshq%Loo?XlH!nL7!t?q}fCkatOBkKA_Sy}_V9!2-7&-0HTjuuks zT;6nbKDx&2BJS>Uu+p-B?G7)eG!nMr8OP0RJh2|V_{#_#{Qc)2xo1M9URP3N=TZM@(i^_B`q!}LW3#2U-!s!RLepu-zqzfRiqjRz|I4eEzscy;D{sVV z=?(hEg^b+2nb;S-iMt1?MLz!Co2*#VIqACn9&l~wq@IA*@7SA|UD%Uz{#?i%@gNrH zqN-9Yy7^e3XInR%%9SUfu_>iyM{d|seP&-2pgO$e7@%nWSZS}EB4bG?H-xfj;wzs3 zSD%R025$aHERfn|zXuZ$7U$mflkU3~=$TfAC|VhSa-Jkhv|y3^pygoCsP&1AOy&+3 zr)AzK1_orkE+GE#RT7%oZ6@q$_e$YG2^CS<&?*Nn)^hSq{*&hjjQee#i`VYWD?dd$V+*%QWwGTe z+$5ZmU9v8hq&qj`m*t6q7Yr`=FqbU7IRMjgy~;>D6R|CI(qmK~=jV=InQIg*EVpOHKxlm! zL;BpWYo;tml;+A?3NDw389vl_C_tscaP5}i0Ct4^g~0=!Wk2>c39Vp(riakOiU-x7 zEV24M3;?+(Oubz7meXqT-18_Dbc1aJ%zWn- zD|Jjg?)YE&T_C{<*m&{v71pz}S?ImQOLgSR$*R*9gj+YEB@oq{N9=$FW(vJ!ywBRA z+E$D>ao$)7O=gwcIh~hVyi(lmk@oz3bVD@ScCjkxSH>MHN@InGyJj#FXgAfP@uC>% zLJr=SeJ@#PCck8-v(V3<55RBTs_5m;5tFZdJ`Fi*qzvCrlngX*$?kEJn<^*v&Z;9cs83{rx*&l&Z-eJ&#sallO zxOaIP#c&H}^oxthsdO@Eml0FKAff2^b^mSw-tAG|p8*A}yEzT=ET-49Q!anq*l5T8%JsnmvjZ;RTFaAcP#C;!3dwp{Y!)9#2 zAwC($m3QPer=#!2d9xq&`(UY}67VGNZ2{NmS`@mIToNf`CI|IW!+$28&Cr=BBY9sa zu~WE~4_|NlOFxhWPkjTw;qMJ=MweV63PfYFiA!gkUfsi3@8or&?t*RU2{Ayn*8hN* zpQD=l+e&`$(v{_NFWbNqn#(@>ypT<|{_cNavOH3NYzAF_-K<;Z6yu%^ z`!Ci{(_uk(I?ld{*s5RU;4tJw8F&-57r6W5U``ou2`0L{98Wv=Ldl-lA*y4#tCfj3 z@piEMKu!WkOn@Uq;jrh6D?s9Svl5%2Ib+GAM^;%hL=Rqe@0wo0)6?e*ZYAjg6oPFP zWy?=pap^CxuJiA1y@*%t5@CfwyV)$BUP-?6tfDx9Bma8(;Wsg}{Rb@X61ve5~}diM9IvbrqZ?z(@2bB1UT;^P-%J9FjxE4qS3m)+*Bn@#AW`Ntx{M5VhXgd-?jTeD) z{lk(w@RMoqbFZ4&Gl^`wc4hAxv|Zzs*h#xrU_%jjN3>j{&*jI^>YGV7QHXON{oNa% zzjgY^+<9;E#>zJHpFmhRrxNqO2*sSUUsr4*o=|K`^g++ZK)YAQpAJEHzgPI#yZ$$s zjAMsf1BoWg22`y(d^-h=w z`p67*5CjQ{5lSRq&f*gku%~l}_#R4Pbg&OeIU3n#-r% z2CWz5_BdfyHWqL0udUQOQ6ol^^k?KJ#;Qaf0ZKx{lZG;kL^>@go5^C2{~^R9Ua>H2 zz6gFT_Y)kTN563uciC3)_>j4<=G!pQ6l-t`=Xq2VJy`bQsX;mEMN{}X+DvL(emrVA zl%#;ICvc1>`v-Kcin9}6&1GO-CcFA7a8BGoNWsN9%#$R~FY6IuHrt%~1(YK4Hk6v54p z4_hGF>^p5;=0I8FgqCIHzE$JL>22Am(mEonqQEQqLdRnp+3)9hfnd@p2W-8J=1m6j zG1DyZAI$bGsoPkdXZ{%sL{z9pOatY_=1}Dyh9rTckFBtQ>7!_vM{kLMR|SrBX^+rU z@rW|@tOR{t(Ou_s|LQvp*bQmn=Vpt)-E?%Hkq)7gn^dYHZ|c~cj`~?zwK(x(g@HLs zMAOiZ)o-*DTUL|~1OFIF0M{1(jnD(lu2}9tjez8i6gf@JeiC+EN>pBuK2De7sc-{< zE{veA*ThU(bxk`+hN@9lpYu8o=eu?^Lp9*y1kuYm`kpFE*ofcE=v#|>qzL;ILJ$aN zU@;iJ{mMhBlo8vKX8BK(#I3pwegS2_y1*PI>3WJQW&HJb#9EiA)%Q4zZU*d|#WTVDBY zxU7N&f-py{?TADI2(HCN>#mUmmXfg0<}7?awe$N>r+4j?&#bpRq7Z#ZummL$C{Hfz zthUL5e$?}+xrdQ7c}#T*SY5upF{2N>`;<=nHR2i2deabk;$Hb&d&}ybF#ElfN##{h zp~)!$kC!*u@yGGEpod&x50mMleA>bi*4yYPsRk1(GT`&Qo*=iIqVSOnB)PkCO^&dw z9KJ!v&c;Hgd}aPE{PT>D$7N7;T_gfKAfb6_@p2?4$QqOxr`(^vLK zb9?q#RP*SG%Y)1ZFxVDtEgO|s9&dvfMg60CM5$03g0#yAA+^Wjrq(TX(~Nmu*wFm= zt4QaMYd|6%07chs96XI`6PZIf7uT9J1Y!-Y;cD8x;a0_|iObS^AiP~Ezv;jGXO86C zO7S`I6lG5EtqhEt)P!C7ycLX((I91|C632H(mSYvu2*P!YqRQ>=J)=$5~j{d2EAmj zhp2Us#2jm5$->$~N_np4mX8hJHB5vSFtBNd)`TQosPsjq)pYB9WdvNMQaF^|1BF>;h% z6qE-do_6c2=fv(s?~@CEyrubfuA5Vey=*8P^I$Hj*B6@~WFP$U&T9P*>_U%=eAJ_# z6e%)#!~pmC)+WBjNKgQEP z4&u4;*Ean2F4@P%m-4+^CN3~{t)lD??enM_0CnIj+!h8wwlh)bJ}@>P>l0;AbK!Z1 zM%ltU-&9fmM{-bAsj}fT8!x7I+9eUXSvB`MX%8JXNg=9au$w?b(3TgjpxWVALo!Vw(ci$BqbJDri2 zv}-njrr0xKVYG7~Cg%T~{__C_4wSd7kU=l@Zpwpj|Ph540CzBD6sRPo{3JkT^h_>HV`)1@& zzFVJwqv?r58Qe^*$7~yaw@=OJ)2zMm>Z8oqAs?_KX_neFR0Z@I6&rfL@po`<=Un9j zlE?k-U;r6)GlOXLsz7C4PF{J5>IdGXTnnxfdiqq@_bP1r73sG~HzL9*4t5&rsB!u# zu~X;)hqdy__}5$}AY@^v<{ldJ#A9uX%oT?nq#iGE;5;*lirrAY?+&3Nh1rLpp+*%iztLyTJr+Jq_PYTINONzWt0@UiPL5 z`OB?vecxMjMpV8UH2bPn|3hNsx_lF!p1Flm`u^=~$pSQI!$Tv=te-ZW%!O+Ab9%Vn zz0%>KEh#>CchtT_A_hs(uxfVJ z)7kvxFLJ?2t7?2jC&5HtMkW?bdy7HEg7@$N`}=2SZm&DS#A=BGqjIewGvOY$Xd*G= zj`#r)gVvB1WF=rZe1;Yi{F@Aj5UvEqA^Z7X;{$Y&OtB2sz%6yzRID^J_{K2CDRE1h z4ejgXk(fH+@yeW;`DPb%7;qd1__%kV&UDShW@h0^_js(tm4S1I6N0yhLp4Q8F4h-#w3|5s^8ggGV2X?lt_El7RyD84=TSpD?L z-pS?nm3!@&638+pUm&;#jnRdN1p_2w;p)-qs=s5C?gT((2~=ydVZ$D z#RI{*#W0|&NQB3|J4^D~xufOxX+NHZ2}!Yb5g)?86c8=O{?KN8YK|ar<0?vStwuvH z)_~+W{I6Qm{!DX#5R~WJ-PU+}!T$w-aRS;3mrv>?L!K+1cX5a=w;q6V8-=~iewF0} zv~v^&8e0>iO}pVU)MzUp{gFD@+t4}7g_A^P>e#BY;g945)*#_!_oz06Rg3e3%)M?S zt1fI}aP;4!pbZbhT*@cP9#Fz&slN@*C&92x-=4wzgf0P3JubDCCW7|RVBlrLu@8Tn z9Jby8CfSJhiwisQclQJr8O+pgBJd|W#0`cIt9I_2*?pgRZ~J~l=zUcEcHbUht81Q&5ib?qu8TpWoKmxFkS#Dbd|w z1%+WtY*CXyd|8jvDS0Vx<=>7R0piQu zj+X*A1z;Gf$jZ6Ouv0;)Dc?TB7EEr{n| zW^P?yXIL8SVlILM5V>VUGt0vU4qu`o!v~cXt);BgxHR$=JS(;_9dR=ez9f(swM#h7 zY)AzC!*%QcpDbHes#Uz0-N=sjoumprH^dG@Z}-$kG6iGngou+EzV(xqf>$FC8F^-_ zDRxdy%RO?wDaj99^y_sGb}9Gzg!{$0*5{IesL>yJM~bs^bEzIe+si-qU2Vtwfry}g zseK)hMiFotyry?^Ct5D5daw?S2{wKAlaOck2t!!&i-GazMb3oy^=1vZs|rXu_|2e6GDa|J71cBK9omwhXbC9u^4&N zhSfylvR1eK>}4r#C>8Vmd? zgIHa;A^`;eJiK=Aj?N=~h59vj$zQk$GNoHKcjbXZc<-eJ4lJ^ zgObwa*4fidUcTsa7H@7DXD;Lc`fEH(rM@#L;MQCmCuNhDH1g}oVrAv&9vQ*dh-PqH z>v~GVWC_TYQd)W&B{K$YxTttiBgaptb@7=ea%Y_9nHmQl3Z$<0+#K*wI4@FKKo&fK z@8HMhQR82Fa{fFtIQChkpgw>-o}jrrW+HBXL_DGC*heE8Zuc3(7lIPiPZJ1L=%A83 zIq#XDvZ@^<;r_pACjZ!(ajy4CPq0B!fP0;U@y@Aw;+-lgm@u|PnxlaEQ^CZnWv9V#2Z!n32OawvV;I7jaEXx$3OcN#0rr#zuyP98 zo#ys&i7ds$A{*X^NVXnn9MoB*$_rw5PpZkzdTxI5t8#aIZ8i6FQ4c?4Qbv@Q`!}P# zt;YSfs8#fCc-cwIbLXuX*BGCXc|Y3do)|LN$-3X}oq*|xNKjdFKcpGZ)4hXT4CpSo zw37P}V{gBtd_$!$Cv(|p<4V8Y`=FbqtB+W@n<)1Yld!G}SBAR#^k?ZHGPIJD#HbNG z!*aIdp=(z5vyAiR?V(EPi{>Mnz-t2X$lHhRA#Y`HNzK$_{8FkFS?M)Yj zezwbNdNX};6@vU zyL}+*@W2O5^0mct9XA#Fp~Ro8k%TvnDb#(uK4A2XAVw^4CQV*|jcdTVnzE9%JKA`W zmcDx}G55=T^i!7oA><;4_y{|~WfXoscUy~q<1;8H1Il`85|pyNlFku^W{g-%ucU4r zO$EWL2EtKtgnnfv`N17C5G>#mNtzzNfO6E%G*>Gu43N}v?_?$y%rkd2ms#-ydbne` zzY#9;4mS5#PchPz)&3?x%NIl2E`r{EkFKh5rZvkt)9pJ1a$DZ&Tb;Sz$56+=!ZVsN z9Vo_sAFyZ==6ySSwMzCA2fZ;7N#;R*H(2~)fv!8E3_l%m++|EYeFRzg?#;yTA!sRf zz_hJyrfGAYLuO)lAy=eyYtCHe@J63Ty$#)B^HX~b(dDCUA%PCh1eL|d_OhSmk(HLe zNyFPKTuce3We?4vdjT2G$S@i+42WxD!}U2Th5v11OV@x5`d=Z#7Q3keQ-5!1OM2qYIYnPB8Fg zf;aFnF%TD5lo zz#V&L3g9Q6oK@369SsYL6z~uHo~+s7Oz^MYR|oJ1LLq=E8E`X$eKHT9nSi*gmj|#r zB(5Ecx=Wn<*zx`V%xx0HSW+N8TdAH<*i0~7Hs%#qIKZK#dQ0?b(r%TlJsLDiXjYAW zq(Lz3(1kdR=b~qT{Wk_1CDeuqxmpT0!U^r(!!ECpQQ|4h1V@E;yr?(6r3w}7PtAMz zr7s_W0DkT3$2gt?Z@OcEH{CwK^(pYc9Ru8dTY=-!%q|#@+UwdXsBIF3jGs~AUj2(a zkvh-=#lKbak&4yST_=lB9^?ju@Yzv%c7=3<{ zf1PeHq;jNhhmpaa4@lKA^r@Fiy#BTUCIizq{N*EKko`dqP4ge^NU_*wY9xTM%7At( znrz1OSFBn~0uUwv9tpaHEB})93u}^q`j8UFNC4X8B%=OEbpjWeZ{`QkD-jcsWI>1S zE47;55E-zCKP?Es%~i|h>r?Z|&p$cECm%PR?ao)DYY%6F2ksc)jkgWVpr{h~&f5og z<88&VL~}tl&O3-g%ForK)jchyI8IC8cfK{lv=q}axdeXaTl0!o3!dMXWv9N~swq!F z;I^uV!a{MIi#Qv_XlBVX0RAhreX)}gy7o2Jh7R}}!yYnle%XPhTr>G((lptO5T-Qc&xN#+#7NlLBoLK!4b0XLV^)Wnl6e^>hON#M5f#5)GqYEP$TSQR(?B zyk*8e;+Ek}Gna!Y@YKt5yz!19c1GpWh&Cq-N`?yHKBv1sKrE-kRT%(F{BujyQY~hu z5)dK*HKm}n2dv3rV2BuKG99dtfGgDClp$*OuOh>4BCzD);tmziW2}QjK;Z1bWXrVl zWV*PhaalISvqc8|?ughMuYNx-O%fd~5dYkhGkoIlS)-aMW{T>!vO99;KU|nJzgeH6 zHkZU+9ufw7mvSPW1B7y9!ddmwLOfAlx8rJJ;4eNwKPEJFl>8IGKT5WG2Y;>!{M#kT zBBsJ*R2T*Asl{NpkP*n0{tHGtf35$_jHeRrgg6Y|0+mvH0s~SHzwv=A;~$BApdj$v zL5X|k=HE>oKs|}73kg^OEWJGg0{H-JFI+mWrD^DWKuggn0n33HA`Mh@_wNsZHT?wI zYT|EH4$HH*)BtBv6=j*IqmNLnhyX!ven886a}XSF(@I9IcMCA+nLBA`A=5JMr2{R8 zj-KngBVw-zTw-Kvm!9>ussk3gPVh90o*z1q^ z^zEa^RFGWokM<$3_aM(M_%D72Rs5d-t{lp$`A=5He+>L%bXzl`H0Pre*3=YeOFx~C-li{4m$L_ATUv5TZhlSD}f^c5iJ_u3s`7wj}CYJd{IMv?9H zr-HvmAxP@?f1=>uv{1tW*clQ<0bD&YrOcDTswYV=;LoNTmknyv?>8oXpy(TDb>N>d z%bEFi&gR=NV{Aq6!hz9O&rb?7OFUg#aGr%;Yv7KWOZ1sDn0zGBO=r6{byM3ky;4tw zuMq>O)fKpn2a}D#GHZX?s#h9UW#5=Bt%@wBqKWc+_I))Ui%<5qC2E)PT}-NjC|*eI zxFR9bEVXMDNb9%me|#-(C2$?#1M0y)nwUoSsm*&3^FHhUgkGh!80%jVi>!+4hD7ojPTCJFH+4mO@}q<^@yjB6}PD1L()xK-(DfD*j}i5yF$ zyQyucG_93PZ~5Mmgs8p!h{qp#<`PgFBITlpCHkRbGoyr8kPQB7mHp!w<90??=UR+Q zM*$p8&Af@lY>r;M|0Vdx_6y^CZ;jyJRsc?0oqxw`qSpWc%~8=R-ZVP(q>$Od)ksp#+G}jS@7ARGW2w^m^HB&q)vXv!PaQBK3C=Ho8ua#_}2k zx@;5HeME<<0GEdyQUyZak@$W|5fWT3d;Nbo4*&8W+P`DuJCP&Cy!wQ@wAY%n-i5T) z0sFfQd;2~QJoaM5v)Fy>G0W?Z>+Jr0m_Qs(ANVr@{*fLHF!p{jGG71X>m_FMSbkk1 z_^V)x=;I?@z`scVG$&)`ctV7;bNlo@yf46t?~|q);L5%My7Loy!T_PA)sX~PedeX* z-&248)Ombv13=5wZi?iK>3wx;VABDgoayu2e0nq&M4)c^YQ#-c2F^CAp2=|HH^ogN z5HQHHGWZgZl${QxGM+A}q+oGxQb)9ue-P-dX-V|8e<(Q@>tCadNPwhhYtp>T*nSZg z@CROmheL}f@&v#j@Y_Vj<@IYD`*fE4&mj1R#)d6sQk)wTBbsJZ&mT&wD`~a|y0}gD z;7J!f(FiI|ljLP5jZs^N=g+iDBpk_oh5*b;!E@KkKEuVNufJ@%>8Y0I-B z;`GiSdPALy^1hD;BQ5H9zYXs3>q_0OjYBHH-m%h}B+=$33fmI%_7PKV2un4J`SZR; z=hAw2&J2G|UJ06c7EVCd*anB~JPY6-Y|RYQ{AX`uY~9fuc;V2@>gaSmNuIyLky9r9 zQF%?F6BQ>f`zJRC&>bz(+E;`a6~xn5=eTw(wJ<>7nv$3u{V_d;$c2AmfL-1ZOCD6& z3umVrYi2-$1hCO8UF>)(b;*F@kt6*1{47znw)2 zw0PeG6Zd|i6+#dX$Sc5pc^q14kkx^umPD$|yR=lI1aH6fXM53vgnW8_FaBIhD9L01 z{8J?V7Wiw_yfXs+i}Mbv?ym&!? z`9_I|DCpKNio(nRc1JE1f_}nmI2Lxn+9feu=6?qI{X+0e|$6>=)d}X9WC7qJ$a0 zJ*3J0f8v^HWi6ty-5Uab#hUIa``15^M*w1E0GmkoW8zocpD0-1`Ter$31H^9OR14G zbtIrI)%$8fU0K0_JW^UpKrRVbc1#aYSq+Oj+Z`}?=eDl6k3O3t!m zR>qvWFcFXdp=^?Y@ZCB+F%PJzQun0Sq9w;^7?lyUF@Ha4@D(>&L{ZZAwA7WKmgJD` z?YDqms{pmgXm!_$@Q^BmRO3cag1^MpW{Tv03S<60{j>xyE`W;@6aIbqNN_awdH?GG zf29#*4)~`y(Ck40h+HgtJeKBW!cB|L|NWaL^C@&Vd? zZ54u*=a_U$i^(K_4hAg}B>`}f08dE3VbWDid&CFUu)+ckV=E!gKaB`LG!+aLnAMQS zXNc;!8Z_z>aY&c#7~Khv-Q@qYCO_i5Kk)**I3*uAYWYLg>!_NLdTxvO8$39?{g9_C z3To#5eY<0TCXTOfLEHxaaNhxs*WW|3-${bMgweow{{oyF8xk-tfp5N4pJkD;_L;g< z;$8VR4gTE-z*;cC2;uqDx#oIwJp z(*nia+jnA}4hg8Q$suvK{r!4aAR5O?@Jud{6O~*KyTpRga6NT znzk4b{Pfil*QX{K@Ybq%daJc+4he91*+KJ0hksL%07b2;iUb5j1-9IardMyb1h#d1 z7YT3=7?Q{}g#o*q@#0*!M}{1S5jZ<^ihbiDwg-nuJOEXmc^WM=5R{?Id# z^df@bmS`TEj<$;t+oAyd_IlPmJ@?;gBw5;Cw!JPT$LqJZs>189w?h}_jEY?FCwwD) zPa6CerGL9aQ~p-~c=B3_Y3Vw=Li+C${FUB+^e-LQL4FdT_3!S*vkwxLnwf2 z$H2E=n1fZ9sB>d$LSU2x=;R6ULPh;kuH?Z`v!DbLK#gWWg&M$G&j3fMpom97aNl(l z93=Evv7}Q$u#u2LVs6U*5pOV7zDBmeCp8lu?IbVNl)WD6@->I<^~X+i$jL0MeKdTX zqKfV7fWLOkiun2V9_#V@RIlFxZB2tzy1af3sZ)V}oh+{#{GkK?rlrEoJ4OZAp8=0w z71R1xC5d(ce)(B z{;5o;uTsC(FY*mpQ2^Jcz_(wVFMCBdRRGk7$$Ku$j`cFSh@+mkBTYVw1W?cX-DIks z?N2X_5WA6()m217sdtvg7B-GnF&|@YeE6JE!`_lw{Y8AMdtiFaI|2%~oqeC-{KrcD zP6qLl+Ztsk5>3!|6%pon`~KNQt+lBkxrh)`>c{soKuT2LugUapfd3|A{u0G0pZ7m3 z>dzymyDam;H>RBiF=T_161paygpaFmOH{8JW1$}aV;&rgC0z4K{0YdjmCS6y&&foXl z1QOr?M@BbxU=1`1POR!E=)xHip@c7kA|r3#%1SYb85-%^<|`P9O_hNiB_ zgboVR51-{S(RDdt(<8*BjiFBD?i}5+Y-}1;6 zDixbsv;Fzl+z?MsVyW%v75FDDjg5hS-1~opgMZCJ7rlXhubzJj*0a|W4m>KrToR7z z4NcG^K~gywE`bElO{09RN`uBMG`pao1OUzSpl0JBp(Cdt&^)N|J6YvULA-O4z$u^q@KmO2n31X0C6Df_1avo3!?(FWKT)(?WSKcS=jCBXG`B`Y~n+bpOJ^q~)n`dBLqy6_U5Rk~~r z7;ak~pBhjL7etUhR57L^0^%kDK04R*tdz#kfgEBt)1jYec>C`=I_V`Lzt)XSJWh(2 zZ5w_Y>_vc3a!4#JLPuGkI9_U&x1aLtkREc1o+c9h@`aM(q^u48seH$~dy>GPD)0wP z7uWM+V0UP2(Gypt^8PcyKiA9cobb0E@F!vfptI-CoG(S3PDaddx0lj*D3uEE_=|H4 z24+g&t-Hj$jAZKDY4;uyK<{;F8FhdJL~ogvtQRmgOxe)&kU)DvU|Y7;ssU`=VZEhl zY^F=l@G@W&tu*{NHqtYwMh^%sLg4C;A5{n<4tNx7VzNLYAAqGGsB#)YZ2}$L^fdS3 zm8%)|_Epa+WbaadKXqJzX2d~gvY)28PjBEK_k^|WeSOCem=1q;>=6ZlqZ#nn)e^&k z@tG3TI-Z$0lY^^k1b>hY0??Q2-=W8#-_d8r)xEKeM!sl}!SyWXw@FpzM7aC;OHdidX_0OUUHfM zRb+sUuJGQ(No_xWmo@bwsk;TQQ&gZ%)>oaLdchz_037Xa-8qF47akaIovgx1+BqSL z!}-p^Jm3f734WqkHwp#MSN_^QpJPvUX?oKM{L>Wbxd0a@rlmUoJbb0Z@to?iy3+;z zJ+>I8JCVI;{G!*GKl@lJd8K{{&x(OHI-LXGczzDRGzz-=d=WTSy<4Dr!8?amGI?(Y z$c;GIdzvGPm|PgRmQ^48rqPHE74oS8jobn@?~TEm5Vau>dF+0J*%T+EMmlyb26;rg zFM#vHDsn*a=2NUA=C4WYi!zV|5u#n=32!flSi5J5j4e=a0(K;t9@Go1DV0*eRIeX! zY9(g~{Lhbon|F-&f8_vp`nt*M+Jb+EpWZp)kLCLQSHxa0gL@NVX zWvD$(TIv6eDnnhw>qfa-1BK6(BBlDO_}cEa^w%a(I{srl3MP;e4O{7weho z*SF{2Vip+(rtVTL)?5Ji($jMs&keTUx?5lnOZXz()oN^a&kA3Sf&@5A{RHj`0U}s6 z!OXG3js+$yv~#HeZI447DgkPJ)foWZrc1^)@-X7iIi|?ENBU9){n5ERHL@ukKswgp zul0Gmv@jv&pUM@0NaY057F;S>kU(-`4(K=Tq1Kp(Il%8w5j1kYYq!G#{u-~pE%_6j zGT#%yUz0`=bL33oAF(?$^8ceR3oh@&>iXwK#ys#>4(6Z|cl!H)8vMNqK(FAhV32Do z_46DjKYHx&w@%sLdwJ9mO5cU# zOcJ!gUIIi(zYsicwHBF*)x*ceNC@L{zq7YL0(lK8@OOFrU7a~5gTG3z4B$u!U_juG zJyXGTc^`Q6CBb-j7QsKWvMmGrodjSlo`1@~gLRbp<=kJbdEKA@p1LY{`l?9*yk(cT zX{V?{0e-KV?k0K2X%-ZV(}(GewoNDVJvGm%TgiO26nuAX04?(3i1|ysJg}{JWXrh$ z>n*VQHE2LW@!O;|8Oy*^9*sTN7xj_|C=EW47wt8Pu4K;0PrLXhShJjKu3$!&fnIMuk$oNv0TZVY`xrl>?>sqB<88_(E-?Yg`n!WQ%3@W z$50Z-z^thDXQ%^y*DVB9gg_`KRC&|g^VfimFTY7&>R129tTYXOE{uV3K|K1B;PSp; zs|_Tj$Ol?qA*nfUwmqgX$cesap^+gjG?s3EquE- zhXklw8x-*6cX>YB?@YY0N|eaZk3+V2L!&vqX-zq#0LgY zO(n5sZbosOGBOsx{}0@Ghf!rkD|V#zR)~?L#CPNZ&}bchVupSQ_(OVO9sD&!B~)#* zDe#vBYZn9mIe-fjllUhfp1dY_^yShc{YSt*HTHg1V*ZhzVxyivxhBt_3E;0hhvh_z z0K)%?Y=;Fr zL;y7+Ko=44sSUK^#_bX)O}U>a)PYd*9_N8-Z3_KPJu}^Y^jK-r+=iNrk`{TeL9nm+ z#F7a5j$DGehs`d)?>In=KqBPzD@Gc+t817DfN`}@1O7fOA_e?`RowrsJz`i8vl967 zb0tb2TRzp`&+ePk2mX=gIJ|LWe*$`8srFaV-Csolc80_^uavmBL)>+)z%9E4j%FpU z9gDkNaQ*tkawTa0P1?-EuAi#?UV^@Qz<=WJitX>}@_9GrXZ4JTlw z);M-qQwsj}R-g-CUl3Gh|?&zgUuyRf(P=v)}VzgE@OK z?-)=FK$7^ELp6E1DgT~hNl@$V!L}p_9Kl=+E4H9XLToi<(y9t|;;jf71(k$suOB^n z{<+`}tcD1u0~P_y#Kis2kBM;seCy>BPhFFf1%EQ*uqO-t=>(uJ&%fZBz@M2%Q^vrm zhdLOT(!eh~HA5+;*7VYa!mVbei*Y2&?zQ0&k zes^}WwCek#$k9k!r)BuX-9iqYQn3KxN=k|g)cNb=K?F9xq9jm}UBDw_jKsRsJWpCoPg^sG3Zl3=F{4b1wnU=GVB}t6PEI61OJ4dqL&Ad^HnmwsPYb+NotkdmlpW|RcYWCo}7UM&QFL}T`Y9O zOG^S6^TW~dnDZB&LPcHXGcXf6tV{{Iz&;SCk9t?3u7Wl1t1%$PIuCvIVyqc8#>oJC z==7JMl*M}a^ik*UDyx$|3YnC$Jv zEb;*ctNs9kqDl(fb2SOdAOVgfHU>NS1ptzICLavN2DDMt#Jtx1*P9kMI{`|>ki}JI z7ZI@V#tskADJ1#K5Ez~u_@kW| z*9-X9|4V>1y%<&=!mt27|KuD+VR8X(*(q>1EphcoOdHA=32-F_vh9M*mXz2gfoyr&b;Bl(WIQV|QGDxu74N50JFVp4MeE{a4xu<+h&UdC zrM`&yE`ergVWfY#eyg#eWQ2IEbg&CaTT!$*DEU94)tqVp^58rMO^t%6(&yY?jU+VY zl=}IPqm=uzUQcRBaXsL___=eB%htZ1f40PxLs<3xeSrTuJ%1p(tL+-VKdu05BHN$r zc;FyRXB>-YcclxzPZId-6LUO$)zqNgbFsjMi78D{DFMC$blL!^@#1U7Eu*s)9mY)P zafnrFfL3~>7ht`0{B=bj7$25K4MS*P&&nh9X~1-tY_~G7I-WFV+#~K;I_Ddt0FXT; zPde86i+eJmbTDMP=iq7~*aZA$PDFcLvWu(*hDSQzuI8Cb1pFlh{G%a*M6bVB@VDp3 z*zx|zs$klXApvmd9C2Y{)UPjGF7a%u+0PdIb6#z6qTs(4&%Y0Hs|5e*7e!&7|7V_< zugS5+NSm-OQo>3off z_`VAG#V4B~F;Nr29?{vrpY(cSIa#g2@`+bT&7%3@ujj0j~2&{qL?CEPunGXyRP!-sl%Y;2;4E zp^kNK>NdM`8ek?7XcklW5}}$i1YG8S3Bo=y&>(5ep+@c$FE=5Ogbabu7$jf9U#CsY z7AN#pB!s|S=<(O5u~PFqoJ+(as|fY)?}eKw5}||O zFClA^4gPy$q9E|>zTlbtE%^5b&MpFQQl3B8IM^q<_A~OrEv7#j0MG3UKKsOMc}pr1 zz{mn?kN|o&TH z2$Z&JE#O+f-zWLAch7%sObiG-dtLB_%O!@(v?(Gw*yqHv{Wk#q?ADp6I2GU@x|!Z& ze`Y59QQiMu0F0~3fX``3fFm)|pU>uso!KR9;fqxzp7~;Q$!Y-IVf|#~SxW?L`p_gI z#>-wfm#JR1j||v=BaReutAx-6>~s-=I*IVbxW%8@-g(N9W1aZC_0~VuXBN*u;1K-l z{}sQGma>sHG@(UqG{7HSC)8Ikc$TrFDN&}}pX~jnf`1DBu{-$h3m&>$dZ+j0P4!E7 zRyQd4HwnOLiTN|m$ns6=f+SeY!!y0uHGG zjz82405d>Hl868;andzvn4YFG{sz6yy78FZv}@cvl>>`Ti0u-!kY3G(CkBfg2v#A5 zR(#zzf7jDis!B{Wla!`I3VYDde56)n;#lNnEp!Ba zHBvFbCWm^B&=3C5lh4J+?ykUpSb6>rJ!`K3Ph_=nLdxm0se|piWo=f?sLTXF;M_` z`ufWAFHpBJr`_{+O1nLa)%_?yeErYAm@N#hH``yrvr9U^U`YUf8))^Xo|UFn^=+31 zxOAbwbPimf3ZA@Lwkph%j2`{ZDOOeNDl62fN#eI&aA0g>%&xVnMY=B$$92&O+)PW9 zW!(>r1IVIV0aIBG(|3Ma4>5Lnu=#$$VhU0kepAv7nWTOpqu^c=UWT-n-iiSDj?Khc z{%oVqv;&dqM@5$*5#8&UiRtTKuk-(6Rq8h&nmenr=b!L6sB9~DM!|oj0GvAT_xj&G zZiWJRMG$HAtHZ*OfX`KZ0)_+N{D^qfg#rR#E{c~B?33;)A@q9=zD!x2Q|=mi%vR3d zO7CRl`8U;o9C=Wq2)Jt=7L9(W?p(J}1f0Fa>Bo|!P`hux1cvXZA`U=MqEAf&%=@;q zOZ~)=oM)#%DBpSbImf#YBJo@*aR-7!RHOuyDqN~9Qt^9x$L0AV7X#AyFOX(p3eo=qb z3@6s|CSg)w#(H9C5?{via%TH8B>S`5i4ymmeNB?Nds~kzd2(Q23%EXObI%&NS%oHQ z>y$kJe-!)^4@A9|l?(ohkKD0mJpWN)9>qh?mQ|@=HPZVez+e01&M^2dR@$)hIy-Ys zejFZba7tA~=2Y6kqA>ldA9`wzmyQIlyLo`~V`6tiJax^q4lbxTDg(QTw0g6yb|PIz zru$x0{# z`(wAqqcuKVr{I zG4}Azy(->MGuY=3UlcrlVAuI?!G9f||Kh{LPU~zF;Ga4#AiLC0GLNM!U4qG{5daTA zTjJ$I!FSy=G+hJF7q~Vtc>$#m14>wW49yH}kpNg->1^ZUK<&2ubbpq$_alzQTubL} z7BJM>3rg)v%;|{k;Y2O<$k#xLwN^k5OGXbFK%28@2TF!Dhd4kgO53v#I2(o%df&Ua zf^@hEsc$glHJeJrZ`XW4DH1S?I5s4W$w+tUi|F$Nm{w8{o+ z@0GsMD>;c!3_TL(cwpZ^pL#5mLGs`^r?_g@t=tLeXQ}l8bf*FQT`dV*)svwkiFK@$ zXQBR%gEoC6m%-`W3dL{wGvr(E8CU})YSg79WMO!hC*0Hf6QZ?( z)4hHl3ejtOQ!1esvHlXkg)wo*p6Tkhko>>=T#0E3>>nF+E8ve&G8p1^-B(Nvu)JHkzZHERiWi~dbgp1* z^UFC2>0(Qq4Rh%q0W2*tV3P={&)xcO38)4dG)p2u4uI&6w~|U<~`!(iK*=$7Qp3wljZ;HzF;x{2Ch;=8~jORudXfl ztDLIg*#rODLlQ|o8IymRQ-QFO!TsK-)rd!oJSG4hzFgw@1Hl_BHQ?NsI5#4$9t)nn zUSd|7lEK0SO^l%_1CV2T`}8bKNpwilo~0hZ*CCmFglrr`S{yxBF#{ad4uMj(;C~vxA9N6a8?Vkk2mJfFCe};j7+2QwM z-zs?ZO-2p4Fd=q^1H5!p;>AP3v_=Hd?u!B6lZs76Z#x~G_uiEV*q*;bBe%XR)UN?o zhri}_5-mk$Krd}-zNj|wh7zXku32mgiw(02#Cjex&X1?U_672$x;I;=O$ ziM?d5Hq~fgzV_A2CBFGWi3jg8vjj|7pukNNR79Y}tVCN8P+@H-BoMP}?h~ZR_#JXB zmY3eH>t9+gN2an<6%hSKwZ;C1nWY2`Ml`AW|{QEg=58y9-UsHeJFA;Sx z?QnrGP848PizVi-tbiZ5d572?nj}9GIGzDtxnkP+5&^G&3;rhx{tW_f=D^=c0@mgE z>*Lt|N5^)8d*F17TN)3mSprYZar;Xp?z^SH?R#}1K)ie;c=6C=)fP1Wh?>7dVg^yW z)|Ck4K$F$az()k^tTS5`D4G%{GZO6T6UrELEo}qsszHzr9$#;o*x3hvS@$*d1OB2s z4wcs+xd3C;_0w|=5&-^!z`+c7{A!8EuL_Rlz>te-0LHg5+3jUfci*qXQoqo#hG)|A zZ~d+CHu`3-7a-Z|uvH!xOQWwf%UiSvzIZbX?-4L&3DH z8V)g44d`Om++f~!SfHKs=N9Z&p#e5M^g0Qvmm=E58!3`7ZFPWNh<9lSK8qnpSkoHs z>ZE~x-QX{qxTfylF9~~3n>~^R{*Hz|^Z@^?8d_$69~JPk1^fpylk_)aU~si9aCGtd zZv^mXKjAHA?3v-22mdsD?rF12I{4eysZ;_`b8<&ju>bOP!E+T6xOYJWM#SyI0WMAi z*N#iGL5z=aXFt&)m?dMlS zU}s27h6QdefrF{w%7Nf$CYV=WE|^|G!R(ioM+BPL^Hy5FrhidO{;#|Dgg1uou-0Pt zQ4)oHaFB*({NDj36a}(T^;X2HLXfp=g2e3=oq6whu$q1dJzsFv2N3D zw~n}Q5SAm#X#oAg4smg8%9M@$UCO zpO4KS7VsUrEsa~HiN49H8dbnL0HeqqAp`cge9a3b;NUL_g3B<+@(DE7Cq^1lOKBy| z2u1sKNc=LS=Sn>f&(J>wCLW7P*OV}^L=P-%Uu1pn&ntT{BCt0B_J*c`&!8&jo0Y`z z9C+edCh#x!ERzx%(@pCZ{8NrKydgY)m#iexzr#b9w<`H>(dCKvRqdH2Q!^e018!@n5Lc{~TM90QNOSmLE)!E|m2 zK@<45;C~ju9{~7P7+-ve1zQmFaiB}k;q(PLjDkZ#WLfm(2ftz-S z$zXM*vyzyVz_p_ia{yNl1tm5H_#K_9CpxUiS1T|))xo*L~QUE${ty2pA z%hEepiBTcUi@o81K=WNyzrHSId(_Do#%+#_6ppxTVOmen}26m zKwvU^1%hiwg0d7`J(6WSa9+*wEZ80&n@+bF^!cQr;`knGU8)d2u0)cuXeR|a69*A+ z<|KIUosVHO#bM=&i#I}XB;sA{OrZH&^diG z<*iikO4Dp-F(Ye*Mgzg! z7Y5iF88R?0S2E%8Oh5vMGr_^sY~YuVWI5M+Ez_sPC2xs!bZ*{1gFfipOh}&U-Ka<1T1Z$Bdy4&;$XLR6Yl%>Sf&ln`XGn zpg^J>NR$9atk>e#Z*DYL5xt#(@$f}}i(~WqqFA*W9~9;o$0hK>fg$@Z9|12MncppX zi4>~U9rpU0;LrROwFUp)!M`E^FXf}-S!(Z_Ljtl&{iORtu`3xg>Xc?gXEl9Gq>}mz z6U)1GkGN?<+_Xd7yjx&E<0+ISP?oX;ndAAYFTue~a5$AE;1>k;r@-M<)RjF8WIJG^JB9IOEGc%VPW>QlmBdrmOB~OQ(8=*+*18cBT~DZsPW z1W#Qx{kjXzaq|vw%dX-7_gpNNMqzifI_+dg$fUUoW~E?OQq?W6OQM>3xuoQ0O3VvQ z8d22a=IDt?#Y!)v<5p$Qo4${nMRq-wBjzPtuczZ^Kmy}Iwa02hK#JNaj_0OEe^3A~ z9td7MG^G5=Yl5;gQa>Q3QyHNn%@<{(V=@4~>m>SBR{f_X{YvJ2d@ zSD3Itb-eKaI5!SGVtPdB`t{X?$4qk+1$f56l73bZHfgcVA-(QkedM?Yxv;lm>8_ex zjR_^_>30I6bw212iH8Aq(_^=KekJhawGw3s3T5Ok*8 zizWiKq?axDpMLPqBLHW8s$Yx*^aB3%1t8rXN$41&5g_8d{l(%Li&mb-t6v@O51uap zh#6fx07irP(zMP6xMhd9b&n=#&|zBWbIDr06{<^X{*2{%7;GY>E+=BmFxaF`9D{$sU`ua#fuizhb%MxPAzu97xN{cPFX2VydAsp-4j^N20zrhoaSdMm(Fh zem&`pS!rL8+p5E!(3j`mr|i$(Y?|``p>jR;dLhk>1)GPblQgTVC4phl zZi+A-pw&9u77_JbzNojOixVcaFYW{Q(;$T17w`=T{%Hi@Mgf1@v(CzmN=;gclYr>G zwRdww4PXYb341JJAug?MhIQqjy@VZI?MMfJX=Pe>`wF@+Q#{Xdc_>$lzq)&?ecirk zZlUL@>>)vyIml?&bV_7@Kjt#1_@tdCrN}YY^JkEkCxO4zSYyB-h@%cS+-r#$21kR2 zzUh^jHT7HY-zfO&3BZj8{*5=ATIiBHx0woGL~$Hy)Bpxgt%EetZ&Hy2BUGyy6c>BZ zDkc_aOV|K2I(xy8>9Ravu!QZ0M&|Gx z9bt*J;1mtH3GFCJUr;qqBv>679t+^OpNQguexz}UHGie=Q;8_dG;f+~*vDbdKkgj6 z?>VnLFV^Ts`%Mi;pvnd*WCZnNO#zQg;E#fTX4fTl3?f7;E!F`3WG~xcqu^iN+wheQ z{%xbOUhr?8uX8eE%kB2W{OcVBlk*a3p{C}V6eE3;0Y5bFnJF!Anq(kmY-xdJOhxHo zZHjdbc7{eg!`kc7{nxdD~hd#yITnxvN$Y#m95ZL9F>~KtJ9nvAe zT3Lp45Q4rpsDHv7qqEl8VNGo+=HIUM=(iJTxBKfj#!{h#NZ{_AgKPv zK7fBIdByD=HAHU<{$~RGn*?AB{*KkIZy3}K{1ZIjAo$l`c*5+1m>QtC7H7q^Yt^aM z0Q+5pDkpr_HTLdwaS;0xVzn*M5iMOGgDv>?XIsL9r+cz3jghw+IR)Vi(gY*u9f96A z>h%HsOhMT#_-_LIR|H@S{vjmw_v7ys{8PMH>i#nYZ0$yL2}FRcFHl#?sJ*tN7O{cn z8O-o@s}9j@f42J{=&Bs)d3SdI`t^9mHwO4qwXAzLux!6SW_kNDa+>l{w#mE-@kDh^ z+>qC=x^wop5njRIZwSB^{NsP=5Tnn(Hy;8sP*q>^Bkow1K~q0Bpg(1BkBe-ij#tCbg>+N&B*+Q?I_pIU}i{P&5?s-ar@6 zKW0ZePVnREb&ADJ1nQ!$z{Td=nv^|C-F?gMqGArts(H;N~5k^;CHm1?gajwvi(ye zq%HV&;a|h8=ilMQSR`Qm;BPN0>38KwB0zRBs^R85>~gJM+22nB*4NwL)%3m=Q}H#O zN^EQvbPlC!gP%0;cg)x7*|zvTz9`0*Hd?cv*Vs9ioyxyy5=hyH3gxS2=%Au(!T(Hv zf4%~+1^*Ta*c|xVi%a@@e}T{j`&@P2-I>r8-X1C>G4S^j4{l(CHUW}t*V3*flmzi4 z*ZpU&n?C=Mb(p8XhGl1hwOF7OYcizkE-dmP%r z4m*cW^zX%cF4w(DfBQJJ-k1#@eS&{xhJ0N;O9Fp(e9(;C-xmB|8Q{+h0;pFzw+L?1VB5~`NxPrCuO7N zRj(cVGsq1iUbQw^)93Z(dRuF4@2kzex9SX&RDd4ApZyudUdsKFz`tt~9J_5~ibGMo zBqGzfppx7$A8F1S_;Wq2wa*UtGm!vn!9VfdxEcVnG4OA>4E^38d-l1Ky+*xD zb+61#n2;7?W?Gc3sW9VB%(Ptdj=@Y>W}5lU@Ap3Q-rwK9&$FHLe81;8&pGEAsmWnf zg-5k~KKc@N&&-1Ay;}dP7ugi}tG1UfJ6>qBcZwLpf6__8-P%wUS6zL(ChBp~s43qb zJi12#1Zbmyq(}i`hG*#|N0&u>@n)~qAA1E?&*GZWWjgOpw%J1wKOz~mnj?D;cLZ_R zUt=ydCuzBfcE$K8LTTBWsqv&b!o+@)H95MjOqaufL@E@{GBA??F#^2VXC{#|ES|_c zR>{>p{%G@v?!xz3d-~7xpo1qT*F8|adb22jO7`T_WM8kd*uArvlGtlpUDco-TdQz5 z?GY85i(~Bgv;I6#&|CmzP?F_?PbR`?Xd-RzLW;-pk5uL=^Ot#eF$;gjQL9q2`We7G zaW>*{#*EMRALR}fJ>0dY)myj%c<9%D+*ZLfkx(=``*O)w{5a|12PJnDvlCb}eu2mP6u< zZSAy$kEPAoB`5W$=53ON7||6@A@%7~@1l8@fovk-E|N3v6FN8&)0GXt!oDYmZU%ad zMuU5(yuguG@883%1g~Lh>ibup@RPaXEsIXAK6~uu=@~a%xZh%1E{*1*lg=^>f>ioW%I3>(ux61J2iwr6RZu(fTGyIF@2WBoDwgn z7@p%}paZ}d5}syBv9Vpkt^e0Xu+uNT)!pSyQNIIiy*cku3I zd-P=vyijK1j_(TQ)09)&yZxioka}AlFe1RJaFZekme-DJAZt5LW8?O=s1jZt;yjDy zn74npwoUR9mX~Q#(P)or=3U8yA`4a~iv4L7ry55UQ741c#gpRE(!eD$sJwaBIBpp* z#o+&CrHY)4{G=?5(ahV{7mfEHy$I@4;5b5=@Vymx{w7{{7{0vYt(Ndl2!v!BnO{&J z`Y|O=i2NpU!U`BWoD-?2$1-fJ3WSbVfO}#ogA`nzaw_J=r?P>kD$vc-mp&1qihXmQ z@eXSm|4Q5pb5%CB^`!ebR{r5;W%+xXc=l^Ar2u<xZ z2D_TD+$gw13iM-a@n!| z4^it<=?pWp5kQlT&SRDVdF3~H_cTy33bW_nrke^3C1jDiU9>xD-MU?6>WkUkvyDb_ zwcJQ^()CNYPUWj+75N;&>oAH&CQ==|i+KKt2$}jSNuZ(?G6>MsOoXTlhg*2=!@ilN zGJ8^bGlQ?sqOEe?U6&U*>E`k((ADPWZMQEd;a8g}xR|-@VN0|1_sbe8<;&kr>%i5a z>Wn+Re+TB{7=c58ih86786bzaP3Spg@CEhQo|{I;@=a>@oPNEg_+4zgzqrUBYq2`x zP1bIy+WbCbGL~*|*P=u5t^0~?fAtJA2x2jHDV+3D;=c}M2FVq$XK46`{^?Qn3p3b#5HrS&ll_P&H{AGB&zWyU+tW5|04`brc zS~Ss53x1ku1|Zxp<=jR9YmFQE>3_)*)nNIn&ODaE6ZYt!*H7P^LoXstW|Xa8)tC=| zyf|g1Lkif5j#n3%TV9@qtg{Os=#l$+1be#ECI*|9{DvWtwcYX!01@fqI^ei0q>?)+ zVOTauDRgB`h15e|-j>%nVX}Qz&&k&$KENBWs7o||i+lx?Q0~l0Na$)Tp2)7%lnB=F za_CaiqZ~dXFcug=;SG?t6hU+_==n@Ze;#hz-IFO>x&-m)VKy~~ihBiL5@ChURqiyu zoJg+u$6<6wtDvO7vFg8j8)0+HLN-r;W#t&Hyaj{6#68X zpPsrG;M-6hPDVOg`2zF{`P>nT2YA-Q;e?H_PrugvFrj!cJIjHtqqoqFnf@S|o%*f5 zEhWK&M}p4w+VTbeG?0(_OQ*M96$#hME6yiNR5XMgR7z%liUTq`9##mX;@>SUK?DL#0kW~YkuiPDlif5^fL7|J?GRT#*GXN%4VNmuU6Cv&9 z3pVC~WJRM=p$W(V)Jm?`8_h_nt*x62Nyto_?9(qP8S*4*!g@Vyz)x>?X(`orI>FbNxmCA^kMALvA| zoW$hTh(GQ)>al1mONF6)+$4)xFYS6z9%4Ktj0H&O4_#&~lNGrh%OQUEn1vLmpfb~# zx8#$DTmGmEfN-J!vXerBo*vxe#tJMTYdq+^zI%3mZrz+e8Cc^kUjj4`!rFG}vM8Y! zrN4%#3&lmwbKcTTFY%~yc(4jTW--}w(%AMy#zWvhkVP`2heeVP|1l|s(=>0o3L@TX zth@ywV-Ue@rpTMB0ayK3d#L&(d3@l!l8p`p! zx`s?0FP}JF5FoiJ2uXb2$jj;~%=(krx-aU;%DaIl496^Y0|_t_*&nS2l}fluIh#9G zobGP|ev{;H(b`rHCC>O~W{JsB>WnBAkrnM=Km*EYs^exj+__CAj`3TR#POK#^Ja(X zS;gV5ws*$=vcR?tDt0(w76upaiL{jdxN_o`65CUueq-mp>~x&idGQ;HbKGcfMarblUI24)xKjc!Zk^lez literal 0 HcmV?d00001 diff --git a/rsync-studio-licensing/public/icons/apple-touch-icon.png b/rsync-studio-licensing/public/icons/apple-touch-icon.png new file mode 100755 index 0000000000000000000000000000000000000000..14183aececda33f4188e024eb80fa45ab847dcce GIT binary patch literal 22309 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ν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%0ADQM#B&j(frZ(L@qO<)yW%n4@d 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 Q2mk;807*qoM6N<$g5J*>zW@LL literal 0 HcmV?d00001 diff --git a/rsync-studio-licensing/public/icons/favicon-16x16.png b/rsync-studio-licensing/public/icons/favicon-16x16.png new file mode 100755 index 0000000000000000000000000000000000000000..32b6caae0d40c8640293f6102e736e1779acae28 GIT binary patch literal 669 zcmV;O0%HA%P)m`b~@`AU_5R6f0GV|TuE*I}NQFl#uJyq4G>gfL0Z=@__kRY>RgOyke_Z}VNt(esaR~{hqH6dfvG<!bB_l(Um7dqa%zTo*sJI-wy0sBYE$3LuiX}9C-MsR1bBCOLXXjlLM#H7Ns z6Z?lr(n#Qs6IeEw_X+=op6-Fc5EchVJ>MLx*t<}9^TQckxoIhhexHcnctaA9W!q_%AXc7-@21(oNgD00000NkvXXu0mjf DsE0UR literal 0 HcmV?d00001 diff --git a/rsync-studio-licensing/public/icons/favicon-32x32.png b/rsync-studio-licensing/public/icons/favicon-32x32.png new file mode 100755 index 0000000000000000000000000000000000000000..c9f33f98dc773cafb483e0c25a006a26b78663e0 GIT binary patch literal 1865 zcmV-P2e$Z$P)S175yw9>Ywdl`J@=J&(%!47A$Un`lhXQVDG~9PfTALz1^vli{7D4Se?m|Y^>;xO zG~f>^h#-ne2&s=q6Vf#Hfz7K;(zLm`x%WKw-fR3}*4}sDP!H_0_Bng6nOQU6neUA3 z`|eE>0YvZ>L_o;*7?A%HBfkn5vSUxXQL-!nQA9!ft9z%fFaBTUxN?7NJCyrx$!lw= z`Nk~60FeY}HrC%0%ni%$#rIckS%_g~h#8`w*@#w<N zL!|XU>(;CsXi{QWz^H&CC_xPsK~+!z$*YISEw{Y8U8@A++L)z805>FiuMKN#T|5DenMhd|+2#aR^N^ zQtRCeB2mBG6Wf6C0DxNFgRctg9SOrixUtdqk$WzRSO>T!8HbjH#Ua#<5d%aOVh}=5 zVvu|(A{hk&ngN*%l9^x0FpN4um0+QS{qw@D&D6Rb#Lyf;3>Xx!dn7c;hzdb*g;6P@ zGAIH_V5?SUNeID1QYF}`-JmimMF?n6#IYuYYuopZ;r$(-$Tz1So=S`&=>zA$5gCMKBRJB4~E8@Qvq2oLVaZ*qp)T z+cnqkJE&Hc0>=&n76-x$$4eerQhsn|!r!koe0&xD^m@&Fshxc73YZbwq9bM*Odgw{ z4!SA{Uw&%HskIU_xOA)G=l`B^Z9UPLr*P1U)n(+hfwXZ>hX=D82!i%oT9*aN!7%Ts^y#-PV^uD3~RrM-pwGfBI;_iAM|m_-e(q z^~85h4%t8Nsn_z5nNTRaH!*(l;*3kT8=hSa9NnuFL9nj!^_1rjI0$?7xuv`W%oW1? zKrw@9U`Cf}J49~B9CU{VIB#zHB4?WvM7 z`u@?tulZ7#FC1Kj!V6Cne10u*{GjrW8;zIt%#ij_7(~?TK-bTq&e$SsOpT*^m7s9? zr3nB}9t?c@`2qXpg^ihUe`;(@jg6VHcTV``CrXYV^fGnff=6c2<)UcHOmnkBw+e2&L5P3)c2UcF+0VdlTcecN6EX*SvYJVOV%K)nw(#99KbvhHd4jAV*P5egE1GJTBo&>N)U+Al}#IWcbiEGNTQTM zS)aL%7`L;otAyU6!riekEQI+oP(lHw}rlrB=Ez&Ddtv_Jj##eFk@@8GPCfDcOKl zd24~@(dqV1 zO;33@8}3lvl5A&4kM_FzK36|Pu@Bw%NAic2i@^T?=)~E-EHfmz00000NkvXXu0mjf DzgK|Z literal 0 HcmV?d00001 diff --git a/rsync-studio-licensing/public/icons/favicon-48x48.png b/rsync-studio-licensing/public/icons/favicon-48x48.png new file mode 100755 index 0000000000000000000000000000000000000000..c027bec1faa7a054c4daddf3ddb647b4f9d78cde GIT binary patch literal 3476 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 literal 0 HcmV?d00001 diff --git a/rsync-studio-licensing/public/icons/og-rsync-studio.png b/rsync-studio-licensing/public/icons/og-rsync-studio.png new file mode 100755 index 0000000000000000000000000000000000000000..4defebc9c1cb787afe343cf04f280d863781eb31 GIT binary patch literal 86623 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%0Aog3Rh7aO~}<;}bkZ|Bxi%dm8E6B=P>Y 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 literal 0 HcmV?d00001 diff --git a/rsync-studio-licensing/public/icons/rsync-studio-icon-128.png b/rsync-studio-licensing/public/icons/rsync-studio-icon-128.png new file mode 100755 index 0000000000000000000000000000000000000000..54c0cd7328a1cc1caaa093712818e4ff9825181f GIT binary patch literal 14049 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 TU6yfc00000NkvXXu0mjf6XbZI literal 0 HcmV?d00001 diff --git a/rsync-studio-licensing/public/icons/rsync-studio-icon-64.png b/rsync-studio-licensing/public/icons/rsync-studio-icon-64.png new file mode 100755 index 0000000000000000000000000000000000000000..42762992e93e95a1ddd85757ed1be66f6f0ed006 GIT binary patch literal 5299 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 + + diff --git a/rsync-studio-licensing/public/index.php b/rsync-studio-licensing/public/index.php old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/public/robots.txt b/rsync-studio-licensing/public/robots.txt old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/public/site.webmanifest b/rsync-studio-licensing/public/site.webmanifest new file mode 100755 index 0000000..6878693 --- /dev/null +++ b/rsync-studio-licensing/public/site.webmanifest @@ -0,0 +1,13 @@ +{ + "name": "Rsync Studio", + "short_name": "Rsync Studio", + "description": "Native rsync job management for macOS.", + "start_url": "/", + "display": "standalone", + "background_color": "#f7f9fc", + "theme_color": "#0b1220", + "icons": [ + {"src": "/icons/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png"}, + {"src": "/icons/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png"} + ] +} diff --git a/rsync-studio-licensing/resources/css/app.css b/rsync-studio-licensing/resources/css/app.css old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/resources/js/app.js b/rsync-studio-licensing/resources/js/app.js old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/resources/views/admin/index.blade.php b/rsync-studio-licensing/resources/views/admin/index.blade.php old mode 100644 new mode 100755 index 8df543f..b0e4829 --- a/rsync-studio-licensing/resources/views/admin/index.blade.php +++ b/rsync-studio-licensing/resources/views/admin/index.blade.php @@ -1 +1,6 @@ -@extends('layouts.app') @section('content')

Licensing administration

{{ $licenseCount }}

Licences

{{ $activeCount }}

Not revoked

{{ $activationCount }}

Active installations

{{ $userCount }}

Portal users

Manage licences@endsection +@extends('layouts.app') +@section('content') +
Admin

Licensing administration

Manage licences, activations and customer support.

+
{{ $licenseCount }}

Licences

{{ $activeCount }}

Not revoked

{{ $activationCount }}

Active installations

{{ $userCount }}

Portal users

+ +@endsection diff --git a/rsync-studio-licensing/resources/views/admin/license.blade.php b/rsync-studio-licensing/resources/views/admin/license.blade.php old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/resources/views/admin/licenses.blade.php b/rsync-studio-licensing/resources/views/admin/licenses.blade.php old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/resources/views/admin/support/index.blade.php b/rsync-studio-licensing/resources/views/admin/support/index.blade.php new file mode 100755 index 0000000..db55a42 --- /dev/null +++ b/rsync-studio-licensing/resources/views/admin/support/index.blade.php @@ -0,0 +1,24 @@ +@extends('layouts.app', ['title' => 'Support Inbox — Rsync Studio']) +@section('content') +
Admin

Support inbox

Customer, licence, billing and privacy requests.

+
+ + +
+ +{{ $tickets->links() }} +@endsection diff --git a/rsync-studio-licensing/resources/views/admin/support/show.blade.php b/rsync-studio-licensing/resources/views/admin/support/show.blade.php new file mode 100755 index 0000000..4248c64 --- /dev/null +++ b/rsync-studio-licensing/resources/views/admin/support/show.blade.php @@ -0,0 +1,14 @@ +@extends('layouts.app', ['title' => $ticket->reference.' — Support']) +@section('content') +← Support inbox +
{{ $ticket->reference }}

{{ $ticket->subject }}

{{ $ticket->name }} · {{ $ticket->email }}

{{ ucfirst($ticket->status) }}
+
+

Request

{{ ucfirst($ticket->category) }}{{ $ticket->created_at->format('j M Y H:i') }}
{!! nl2br(e($ticket->message)) !!}
Reply by email
+ +
+@endsection diff --git a/rsync-studio-licensing/resources/views/auth/forgot-password.blade.php b/rsync-studio-licensing/resources/views/auth/forgot-password.blade.php old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/resources/views/auth/login.blade.php b/rsync-studio-licensing/resources/views/auth/login.blade.php old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/resources/views/auth/register.blade.php b/rsync-studio-licensing/resources/views/auth/register.blade.php old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/resources/views/auth/reset-password.blade.php b/rsync-studio-licensing/resources/views/auth/reset-password.blade.php old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/resources/views/auth/verify-email.blade.php b/rsync-studio-licensing/resources/views/auth/verify-email.blade.php old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/resources/views/checkout/buy.blade.php b/rsync-studio-licensing/resources/views/checkout/buy.blade.php new file mode 100755 index 0000000..6b4ea18 --- /dev/null +++ b/rsync-studio-licensing/resources/views/checkout/buy.blade.php @@ -0,0 +1,91 @@ +@extends('layouts.app') +@section('content') +
+ Rsync Studio +

Choose your licence

+

Every subscription starts with a 7-day free trial. Cancel before the trial ends and you won't be charged.

+ @if($paddleEnvironment === 'sandbox')
Sandbox checkout — no real payment is taken
@endif +
+ +
+@foreach($plans as $code => $plan) +
+
+
+
+

{{ $plan['name'] }}

+
{{ $plan['billing'] }} billing
+
+ @if($plan['billing'] === 'Annual')Best value@endif +
+
{{ $plan['display_price'] }}
+
    +
  • 7-day free trial
  • +
  • {{ $plan['activation_limit'] }} active Mac{{ $plan['activation_limit'] === 1 ? '' : 's' }}
  • +
  • Secure online activation
  • +
  • Licence management portal
  • +
+
+ +
+@endforeach +
+ + + + + +@endsection diff --git a/rsync-studio-licensing/resources/views/layouts/app.blade.php b/rsync-studio-licensing/resources/views/layouts/app.blade.php old mode 100644 new mode 100755 index db27fb8..699b519 --- a/rsync-studio-licensing/resources/views/layouts/app.blade.php +++ b/rsync-studio-licensing/resources/views/layouts/app.blade.php @@ -1 +1,315 @@ -{{ $title ?? 'Rsync Studio' }}
@if(session('status'))
{{ session('status') }}
@endif @if($errors->any())
{{ $errors->first() }}
@endif @yield('content')
+ + + + + + + + @php + $pageTitle = $title ?? 'Rsync Studio'; + $pageDescription = $description ?? 'Native rsync job management for macOS. Create, schedule, watch and review reliable local and SSH sync jobs.'; + $canonicalUrl = url()->current(); + $socialImage = url('/icons/og-rsync-studio.png'); + @endphp + + {{ $pageTitle }} + + + + + + + + + @if(app()->environment('production')) + + @else + + @endif + + + + + + + + + + + + + + + + + + + + + + + + @stack('head') + + + + +@hasSection('fullbleed') + @yield('fullbleed') +@else +
+ @if(session('status'))
{{ session('status') }}
@endif + @if($errors->any())
{{ $errors->first() }}
@endif + @yield('content') +
+@endif + + + + + + + + + + + + diff --git a/rsync-studio-licensing/resources/views/legal/cookies.blade.php b/rsync-studio-licensing/resources/views/legal/cookies.blade.php new file mode 100755 index 0000000..b46c1cb --- /dev/null +++ b/rsync-studio-licensing/resources/views/legal/cookies.blade.php @@ -0,0 +1,16 @@ +@extends('layouts.app', ['title' => 'Cookie Policy — Rsync Studio']) + +@section('content') + +@endsection diff --git a/rsync-studio-licensing/resources/views/legal/privacy.blade.php b/rsync-studio-licensing/resources/views/legal/privacy.blade.php new file mode 100755 index 0000000..04866ae --- /dev/null +++ b/rsync-studio-licensing/resources/views/legal/privacy.blade.php @@ -0,0 +1,39 @@ +@extends('layouts.app', ['title' => 'Privacy Policy — Rsync Studio']) + +@section('content') +@php + $legal = config('rsync-studio.legal'); + $retention = config('rsync-studio.privacy.support_retention_days', 730); +@endphp + +@endsection diff --git a/rsync-studio-licensing/resources/views/legal/terms.blade.php b/rsync-studio-licensing/resources/views/legal/terms.blade.php new file mode 100755 index 0000000..617f52f --- /dev/null +++ b/rsync-studio-licensing/resources/views/legal/terms.blade.php @@ -0,0 +1,19 @@ +@extends('layouts.app', ['title' => 'Terms of Service — Rsync Studio']) + +@section('content') +@php($legal = config('rsync-studio.legal')) + +@endsection diff --git a/rsync-studio-licensing/resources/views/portal/index.blade.php b/rsync-studio-licensing/resources/views/portal/index.blade.php old mode 100644 new mode 100755 index f43bef1..c6f1ea5 --- a/rsync-studio-licensing/resources/views/portal/index.blade.php +++ b/rsync-studio-licensing/resources/views/portal/index.blade.php @@ -1 +1,113 @@ -@extends('layouts.app') @section('content')

My licences

@forelse($licenses as $license)

{{ $license->product->name }} · {{ $license->edition }}

Licence ending {{ $license->license_key_last4 }} · {{ $license->activations->whereNull('deactivated_at')->count() }}/{{ $license->activation_limit }} activations

{{ $license->is_usable ? 'Active':'Unavailable' }}

Manage
@empty
No licences are associated with {{ auth()->user()->email }}.
@endforelse@endsection +@extends('layouts.app') + +@section('content') +
+
+ Account +

My licences

+

Manage subscriptions, licence keys and activated Macs.

+
+ Buy another licence +
+ +@php + $activeLicences = $licenses->filter(fn ($license) => $license->is_usable); + $historyLicences = $licenses->reject(fn ($license) => $license->is_usable); +@endphp + +@if($activeLicences->isEmpty()) +
+

No active licences

+

No active Rsync Studio licence is associated with {{ auth()->user()->email }}.

+ Choose a plan +
+@else +
+ @foreach($activeLicences as $license) + @php + $activeCount = $license->activations->whereNull('deactivated_at')->count(); + $isDuplicatePersonal = $hasProfessional && $license->edition === 'Personal'; + $billing = str_contains(strtolower((string) optional($license->product)->code), 'annual') ? 'Annual' : 'Monthly'; + @endphp +
+
+
+
+
+ Active + {{ $license->edition }} + {{ $billing }} +
+

Rsync Studio {{ $license->edition }}

+

Licence ending {{ $license->license_key_last4 }}

+
+ Manage licence +
+ +
+
+ Macs activated + {{ $activeCount }} of {{ $license->activation_limit }} +
+
+ Subscription + {{ ucfirst($license->subscription_status ?: 'active') }} +
+
+ {{ $license->subscription_status === 'trialing' ? 'Trial ends' : 'Renews' }} + {{ optional($license->current_period_ends_at)->format('j M Y') ?: '—' }} +
+
+ +
+ +
+ + @if($isDuplicatePersonal) +
+
+ You already have an active Professional subscription. +

This Personal plan is a separate Paddle subscription and could be billed separately. Cancel it if it was only created while upgrading.

+
+
+ @csrf + @method('DELETE') + +
+
+ @elseif($license->edition === 'Personal') +
+
+ Need more Macs? + Upgrade this subscription to Professional for up to 3 Macs. +
+
+ @csrf + +
+
+ @endif +
+
+ @endforeach +
+@endif + +@if($historyLicences->isNotEmpty()) +
+ Licence history {{ $historyLicences->count() }} +
+ @foreach($historyLicences as $license) +
+
+ Rsync Studio {{ $license->edition }} + Licence ending {{ $license->license_key_last4 }} +
+
{{ ucfirst($license->subscription_status ?: ($license->revoked_at ? 'revoked' : 'unavailable')) }}
+ Details +
+ @endforeach +
+
+@endif +@endsection diff --git a/rsync-studio-licensing/resources/views/portal/show.blade.php b/rsync-studio-licensing/resources/views/portal/show.blade.php old mode 100644 new mode 100755 index ff70c71..1832157 --- a/rsync-studio-licensing/resources/views/portal/show.blade.php +++ b/rsync-studio-licensing/resources/views/portal/show.blade.php @@ -1 +1,80 @@ -@extends('layouts.app') @section('content')

{{ $license->product->name }}

{{ $license->edition }} · key ending {{ $license->license_key_last4 }}

@csrf

Installations

@foreach($license->activations->whereNull('deactivated_at') as $a)@endforeach
InstallationPlatformVersionLast seen
{{ $a->installation_name ?: $a->installation_id }}{{ $a->platform }}{{ $a->app_version }}{{ optional($a->last_seen_at)->toDayDateTimeString() }}
@csrf @method('DELETE')
@endsection +@extends('layouts.app') + +@section('content') +@php + $activeActivations = $license->activations->whereNull('deactivated_at'); + $billing = str_contains(strtolower((string) optional($license->product)->code), 'annual') ? 'Annual' : 'Monthly'; +@endphp + +← My licences + +
+
+
+ {{ $license->is_usable ? 'Active' : 'Unavailable' }} + {{ $license->edition }} + {{ $billing }} +
+

Rsync Studio {{ $license->edition }}

+

Licence ending {{ $license->license_key_last4 }}

+
+
+ @csrf + +
+
+ +
+
+
+
+

Activated Macs

+

{{ $activeActivations->count() }} of {{ $license->activation_limit }} activation slots in use.

+
+ {{ $activeActivations->count() }}/{{ $license->activation_limit }} +
+ + @forelse($activeActivations as $activation) +
+
⌘
+
+ {{ $activation->installation_name ?: 'Mac' }} + {{ $activation->platform ?: 'macOS' }}@if($activation->app_version) · Rsync Studio {{ $activation->app_version }}@endif + Last seen {{ optional($activation->last_seen_at)->diffForHumans() ?: 'not yet recorded' }} +
+
+ @csrf + @method('DELETE') + +
+
+ @empty +
No Macs are currently activated with this licence.
+ @endforelse +
+ + +
+@endsection diff --git a/rsync-studio-licensing/resources/views/portal/welcome.blade.php b/rsync-studio-licensing/resources/views/portal/welcome.blade.php old mode 100644 new mode 100755 index c40dd42..ef03706 --- a/rsync-studio-licensing/resources/views/portal/welcome.blade.php +++ b/rsync-studio-licensing/resources/views/portal/welcome.blade.php @@ -1 +1,147 @@ -@extends('layouts.app') @section('content')

Rsync Studio licensing

Manage your Rsync Studio licence, installations and recovery options securely.

@guestSign in@endguest
@endsection +@extends('layouts.app', [ + 'title' => 'Rsync Studio — Native rsync for macOS', + 'description' => 'Create, schedule, watch and review local and SSH rsync jobs with a native macOS interface. Start a 7-day free trial.' +]) + +@section('fullbleed') +
+
+
+
+ Native macOS rsync management +

Rsync without the command-line friction.

+

Build reliable local and SSH sync jobs, test them safely with Dry Run, schedule recurring transfers, watch folders for changes and keep a complete run history — all from one native Mac app.

+ +

Personal for 1 Mac · Professional for up to 3 Macs · Monthly or annual

+
+ ✓ Native macOS app + ✓ Local & SSH jobs + ✓ Dry Run safeguards +
+
+ +
+
+ + Rsync Studio — Jobs +
+
+ +
+
Sync jobsSync All
+
+
DeveloperReady
+

Developer folder → remote server · SSH

+
+
+
+
Web Sites22:00
+

Sites folder → remote server · Daily

+
+
+
+
Project WatchWatching
+

Project folder · File watch

+
+
+
Last run: Successrsync 3.4.1
+
+
+
+
+
+ +
+
+
+ Everything in one place +

Built for everyday rsync work.

+

Keep the power of rsync while replacing repetitive commands and scattered scripts with a clear, repeatable workflow.

+
+
+
↔

Local & SSH sync

Create local copies or securely sync to remote Macs and Linux servers over SSH.

+
✓

Dry Run first

Preview changes before files are transferred or deleted, so risky jobs can be checked before they run.

+
◷

Flexible schedules

Run jobs once, hourly, daily, weekly, monthly or on your own recurring interval.

+
⌁

Watch for changes

Use macOS file events to trigger selected jobs when files or folders change.

+
≡

Complete run history

Review commands, results, stdout, stderr and transfer statistics for previous runs.

+
⌘

Mac-first experience

Manage jobs, defaults, background operation and connection settings from a native macOS interface.

+
+
+
+ +
+
+
+ A safer workflow +

From setup to sync in four clear steps.

+
+
+
1

Create a job

Choose your source, destination and rsync options once.

+
2

Run a Dry Run

Check the generated operation before changing any files.

+
3

Run or automate

Start it manually, schedule it or attach a file watcher.

+
4

Review history

See the result and retain the command and transfer output.

+
+
+
+ +
+
+
+
+ Designed around your Mac +

Your sync workflow stays direct.

+

Rsync Studio runs rsync and SSH from your Mac. The licensing service is separate from your file-transfer path.

+
+
+
K
Keychain-aware settingsStored passwords use macOS Keychain rather than application preferences.
+
S
SSH-native connectionsUse the standard macOS SSH client, keys and known-host verification for remote jobs.
+
D
Dry Run safeguardsTest jobs before enabling destructive options such as destination deletion.
+
+
+
+
+ +
+
+
+ Simple licensing +

Choose the number of Macs you need.

+

Both plans include the full Rsync Studio workflow and a 7-day free trial. Checkout shows pricing in your supported local currency.

+
+
+
+

Personal

+

For a single Mac and an individual sync workflow.

+
1 Mac
Monthly or annual subscription
+
  • Local and SSH jobs
  • Scheduling and file watch
  • Dry Run and history
  • 7-day free trial
+ Choose Personal +
+ +
+
+
+ +
+
+

Make rsync easier to run every day.

Start with a 7-day free trial and choose Personal or Professional at checkout.

+ Start free trial +
+
+
+@endsection diff --git a/rsync-studio-licensing/resources/views/support.blade.php b/rsync-studio-licensing/resources/views/support.blade.php new file mode 100755 index 0000000..aba46f0 --- /dev/null +++ b/rsync-studio-licensing/resources/views/support.blade.php @@ -0,0 +1,100 @@ +@extends('layouts.app', [ + 'title' => 'Support — Rsync Studio', + 'description' => 'Contact Rsync Studio support for technical, licence, billing and privacy enquiries.' +]) + +@section('content') +
+ Support +

How can we help?

+

Send us the details below. Your request is saved securely, assigned a reference and emailed to the support team.

+
+ +
+
+
+
+

Contact support

+

We will reply to the email address you provide.

+
+ Support ticket +
+ +
+ @csrf + + +
+
+ + + @error('name')
{{ $message }}
@enderror +
+
+ + + @error('email')
{{ $message }}
@enderror +
+
+ +
+
+ + + @error('category')
{{ $message }}
@enderror +
+
+ + + @error('subject')
{{ $message }}
@enderror +
+
+ +
+ + +
Do not include passwords, private SSH keys or your full licence token.
+ @error('message')
{{ $message }}
@enderror +
+ + + @error('privacy_notice')
{{ $message }}
@enderror + +
+ + @auth + @if(auth()->user()->hasVerifiedEmail())Open licence portal@endif + @endauth +
+
+
+ + +
+@endsection diff --git a/rsync-studio-licensing/resources/views/welcome.blade.php b/rsync-studio-licensing/resources/views/welcome.blade.php old mode 100644 new mode 100755 diff --git a/rsync-studio-licensing/routes/api.php b/rsync-studio-licensing/routes/api.php old mode 100644 new mode 100755 index 767dc20..9548279 --- a/rsync-studio-licensing/routes/api.php +++ b/rsync-studio-licensing/routes/api.php @@ -1,3 +1,12 @@ group(function () { + Route::post('/activate', [LicenseActivationController::class, 'activate'])->middleware('throttle:license-activation'); + Route::post('/validate', [LicenseActivationController::class, 'validateInstallation'])->middleware('throttle:license-activation'); + Route::post('/deactivate', [LicenseActivationController::class, 'deactivate'])->middleware('throttle:license-activation'); + Route::post('/webhooks/{provider}', PaymentWebhookController::class)->whereIn('provider', ['paddle', 'lemon-squeezy']); +}); diff --git a/rsync-studio-licensing/routes/api.stage4.php b/rsync-studio-licensing/routes/api.stage4.php deleted file mode 100644 index 2f3994a..0000000 --- a/rsync-studio-licensing/routes/api.stage4.php +++ /dev/null @@ -1,11 +0,0 @@ -group(function () { - Route::post('/activate', [LicenseActivationController::class, 'activate'])->middleware('throttle:license-activation'); - Route::post('/deactivate', [LicenseActivationController::class, 'deactivate'])->middleware('throttle:license-activation'); - Route::post('/webhooks/{provider}', PaymentWebhookController::class)->whereIn('provider', ['paddle','lemon-squeezy']); -}); diff --git a/rsync-studio-licensing/routes/console.php b/rsync-studio-licensing/routes/console.php new file mode 100755 index 0000000..b98b725 --- /dev/null +++ b/rsync-studio-licensing/routes/console.php @@ -0,0 +1,6 @@ +dailyAt('03:20')->withoutOverlapping(); diff --git a/rsync-studio-licensing/routes/web.php b/rsync-studio-licensing/routes/web.php old mode 100644 new mode 100755 index 97fbe0f..fd9f8c6 --- a/rsync-studio-licensing/routes/web.php +++ b/rsync-studio-licensing/routes/web.php @@ -1,3 +1,55 @@ view('portal.welcome'))->name('home'); +Route::get('/buy', CheckoutController::class)->name('buy'); +Route::get('/support', [SupportController::class, 'create'])->name('support'); +Route::post('/support', [SupportController::class, 'store'])->middleware('throttle:5,10')->name('support.store'); +Route::view('/privacy', 'legal.privacy')->name('privacy'); +Route::view('/terms', 'legal.terms')->name('terms'); +Route::view('/cookies', 'legal.cookies')->name('cookies'); +Route::middleware('guest')->group(function () { + Route::get('/login', [AuthenticatedSessionController::class, 'create'])->name('login'); + Route::post('/login', [AuthenticatedSessionController::class, 'store'])->middleware('throttle:login'); + Route::get('/register', [RegisteredUserController::class, 'create'])->name('register'); + Route::post('/register', [RegisteredUserController::class, 'store'])->middleware('throttle:registration'); + Route::get('/forgot-password', [PasswordController::class, 'requestForm'])->name('password.request'); + Route::post('/forgot-password', [PasswordController::class, 'email'])->name('password.email')->middleware('throttle:5,1'); + Route::get('/reset-password/{token}', [PasswordController::class, 'resetForm'])->name('password.reset'); + Route::post('/reset-password', [PasswordController::class, 'reset'])->name('password.update'); +}); +Route::middleware('auth')->group(function () { + Route::post('/logout', [AuthenticatedSessionController::class, 'destroy'])->name('logout'); + Route::get('/verify-email', [EmailVerificationController::class, 'notice'])->name('verification.notice'); + Route::get('/verify-email/{id}/{hash}', [EmailVerificationController::class, 'verify'])->middleware(['signed', 'throttle:6,1'])->name('verification.verify'); + Route::post('/email/verification-notification', [EmailVerificationController::class, 'resend'])->middleware('throttle:6,1')->name('verification.send'); +}); +Route::middleware(['auth', 'verified'])->prefix('portal')->name('portal.')->group(function () { + Route::get('/', [PortalController::class, 'index'])->name('index'); + Route::get('/licences/{license}', [PortalController::class, 'show'])->name('show'); + Route::post('/licences/{license}/upgrade', [PortalController::class, 'upgrade'])->middleware('throttle:5,1')->name('upgrade'); + Route::delete('/licences/{license}/subscription', [PortalController::class, 'cancel'])->middleware('throttle:5,1')->name('cancel'); + Route::post('/licences/{license}/resend', [PortalController::class, 'resend'])->middleware('throttle:3,10')->name('resend'); + Route::delete('/licences/{license}/activations/{activation}', [PortalController::class, 'deactivate'])->name('deactivate'); +}); +Route::middleware(['auth', 'verified', AdminOnly::class])->prefix('admin')->name('admin.')->group(function () { + Route::get('/', [AdminController::class, 'index'])->name('index'); + Route::get('/licences', [AdminController::class, 'licenses'])->name('licenses'); + Route::get('/licences/{license}', [AdminController::class, 'show'])->name('license'); + Route::post('/licences/{license}/revoke', [AdminController::class, 'revoke'])->name('revoke'); + Route::post('/licences/{license}/restore', [AdminController::class, 'restore'])->name('restore'); + Route::get('/support', [SupportTicketController::class, 'index'])->name('support.index'); + Route::get('/support/{ticket}', [SupportTicketController::class, 'show'])->name('support.show'); + Route::patch('/support/{ticket}',[SupportTicketController::class, 'update'])->name('support.update'); +}); diff --git a/rsync-studio-licensing/routes/web.stage5.php b/rsync-studio-licensing/routes/web.stage5.php deleted file mode 100644 index 61f0703..0000000 --- a/rsync-studio-licensing/routes/web.stage5.php +++ /dev/null @@ -1,14 +0,0 @@ -view('portal.welcome'))->name('home'); -Route::middleware('guest')->group(function(){Route::get('/login',[AuthenticatedSessionController::class,'create'])->name('login');Route::post('/login',[AuthenticatedSessionController::class,'store'])->middleware('throttle:login');Route::get('/register',[RegisteredUserController::class,'create'])->name('register');Route::post('/register',[RegisteredUserController::class,'store'])->middleware('throttle:registration');Route::get('/forgot-password',[PasswordController::class,'requestForm'])->name('password.request');Route::post('/forgot-password',[PasswordController::class,'email'])->name('password.email')->middleware('throttle:5,1');Route::get('/reset-password/{token}',[PasswordController::class,'resetForm'])->name('password.reset');Route::post('/reset-password',[PasswordController::class,'reset'])->name('password.update');}); -Route::middleware('auth')->group(function(){Route::post('/logout',[AuthenticatedSessionController::class,'destroy'])->name('logout');Route::get('/verify-email',[EmailVerificationController::class,'notice'])->name('verification.notice');Route::get('/verify-email/{id}/{hash}',[EmailVerificationController::class,'verify'])->middleware(['signed','throttle:6,1'])->name('verification.verify');Route::post('/email/verification-notification',[EmailVerificationController::class,'resend'])->middleware('throttle:6,1')->name('verification.send');}); -Route::middleware(['auth','verified'])->prefix('portal')->name('portal.')->group(function(){Route::get('/',[PortalController::class,'index'])->name('index');Route::get('/licences/{license}',[PortalController::class,'show'])->name('show');Route::post('/licences/{license}/resend',[PortalController::class,'resend'])->middleware('throttle:3,10')->name('resend');Route::delete('/licences/{license}/activations/{activation}',[PortalController::class,'deactivate'])->name('deactivate');}); -Route::middleware(['auth','verified',AdminOnly::class])->prefix('admin')->name('admin.')->group(function(){Route::get('/',[AdminController::class,'index'])->name('index');Route::get('/licences',[AdminController::class,'licenses'])->name('licenses');Route::get('/licences/{license}',[AdminController::class,'show'])->name('license');Route::post('/licences/{license}/revoke',[AdminController::class,'revoke'])->name('revoke');Route::post('/licences/{license}/restore',[AdminController::class,'restore'])->name('restore');}); diff --git a/rsync-studio-licensing/scripts/create-rsync-studio-catalog.sh b/rsync-studio-licensing/scripts/create-rsync-studio-catalog.sh new file mode 100755 index 0000000..d430c09 --- /dev/null +++ b/rsync-studio-licensing/scripts/create-rsync-studio-catalog.sh @@ -0,0 +1,247 @@ +#!/usr/bin/env bash + +set -euo pipefail + +PADDLE_API_KEY="${PADDLE_API_KEY:-}" + +if [[ -z "$PADDLE_API_KEY" ]]; then + echo "ERROR: PADDLE_API_KEY is not set." + echo 'Run: export PADDLE_API_KEY="pdl_sdbx_apikey_..."' + exit 1 +fi + +API="https://sandbox-api.paddle.com" + +api_post() { + local endpoint="$1" + local payload="$2" + + curl --fail-with-body --silent --show-error \ + --request POST \ + --url "${API}${endpoint}" \ + --header "Authorization: Bearer ${PADDLE_API_KEY}" \ + --header "Content-Type: application/json" \ + --data "$payload" +} + +create_product() { + local name="$1" + local description="$2" + + api_post "/products" "$(jq -n \ + --arg name "$name" \ + --arg description "$description" \ + '{ + name: $name, + description: $description, + type: "standard", + tax_category: "standard" + }' + )" +} + +create_price() { + local product_id="$1" + local name="$2" + local description="$3" + local cycle="$4" + local usd="$5" + local gbp="$6" + local eur="$7" + local aud="$8" + + api_post "/prices" "$(jq -n \ + --arg product_id "$product_id" \ + --arg name "$name" \ + --arg description "$description" \ + --arg cycle "$cycle" \ + --arg usd "$usd" \ + --arg gbp "$gbp" \ + --arg eur "$eur" \ + --arg aud "$aud" \ + '{ + product_id: $product_id, + name: $name, + description: $description, + + billing_cycle: { + interval: $cycle, + frequency: 1 + }, + + trial_period: { + interval: "day", + frequency: 7 + }, + + unit_price: { + amount: $usd, + currency_code: "USD" + }, + + unit_price_overrides: [ + { + country_codes: ["GB"], + unit_price: { + amount: $gbp, + currency_code: "GBP" + } + }, + { + country_codes: ["IE"], + unit_price: { + amount: $eur, + currency_code: "EUR" + } + }, + { + country_codes: ["AU"], + unit_price: { + amount: $aud, + currency_code: "AUD" + } + } + ], + + tax_mode: "account_setting", + + quantity: { + minimum: 1, + maximum: 1 + } + }' + )" +} + +echo +echo "Creating Rsync Studio Paddle sandbox catalog..." +echo + +# +# Personal +# + +PERSONAL_PRODUCT=$(create_product \ + "Rsync Studio Personal" \ + "Rsync Studio for personal use.") + +PERSONAL_PRODUCT_ID=$(echo "$PERSONAL_PRODUCT" | jq -r '.data.id') + +echo "Created Personal product: $PERSONAL_PRODUCT_ID" + +PERSONAL_MONTHLY=$(create_price \ + "$PERSONAL_PRODUCT_ID" \ + "Personal Monthly" \ + "Rsync Studio Personal — monthly subscription with 7-day free trial." \ + "month" \ + "199" \ + "199" \ + "199" \ + "299") + +PERSONAL_MONTHLY_ID=$(echo "$PERSONAL_MONTHLY" | jq -r '.data.id') + +echo "Created Personal Monthly: $PERSONAL_MONTHLY_ID" + +PERSONAL_ANNUAL=$(create_price \ + "$PERSONAL_PRODUCT_ID" \ + "Personal Annual" \ + "Rsync Studio Personal — annual subscription with 7-day free trial." \ + "year" \ + "1499" \ + "1499" \ + "1699" \ + "2499") + +PERSONAL_ANNUAL_ID=$(echo "$PERSONAL_ANNUAL" | jq -r '.data.id') + +echo "Created Personal Annual: $PERSONAL_ANNUAL_ID" + +# +# Professional +# + +PRO_PRODUCT=$(create_product \ + "Rsync Studio Professional" \ + "Rsync Studio for professional and commercial use.") + +PRO_PRODUCT_ID=$(echo "$PRO_PRODUCT" | jq -r '.data.id') + +echo "Created Professional product: $PRO_PRODUCT_ID" + +PRO_MONTHLY=$(create_price \ + "$PRO_PRODUCT_ID" \ + "Professional Monthly" \ + "Rsync Studio Professional — monthly subscription with 7-day free trial." \ + "month" \ + "399" \ + "399" \ + "449" \ + "699") + +PRO_MONTHLY_ID=$(echo "$PRO_MONTHLY" | jq -r '.data.id') + +echo "Created Professional Monthly: $PRO_MONTHLY_ID" + +PRO_ANNUAL=$(create_price \ + "$PRO_PRODUCT_ID" \ + "Professional Annual" \ + "Rsync Studio Professional — annual subscription with 7-day free trial." \ + "year" \ + "2999" \ + "2999" \ + "3499" \ + "4999") + +PRO_ANNUAL_ID=$(echo "$PRO_ANNUAL" | jq -r '.data.id') + +echo "Created Professional Annual: $PRO_ANNUAL_ID" + +echo +echo "============================================================" +echo " RSYNC STUDIO — PADDLE SANDBOX CATALOG" +echo "============================================================" +echo +echo "PERSONAL" +echo " Product ID: $PERSONAL_PRODUCT_ID" +echo " Monthly Price ID: $PERSONAL_MONTHLY_ID" +echo " Annual Price ID: $PERSONAL_ANNUAL_ID" +echo +echo "PROFESSIONAL" +echo " Product ID: $PRO_PRODUCT_ID" +echo " Monthly Price ID: $PRO_MONTHLY_ID" +echo " Annual Price ID: $PRO_ANNUAL_ID" +echo +echo "------------------------------------------------------------" +echo "Pricing" +echo "------------------------------------------------------------" +echo +printf "%-24s %-12s %-12s %-12s %-12s\n" \ + "Plan" "USD" "UK" "Ireland" "Australia" +printf "%-24s %-12s %-12s %-12s %-12s\n" \ + "Personal Monthly" '$1.99' '£1.99' '€1.99' 'A$2.99' +printf "%-24s %-12s %-12s %-12s %-12s\n" \ + "Personal Annual" '$14.99' '£14.99' '€16.99' 'A$24.99' +printf "%-24s %-12s %-12s %-12s %-12s\n" \ + "Professional Monthly" '$3.99' '£3.99' '€4.49' 'A$6.99' +printf "%-24s %-12s %-12s %-12s %-12s\n" \ + "Professional Annual" '$29.99' '£29.99' '€34.99' 'A$49.99' +echo +echo "All four prices include a 7-day FREE trial." +echo +echo "============================================================" + +cat > rsync-studio-paddle-ids.env <set('rsync-studio.paddle.client_side_token', 'test_example'); + config()->set('rsync-studio.paddle.environment', 'sandbox'); + config()->set('rsync-studio.paddle.personal_monthly_price_id', 'pri_personal_monthly'); + config()->set('rsync-studio.paddle.personal_annual_price_id', 'pri_personal_annual'); + config()->set('rsync-studio.paddle.professional_monthly_price_id', 'pri_professional_monthly'); + config()->set('rsync-studio.paddle.professional_annual_price_id', 'pri_professional_annual'); + + $this->get('/buy') + ->assertOk() + ->assertSee('7-day free trial') + ->assertSee('pri_personal_monthly') + ->assertSee('pri_personal_annual') + ->assertSee('pri_professional_monthly') + ->assertSee('pri_professional_annual') + ->assertSee('test_example'); + } +} diff --git a/rsync-studio-licensing/tests/Feature/LicenseActivationTest.php b/rsync-studio-licensing/tests/Feature/LicenseActivationTest.php old mode 100644 new mode 100755 index 4db0d4f..7d81a87 --- a/rsync-studio-licensing/tests/Feature/LicenseActivationTest.php +++ b/rsync-studio-licensing/tests/Feature/LicenseActivationTest.php @@ -1,6 +1,8 @@ 'test','name'=>'Test','edition'=>'Professional','activation_limit'=>1,'max_major_version'=>1,'active'=>true]); - [, $key]=app(LicenseIssuer::class)->issue($product,'Test','test@example.com'); - $one=['licenseKey'=>$key,'installationID'=>'11111111-1111-4111-8111-111111111111','appVersion'=>'1.0.0','platform'=>'macOS']; - $this->postJson('/api/v1/activate',$one)->assertOk()->assertJsonStructure(['licenseToken']); - $this->postJson('/api/v1/activate',$one)->assertOk(); - $this->postJson('/api/v1/activate',array_merge($one,['installationID'=>'22222222-2222-4222-8222-222222222222']))->assertStatus(409); + $product = LicenseProduct::create(['code' => 'test', 'name' => 'Test', 'edition' => 'Professional', 'activation_limit' => 1, 'max_major_version' => 1, 'active' => true]); + [, $key] = app(LicenseIssuer::class)->issue($product, 'Test', 'test@example.com'); + $one = ['licenseKey' => $key, 'installationID' => '11111111-1111-4111-8111-111111111111', 'appVersion' => '1.0.0', 'platform' => 'macOS']; + $this->postJson('/api/v1/activate', $one)->assertOk()->assertJsonStructure(['licenseToken']); + $this->postJson('/api/v1/activate', $one)->assertOk(); + $this->postJson('/api/v1/activate', array_merge($one, ['installationID' => '22222222-2222-4222-8222-222222222222']))->assertStatus(409); + } + + public function test_validation_refreshes_an_active_installation_without_calling_paddle(): void + { + $product = LicenseProduct::create([ + 'code' => 'validate-active', + 'name' => 'Validate Active', + 'edition' => 'Professional', + 'activation_limit' => 1, + 'max_major_version' => 1, + 'active' => true, + ]); + [, $key] = app(LicenseIssuer::class)->issue($product, 'Test', 'test@example.com'); + $request = [ + 'licenseKey' => $key, + 'installationID' => '11111111-1111-4111-8111-111111111111', + 'appVersion' => '1.0.0', + 'platform' => 'macOS', + ]; + + $token = $this->postJson('/api/v1/activate', $request)->assertOk()->json('licenseToken'); + + $this->postJson('/api/v1/validate', [ + 'licenseToken' => $token, + 'installationID' => $request['installationID'], + 'appVersion' => '1.0.1', + 'platform' => 'macOS', + ])->assertOk()->assertJson([ + 'active' => true, + ])->assertJsonStructure(['licenseToken']); + } + + public function test_validation_rejects_an_installation_deactivated_from_the_portal(): void + { + $product = LicenseProduct::create([ + 'code' => 'validate-deactivated', + 'name' => 'Validate Deactivated', + 'edition' => 'Personal', + 'activation_limit' => 1, + 'max_major_version' => 1, + 'active' => true, + ]); + [, $key] = app(LicenseIssuer::class)->issue($product, 'Test', 'test@example.com'); + $request = [ + 'licenseKey' => $key, + 'installationID' => '22222222-2222-4222-8222-222222222222', + 'appVersion' => '1.0.0', + 'platform' => 'macOS', + ]; + + $token = $this->postJson('/api/v1/activate', $request)->assertOk()->json('licenseToken'); + LicenseActivation::query()->where('installation_id', strtolower($request['installationID']))->update(['deactivated_at' => now()]); + + $this->postJson('/api/v1/validate', [ + 'licenseToken' => $token, + 'installationID' => $request['installationID'], + 'appVersion' => '1.0.0', + 'platform' => 'macOS', + ])->assertStatus(403)->assertJson([ + 'message' => 'This Mac has been deactivated from the licence portal.', + ]); } } diff --git a/rsync-studio-licensing/tests/Feature/PaddleSubscriptionProvisioningTest.php b/rsync-studio-licensing/tests/Feature/PaddleSubscriptionProvisioningTest.php new file mode 100755 index 0000000..527216e --- /dev/null +++ b/rsync-studio-licensing/tests/Feature/PaddleSubscriptionProvisioningTest.php @@ -0,0 +1,105 @@ + strtolower($edition).'-'.$price, + 'name' => $edition, + 'edition' => $edition, + 'activation_limit' => $activations, + 'max_major_version' => 1, + 'payment_provider' => 'paddle', + 'external_product_id' => $edition === 'Personal' ? 'pro_personal' : 'pro_professional', + 'external_price_id' => $price, + 'active' => true, + ]); + } + + private function subscription(string $type, string $status, string $price, string $product, array $extra = []): array + { + return [ + 'event_type' => $type, + 'data' => array_replace_recursive([ + 'id' => 'sub_test', + 'status' => $status, + 'customer_id' => 'ctm_test', + 'transaction_id' => 'txn_test', + 'custom_data' => ['customer_name' => 'Mark', 'customer_email' => 'mark@example.com'], + 'current_billing_period' => ['starts_at' => '2026-09-09T00:00:00Z', 'ends_at' => '2026-10-09T00:00:00Z'], + 'scheduled_change' => null, + 'items' => [[ + 'recurring' => true, + 'price' => ['id' => $price, 'product_id' => $product], + ]], + ], $extra), + ]; + } + + public function test_trialing_subscription_issues_a_usable_license(): void + { + $this->product('pri_personal_monthly', 'Personal', 1); + + app(PurchaseProvisioner::class)->provision('paddle', $this->subscription( + 'subscription.created', 'trialing', 'pri_personal_monthly', 'pro_personal' + )); + + $license = License::firstOrFail(); + $this->assertSame('Personal', $license->edition); + $this->assertSame('sub_test', $license->external_subscription_id); + $this->assertSame('trialing', $license->subscription_status); + $this->assertTrue($license->is_usable); + } + + public function test_upgrade_changes_entitlement_without_changing_license(): void + { + $this->product('pri_personal_monthly', 'Personal', 1); + $this->product('pri_professional_monthly', 'Professional', 3); + $service = app(PurchaseProvisioner::class); + + $service->provision('paddle', $this->subscription('subscription.created', 'active', 'pri_personal_monthly', 'pro_personal')); + $id = License::firstOrFail()->id; + $service->provision('paddle', $this->subscription('subscription.updated', 'active', 'pri_professional_monthly', 'pro_professional')); + + $license = License::firstOrFail(); + $this->assertSame($id, $license->id); + $this->assertSame('Professional', $license->edition); + $this->assertSame(3, $license->activation_limit); + } + + public function test_scheduled_cancellation_does_not_revoke_before_effective_date(): void + { + $this->product('pri_personal_monthly', 'Personal', 1); + app(PurchaseProvisioner::class)->provision('paddle', $this->subscription( + 'subscription.updated', 'active', 'pri_personal_monthly', 'pro_personal', + ['data' => ['scheduled_change' => ['action' => 'cancel', 'effective_at' => '2026-10-09T00:00:00Z']]] + )); + + $license = License::firstOrFail(); + $this->assertNull($license->revoked_at); + $this->assertNotNull($license->cancel_scheduled_at); + } + + public function test_canceled_subscription_revokes_license(): void + { + $this->product('pri_personal_monthly', 'Personal', 1); + $service = app(PurchaseProvisioner::class); + $service->provision('paddle', $this->subscription('subscription.created', 'active', 'pri_personal_monthly', 'pro_personal')); + $service->provision('paddle', $this->subscription('subscription.canceled', 'canceled', 'pri_personal_monthly', 'pro_personal', ['data' => ['current_billing_period' => null]])); + + $license = License::firstOrFail(); + $this->assertNotNull($license->revoked_at); + $this->assertFalse($license->is_usable); + } +} diff --git a/rsync-studio-licensing/tests/Feature/PortalSubscriptionManagementTest.php b/rsync-studio-licensing/tests/Feature/PortalSubscriptionManagementTest.php new file mode 100755 index 0000000..5ebb77f --- /dev/null +++ b/rsync-studio-licensing/tests/Feature/PortalSubscriptionManagementTest.php @@ -0,0 +1,66 @@ + $code, + 'name' => 'Rsync Studio '.$edition.' '.(str_contains($code, 'annual') ? 'Annual' : 'Monthly'), + 'edition' => $edition, + 'activation_limit' => $limit, + 'max_major_version' => 1, + 'payment_provider' => 'paddle', + 'external_product_id' => 'pro_'.strtolower($edition), + 'external_price_id' => $price, + 'active' => true, + ]); + } + + public function test_personal_subscription_is_upgraded_in_place(): void + { + config()->set('rsync-studio.paddle.personal_monthly_price_id', 'pri_personal_monthly'); + config()->set('rsync-studio.paddle.professional_monthly_price_id', 'pri_professional_monthly'); + + $personal = $this->product('personal-monthly', 'Personal', 'pri_personal_monthly', 1); + $professional = $this->product('professional-monthly', 'Professional', 'pri_professional_monthly', 3); + $user = User::factory()->create(['email' => 'mark@example.com', 'email_verified_at' => now()]); + $license = License::create([ + 'license_product_id' => $personal->id, + 'license_key_hash' => str_repeat('a', 64), + 'license_key_last4' => 'TEST', + 'customer_email' => $user->email, + 'edition' => 'Personal', + 'activation_limit' => 1, + 'max_major_version' => 1, + 'payment_provider' => 'paddle', + 'external_subscription_id' => 'sub_test', + 'external_price_id' => 'pri_personal_monthly', + 'subscription_status' => 'active', + ]); + + $this->mock(PaddleClient::class, function (MockInterface $mock) { + $mock->shouldReceive('updateSubscriptionPrice')->once()->with('sub_test', 'pri_professional_monthly')->andReturn(['status' => 'active']); + }); + + $this->actingAs($user)->post(route('portal.upgrade', $license))->assertRedirect(route('portal.show', $license)); + + $license->refresh(); + $this->assertSame($professional->id, $license->license_product_id); + $this->assertSame('Professional', $license->edition); + $this->assertSame(3, $license->activation_limit); + $this->assertSame('sub_test', $license->external_subscription_id); + } +} diff --git a/rsync-studio-licensing/vite.config.js b/rsync-studio-licensing/vite.config.js old mode 100644 new mode 100755