From 17fb2065e2ab1a24d81fe683ac082cf4216f4b70 Mon Sep 17 00:00:00 2001 From: rjindael Date: Sat, 22 Oct 2022 16:41:36 -0700 Subject: [PATCH] Initial commit --- .dockerignore | 17 + .editorconfig | 18 + .env.example | 91 + .env.testing | 91 + .gitattributes | 10 + .gitignore | 22 + .gitlab-ci.yml | 13 + LICENSE | 661 + README.md | 44 + app/Broadcasting/GameServerChannel.php | 32 + app/Cdn/Manager.php | 50 + .../Commands/MeilisearchKeyGenerate.php | 129 + app/Console/Commands/PusherIdGenerate.php | 129 + app/Console/Commands/PusherSecretGenerate.php | 129 + app/Console/Kernel.php | 30 + app/Discord/User.php | 52 + app/Enums/Actions.php | 68 + app/Enums/ArbiterLogSeverity.php | 54 + app/Enums/AssetGenre.php | 40 + app/Enums/AssetModeration.php | 10 + app/Enums/AssetType.php | 290 + app/Enums/ChatStyle.php | 12 + app/Enums/CreatorType.php | 11 + app/Enums/DevelopPage.php | 35 + app/Enums/GameServerState.php | 26 + app/Enums/PlaceAccess.php | 9 + app/Enums/PlaceSort.php | 29 + app/Enums/SignatureType.php | 79 + app/Events/GameServer/ConsoleOutput.php | 61 + app/Events/GameServer/NewPlaceJob.php | 37 + app/Events/GameServer/NewThumbnailJob.php | 37 + app/Events/GameServer/ResourceReport.php | 45 + app/Events/GameServer/StateChange.php | 50 + app/Events/IpAddressBanModified.php | 16 + app/Exceptions/Handler.php | 41 + app/GPBMetadata/Resources/Tadah.php | 25 + app/Helpers/Agent.php | 33 + app/Helpers/Cdn.php | 82 + app/Helpers/IpAddressBanManager.php | 35 + app/Helpers/PaginationTransformer.php | 47 + .../Account/DashboardController.php | 31 + .../Account/DisabledAccountController.php | 68 + .../Controllers/Account/DiscordController.php | 29 + .../Account/InviteKeyController.php | 70 + .../Controllers/Account/SessionController.php | 39 + .../Account/SettingsController.php | 79 + .../Controllers/Admin/ActionLogController.php | 27 + .../Controllers/Admin/AlertController.php | 26 + app/Http/Controllers/Admin/BanController.php | 27 + .../Admin/BanInformationController.php | 41 + .../Admin/GameServerController.php | 123 + .../Admin/IpAddressBanController.php | 27 + .../Controllers/Admin/PanelController.php | 28 + .../Admin/PermissionsController.php | 172 + .../Admin/UserProfileController.php | 40 + .../Arbiter/IdentificationController.php | 23 + .../Controllers/Arbiter/LogController.php | 64 + .../Controllers/Arbiter/StateController.php | 28 + ...mailVerificationNotificationController.php | 24 + .../Auth/PasswordResetController.php | 108 + app/Http/Controllers/CatalogController.php | 13 + app/Http/Controllers/Controller.php | 13 + app/Http/Controllers/DevelopController.php | 13 + app/Http/Controllers/ForumController.php | 31 + app/Http/Controllers/GamesController.php | 13 + app/Http/Controllers/HomeController.php | 38 + app/Http/Controllers/ItemController.php | 25 + .../Controllers/Roblox/FastFlagController.php | 25 + .../Roblox/MiscellaneousScriptController.php | 14 + .../Roblox/OnlinePlayController.php | 120 + .../Roblox/StaticAssetController.php | 33 + .../Controllers/Roblox/StudioController.php | 35 + app/Http/Controllers/UsersController.php | 21 + app/Http/Kernel.php | 72 + .../Livewire/Account/ModerationHistory.php | 41 + .../Account/TwoFactorAuthentication.php | 34 + app/Http/Livewire/Account/UpdateBlurb.php | 63 + app/Http/Livewire/Account/UpdatePassword.php | 74 + app/Http/Livewire/Account/UpdateUsername.php | 73 + app/Http/Livewire/Admin/ActionLog.php | 50 + app/Http/Livewire/Admin/Alert.php | 94 + app/Http/Livewire/Admin/Ban/IpAddress.php | 147 + .../Livewire/Admin/Ban/IpAddressSearch.php | 49 + app/Http/Livewire/Admin/Ban/Pardon.php | 71 + .../Livewire/Admin/Ban/PardonIpAddress.php | 65 + app/Http/Livewire/Admin/Ban/Search.php | 51 + app/Http/Livewire/Admin/Ban/User.php | 165 + app/Http/Livewire/Admin/GameServer/All.php | 62 + app/Http/Livewire/Admin/GameServer/Create.php | 124 + app/Http/Livewire/Admin/GameServer/Delete.php | 49 + app/Http/Livewire/Admin/GameServer/Manage.php | 146 + .../Admin/User/AssociatedAccounts.php | 46 + .../Livewire/Admin/User/ModerationHistory.php | 49 + app/Http/Livewire/Auth/Register.php | 187 + app/Http/Livewire/Dashboard/BestFriends.php | 19 + app/Http/Livewire/Dashboard/Feed.php | 97 + .../Dashboard/RecentlyPlayedGames.php | 19 + app/Http/Livewire/Develop/Assets.php | 66 + app/Http/Livewire/Develop/Create.php | 185 + app/Http/Livewire/Develop/Panel.php | 64 + app/Http/Livewire/Forum/Create.php | 13 + app/Http/Livewire/Forum/Replies.php | 31 + app/Http/Livewire/Forum/Thread.php | 30 + app/Http/Livewire/Forum/Threads.php | 49 + app/Http/Livewire/Games/Search.php | 46 + app/Http/Livewire/Item/Comments.php | 23 + app/Http/Livewire/Item/Configure.php | 118 + app/Http/Livewire/Layout/SearchBar.php | 28 + app/Http/Livewire/Users/FriendButton.php | 99 + app/Http/Livewire/Users/Search.php | 45 + app/Http/Middleware/AdminGuard.php | 27 + app/Http/Middleware/Authenticate.php | 22 + app/Http/Middleware/AuthenticateArbiter.php | 30 + .../Middleware/BlockBannedIpAddresses.php | 32 + app/Http/Middleware/EncryptCookies.php | 17 + app/Http/Middleware/EnsureEmailIsVerified.php | 43 + app/Http/Middleware/IsBanned.php | 38 + app/Http/Middleware/Localization.php | 28 + .../PreventRequestsDuringMaintenance.php | 17 + .../Middleware/RedirectIfAuthenticated.php | 34 + app/Http/Middleware/ToolGuard.php | 32 + app/Http/Middleware/TrimStrings.php | 19 + app/Http/Middleware/TrustHosts.php | 20 + app/Http/Middleware/TrustProxies.php | 28 + .../Middleware/UpdateCurrentIpAddress.php | 27 + app/Http/Middleware/VerifyCsrfToken.php | 17 + .../GameServer/AppendConsoleOutput.php | 19 + app/Listeners/GameServer/ChangeState.php | 19 + app/Listeners/GameServer/Ping.php | 19 + .../SendEmailVerificationNotification.php | 27 + app/Models/Action.php | 159 + app/Models/Asset.php | 185 + app/Models/AssetComment.php | 38 + app/Models/AssetOwnership.php | 38 + app/Models/AssetVersion.php | 53 + app/Models/Badge.php | 27 + app/Models/Ban.php | 170 + app/Models/ForumCategory.php | 41 + app/Models/ForumReply.php | 36 + app/Models/ForumThread.php | 50 + app/Models/Friendship.php | 50 + app/Models/GameServer.php | 293 + app/Models/InviteKey.php | 87 + app/Models/IpAddressBan.php | 77 + app/Models/PlaceJob.php | 10 + app/Models/PoisonedIpAddress.php | 41 + app/Models/Status.php | 30 + app/Models/ThumbnailJob.php | 10 + app/Models/Universe.php | 43 + app/Models/User.php | 683 + .../AccountSecurityNotification.php | 126 + app/Proto/AssetType.php | 73 + app/Proto/ClientVersion.php | 53 + app/Proto/Operation.php | 73 + app/Proto/Response.php | 139 + app/Proto/Signal.php | 193 + app/Proto/Signal/Place.php | 115 + app/Proto/Signal/Thumbnail.php | 115 + app/Proto/Signal_Place.php | 16 + app/Proto/Signal_Thumbnail.php | 16 + app/Providers/AppServiceProvider.php | 80 + app/Providers/AuthServiceProvider.php | 30 + app/Providers/BroadcastServiceProvider.php | 21 + app/Providers/EventServiceProvider.php | 45 + app/Providers/FortifyServiceProvider.php | 89 + app/Providers/HorizonServiceProvider.php | 34 + app/Providers/RouteServiceProvider.php | 57 + app/Providers/TelescopeServiceProvider.php | 70 + app/Roblox/Script/Script.php | 176 + app/Roblox/Script/ScriptBuilder.php | 62 + app/Roles/Admin.php | 22 + app/Roles/Economy.php | 82 + app/Roles/Forums.php | 62 + app/Roles/GameServers.php | 102 + app/Roles/Places.php | 67 + app/Roles/Roles.php | 64 + app/Roles/SelfHostedServers.php | 37 + app/Roles/Users.php | 102 + .../Matching/CaseInsensitiveUriValidator.php | 18 + app/Rules/IsAlphaNumeric.php | 30 + app/Rules/IsCurrentPassword.php | 42 + app/Rules/IsRobloxXml.php | 53 + app/Rules/IsSiprNameOrIpAddress.php | 39 + app/Rules/IsUniqueEmail.php | 31 + app/Rules/IsValidInviteKey.php | 38 + app/Rules/IsValidSession.php | 44 + app/Signing/Signature.php | 59 + app/Signing/Signer.php | 73 + app/Traits/EmailValidationRules.php | 16 + app/Traits/PasswordValidationRules.php | 32 + app/Traits/UsernameValidationRules.php | 20 + app/View/Components/AppLayout.php | 91 + app/View/Components/AuthLayout.php | 31 + app/View/Components/ErrorLayout.php | 34 + app/helpers.php | 268 + artisan | 53 + bootstrap/app.php | 55 + bootstrap/cache/.gitignore | 2 + composer.json | 103 + composer.lock | 9472 ++++++++++++ config/app.php | 217 + config/auth.php | 111 + config/broadcasting.php | 70 + config/cache.php | 110 + config/ciphersweet.php | 21 + config/cors.php | 34 + config/database.php | 147 + config/disposable-email.php | 70 + config/filesystems.php | 86 + config/fortify.php | 143 + config/hashing.php | 52 + config/horizon.php | 203 + config/livewire.php | 158 + config/logging.php | 119 + config/mail.php | 117 + config/octane.php | 221 + config/parsedown.php | 38 + config/queue.php | 93 + config/recaptcha.php | 179 + config/scout.php | 137 + config/services.php | 39 + config/session.php | 201 + config/tadah.php | 17 + config/telescope.php | 176 + config/view.php | 36 + database/.gitignore | 1 + database/factories/UserFactory.php | 31 + .../2014_10_12_000000_create_users_table.php | 52 + ...12_100000_create_password_resets_table.php | 32 + ..._add_two_factor_columns_to_users_table.php | 38 + ..._08_19_000000_create_failed_jobs_table.php | 36 + ...01_create_personal_access_tokens_table.php | 36 + ...01_09_205316_create_game_servers_table.php | 46 + .../2022_01_09_205341_create_badges_table.php | 37 + ...2_01_09_205414_create_place_jobs_table.php | 33 + ..._02_13_073348_create_invite_keys_table.php | 37 + ...022_02_19_063207_create_sessions_table.php | 35 + .../2022_03_06_004335_create_bans_table.php | 45 + ...06_074551_create_ip_address_bans_table.php | 39 + ...14_224312_create_poisoned_ip_addresses.php | 34 + ..._20_025917_create_thumbnail_jobs_table.php | 32 + ..._03_26_044913_create_job_batches_table.php | 39 + ...022_04_12_154421_create_statuses_table.php | 37 + .../2022_04_12_224438_create_assets_table.php | 64 + ..._13_095641_create_asset_versions_table.php | 36 + ...22_04_13_095721_create_universes_table.php | 48 + ..._13_100911_create_asset_comments_table.php | 35 + ...3_101743_create_asset_ownerships_table.php | 35 + ..._04_16_080833_create_friendships_table.php | 35 + ...2022_07_02_101148_create_actions_table.php | 34 + ...7_02_135149_create_forum_threads_table.php | 39 + ...7_02_135209_create_forum_replies_table.php | 37 + ...2_135303_create_forum_categories_table.php | 37 + database/seeders/DatabaseSeeder.php | 19 + docker-compose.yml | 107 + docker/Dockerfile | 63 + docker/php.ini | 4 + docker/release/Dockerfile | 90 + docker/release/php.ini | 34 + docker/release/start-container | 17 + docker/release/supervisord.conf | 26 + docker/start-container | 17 + docker/supervisord.conf | 14 + lang/en_US.json | 7 + lang/en_US/auth.php | 20 + lang/en_US/pagination.php | 19 + lang/en_US/passwords.php | 22 + lang/en_US/validation.php | 164 + package-lock.json | 12417 ++++++++++++++++ package.json | 30 + phpstan.neon | 13 + public/content | 1 + public/favicon.ico | Bin 0 -> 4286 bytes public/fonts/TwemojiMozilla.ttf | Bin 0 -> 1437964 bytes public/img/blobs/dead.png | Bin 0 -> 8803 bytes public/img/blobs/exhausted.png | Bin 0 -> 8745 bytes public/img/blobs/ghastly.png | Bin 0 -> 8673 bytes public/img/blobs/inquisitive.png | Bin 0 -> 8124 bytes public/img/blobs/open_mouth.png | Bin 0 -> 1389 bytes public/img/blobs/scared.png | Bin 0 -> 12033 bytes public/img/blobs/sick.png | Bin 0 -> 11222 bytes public/img/blobs/sweaty.png | Bin 0 -> 10678 bytes public/img/blobs/tired.png | Bin 0 -> 9874 bytes public/img/dead.png | Bin 0 -> 443 bytes public/img/hero/register.png | Bin 0 -> 717953 bytes public/img/laravel/horizon.png | Bin 0 -> 648 bytes public/img/laravel/telescope.png | Bin 0 -> 1918 bytes public/img/logo/big.png | Bin 0 -> 246083 bytes public/img/logo/dahllor.svg | 9 + public/img/logo/small.png | Bin 0 -> 43864 bytes public/img/placeholder/icon.png | Bin 0 -> 5780 bytes public/img/placeholder/widescreen.png | Bin 0 -> 13055 bytes public/index.php | 55 + public/robots.txt | 2 + public/vid/landing.mp4 | Bin 0 -> 13009549 bytes public/vid/landing.webm | Bin 0 -> 7858399 bytes resources/css/fa6-pro.min.css | 5 + resources/flags/ClientAppSettings/2012.json | 4 + resources/flags/ClientAppSettings/2016.json | 1141 ++ resources/img/animation.png | Bin 0 -> 85823 bytes resources/img/audio.png | Bin 0 -> 55723 bytes resources/img/script.png | Bin 0 -> 49482 bytes resources/img/tshirt-template.png | Bin 0 -> 28258 bytes resources/js/app.js | 2 + resources/js/modules/alpine.js | 7 + resources/js/modules/axios.js | 4 + resources/js/modules/bootstrap.js | 7 + resources/js/modules/echo.js | 18 + resources/js/modules/index.js | 5 + resources/js/modules/jquery.js | 7 + resources/js/tadah/account/disabledAccount.js | 9 + resources/js/tadah/account/index.js | 3 + .../js/tadah/account/sessionManagement.js | 21 + resources/js/tadah/account/view.js | 14 + resources/js/tadah/admin/ban.js | 87 + resources/js/tadah/admin/index.js | 12 + resources/js/tadah/auth/heartbeat.js | 7 + resources/js/tadah/auth/index.js | 1 + resources/js/tadah/gameServer/index.js | 1 + resources/js/tadah/gameServer/view.js | 124 + resources/js/tadah/helpers.js | 35 + resources/js/tadah/index.js | 7 + resources/js/tadah/register.js | 191 + resources/js/tadah/styles.js | 17 + resources/lua/Edit.lua | 14 + resources/lua/Gameserver.lua | 230 + resources/lua/GroupBuild.lua | 52 + resources/lua/Join.lua | 8 + resources/lua/LoadPlaceInfo.lua | 9 + resources/lua/MultiplayerSharedScript.lua | 213 + resources/lua/PlaySolo.lua | 64 + resources/lua/SingleplayerSharedScript.lua | 38 + resources/lua/Studio.lua | 23 + resources/lua/Visit.lua | 77 + resources/sass/_tadah.scss | 6 + resources/sass/app.scss | 67 + resources/sass/tadah/_bootstrap.scss | 5 + resources/sass/tadah/_extra.scss | 720 + resources/tadah.proto | 62 + resources/views/admin/action-log.blade.php | 20 + resources/views/admin/alert.blade.php | 20 + .../components/game-server/status.blade.php | 51 + .../components/game-server/syntax.blade.php | 5 + .../components/game-server/topbar.blade.php | 98 + .../admin/components/mini-profile.blade.php | 8 + .../admin/components/panel/item.blade.php | 15 + .../admin/components/panel/row.blade.php | 7 + .../views/admin/game-server/all.blade.php | 25 + .../views/admin/game-server/create.blade.php | 20 + .../views/admin/game-server/manage.blade.php | 17 + .../views/admin/game-server/view.blade.php | 105 + resources/views/admin/panel.blade.php | 65 + resources/views/admin/permissions.blade.php | 99 + resources/views/admin/user/ban.blade.php | 104 + .../views/admin/user/ip-address-ban.blade.php | 63 + resources/views/admin/user/profile.blade.php | 104 + resources/views/auth/2fa.blade.php | 21 + .../views/auth/account-disabled.blade.php | 71 + .../views/auth/confirm-password.blade.php | 22 + resources/views/auth/login.blade.php | 33 + resources/views/auth/register.blade.php | 36 + .../views/auth/request-password.blade.php | 24 + resources/views/auth/reset-password.blade.php | 39 + resources/views/auth/update-email.blade.php | 35 + resources/views/auth/verify-email.blade.php | 40 + resources/views/catalog/index.blade.php | 4 + .../views/components/user/headshot.blade.php | 1 + .../views/components/user/thumbnail.blade.php | 1 + resources/views/develop/index.blade.php | 7 + resources/views/document/privacy.blade.php | 10 + resources/views/document/rules.blade.php | 10 + resources/views/document/statistics.blade.php | 10 + resources/views/document/tos.blade.php | 10 + resources/views/errors/401.blade.php | 1 + resources/views/errors/403.blade.php | 1 + resources/views/errors/404.blade.php | 1 + resources/views/errors/419.blade.php | 1 + resources/views/errors/429.blade.php | 1 + resources/views/errors/500.blade.php | 1 + resources/views/errors/503.blade.php | 1 + resources/views/forum/category.blade.php | 19 + resources/views/forum/index.blade.php | 18 + resources/views/forum/sidebar.blade.php | 25 + resources/views/forum/thread.blade.php | 11 + resources/views/games/index.blade.php | 6 + resources/views/item/configure.blade.php | 23 + resources/views/item/view.blade.php | 99 + resources/views/landing.blade.php | 28 + resources/views/layouts/app.blade.php | 58 + resources/views/layouts/auth.blade.php | 43 + resources/views/layouts/error.blade.php | 24 + .../account/moderation-history.blade.php | 28 + .../two-factor-authentication.blade.php | 18 + .../livewire/account/update-blurb.blade.php | 16 + .../account/update-password.blade.php | 54 + .../account/update-username.blade.php | 45 + .../views/livewire/admin/action-log.blade.php | 39 + .../views/livewire/admin/alert.blade.php | 46 + .../admin/ban/ip-address-search.blade.php | 47 + .../livewire/admin/ban/ip-address.blade.php | 31 + .../admin/ban/pardon-ip-address.blade.php | 20 + .../views/livewire/admin/ban/pardon.blade.php | 33 + .../views/livewire/admin/ban/search.blade.php | 47 + .../views/livewire/admin/ban/user.blade.php | 89 + .../livewire/admin/game-server/all.blade.php | 28 + .../admin/game-server/create.blade.php | 82 + .../admin/game-server/delete.blade.php | 21 + .../admin/game-server/manage.blade.php | 80 + .../admin/user/associated-accounts.blade.php | 28 + .../admin/user/moderation-history.blade.php | 28 + .../views/livewire/auth/register.blade.php | 138 + .../livewire/dashboard/best-friends.blade.php | 14 + .../views/livewire/dashboard/feed.blade.php | 61 + .../dashboard/recently-played-games.blade.php | 7 + .../views/livewire/develop/assets.blade.php | 55 + .../views/livewire/develop/create.blade.php | 42 + .../views/livewire/develop/panel.blade.php | 38 + .../views/livewire/forum/create.blade.php | 3 + .../views/livewire/forum/replies.blade.php | 42 + .../views/livewire/forum/thread.blade.php | 53 + .../views/livewire/forum/threads.blade.php | 34 + .../views/livewire/games/search.blade.php | 75 + .../views/livewire/item/comments.blade.php | 11 + .../views/livewire/item/configure.blade.php | 84 + .../livewire/layout/search-bar.blade.php | 48 + .../livewire/users/friend-button.blade.php | 14 + .../views/livewire/users/search.blade.php | 65 + resources/views/my/account.blade.php | 211 + .../my/components/dashboard/news.blade.php | 1 + .../views/my/components/session.blade.php | 45 + resources/views/my/dashboard.blade.php | 31 + resources/views/my/invites.blade.php | 99 + resources/views/partials/footer.blade.php | 44 + .../partials/language-dropdown.blade.php | 10 + resources/views/partials/navigation.blade.php | 124 + resources/views/users/list.blade.php | 5 + resources/views/users/profile.blade.php | 108 + resources/xml/BodyColors.xml | 17 + resources/xml/Decal.xml | 16 + resources/xml/Pants.xml | 13 + resources/xml/Shirt.xml | 13 + resources/xml/TShirt.xml | 13 + routes/api.php | 12 + routes/arbiter.php | 12 + routes/auth.php | 70 + routes/channels.php | 17 + routes/roblox.php | 142 + routes/web.php | 131 + storage/app/.gitignore | 4 + storage/app/keys/.gitignore | 2 + storage/app/public/.gitignore | 2 + storage/debugbar/.gitignore | 2 + storage/framework/.gitignore | 9 + storage/framework/cache/.gitignore | 3 + storage/framework/cache/data/.gitignore | 2 + storage/framework/sessions/.gitignore | 2 + storage/framework/testing/.gitignore | 2 + storage/framework/views/.gitignore | 2 + storage/logs/.gitignore | 2 + webpack.mix.js | 19 + 460 files changed, 46775 insertions(+) create mode 100644 .dockerignore create mode 100644 .editorconfig create mode 100644 .env.example create mode 100644 .env.testing create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 app/Broadcasting/GameServerChannel.php create mode 100644 app/Cdn/Manager.php create mode 100644 app/Console/Commands/MeilisearchKeyGenerate.php create mode 100644 app/Console/Commands/PusherIdGenerate.php create mode 100644 app/Console/Commands/PusherSecretGenerate.php create mode 100644 app/Console/Kernel.php create mode 100644 app/Discord/User.php create mode 100644 app/Enums/Actions.php create mode 100644 app/Enums/ArbiterLogSeverity.php create mode 100644 app/Enums/AssetGenre.php create mode 100644 app/Enums/AssetModeration.php create mode 100644 app/Enums/AssetType.php create mode 100644 app/Enums/ChatStyle.php create mode 100644 app/Enums/CreatorType.php create mode 100644 app/Enums/DevelopPage.php create mode 100644 app/Enums/GameServerState.php create mode 100644 app/Enums/PlaceAccess.php create mode 100644 app/Enums/PlaceSort.php create mode 100644 app/Enums/SignatureType.php create mode 100644 app/Events/GameServer/ConsoleOutput.php create mode 100644 app/Events/GameServer/NewPlaceJob.php create mode 100644 app/Events/GameServer/NewThumbnailJob.php create mode 100644 app/Events/GameServer/ResourceReport.php create mode 100644 app/Events/GameServer/StateChange.php create mode 100644 app/Events/IpAddressBanModified.php create mode 100644 app/Exceptions/Handler.php create mode 100644 app/GPBMetadata/Resources/Tadah.php create mode 100644 app/Helpers/Agent.php create mode 100644 app/Helpers/Cdn.php create mode 100644 app/Helpers/IpAddressBanManager.php create mode 100644 app/Helpers/PaginationTransformer.php create mode 100644 app/Http/Controllers/Account/DashboardController.php create mode 100644 app/Http/Controllers/Account/DisabledAccountController.php create mode 100644 app/Http/Controllers/Account/DiscordController.php create mode 100644 app/Http/Controllers/Account/InviteKeyController.php create mode 100644 app/Http/Controllers/Account/SessionController.php create mode 100644 app/Http/Controllers/Account/SettingsController.php create mode 100644 app/Http/Controllers/Admin/ActionLogController.php create mode 100644 app/Http/Controllers/Admin/AlertController.php create mode 100644 app/Http/Controllers/Admin/BanController.php create mode 100644 app/Http/Controllers/Admin/BanInformationController.php create mode 100644 app/Http/Controllers/Admin/GameServerController.php create mode 100644 app/Http/Controllers/Admin/IpAddressBanController.php create mode 100644 app/Http/Controllers/Admin/PanelController.php create mode 100644 app/Http/Controllers/Admin/PermissionsController.php create mode 100644 app/Http/Controllers/Admin/UserProfileController.php create mode 100644 app/Http/Controllers/Arbiter/IdentificationController.php create mode 100644 app/Http/Controllers/Arbiter/LogController.php create mode 100644 app/Http/Controllers/Arbiter/StateController.php create mode 100644 app/Http/Controllers/Auth/EmailVerificationNotificationController.php create mode 100644 app/Http/Controllers/Auth/PasswordResetController.php create mode 100644 app/Http/Controllers/CatalogController.php create mode 100644 app/Http/Controllers/Controller.php create mode 100644 app/Http/Controllers/DevelopController.php create mode 100644 app/Http/Controllers/ForumController.php create mode 100644 app/Http/Controllers/GamesController.php create mode 100644 app/Http/Controllers/HomeController.php create mode 100644 app/Http/Controllers/ItemController.php create mode 100644 app/Http/Controllers/Roblox/FastFlagController.php create mode 100644 app/Http/Controllers/Roblox/MiscellaneousScriptController.php create mode 100644 app/Http/Controllers/Roblox/OnlinePlayController.php create mode 100644 app/Http/Controllers/Roblox/StaticAssetController.php create mode 100644 app/Http/Controllers/Roblox/StudioController.php create mode 100644 app/Http/Controllers/UsersController.php create mode 100644 app/Http/Kernel.php create mode 100644 app/Http/Livewire/Account/ModerationHistory.php create mode 100644 app/Http/Livewire/Account/TwoFactorAuthentication.php create mode 100644 app/Http/Livewire/Account/UpdateBlurb.php create mode 100644 app/Http/Livewire/Account/UpdatePassword.php create mode 100644 app/Http/Livewire/Account/UpdateUsername.php create mode 100644 app/Http/Livewire/Admin/ActionLog.php create mode 100644 app/Http/Livewire/Admin/Alert.php create mode 100644 app/Http/Livewire/Admin/Ban/IpAddress.php create mode 100644 app/Http/Livewire/Admin/Ban/IpAddressSearch.php create mode 100644 app/Http/Livewire/Admin/Ban/Pardon.php create mode 100644 app/Http/Livewire/Admin/Ban/PardonIpAddress.php create mode 100644 app/Http/Livewire/Admin/Ban/Search.php create mode 100644 app/Http/Livewire/Admin/Ban/User.php create mode 100644 app/Http/Livewire/Admin/GameServer/All.php create mode 100644 app/Http/Livewire/Admin/GameServer/Create.php create mode 100644 app/Http/Livewire/Admin/GameServer/Delete.php create mode 100644 app/Http/Livewire/Admin/GameServer/Manage.php create mode 100644 app/Http/Livewire/Admin/User/AssociatedAccounts.php create mode 100644 app/Http/Livewire/Admin/User/ModerationHistory.php create mode 100644 app/Http/Livewire/Auth/Register.php create mode 100644 app/Http/Livewire/Dashboard/BestFriends.php create mode 100644 app/Http/Livewire/Dashboard/Feed.php create mode 100644 app/Http/Livewire/Dashboard/RecentlyPlayedGames.php create mode 100644 app/Http/Livewire/Develop/Assets.php create mode 100644 app/Http/Livewire/Develop/Create.php create mode 100644 app/Http/Livewire/Develop/Panel.php create mode 100644 app/Http/Livewire/Forum/Create.php create mode 100644 app/Http/Livewire/Forum/Replies.php create mode 100644 app/Http/Livewire/Forum/Thread.php create mode 100644 app/Http/Livewire/Forum/Threads.php create mode 100644 app/Http/Livewire/Games/Search.php create mode 100644 app/Http/Livewire/Item/Comments.php create mode 100644 app/Http/Livewire/Item/Configure.php create mode 100644 app/Http/Livewire/Layout/SearchBar.php create mode 100644 app/Http/Livewire/Users/FriendButton.php create mode 100644 app/Http/Livewire/Users/Search.php create mode 100644 app/Http/Middleware/AdminGuard.php create mode 100644 app/Http/Middleware/Authenticate.php create mode 100644 app/Http/Middleware/AuthenticateArbiter.php create mode 100644 app/Http/Middleware/BlockBannedIpAddresses.php create mode 100644 app/Http/Middleware/EncryptCookies.php create mode 100644 app/Http/Middleware/EnsureEmailIsVerified.php create mode 100644 app/Http/Middleware/IsBanned.php create mode 100644 app/Http/Middleware/Localization.php create mode 100644 app/Http/Middleware/PreventRequestsDuringMaintenance.php create mode 100644 app/Http/Middleware/RedirectIfAuthenticated.php create mode 100644 app/Http/Middleware/ToolGuard.php create mode 100644 app/Http/Middleware/TrimStrings.php create mode 100644 app/Http/Middleware/TrustHosts.php create mode 100644 app/Http/Middleware/TrustProxies.php create mode 100644 app/Http/Middleware/UpdateCurrentIpAddress.php create mode 100644 app/Http/Middleware/VerifyCsrfToken.php create mode 100644 app/Listeners/GameServer/AppendConsoleOutput.php create mode 100644 app/Listeners/GameServer/ChangeState.php create mode 100644 app/Listeners/GameServer/Ping.php create mode 100644 app/Listeners/SendEmailVerificationNotification.php create mode 100644 app/Models/Action.php create mode 100644 app/Models/Asset.php create mode 100644 app/Models/AssetComment.php create mode 100644 app/Models/AssetOwnership.php create mode 100644 app/Models/AssetVersion.php create mode 100644 app/Models/Badge.php create mode 100644 app/Models/Ban.php create mode 100644 app/Models/ForumCategory.php create mode 100644 app/Models/ForumReply.php create mode 100644 app/Models/ForumThread.php create mode 100644 app/Models/Friendship.php create mode 100644 app/Models/GameServer.php create mode 100644 app/Models/InviteKey.php create mode 100644 app/Models/IpAddressBan.php create mode 100644 app/Models/PlaceJob.php create mode 100644 app/Models/PoisonedIpAddress.php create mode 100644 app/Models/Status.php create mode 100644 app/Models/ThumbnailJob.php create mode 100644 app/Models/Universe.php create mode 100644 app/Models/User.php create mode 100644 app/Notifications/AccountSecurityNotification.php create mode 100644 app/Proto/AssetType.php create mode 100644 app/Proto/ClientVersion.php create mode 100644 app/Proto/Operation.php create mode 100644 app/Proto/Response.php create mode 100644 app/Proto/Signal.php create mode 100644 app/Proto/Signal/Place.php create mode 100644 app/Proto/Signal/Thumbnail.php create mode 100644 app/Proto/Signal_Place.php create mode 100644 app/Proto/Signal_Thumbnail.php create mode 100644 app/Providers/AppServiceProvider.php create mode 100644 app/Providers/AuthServiceProvider.php create mode 100644 app/Providers/BroadcastServiceProvider.php create mode 100644 app/Providers/EventServiceProvider.php create mode 100644 app/Providers/FortifyServiceProvider.php create mode 100644 app/Providers/HorizonServiceProvider.php create mode 100644 app/Providers/RouteServiceProvider.php create mode 100644 app/Providers/TelescopeServiceProvider.php create mode 100644 app/Roblox/Script/Script.php create mode 100644 app/Roblox/Script/ScriptBuilder.php create mode 100644 app/Roles/Admin.php create mode 100644 app/Roles/Economy.php create mode 100644 app/Roles/Forums.php create mode 100644 app/Roles/GameServers.php create mode 100644 app/Roles/Places.php create mode 100644 app/Roles/Roles.php create mode 100644 app/Roles/SelfHostedServers.php create mode 100644 app/Roles/Users.php create mode 100644 app/Routing/Matching/CaseInsensitiveUriValidator.php create mode 100644 app/Rules/IsAlphaNumeric.php create mode 100644 app/Rules/IsCurrentPassword.php create mode 100644 app/Rules/IsRobloxXml.php create mode 100644 app/Rules/IsSiprNameOrIpAddress.php create mode 100644 app/Rules/IsUniqueEmail.php create mode 100644 app/Rules/IsValidInviteKey.php create mode 100644 app/Rules/IsValidSession.php create mode 100644 app/Signing/Signature.php create mode 100644 app/Signing/Signer.php create mode 100644 app/Traits/EmailValidationRules.php create mode 100644 app/Traits/PasswordValidationRules.php create mode 100644 app/Traits/UsernameValidationRules.php create mode 100644 app/View/Components/AppLayout.php create mode 100644 app/View/Components/AuthLayout.php create mode 100644 app/View/Components/ErrorLayout.php create mode 100644 app/helpers.php create mode 100644 artisan create mode 100644 bootstrap/app.php create mode 100644 bootstrap/cache/.gitignore create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 config/app.php create mode 100644 config/auth.php create mode 100644 config/broadcasting.php create mode 100644 config/cache.php create mode 100644 config/ciphersweet.php create mode 100644 config/cors.php create mode 100644 config/database.php create mode 100644 config/disposable-email.php create mode 100644 config/filesystems.php create mode 100644 config/fortify.php create mode 100644 config/hashing.php create mode 100644 config/horizon.php create mode 100644 config/livewire.php create mode 100644 config/logging.php create mode 100644 config/mail.php create mode 100644 config/octane.php create mode 100644 config/parsedown.php create mode 100644 config/queue.php create mode 100644 config/recaptcha.php create mode 100644 config/scout.php create mode 100644 config/services.php create mode 100644 config/session.php create mode 100644 config/tadah.php create mode 100644 config/telescope.php create mode 100644 config/view.php create mode 100644 database/.gitignore create mode 100644 database/factories/UserFactory.php create mode 100644 database/migrations/2014_10_12_000000_create_users_table.php create mode 100644 database/migrations/2014_10_12_100000_create_password_resets_table.php create mode 100644 database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php create mode 100644 database/migrations/2019_08_19_000000_create_failed_jobs_table.php create mode 100644 database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php create mode 100644 database/migrations/2022_01_09_205316_create_game_servers_table.php create mode 100644 database/migrations/2022_01_09_205341_create_badges_table.php create mode 100644 database/migrations/2022_01_09_205414_create_place_jobs_table.php create mode 100644 database/migrations/2022_02_13_073348_create_invite_keys_table.php create mode 100644 database/migrations/2022_02_19_063207_create_sessions_table.php create mode 100644 database/migrations/2022_03_06_004335_create_bans_table.php create mode 100644 database/migrations/2022_03_06_074551_create_ip_address_bans_table.php create mode 100644 database/migrations/2022_03_14_224312_create_poisoned_ip_addresses.php create mode 100644 database/migrations/2022_03_20_025917_create_thumbnail_jobs_table.php create mode 100644 database/migrations/2022_03_26_044913_create_job_batches_table.php create mode 100644 database/migrations/2022_04_12_154421_create_statuses_table.php create mode 100644 database/migrations/2022_04_12_224438_create_assets_table.php create mode 100644 database/migrations/2022_04_13_095641_create_asset_versions_table.php create mode 100644 database/migrations/2022_04_13_095721_create_universes_table.php create mode 100644 database/migrations/2022_04_13_100911_create_asset_comments_table.php create mode 100644 database/migrations/2022_04_13_101743_create_asset_ownerships_table.php create mode 100644 database/migrations/2022_04_16_080833_create_friendships_table.php create mode 100644 database/migrations/2022_07_02_101148_create_actions_table.php create mode 100644 database/migrations/2022_07_02_135149_create_forum_threads_table.php create mode 100644 database/migrations/2022_07_02_135209_create_forum_replies_table.php create mode 100644 database/migrations/2022_07_02_135303_create_forum_categories_table.php create mode 100644 database/seeders/DatabaseSeeder.php create mode 100644 docker-compose.yml create mode 100644 docker/Dockerfile create mode 100644 docker/php.ini create mode 100644 docker/release/Dockerfile create mode 100644 docker/release/php.ini create mode 100644 docker/release/start-container create mode 100644 docker/release/supervisord.conf create mode 100644 docker/start-container create mode 100644 docker/supervisord.conf create mode 100644 lang/en_US.json create mode 100644 lang/en_US/auth.php create mode 100644 lang/en_US/pagination.php create mode 100644 lang/en_US/passwords.php create mode 100644 lang/en_US/validation.php create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 phpstan.neon create mode 100644 public/content create mode 100644 public/favicon.ico create mode 100644 public/fonts/TwemojiMozilla.ttf create mode 100644 public/img/blobs/dead.png create mode 100644 public/img/blobs/exhausted.png create mode 100644 public/img/blobs/ghastly.png create mode 100644 public/img/blobs/inquisitive.png create mode 100644 public/img/blobs/open_mouth.png create mode 100644 public/img/blobs/scared.png create mode 100644 public/img/blobs/sick.png create mode 100644 public/img/blobs/sweaty.png create mode 100644 public/img/blobs/tired.png create mode 100644 public/img/dead.png create mode 100644 public/img/hero/register.png create mode 100644 public/img/laravel/horizon.png create mode 100644 public/img/laravel/telescope.png create mode 100644 public/img/logo/big.png create mode 100644 public/img/logo/dahllor.svg create mode 100644 public/img/logo/small.png create mode 100644 public/img/placeholder/icon.png create mode 100644 public/img/placeholder/widescreen.png create mode 100644 public/index.php create mode 100644 public/robots.txt create mode 100644 public/vid/landing.mp4 create mode 100644 public/vid/landing.webm create mode 100644 resources/css/fa6-pro.min.css create mode 100644 resources/flags/ClientAppSettings/2012.json create mode 100644 resources/flags/ClientAppSettings/2016.json create mode 100644 resources/img/animation.png create mode 100644 resources/img/audio.png create mode 100644 resources/img/script.png create mode 100644 resources/img/tshirt-template.png create mode 100644 resources/js/app.js create mode 100644 resources/js/modules/alpine.js create mode 100644 resources/js/modules/axios.js create mode 100644 resources/js/modules/bootstrap.js create mode 100644 resources/js/modules/echo.js create mode 100644 resources/js/modules/index.js create mode 100644 resources/js/modules/jquery.js create mode 100644 resources/js/tadah/account/disabledAccount.js create mode 100644 resources/js/tadah/account/index.js create mode 100644 resources/js/tadah/account/sessionManagement.js create mode 100644 resources/js/tadah/account/view.js create mode 100644 resources/js/tadah/admin/ban.js create mode 100644 resources/js/tadah/admin/index.js create mode 100644 resources/js/tadah/auth/heartbeat.js create mode 100644 resources/js/tadah/auth/index.js create mode 100644 resources/js/tadah/gameServer/index.js create mode 100644 resources/js/tadah/gameServer/view.js create mode 100644 resources/js/tadah/helpers.js create mode 100644 resources/js/tadah/index.js create mode 100644 resources/js/tadah/register.js create mode 100644 resources/js/tadah/styles.js create mode 100644 resources/lua/Edit.lua create mode 100644 resources/lua/Gameserver.lua create mode 100644 resources/lua/GroupBuild.lua create mode 100644 resources/lua/Join.lua create mode 100644 resources/lua/LoadPlaceInfo.lua create mode 100644 resources/lua/MultiplayerSharedScript.lua create mode 100644 resources/lua/PlaySolo.lua create mode 100644 resources/lua/SingleplayerSharedScript.lua create mode 100644 resources/lua/Studio.lua create mode 100644 resources/lua/Visit.lua create mode 100644 resources/sass/_tadah.scss create mode 100644 resources/sass/app.scss create mode 100644 resources/sass/tadah/_bootstrap.scss create mode 100644 resources/sass/tadah/_extra.scss create mode 100644 resources/tadah.proto create mode 100644 resources/views/admin/action-log.blade.php create mode 100644 resources/views/admin/alert.blade.php create mode 100644 resources/views/admin/components/game-server/status.blade.php create mode 100644 resources/views/admin/components/game-server/syntax.blade.php create mode 100644 resources/views/admin/components/game-server/topbar.blade.php create mode 100644 resources/views/admin/components/mini-profile.blade.php create mode 100644 resources/views/admin/components/panel/item.blade.php create mode 100644 resources/views/admin/components/panel/row.blade.php create mode 100644 resources/views/admin/game-server/all.blade.php create mode 100644 resources/views/admin/game-server/create.blade.php create mode 100644 resources/views/admin/game-server/manage.blade.php create mode 100644 resources/views/admin/game-server/view.blade.php create mode 100644 resources/views/admin/panel.blade.php create mode 100644 resources/views/admin/permissions.blade.php create mode 100644 resources/views/admin/user/ban.blade.php create mode 100644 resources/views/admin/user/ip-address-ban.blade.php create mode 100644 resources/views/admin/user/profile.blade.php create mode 100644 resources/views/auth/2fa.blade.php create mode 100644 resources/views/auth/account-disabled.blade.php create mode 100644 resources/views/auth/confirm-password.blade.php create mode 100644 resources/views/auth/login.blade.php create mode 100644 resources/views/auth/register.blade.php create mode 100644 resources/views/auth/request-password.blade.php create mode 100644 resources/views/auth/reset-password.blade.php create mode 100644 resources/views/auth/update-email.blade.php create mode 100644 resources/views/auth/verify-email.blade.php create mode 100644 resources/views/catalog/index.blade.php create mode 100644 resources/views/components/user/headshot.blade.php create mode 100644 resources/views/components/user/thumbnail.blade.php create mode 100644 resources/views/develop/index.blade.php create mode 100644 resources/views/document/privacy.blade.php create mode 100644 resources/views/document/rules.blade.php create mode 100644 resources/views/document/statistics.blade.php create mode 100644 resources/views/document/tos.blade.php create mode 100644 resources/views/errors/401.blade.php create mode 100644 resources/views/errors/403.blade.php create mode 100644 resources/views/errors/404.blade.php create mode 100644 resources/views/errors/419.blade.php create mode 100644 resources/views/errors/429.blade.php create mode 100644 resources/views/errors/500.blade.php create mode 100644 resources/views/errors/503.blade.php create mode 100644 resources/views/forum/category.blade.php create mode 100644 resources/views/forum/index.blade.php create mode 100644 resources/views/forum/sidebar.blade.php create mode 100644 resources/views/forum/thread.blade.php create mode 100644 resources/views/games/index.blade.php create mode 100644 resources/views/item/configure.blade.php create mode 100644 resources/views/item/view.blade.php create mode 100644 resources/views/landing.blade.php create mode 100644 resources/views/layouts/app.blade.php create mode 100644 resources/views/layouts/auth.blade.php create mode 100644 resources/views/layouts/error.blade.php create mode 100644 resources/views/livewire/account/moderation-history.blade.php create mode 100644 resources/views/livewire/account/two-factor-authentication.blade.php create mode 100644 resources/views/livewire/account/update-blurb.blade.php create mode 100644 resources/views/livewire/account/update-password.blade.php create mode 100644 resources/views/livewire/account/update-username.blade.php create mode 100644 resources/views/livewire/admin/action-log.blade.php create mode 100644 resources/views/livewire/admin/alert.blade.php create mode 100644 resources/views/livewire/admin/ban/ip-address-search.blade.php create mode 100644 resources/views/livewire/admin/ban/ip-address.blade.php create mode 100644 resources/views/livewire/admin/ban/pardon-ip-address.blade.php create mode 100644 resources/views/livewire/admin/ban/pardon.blade.php create mode 100644 resources/views/livewire/admin/ban/search.blade.php create mode 100644 resources/views/livewire/admin/ban/user.blade.php create mode 100644 resources/views/livewire/admin/game-server/all.blade.php create mode 100644 resources/views/livewire/admin/game-server/create.blade.php create mode 100644 resources/views/livewire/admin/game-server/delete.blade.php create mode 100644 resources/views/livewire/admin/game-server/manage.blade.php create mode 100644 resources/views/livewire/admin/user/associated-accounts.blade.php create mode 100644 resources/views/livewire/admin/user/moderation-history.blade.php create mode 100644 resources/views/livewire/auth/register.blade.php create mode 100644 resources/views/livewire/dashboard/best-friends.blade.php create mode 100644 resources/views/livewire/dashboard/feed.blade.php create mode 100644 resources/views/livewire/dashboard/recently-played-games.blade.php create mode 100644 resources/views/livewire/develop/assets.blade.php create mode 100644 resources/views/livewire/develop/create.blade.php create mode 100644 resources/views/livewire/develop/panel.blade.php create mode 100644 resources/views/livewire/forum/create.blade.php create mode 100644 resources/views/livewire/forum/replies.blade.php create mode 100644 resources/views/livewire/forum/thread.blade.php create mode 100644 resources/views/livewire/forum/threads.blade.php create mode 100644 resources/views/livewire/games/search.blade.php create mode 100644 resources/views/livewire/item/comments.blade.php create mode 100644 resources/views/livewire/item/configure.blade.php create mode 100644 resources/views/livewire/layout/search-bar.blade.php create mode 100644 resources/views/livewire/users/friend-button.blade.php create mode 100644 resources/views/livewire/users/search.blade.php create mode 100644 resources/views/my/account.blade.php create mode 100644 resources/views/my/components/dashboard/news.blade.php create mode 100644 resources/views/my/components/session.blade.php create mode 100644 resources/views/my/dashboard.blade.php create mode 100644 resources/views/my/invites.blade.php create mode 100644 resources/views/partials/footer.blade.php create mode 100644 resources/views/partials/language-dropdown.blade.php create mode 100644 resources/views/partials/navigation.blade.php create mode 100644 resources/views/users/list.blade.php create mode 100644 resources/views/users/profile.blade.php create mode 100644 resources/xml/BodyColors.xml create mode 100644 resources/xml/Decal.xml create mode 100644 resources/xml/Pants.xml create mode 100644 resources/xml/Shirt.xml create mode 100644 resources/xml/TShirt.xml create mode 100644 routes/api.php create mode 100644 routes/arbiter.php create mode 100644 routes/auth.php create mode 100644 routes/channels.php create mode 100644 routes/roblox.php create mode 100644 routes/web.php create mode 100644 storage/app/.gitignore create mode 100644 storage/app/keys/.gitignore create mode 100644 storage/app/public/.gitignore create mode 100644 storage/debugbar/.gitignore create mode 100644 storage/framework/.gitignore create mode 100644 storage/framework/cache/.gitignore create mode 100644 storage/framework/cache/data/.gitignore create mode 100644 storage/framework/sessions/.gitignore create mode 100644 storage/framework/testing/.gitignore create mode 100644 storage/framework/views/.gitignore create mode 100644 storage/logs/.gitignore create mode 100644 webpack.mix.js diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..913af3b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,17 @@ +# Artifacts +vendor/ +storage/ +app/bootstrap/cache/* + +# Developer utilities +.git* +.env* +.editorconfig +Dockerfile +docker-compose.yml +docker/Dockerfile +docker/supervisord.conf +phpstan.neon +README.md + +!.env.example diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..1671c9b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{yml,yaml}] +indent_size = 2 + +[docker-compose.yml] +indent_size = 4 diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..83287ab --- /dev/null +++ b/.env.example @@ -0,0 +1,91 @@ +APP_NAME=Tadah +APP_ENV=local +APP_KEY= +APP_DEBUG=true +APP_URL=http://tadah.loc +APP_TIMEZONE=UTC + +ROBLOX_PRIVATE_KEY_PASSPHRASE= +ARBITER_PRIVATE_KEY_PASSPHRASE= + +HORIZON_PATH=admin/horizon +HORIZON_ENABLED=true + +TELESCOPE_PATH=admin/telescope +TELESCOPE_DRIVER=database +TELESCOPE_ENABLED=true + +SAIL_XDEBUG_MODE=develop,debug + +EMAIL_VERIFICATION=true +REQUIRE_INVITE_KEYS=false +USERS_CREATE_INVITE_KEYS=true +USERS_DISCORD_REQUIRED=true + +LOG_CHANNEL=stack +LOG_DEPRECATIONS_CHANNEL=null +LOG_LEVEL=debug + +DB_CONNECTION=pgsql +DB_HOST=pgsql +DB_PORT=5432 +DB_DATABASE=tadah +DB_USERNAME=sail +DB_PASSWORD=password + +BROADCAST_DRIVER=pusher +CACHE_DRIVER=redis +FILESYSTEM_DISK=local +QUEUE_CONNECTION=redis +SESSION_DRIVER=database +SESSION_LIFETIME=120 + +MEMCACHED_HOST=memcached + +REDIS_HOST=redis +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=smtp +MAIL_HOST=mailhog +MAIL_PORT=1025 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS="tadah@tadah.loc" +MAIL_FROM_NAME="${APP_NAME}" + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= +AWS_USE_PATH_STYLE_ENDPOINT=false + +PUSHER_APP_ID=app-id +PUSHER_APP_KEY=app-key +PUSHER_APP_SECRET=app-key +PUSHER_HOST=soketi +PUSHER_CLIENT_HOST="tadah.loc" +PUSHER_PORT=6001 +PUSHER_SCHEME="http" + +MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +MIX_PUSHER_CLIENT_HOST="${PUSHER_CLIENT_HOST}" +MIX_PUSHER_PORT="${PUSHER_PORT}" +MIX_PUSHER_SCHEME="${PUSHER_SCHEME}" + +SCOUT_DRIVER=meilisearch +MEILISEARCH_HOST=http://meilisearch:7700 +MEILISEARCH_KEY= + +CIPHERSWEET_KEY= + +# https://developers.google.com/recaptcha/docs/faq#id-like-to-run-automated-tests-with-recaptcha.-what-should-i-do +RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI +RECAPTCHA_SECRET_KEY=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe + +OCTANE_SERVER=swoole + +DISCORD_CLIENT_ID= +DISCORD_CLIENT_SECRET= +DISCORD_REDIRECT_URI=http://tadah.loc/my/discord/callback diff --git a/.env.testing b/.env.testing new file mode 100644 index 0000000..dc44246 --- /dev/null +++ b/.env.testing @@ -0,0 +1,91 @@ +APP_NAME=Tadah +APP_ENV=local +APP_KEY= +APP_DEBUG=true +APP_URL=http://tadah.loc +APP_TIMEZONE=UTC + +ROBLOX_PRIVATE_KEY_PASSPHRASE= +ARBITER_PRIVATE_KEY_PASSPHRASE= + +HORIZON_PATH=admin/horizon +HORIZON_ENABLED=false + +TELESCOPE_PATH=admin/telescope +TELESCOPE_DRIVER=database +TELESCOPE_ENABLED=false + +SAIL_XDEBUG_MODE=develop,debug + +EMAIL_VERIFICATION=true +REQUIRE_INVITE_KEYS=false +USERS_CREATE_INVITE_KEYS=true +USERS_DISCORD_REQUIRED=true + +LOG_CHANNEL=stack +LOG_DEPRECATIONS_CHANNEL=null +LOG_LEVEL=debug + +DB_CONNECTION=pgsql +DB_HOST=pgsql +DB_PORT=5432 +DB_DATABASE=tadah +DB_USERNAME=sail +DB_PASSWORD=password + +BROADCAST_DRIVER=pusher +CACHE_DRIVER=redis +FILESYSTEM_DISK=local +QUEUE_CONNECTION=redis +SESSION_DRIVER=database +SESSION_LIFETIME=120 + +MEMCACHED_HOST=memcached + +REDIS_HOST=redis +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=smtp +MAIL_HOST=mailhog +MAIL_PORT=1025 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS="tadah@tadah.loc" +MAIL_FROM_NAME="${APP_NAME}" + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= +AWS_USE_PATH_STYLE_ENDPOINT=false + +PUSHER_APP_ID=app-id +PUSHER_APP_KEY=app-key +PUSHER_APP_SECRET=app-key +PUSHER_HOST=soketi +PUSHER_CLIENT_HOST="tadah.loc" +PUSHER_PORT=6001 +PUSHER_SCHEME="http" + +MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +MIX_PUSHER_CLIENT_HOST="${PUSHER_CLIENT_HOST}" +MIX_PUSHER_PORT="${PUSHER_PORT}" +MIX_PUSHER_SCHEME="${PUSHER_SCHEME}" + +SCOUT_DRIVER=meilisearch +MEILISEARCH_HOST=http://meilisearch:7700 +MEILISEARCH_KEY= + +CIPHERSWEET_KEY= + +# https://developers.google.com/recaptcha/docs/faq#id-like-to-run-automated-tests-with-recaptcha.-what-should-i-do +RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI +RECAPTCHA_SECRET_KEY=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe + +OCTANE_SERVER=swoole + +DISCORD_CLIENT_ID= +DISCORD_CLIENT_SECRET= +DISCORD_REDIRECT_URI=http://tadah.loc/my/discord/callback diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..510d996 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,10 @@ +* text=auto + +*.blade.php diff=html +*.css diff=css +*.html diff=html +*.md diff=markdown +*.php diff=php + +/.github export-ignore +CHANGELOG.md export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..168501f --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +/node_modules +/public/hot +/public/storage +/public/css/app.css +/public/js/app.js +/public/js/app.js.LICENSE.txt +/public/mix-manifest.json +/public/vendor +/storage/*.key +/storage/framework/disposable_domains.json +/vendor +.env +.env.backup +.phpunit.result.cache +docker-compose.override.yml +Homestead.json +Homestead.yaml +npm-debug.log +yarn-error.log +/.idea +/.vscode +_ide_helper* diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..6bc2eaf --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,13 @@ +default: + image: php:8.1-alpine + +before_script: + - apk add -q --no-progress libpng-dev + - docker-php-ext-install gd > /dev/null + - curl -s -S https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + - cp .env.testing .env + - composer i -q -n --no-ansi --no-progress + +static analysis: + script: + - php -d memory_limit=512M vendor/bin/phpstan analyse -c phpstan.neon diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0ad25db --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/README.md b/README.md new file mode 100644 index 0000000..e5d8b4e --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +# Tadah +The Tadah Website + +## CI/CD +Tadah.Web is available on the Tadah CI. TeamCity builds the Docker image and uploads it to the Tadah internal Docker image registry (CI), and then tells the server to pull the newest image (CD). +- [production](https://ci.tadah.sipr/buildConfiguration/Tadah_Web_Production) (on https://tadah.rocks/) +- [development](https://ci.tadah.sipr/buildConfiguration/Tadah_Web_Development) (on https://tadahlabs.rocks/) + +## Notes +- Deploys are run on each push to `dev`. They are pushed to https://tadahlabs.rocks. Upon proper assessment, these updates can manually be pushed to production on https://tadah.rocks. The dev website is barred off and should only be accessible to developers. A mock database will be run on https://tadahlabs.rocks - it shall not be linked to the production database. +- Do not force-push build artifacts, such as CSS or JavaScript assets generated from Laravel Mix. Laravel Mix gets run during the deploy process. Force pushing build artifacts will result in endless merge conflicts, and is generally bad practice. +- Please submit bugs, issues, and features to add as an issue. New features should be a separate branch and should be a pull request once ready to merge with the trunk branch. The production branch should never be touched manually. +- Please sign your commits. + +## Stack +Tadah uses a BALL stack; Bootstrap, Alpine, Livewire, Laravel. On the backend, we use PostgreSQL for our Database. Additionally, Redis is used for cache, Meilisearch is used for search, and Mailhog is used for mail environment simulation. + +Docker is used both on the developer's environment (in the form of Laravel Sail) and on the production environment (in the form a fully independent Docker container.) + +## Local Environment +If on Linux, read steps starting from step 5. If on Windows, read all steps. + +1. Download and install Ubuntu (no version -- get generic) from the Microsoft Store +2. Download and install Docker Desktop for Windows. Install WSL2 if need be. +3. Enable Docker -> Ubuntu integration by opening Docker Desktop and navigating to Settings -> Resources -> WSL Integration and toggling Ubuntu +4. Open your Ubuntu terminal. Navigate to where you are keeping the Tadah repository (i.e. if on `C:\Tadah`, you do `cd /mnt/c/Tadah`) +5. Copy `.env.example` to `.env`. Line breaks might be malformed on Windows. If so, replace all occurrences of `\r\n` in `.env` with `\n` +7. Run `composer install` if you don't have the composer dependencies installed yet. +8. Run `./vendor/bin/sail up -d` +9. Generate the application keys: + - App: `./vendor/bin/sail artisan key:generate` + - Pusher: `./vendor/bin/sail artisan pusher:secret` + - Ciphersweet: `./vendor/bin/sail artisan ciphersweet:key` + - Meilisearch: `./vendor/bin/sail artisan meilisearch:key` +10. Run `./vendor/bin/sail npm ci && npm run dev` +11. Run `./vendor/bin/sail artisan migrate` if your migrations are not up already. +12. You may now navigate to http://127.0.0.1 to view Tadah. + +You may consult the [Laravel Sail documentation](https://laravel.com/docs/8.x/sail) for running Artisan and Composer commands. + +## License +~~Copyright (c) Tadah 2021-2022. All rights reserved. Not for public use.~~ + +Licensed under the GNU Affero General Public License v3.0. A copy of it [has been included](https://github.com/tadah-foss/web/blob/trunk/LICENSE). diff --git a/app/Broadcasting/GameServerChannel.php b/app/Broadcasting/GameServerChannel.php new file mode 100644 index 0000000..83d00f9 --- /dev/null +++ b/app/Broadcasting/GameServerChannel.php @@ -0,0 +1,32 @@ +may(GameServers::roleset(), GameServers::CONNECT); + } +} diff --git a/app/Cdn/Manager.php b/app/Cdn/Manager.php new file mode 100644 index 0000000..f1e98be --- /dev/null +++ b/app/Cdn/Manager.php @@ -0,0 +1,50 @@ +generateRandomKey(); + + if ($this->option('show')) + { + $this->line('' . $key . ''); + return; + } + + if (!$this->setKeyInEnvironmentFile($key)) + { + return; + } + + $this->laravel['config']['scout.meilisearch.key'] = $key; + + $this->info('Meilisearch key set successfully.'); + } + + /** + * Generate a random key for the application. + * + * @return string + * @throws \Exception + */ + protected function generateRandomKey(): string + { + return bin2hex(random_bytes(64)); + } + + /** + * Set the Meilisearch key in the environment file. + * + * @param string $key + * @return bool + */ + protected function setKeyInEnvironmentFile($key): bool + { + if (!$this->confirmToProceed()) + { + return false; + } + + $this->writeNewEnvironmentFileWith($key); + + return true; + } + + /** + * Write a new environment file with the given Meilisearch key. + * + * @param string $key + */ + protected function writeNewEnvironmentFileWith($key) + { + /** @var mixed */ + $laravel = $this->laravel; + + $content = file_get_contents( + $laravel->environmentFilePath() + ); + + if (!Str::contains($content, 'MEILISEARCH_KEY')) + { + file_put_contents( + $laravel->environmentFilePath(), + 'MEILISEARCH_KEY=' . $key, + FILE_APPEND + ); + + return; + } + + file_put_contents( + $laravel->environmentFilePath(), + preg_replace( + $this->keyReplacementPattern(), + 'MEILISEARCH_KEY=' . $key, + $content + ) + ); + } + + /** + * Get a regex pattern that will match env MEILISEARCH_KEY with any random key. + * + * @return string + */ + protected function keyReplacementPattern() + { + $escaped = preg_quote('=' . $this->laravel['config']['scout.meilisearch.key'], '/'); + + return "/^MEILISEARCH_KEY{$escaped}/m"; + } +} diff --git a/app/Console/Commands/PusherIdGenerate.php b/app/Console/Commands/PusherIdGenerate.php new file mode 100644 index 0000000..a83bb2b --- /dev/null +++ b/app/Console/Commands/PusherIdGenerate.php @@ -0,0 +1,129 @@ +generateRandomId(); + + if ($this->option('show')) + { + $this->line('' . $id . ''); + return; + } + + if (!$this->setIdInEnvironmentFile($id)) + { + return; + } + + $this->laravel['config']['broadcasting.connections.pusher.app_id'] = $id; + + $this->info('Pusher app ID set successfully.'); + } + + /** + * Generate a random ID for the application. + * + * @return string + * @throws \Exception + */ + protected function generateRandomId(): string + { + return uuid(); + } + + /** + * Set the application ID in the environment file. + * + * @param string $id + * @return bool + */ + protected function setIdInEnvironmentFile($id): bool + { + if (!$this->confirmToProceed()) + { + return false; + } + + $this->writeNewEnvironmentFileWith($id); + + return true; + } + + /** + * Write a new environment file with the given app ID. + * + * @param string $id + */ + protected function writeNewEnvironmentFileWith($id) + { + /** @var mixed */ + $laravel = $this->laravel; + + $content = file_get_contents( + $laravel->environmentFilePath() + ); + + if (!Str::contains($content, 'PUSHER_APP_ID')) + { + file_put_contents( + $laravel->environmentFilePath(), + 'PUSHER_APP_ID=' . $id, + FILE_APPEND + ); + + return; + } + + file_put_contents( + $laravel->environmentFilePath(), + preg_replace( + $this->idReplacementPattern(), + 'PUSHER_APP_ID=' . $id, + $content + ) + ); + } + + /** + * Get a regex pattern that will match env PUSHER_APP_ID with any random app ID. + * + * @return string + */ + protected function idReplacementPattern() + { + $escaped = preg_quote('=' . $this->laravel['config']['broadcasting.connections.pusher.app_id'], '/'); + + return "/^PUSHER_APP_ID{$escaped}/m"; + } +} diff --git a/app/Console/Commands/PusherSecretGenerate.php b/app/Console/Commands/PusherSecretGenerate.php new file mode 100644 index 0000000..007fcc2 --- /dev/null +++ b/app/Console/Commands/PusherSecretGenerate.php @@ -0,0 +1,129 @@ +generateRandomSecret(); + + if ($this->option('show')) + { + $this->line('' . $secret . ''); + return; + } + + if (!$this->setSecretInEnvironmentFile($secret)) + { + return; + } + + $this->laravel['config']['broadcasting.connections.pusher.secret'] = $secret; + + $this->info('Pusher secret set successfully.'); + } + + /** + * Generate a random secret for the application. + * + * @return string + * @throws \Exception + */ + protected function generateRandomSecret(): string + { + return bin2hex(random_bytes(32)); + } + + /** + * Set the application secret in the environment file. + * + * @param string $secret + * @return bool + */ + protected function setSecretInEnvironmentFile($secret): bool + { + if (!$this->confirmToProceed()) + { + return false; + } + + $this->writeNewEnvironmentFileWith($secret); + + return true; + } + + /** + * Write a new environment file with the given secret. + * + * @param string $secret + */ + protected function writeNewEnvironmentFileWith($secret) + { + /** @var mixed */ + $laravel = $this->laravel; + + $content = file_get_contents( + $laravel->environmentFilePath() + ); + + if (!Str::contains($content, 'PUSHER_APP_SECRET')) + { + file_put_contents( + $laravel->environmentFilePath(), + 'PUSHER_APP_SECRET=' . $secret, + FILE_APPEND + ); + + return; + } + + file_put_contents( + $laravel->environmentFilePath(), + preg_replace( + $this->secretReplacementPattern(), + 'PUSHER_APP_SECRET=' . $secret, + $content + ) + ); + } + + /** + * Get a regex pattern that will match env PUSHER_APP_SECRET with any random secret. + * + * @return string + */ + protected function secretReplacementPattern(): string + { + $escaped = preg_quote('=' . $this->laravel['config']['broadcasting.connections.pusher.secret'], '/'); + + return "/^PUSHER_APP_SECRET{$escaped}/m"; + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php new file mode 100644 index 0000000..562fe09 --- /dev/null +++ b/app/Console/Kernel.php @@ -0,0 +1,30 @@ +command('disposable:update')->weekly(); + } + + /** + * Register the commands for the application. + * + * @return void + */ + protected function commands() + { + $this->load(__DIR__.'/Commands'); + } +} diff --git a/app/Discord/User.php b/app/Discord/User.php new file mode 100644 index 0000000..0e98682 --- /dev/null +++ b/app/Discord/User.php @@ -0,0 +1,52 @@ + sprintf('Bot: %s', env('DISCORD_BOT_TOKEN'))]) + ->get(sprintf('https://discord.com/api/v9/users/%d', $discord_id)); + + $data = json_decode($data); + + $this->id = $data->id; + $this->username = $data->username; + $this->discriminator = $data->discriminator; + $this->avatar = $data->avatar; + $this->avatarUrl = sprintf('https://cdn.discordapp.com/avatars/%d/%s', $discord_id, $data->avatar); + } +} diff --git a/app/Enums/Actions.php b/app/Enums/Actions.php new file mode 100644 index 0000000..d27eca7 --- /dev/null +++ b/app/Enums/Actions.php @@ -0,0 +1,68 @@ + 'Temporarily banned :name until :date.', + self::PermBannedUser => 'Permanently banned :name.', + self::PoisonBannedUser => 'Poison banned :name.', + self::WarnedUser => 'Warned :name.', + self::PardonedUser => 'Pardoned :name.', + self::CreatedGameServer => 'Created game server :ip.', + self::DeletedGameServer => 'Deleted game server :ip.', + self::ModifiedGameServer => 'Modified game server :ip.', + self::AddIPBan => 'Added an IP ban.', + self::RemoveIPBan => 'Removed an IP ban.', + self::SiteAlert => 'Changed the site alert.', + self::ApprovedAsset => 'Approved a :type: :name. (Asset ID: :id)', + self::DeniedAsset => 'Denied a :type: :name. (Asset ID: :id)', + self::ModeratedAsset => 'Moderated a :type: :name. (Asset ID: :id)', + self::ChangedUserPermissions => 'Changed permissions for :name.', + self::DeletedThread => 'Deleted thread :name. (Thread ID: :id)', + self::DeletedReply => 'Deleted reply on :name. (Thread ID: :id)', + self::CreatedCategory => 'Created the :name forum category.', + self::ModifiedCategory => 'Modified the :name forum category.', + self::DeletedCategory => 'Deleted the :name forum category.', + self::ToggleStickiedThread => 'Toggled sticky status for thread :name. (Thread ID: :id)', + self::EditedReply => 'Edited a reply on :name. (Thread ID: :id)', + self::EditedThread => 'Edited thread :name. (Thread ID: :id)', + self::PrunedPosts => 'Pruned all forum posts from :name.', + default => $this->name + }; + } +} diff --git a/app/Enums/ArbiterLogSeverity.php b/app/Enums/ArbiterLogSeverity.php new file mode 100644 index 0000000..dce4bf7 --- /dev/null +++ b/app/Enums/ArbiterLogSeverity.php @@ -0,0 +1,54 @@ + 'info', 'warning' => 'warn', etc.) + * + * @return string + */ + public function event(): string + { + return match($this) + { + ArbiterLogSeverity::Error => 'error', + ArbiterLogSeverity::Warning => 'warn', + ArbiterLogSeverity::Event => 'event', + ArbiterLogSeverity::Information => 'info', + ArbiterLogSeverity::Debug => 'debug', + ArbiterLogSeverity::Boot => 'boot', + }; + } + + /** + * Gets the log color. + * + * @return Color + */ + public function color(): Color + { + return match($this) + { + ArbiterLogSeverity::Error => Hex::fromString('#E74856'), + ArbiterLogSeverity::Warning => Hex::fromString('#F9F1A5'), + ArbiterLogSeverity::Event => Hex::fromString('#3B78FF'), + ArbiterLogSeverity::Information => Hex::fromString('#F2F2F2'), + ArbiterLogSeverity::Debug => Hex::fromString('#0037DA'), + ArbiterLogSeverity::Boot => Hex::fromString('#16C60C'), + }; + } +} diff --git a/app/Enums/AssetGenre.php b/app/Enums/AssetGenre.php new file mode 100644 index 0000000..ad11ff1 --- /dev/null +++ b/app/Enums/AssetGenre.php @@ -0,0 +1,40 @@ + 'Town and City', + self::SciFi => 'Sci-Fi', + self::WildWest => 'Wild West', + self::SkatePark => 'Skate Park', + default => $this->name + }; + } +} diff --git a/app/Enums/AssetModeration.php b/app/Enums/AssetModeration.php new file mode 100644 index 0000000..7eeffde --- /dev/null +++ b/app/Enums/AssetModeration.php @@ -0,0 +1,10 @@ + 'T-Shirt', + self::GroupEmblem => 'Group Emblem', + self::RightArm => 'Right Arm', + self::LeftArm => 'Left Arm', + self::LeftLeg => 'Left Leg', + self::RightLeg => 'Right Leg', + self::GamePass => 'Game Pass', + default => $this->name + }; + } + + public static function sellableTypes(): array + { + return [ + self::TShirt, + self::Audio, + self::Hat, + self::Model, + self::Shirt, + self::Pants, + self::Decal, + self::Face, + self::Gear, + self::Badge + ]; + } + + public function isSellable(): bool + { + return in_array($this, self::sellableTypes()); + } + + public static function freeTypes(): array + { + return [ + self::Audio, + self::Model, + self::Decal, + ]; + } + + public function isFree(): bool + { + return in_array($this, self::freeTypes()); + } + + /** + * Gets the asset types that can be worn by a user. + * + * @return array + */ + public static function wearableTypes(): array + { + return [ + self::Head, + self::Face, + self::Gear, + self::Hat, + self::TShirt, + self::Shirt, + self::Pants + ]; + } + + /** + * Checks if the asset type is a wearable type. + * + * @return bool + */ + public function isWearable(): bool + { + return in_array($this, self::wearableTypes()); + } + + /** + * Gets the asset types that are shown on the inventory sections. + * + * @return array + */ + public static function inventoryTypes(): array + { + return [ + self::Head, + self::Face, + self::Gear, + self::Hat, + self::TShirt, + self::Shirt, + self::Pants, + self::Decal, + self::Model, + self::Plugin, + self::Animation, + self::Place, + self::GamePass, + self::Audio, + self::Badge, + self::LeftArm, + self::RightArm, + self::LeftLeg, + self::RightLeg, + self::Torso, + self::Package + ]; + } + + /** + * Checks if the asset type is shown on the inventory selection. + * + * @return bool + */ + public function isInventoryType(): bool + { + return in_array($this, self::inventoryTypes()); + } + + /** + * Gets the asset types that are shown on the favorites section on user profiles. + * + * @return array + */ + public static function favoriteTypes(): array + { + return [ + self::Head, + self::Face, + self::Gear, + self::Hat, + self::TShirt, + self::Shirt, + self::Pants, + self::Decal, + self::Model + ]; + } + + /** + * Checks if the asset type is shown on the favorites selection. + * + * @return bool + */ + public function isFavoriteType(): bool + { + return in_array($this, self::favoriteTypes()); + } + + /** + * Gets the Font Awesome icon for this asset type. + * + * @return string + */ + public function fontAwesomeIcon(): string + { + return match($this) { + self::Place => 'fa-image-landscape', + self::Model => 'fa-cubes', + self::Decal => 'fa-file-image', + self::Badge => 'fa-certificate', + self::GamePass => 'fa-ticket', + self::Audio => 'fa-volume-high', + self::Animation => 'fa-person-running', + self::Shirt => 'fa-shirt', + self::TShirt => 'fa-shirt-tank-top', + self::Pants => 'fa-clothes-hanger', + self::Plugin => 'fa-puzzle-piece', + }; + } + + /** + * Gets the asset types that are shown on the develop page. + * Note that not everything here is creatable through the develop page (places, models, etc). + * + * @return array + */ + public static function developTypes(): array + { + return [ + self::Place, + self::Model, + self::Decal, + self::Badge, + self::GamePass, + self::Audio, + self::Animation, + self::Shirt, + self::TShirt, + self::Pants, + self::Plugin, + ]; + } + + /** + * Checks if the asset type is shown on the develop page. + * + * @return bool + */ + public function isDevelopType(): bool + { + return in_array($this, self::developTypes()); + } + + /** + * Checks if the asset type can be uploaded through the develop page + * + * @return bool + */ + public function isDevelopCreatable(): bool + { + return match($this) + { + self::TShirt => true, + self::Decal => true, + self::Audio => true, + self::Animation => true, + default => false + }; + } + + /** + * Gets the upload validator for the asset type + * + * @return array + */ + public function rules(): array + { + return match($this) + { + self::TShirt => ['file', 'mimes:png,jpeg', 'max:8192'], + self::Decal => ['file', 'mimes:png,jpeg', 'max:8192'], + self::Audio => ['file', 'mimes:mp3,wav,wmv,midi,txt', 'max:8192'], + self::Animation => ['file', 'max:8192', new IsRobloxXml], + default => [] + }; + } +} diff --git a/app/Enums/ChatStyle.php b/app/Enums/ChatStyle.php new file mode 100644 index 0000000..0884403 --- /dev/null +++ b/app/Enums/ChatStyle.php @@ -0,0 +1,12 @@ + 'fa-rectangle-ad', + self::Games => 'fa-gamepad-modern', + }; + } +} diff --git a/app/Enums/GameServerState.php b/app/Enums/GameServerState.php new file mode 100644 index 0000000..9f23a13 --- /dev/null +++ b/app/Enums/GameServerState.php @@ -0,0 +1,26 @@ + 'Popular', + self::MostVisited => 'Most Visited', + self::MostFavorited => 'Most Favorited', + self::RecentlyUpdated => 'Recently Updated', + default => $this->name + }; + } +} diff --git a/app/Enums/SignatureType.php b/app/Enums/SignatureType.php new file mode 100644 index 0000000..df82271 --- /dev/null +++ b/app/Enums/SignatureType.php @@ -0,0 +1,79 @@ + OPENSSL_ALGO_SHA1, + SignatureType::Arbiter => OPENSSL_ALGO_SHA256 + }; + } + + /** + * Gets the key passphrase for this signature type. + * + * @return string + * @throws \Exception + */ + public function getPrivateKeyPassphrase(): string + { + $passphrase = match($this) { + SignatureType::Roblox => env('ROBLOX_PRIVATE_KEY_PASSPHRASE'), + SignatureType::Arbiter => env('ARBITER_PRIVATE_KEY_PASSPHRASE') + }; + + if (is_null($passphrase)) + { + throw new \Exception('No passphrase set for key ' . $this->name); + } + + return $passphrase; + } + + /** + * Gets the private key for this signature type. + * + * @return \OpenSSLAsymmetricKey + * @throws \Exception + */ + public function getPrivateKey(): \OpenSSLAsymmetricKey + { + $pem = match ($this) { + SignatureType::Roblox => Storage::disk('local')->get('keys/roblox.pem'), + SignatureType::Arbiter => Storage::disk('local')->get('keys/arbiter.pem') + }; + + $key = openssl_pkey_get_private($pem, $this->getPrivateKeyPassphrase()); + + if ($key === false) + { + throw new \Exception('Failed to acquire private key'); + } + + return $key; + } + + /** + * Gets the public key for this signature type. + * + * @return string + */ + public function getPublicKey(): string + { + return openssl_pkey_get_details($this->getPrivateKey())['key']; + } +} diff --git a/app/Events/GameServer/ConsoleOutput.php b/app/Events/GameServer/ConsoleOutput.php new file mode 100644 index 0000000..da2eb66 --- /dev/null +++ b/app/Events/GameServer/ConsoleOutput.php @@ -0,0 +1,61 @@ +game_server->uuid); + } + + /** + * Get the data to broadcast. + * + * @return array + */ + public function broadcastWith(): array + { + return [ + 'severity' => [ + 'event' => $this->severity->event(), + 'color' => (string) $this->severity->color()->toHex() + ], + 'timestamp' => $this->timestamp->format('n/j/Y g:i:s A'), + 'output' => $this->output, + 'blur' => $this->blur + ]; + } +} diff --git a/app/Events/GameServer/NewPlaceJob.php b/app/Events/GameServer/NewPlaceJob.php new file mode 100644 index 0000000..3084ece --- /dev/null +++ b/app/Events/GameServer/NewPlaceJob.php @@ -0,0 +1,37 @@ +game_server->uuid); + } +} diff --git a/app/Events/GameServer/NewThumbnailJob.php b/app/Events/GameServer/NewThumbnailJob.php new file mode 100644 index 0000000..8b3ac82 --- /dev/null +++ b/app/Events/GameServer/NewThumbnailJob.php @@ -0,0 +1,37 @@ +game_server->uuid); + } +} diff --git a/app/Events/GameServer/ResourceReport.php b/app/Events/GameServer/ResourceReport.php new file mode 100644 index 0000000..910416a --- /dev/null +++ b/app/Events/GameServer/ResourceReport.php @@ -0,0 +1,45 @@ +game_server->uuid); + } + + /** + * Get the data to broadcast. + * + * @return array + */ + public function broadcastWith(): array + { + return (array) $this->resources; + } +} diff --git a/app/Events/GameServer/StateChange.php b/app/Events/GameServer/StateChange.php new file mode 100644 index 0000000..5d12343 --- /dev/null +++ b/app/Events/GameServer/StateChange.php @@ -0,0 +1,50 @@ +game_server->uuid); + } + + /** + * Get the data to broadcast. + * + * @return array + */ + public function broadcastWith(): array + { + return [ + 'state' => $this->state->value, + 'utc_offset' => $this->game_server->utc_offset, + 'friendly_name' => $this->game_server->friendly_name + ]; + } +} diff --git a/app/Events/IpAddressBanModified.php b/app/Events/IpAddressBanModified.php new file mode 100644 index 0000000..a98ade9 --- /dev/null +++ b/app/Events/IpAddressBanModified.php @@ -0,0 +1,16 @@ +> + */ + protected $dontReport = [ + // + ]; + + /** + * A list of the inputs that are never flashed for validation exceptions. + * + * @var array + */ + protected $dontFlash = [ + 'current_password', + 'password', + 'password_confirmation', + ]; + + /** + * Register the exception handling callbacks for the application. + * + * @return void + */ + public function register() + { + $this->reportable(function (Throwable $e) { + // + }); + } +} diff --git a/app/GPBMetadata/Resources/Tadah.php b/app/GPBMetadata/Resources/Tadah.php new file mode 100644 index 0000000..b957c0c --- /dev/null +++ b/app/GPBMetadata/Resources/Tadah.php @@ -0,0 +1,25 @@ +internalAddGeneratedFile(hex2bin( + "0ac7060a157265736f75726365732f74616461682e70726f746f1205546164616822f6020a065369676e616c12290a056e6f6e636518012001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70120d0a056a6f62496418022001280912230a096f7065726174696f6e18032001280e32102e54616461682e4f7065726174696f6e12250a0776657273696f6e18042001280e32142e54616461682e436c69656e7456657273696f6e12220a05706c61636518052003280b32132e54616461682e5369676e616c2e506c616365122a0a097468756d626e61696c18062003280b32172e54616461682e5369676e616c2e5468756d626e61696c1a450a05506c616365120f0a07706c616365496418012001280d120e0a06736372697074180220012809121b0a1365787069726174696f6e496e5365636f6e647318032001280d1a4f0a095468756d626e61696c121e0a047479706518012001280e32102e54616461682e417373657454797065120f0a076173736574496418022001280d12110a096163636573734b6579180320012809225f0a08526573706f6e736512230a096f7065726174696f6e18012001280e32102e54616461682e4f7065726174696f6e120f0a0773756363657373180220012808120f0a076d657373616765180320012809120c0a04646174611804200128092a99010a094f7065726174696f6e120c0a084f50454e5f4a4f421000120d0a09434c4f53455f4a4f42100112120a0e455845435554455f534352495054100212190a1552454e45575f54414d50415f4a4f425f4c45415345100312120a0e434c4f53455f414c4c5f4a4f42531004121d0a19434c4f53455f414c4c5f54414d50415f50524f4345535345531005120d0a095448554d424e41494c10062a320a0d436c69656e7456657273696f6e12080a044e4f4e451000120b0a0654414950454910db0f120a0a0554414d504110e00f2a590a09417373657454797065120c0a08434c4f5448494e47100012080a0448454144100112080a044d455348100212090a05504c414345100312080a04555345521004120c0a084845414453484f54100512070a03584d4c1006421aaa020b54616461682e50726f746fca02094170705c50726f746f620670726f746f33" + ), true); + + static::$is_initialized = true; + } +} + diff --git a/app/Helpers/Agent.php b/app/Helpers/Agent.php new file mode 100644 index 0000000..97f737a --- /dev/null +++ b/app/Helpers/Agent.php @@ -0,0 +1,33 @@ +isDesktop()) + { + return 'fa-display'; + } + + if ($this->isTablet()) + { + return 'fa-tablet'; + } + + if ($this->isPhone()) + { + return 'fa-mobile'; + } + + return 'fa-question'; + } +} diff --git a/app/Helpers/Cdn.php b/app/Helpers/Cdn.php new file mode 100644 index 0000000..6072f7d --- /dev/null +++ b/app/Helpers/Cdn.php @@ -0,0 +1,82 @@ +exists($filename)) + { + Storage::disk('content')->put($filename, $data); + } + } + + /** + * Retrieves an accessible URL to a file on the app's configured content delivery system. + * The widescreen parameter is used for the placeholder thumbnail on failure. + * + * @param string $folder + * @param string $filename + * @param bool $widescreen + * @return string + */ + public static function getUrl(string $filename, bool $widescreen = false): string + { + if (Storage::disk('content')->exists($filename)) + { + return asset(sprintf('content/%s', $filename)); + } + + if ($widescreen) + { + return asset('img/placeholder/widescreen.png'); + } + + return asset('img/placeholder/icon.png'); + } +} diff --git a/app/Helpers/IpAddressBanManager.php b/app/Helpers/IpAddressBanManager.php new file mode 100644 index 0000000..16d43a3 --- /dev/null +++ b/app/Helpers/IpAddressBanManager.php @@ -0,0 +1,35 @@ +is_active) + { + continue; + } + + $banned_ip_addresses[] = $ban->ip_address; + } + + Cache::store('octane')->put('banned_ip_addresses', $banned_ip_addresses); + } +} diff --git a/app/Helpers/PaginationTransformer.php b/app/Helpers/PaginationTransformer.php new file mode 100644 index 0000000..b7da776 --- /dev/null +++ b/app/Helpers/PaginationTransformer.php @@ -0,0 +1,47 @@ +count(); + + return self::paginator($collection->forPage($pageNumber, $showPerPage), $totalPageNumber, $showPerPage, $pageNumber, [ + 'path' => Paginator::resolveCurrentPath(), + 'pageName' => 'page', + ]); + } + + /** + * Create a new length-aware paginator instance. + * + * @param \Illuminate\Support\Collection $items + * @param int $total + * @param int $perPage + * @param int $currentPage + * @param array $options + * @return \Illuminate\Pagination\LengthAwarePaginator + */ + protected static function paginator($items, $total, $perPage, $currentPage, $options) + { + return Container::getInstance()->makeWith(LengthAwarePaginator::class, compact( + 'items', 'total', 'perPage', 'currentPage', 'options' + )); + } +} diff --git a/app/Http/Controllers/Account/DashboardController.php b/app/Http/Controllers/Account/DashboardController.php new file mode 100644 index 0000000..b708dce --- /dev/null +++ b/app/Http/Controllers/Account/DashboardController.php @@ -0,0 +1,31 @@ +has('verified') && !is_null($request->user()->email_verified_at)) + { + if ((time() - $request->user()->email_verified_at->timestamp) <= 30) + { + $status = __('Welcome to :project!', ['project' => config('app.name')]); + } + } + + $greeting = $this->greetings[mt_rand(0, count($this->greetings) - 1)]; + $username = $request->user()->username; + + return view('my.dashboard', compact('status', 'greeting', 'username')); + } +} diff --git a/app/Http/Controllers/Account/DisabledAccountController.php b/app/Http/Controllers/Account/DisabledAccountController.php new file mode 100644 index 0000000..1d56437 --- /dev/null +++ b/app/Http/Controllers/Account/DisabledAccountController.php @@ -0,0 +1,68 @@ +user(); + + if (!$user->isBanned()) + { + return redirect()->route('dashboard'); + } + + $ban = (object) [ + 'is_termination' => !$user->ban->is_warning && !$user->ban->is_poison_ban && is_null($user->ban->expiry_date), + 'is_warning' => $user->ban->is_warning, + 'is_poison_ban' => $user->ban->is_poison_ban, + 'reviewed' => $user->ban->created_at->format('m/d/Y h:i:s A (T)'), + 'offensive_item' => $user->ban->offensive_item, + 'moderator_note' => $user->ban->moderator_note, + 'is_appealable' => $user->ban->is_appealable, + ]; + + $ban->expired = false; + + if (!$ban->is_termination && !$ban->is_warning && !$ban->is_poison_ban) + { + $ban->duration = seconds2human($user->ban->expiry_date->timestamp - $user->ban->created_at->timestamp, true); + $ban->expired = $user->ban->expiry_date->isPast(); + $ban->reactivation_date = $user->ban->expiry_date->format('m/d/Y h:i:s A (T)'); + } + elseif ($ban->is_warning) + { + $ban->expired = true; + } + + return view('auth.account-disabled', compact('ban')); + } + + public function store(Request $request) + { + $user = $request->user(); + + if (!$user->isBanned()) + { + return redirect()->route('dashboard'); + } + + if ($user->ban->is_poison_ban || (!$user->ban->is_warning && !$user->ban->is_poison_ban && is_null($user->ban->expiry_date))) + { + abort(403); + } + + if (!$user->ban->is_warning && !$user->ban->expiry_date->isPast()) + { + abort(403); + } + + $user->ban->lift(); + + return redirect()->route('dashboard')->with('success', __('Welcome back! Please adhere to the :project Terms of Service this time.', ['project' => config('app.name')])); + } +} diff --git a/app/Http/Controllers/Account/DiscordController.php b/app/Http/Controllers/Account/DiscordController.php new file mode 100644 index 0000000..b06d85e --- /dev/null +++ b/app/Http/Controllers/Account/DiscordController.php @@ -0,0 +1,29 @@ +redirect(); + } + + public function callback(Request $request) + { + $request->user()->linkDiscordAccount(Socialite::driver('discord')->user()->id); + + return redirect()->route('account')->with('status', __('Successfully linked Discord account!')); + } + + public function unlink(Request $request) + { + $request->user()->unlinkDiscordAccount(); + + return redirect()->route('account')->with('status', __('Your Discord account has been unlinked.')); + } +} diff --git a/app/Http/Controllers/Account/InviteKeyController.php b/app/Http/Controllers/Account/InviteKeyController.php new file mode 100644 index 0000000..8272c25 --- /dev/null +++ b/app/Http/Controllers/Account/InviteKeyController.php @@ -0,0 +1,70 @@ +may(Users::roleset(), Users::PURCHASE_INVITE_KEY)) + { + return __('You may not purchase an invite key.'); + } + + if (!$user->hasEnoughMoney(config('tadah.user_invite_key_cost'))) + { + return __('You do not have enough :currency to purchase an invite key.', ['currency' => config('tadah.currency_name')]); + } + + if (!$user->hasLinkedDiscordAccount() && config('tadah.discord_required')) + { + return __('Please link your Discord account in order to create invite keys.'); + } + + $our_keys = InviteKey::where('creator_id', $user->id) + ->where('created_at', '>', now()->subDays(config('tadah.user_invite_key_cooldown'))->endOfDay()) + ->get(); + + if (count($our_keys) >= config('tadah.user_maximum_keys_in_window')) + { + return __("You've already made :maximum invite keys in the past :cooldown days.", ['maximum' => config('tadah.user_maximum_keys_in_window'), 'cooldown' => config('app.user_invite_key_cooldown')]); + } + + return true; + } + + public function view(Request $request) + { + $keys = InviteKey::where('creator_id', $request->user()->id) + ->orderBy('created_at', 'DESC') + ->paginate(15); + $disabled = $this->mayPurchaseKey() !== true; + + return view('my.invites', compact('keys', 'disabled')); + } + + public function purchase(Request $request) + { + $user = $request->user(); + + if (($reason = $this->mayPurchaseKey()) !== true) + { + return back()->with('error', $reason); + } + + $user->spend(config('tadah.user_invite_key_cost'), 'Bought invite key'); + + InviteKey::generate($user->id, 1); + + return back()->with('success', __('New invite key created.')); + } +} diff --git a/app/Http/Controllers/Account/SessionController.php b/app/Http/Controllers/Account/SessionController.php new file mode 100644 index 0000000..91c0a88 --- /dev/null +++ b/app/Http/Controllers/Account/SessionController.php @@ -0,0 +1,39 @@ +validate([ + 'key' => ['required', new IsValidSession($request->user())] + ]); + } + catch (ValidationException) + { + return response()->json(['success' => false]); + } + + $key = decrypt($data['key']); + if ($key == $request->session()->getId()) + { + Auth::logout(); + } + else + { + Session::getHandler()->destroy($key); + } + + return response()->json(['success' => true]); + } +} diff --git a/app/Http/Controllers/Account/SettingsController.php b/app/Http/Controllers/Account/SettingsController.php new file mode 100644 index 0000000..a6adaad --- /dev/null +++ b/app/Http/Controllers/Account/SettingsController.php @@ -0,0 +1,79 @@ +where('user_id', $request->user()->id)->get()->each(function ($session) use ($request, &$sessions, &$current_session) { + if ($session->id == $request->session()->getId()) + { + $current_session = (object) [ + 'agent' => agent($session->user_agent), + 'location' => geolocate($session->ip_address), + 'last_ping' => time(), + 'ip' => $session->ip_address, + ]; + + return; + } + + $sessions[] = (object) [ + 'key' => encrypt($session->id), + 'agent' => agent($session->user_agent), + 'location' => geolocate($session->ip_address), + 'last_ping' => $session->last_activity, + 'ip' => $session->ip_address, + ]; + }); + + return view('my.account', [ + 'current_session' => $current_session, + 'sessions' => $sessions, + 'discord_user' => $request->user()->discordAccount(), + ]); + } + + public function updateEmail(Request $request) + { + if ($request->isMethod('post')) + { + $user = $request->user(); + + $data = $request->validate([ + 'email' => $this->emailRules(), + 'current_password' => ['required', new IsCurrentPassword($user)], + ]); + + $user->updateEmail($data['email'], $request->ip(), $request->userAgent()); + + return redirect()->route('account')->with('status', __('Your E-Mail address has been succesfully updated!')); + } + + return view('auth.update-email'); + } + + public function heartbeat(Request $request) + { + $user = $request->user(); + + $activity = $user->activity; + $activity['website'] = time(); + + $user->update(compact('activity')); + + return response()->json(['success' => true]); + } +} diff --git a/app/Http/Controllers/Admin/ActionLogController.php b/app/Http/Controllers/Admin/ActionLogController.php new file mode 100644 index 0000000..d708cfd --- /dev/null +++ b/app/Http/Controllers/Admin/ActionLogController.php @@ -0,0 +1,27 @@ +middleware(function ($request, $next) + { + if (!$request->user()->isSuperAdmin()) + { + return abort(404); + } + + return $next($request); + }); + } + + public function view() + { + return view('admin.action-log'); + } +} diff --git a/app/Http/Controllers/Admin/AlertController.php b/app/Http/Controllers/Admin/AlertController.php new file mode 100644 index 0000000..a5b0a31 --- /dev/null +++ b/app/Http/Controllers/Admin/AlertController.php @@ -0,0 +1,26 @@ +middleware(function ($request, $next) + { + if (!$request->user()->isSuperAdmin()) + { + return abort(404); + } + + return $next($request); + }); + } + + public function __invoke() + { + return view('admin.alert'); + } +} diff --git a/app/Http/Controllers/Admin/BanController.php b/app/Http/Controllers/Admin/BanController.php new file mode 100644 index 0000000..e981145 --- /dev/null +++ b/app/Http/Controllers/Admin/BanController.php @@ -0,0 +1,27 @@ +middleware(function ($request, $next) + { + if (!$request->user()->may(Users::roleset(), Users::MODERATION_GENERAL_BAN)) + { + return abort(404); + } + + return $next($request); + }); + } + + public function __invoke() + { + return view('admin.user.ban'); + } +} diff --git a/app/Http/Controllers/Admin/BanInformationController.php b/app/Http/Controllers/Admin/BanInformationController.php new file mode 100644 index 0000000..c8c6f67 --- /dev/null +++ b/app/Http/Controllers/Admin/BanInformationController.php @@ -0,0 +1,41 @@ +middleware(function ($request, $next) + { + if (!$request->user()->may(Users::roleset(), Users::MODERATION_VIEW_BAN_LIST)) + { + return abort(404); + } + + return $next($request); + }); + } + + public function __invoke(Request $request) + { + $ban = Ban::findOrFail($request->input('id')); + + return response()->json([ + 'success' => true, + 'ban' => [ + 'pardon_internal_reason' => $ban->pardon_internal_reason, + 'offensive_item' => $ban->offensive_item, + 'internal_reason' => $ban->internal_reason, + 'moderator_note' => $ban->moderator_note, + 'is_appealable' => $ban->is_appealable, + 'has_been_pardoned' => $ban->has_been_pardoned + ] + ]); + } +} diff --git a/app/Http/Controllers/Admin/GameServerController.php b/app/Http/Controllers/Admin/GameServerController.php new file mode 100644 index 0000000..983c896 --- /dev/null +++ b/app/Http/Controllers/Admin/GameServerController.php @@ -0,0 +1,123 @@ +user()->may(GameServers::roleset(), GameServers::VIEW)) + { + return abort(404); + } + + return view('admin.game-server.all'); + } + + public function store(Request $request) + { + if (!$request->user()->may(GameServers::roleset(), GameServers::CREATE)) + { + return abort(404); + } + + return view('admin.game-server.create'); + } + + public function view(Request $request, $id) + { + if (!$request->user()->may(GameServers::roleset(), GameServers::VIEW)) + { + return abort(404); + } + + $game_server = GameServer::where('uuid', $id)->firstOrFail(); + $data = [ + 'isSetUp' => $game_server->is_set_up, + 'uuid' => $game_server->uuid, + 'state' => $game_server->state()->value + ]; + + return view('admin.game-server.view', compact('game_server', 'data')); + } + + public function manage(Request $request, $id) + { + if (!$request->user()->may(GameServers::roleset(), GameServers::MANAGE)) + { + return abort(404); + } + + $game_server = GameServer::where('uuid', $id)->firstOrFail(); + + return view('admin.game-server.manage', compact('game_server')); + } + + public function state(Request $request) + { + if (!$request->has('uuid')) + { + return abort(404); + } + + $game_server = GameServer::where('uuid', $request->input('uuid'))->firstOrFail(); + + return response()->json(['state' => $game_server->state()->value]); + } + + public function logs(Request $request, $uuid) + { + if (!$request->user()->may(GameServers::roleset(), GameServers::CONNECT) || !$request->has('key')) + { + return abort(404); + } + + $game_server = GameServer::where('uuid', $uuid)->firstOrFail(); + $output = []; + + if (!GameServer::$logKeys[$request->input('key')]) + { + return response()->json(['success' => false]); + } + + if ($request->input('key') == 'console') + { + $trunk = $game_server->retrieveCompleteLog('console'); + unset($trunk['latest']); + + foreach ($trunk as $line) + { + $output[] = [ + 'severity' => [ + 'event' => $line[0]->event(), + 'color' => (string) $line[0]->color()->toHex() + ], + 'timestamp' => $line[1]->format('n/j/Y g:i:s A'), + 'output' => $line[2], + 'blur' => $line[3] + ]; + } + + $trunk = collect($trunk); + $trunk = $trunk->sortBy(function ($line) { + return $line[1]->timestamp; + }); + + $output = $trunk->toArray(); + } + else + { + $output = $game_server->retrieveCompleteLog($request->input('key')); + } + + return response()->json([ + 'success' => true, + 'output' => $output + ]); + } +} diff --git a/app/Http/Controllers/Admin/IpAddressBanController.php b/app/Http/Controllers/Admin/IpAddressBanController.php new file mode 100644 index 0000000..0d95dad --- /dev/null +++ b/app/Http/Controllers/Admin/IpAddressBanController.php @@ -0,0 +1,27 @@ +middleware(function ($request, $next) + { + if (!$request->user()->may(Users::roleset(), Users::MODERATION_IP_ADDRESS_BAN)) + { + return abort(404); + } + + return $next($request); + }); + } + + public function __invoke() + { + return view('admin.user.ip-address-ban'); + } +} diff --git a/app/Http/Controllers/Admin/PanelController.php b/app/Http/Controllers/Admin/PanelController.php new file mode 100644 index 0000000..8cfc894 --- /dev/null +++ b/app/Http/Controllers/Admin/PanelController.php @@ -0,0 +1,28 @@ +middleware(function ($request, $next) + { + if (!$request->user()->may(Admin::roleset(), Admin::VIEW_PANEL)) + { + return abort(404); + } + + return $next($request); + }); + } + + public function __invoke(Request $request) + { + return view('admin.panel')->with('user', $request->user()); + } +} diff --git a/app/Http/Controllers/Admin/PermissionsController.php b/app/Http/Controllers/Admin/PermissionsController.php new file mode 100644 index 0000000..ba55d6e --- /dev/null +++ b/app/Http/Controllers/Admin/PermissionsController.php @@ -0,0 +1,172 @@ +middleware(function ($request, $next) + { + if (!$request->user()->isSuperAdmin()) + { + return abort(404); + } + + return $next($request); + }); + } + + public function view() + { + return view('admin.permissions'); + } + + public function store(Request $request) + { + // 0xbaadc0de + + $rolesets = Roles::allRolesets(); + $view_rolesets = []; + + foreach ($rolesets as $roleset) + { + $view_rolesets[$roleset] = (object) [ + 'name' => $roleset, + 'roles' => Roles::rolesOfRoleset($roleset), + 'basename' => basename(str_replace('\\', '/', $roleset)), // WHAT THE FUCK ?? + ]; + } + + if ($request->has('username')) + { + $request->validate([ + 'username' => ['required', 'exists:users,username'] + ]); + + $user = User::select('id', 'username', 'permissions', 'superadmin')->where('username', $request->input('username'))->first(); + + return view('admin.permissions', [ + 'user' => $user, + 'rolesets' => $view_rolesets, + ]); + } + + if ($request->has('reset_for')) + { + $user = User::findOrFail($request->input('reset_for')); + $user->forceSetPermissions(User::defaultPermissions()); + + Session::flash('success', __('Successfully reset permissions for user :username!', ['username' => $user->username])); + + return view('admin.permissions', [ + 'user' => $user, + 'rolesets' => $view_rolesets, + ]); + } + + try + { + $request->validate([ + 'user' => ['required', 'exists:users,id'] + ]); + } + catch (ValidationException) + { + return back()->with('error', __('An unexpected error occurred. Please try again.')); + } + + /** + * Only permissions that are turned on are sent. + * Additionally, field names are denominated in the format "roleset;role" prefixed with "permission__". + * Example: "permission__App\Roles\Users;MODERATION_GENERAL_BAN" + */ + + $data = $request->all(); + + if (count($data) > (count($rolesets) * 30)) // 30 flags per roleset, impossible to be above this + { + return back()->with('error', __('An unexpected error occurred. Please try again.')); + } + + // We are manually recreating the users permissions based on what it sent + $permissions = []; + + foreach ($data as $field => $value) + { + // If it doesn't start with permission__, leave it be + if (!str_starts_with($field, 'permission__')) + { + continue; + } + + if ($value != 'on') + { + continue; + } + + // Has to be formatted per our spec + $field = substr($field, strlen('permission__')); + + $flag = explode(';', $field); + if (count($flag) !== 2) + { + return back()->with('error', __('An unexpected error occurred. Please try again.')); + } + + $roleset = $flag[0]; + $role = $flag[1]; + + // If the roleset doesn't exist, go away + if (!in_array($roleset, $rolesets) || !class_exists($roleset)) + { + return back()->with('error', __('An unexpected error occurred. Please try again.')); + } + + // If the role doesn't exist, go away + $roles = Roles::rolesOfRoleset($roleset); + if (is_null($roles[$role])) + { + return back()->with('error', __('An unexpected error occurred. Please try again.')); + } + + // If our permissions building array doesn't have this roleset set, set it as 0 + if (!isset($permissions[$roleset])) + { + $permissions[$roleset] = 0; + } + + // Add this flag to the roleset + $permissions[$roleset] |= $roles[$role]; + } + + // Fill in the blanks + foreach ($rolesets as $roleset) + { + if (!isset($permissions[$roleset])) + { + $permissions[$roleset] = 0; + } + } + + $user = User::findOrFail($request->input('user')); + $user->forceSetPermissions($permissions); + Action::log($request->user(), Actions::ChangedUserPermissions, $user); + + Session::flash('success', __('Successfully updated permissions for user :username!', ['username' => $user->username])); + + return view('admin.permissions', [ + 'user' => $user, + 'rolesets' => $view_rolesets, + ]); + } +} diff --git a/app/Http/Controllers/Admin/UserProfileController.php b/app/Http/Controllers/Admin/UserProfileController.php new file mode 100644 index 0000000..c05994f --- /dev/null +++ b/app/Http/Controllers/Admin/UserProfileController.php @@ -0,0 +1,40 @@ +middleware(function ($request, $next) + { + if (!$request->user()->may(Users::roleset(), Users::MODERATION_VIEW_USER_PROFILE)) + { + return abort(404); + } + + return $next($request); + }); + } + + public function view() + { + return view('admin.user.profile'); + } + + public function load(Request $request) + { + $request->validate([ + 'username' => ['required', 'exists:users,username'] + ]); + + $user = User::where('username', $request->input('username'))->first(); + + return view('admin.user.profile', compact('user')); + } +} diff --git a/app/Http/Controllers/Arbiter/IdentificationController.php b/app/Http/Controllers/Arbiter/IdentificationController.php new file mode 100644 index 0000000..2bb005c --- /dev/null +++ b/app/Http/Controllers/Arbiter/IdentificationController.php @@ -0,0 +1,23 @@ +bearerToken()) || !$request->has('friendly_name') || !$request->has('utc_offset')) + { + return abort(404); + } + + $game_server = GameServer::whereEncrypted('access_key', '=', $request->bearerToken())->firstOrFail(); + $game_server->update(['friendly_name' => $request->input('friendly_name'), 'utc_offset' => $request->input('utc_offset')]); + + return response()->make($game_server->uuid)->header('Content-Type', 'text/plain'); + } +} diff --git a/app/Http/Controllers/Arbiter/LogController.php b/app/Http/Controllers/Arbiter/LogController.php new file mode 100644 index 0000000..dabb4aa --- /dev/null +++ b/app/Http/Controllers/Arbiter/LogController.php @@ -0,0 +1,64 @@ +has('severity') || !$request->has('timestamp') || !$request->has('output') || !$request->has('blur')) + { + return abort(404); + } + + $game_server = GameServer::where('uuid', $uuid)->firstOrFail(); + + if (!$game_server->is($request->game_server)) + { + return abort(404); + } + + ConsoleOutput::dispatch($game_server, + ArbiterLogSeverity::tryFrom($request->input('severity')) ?? null, + Carbon::createFromTimestamp($request->input('timestamp'))->setTimezone($game_server->utc_offset), + $request->input('output'), + $request->input('blur') + ); + + return response()->json(['success' => true]); + } + + public function resources(Request $request, $uuid) + { + if (!$request->has('cpu') || !$request->has('ram') || !$request->has('inbound') || !$request->has('outbound')) + { + return abort(404); + } + + $game_server = GameServer::where('uuid', $uuid)->firstOrFail(); + + if (!$game_server->is($request->game_server)) + { + return abort(404); + } + + ResourceReport::dispatch($game_server, (object) [ + 'cpu' => $request->input('cpu'), + 'ram' => $request->input('ram'), + 'net' => [ + 'in' => $request->input('inbound'), + 'out' => $request->input('outbound') + ] + ]); + + return response()->json(['success' => true]); + } +} diff --git a/app/Http/Controllers/Arbiter/StateController.php b/app/Http/Controllers/Arbiter/StateController.php new file mode 100644 index 0000000..913f370 --- /dev/null +++ b/app/Http/Controllers/Arbiter/StateController.php @@ -0,0 +1,28 @@ +has('state')) + { + return abort(404); + } + + if (!$request->game_server->is_set_up) + { + $request->game_server->update(['is_set_up' => true]); + } + + StateChange::dispatch($request->game_server, GameServerState::tryFrom($request->input('state')) ?? GameServerState::Offline); + + return response()->json(['success' => true]); + } +} diff --git a/app/Http/Controllers/Auth/EmailVerificationNotificationController.php b/app/Http/Controllers/Auth/EmailVerificationNotificationController.php new file mode 100644 index 0000000..2fdc580 --- /dev/null +++ b/app/Http/Controllers/Auth/EmailVerificationNotificationController.php @@ -0,0 +1,24 @@ +validate([ + recaptchaFieldName() => ['required', recaptchaRuleName()] + ]); + + return $this->store($request); + } +} diff --git a/app/Http/Controllers/Auth/PasswordResetController.php b/app/Http/Controllers/Auth/PasswordResetController.php new file mode 100644 index 0000000..f25a5dc --- /dev/null +++ b/app/Http/Controllers/Auth/PasswordResetController.php @@ -0,0 +1,108 @@ +validate([ + 'email' => ['required', 'email'], + recaptchaFieldName() => ['required', recaptchaRuleName()] + ]); + + // Hack, since UserProvider does a traditional ->where and can't search encrypted text + if (!is_null($user = User::whereEncrypted('email', '=', $request->email)->first())) + { + $ciphertext = $user->getRawOriginal('email'); + $this->broker()->sendResetLink(['email' => $ciphertext]); + } + + return view('auth.request-password')->with('status', __('A password reset link has been sent if the email was valid.')); + } + + // GET /reset-password/{token} + public function view(Request $request, $token) + { + if (!$request->has('email') || empty($token)) + { + return abort(404); + } + + if (!is_null($user = User::whereEncrypted('email', '=', $request->email)->first())) + { + if (is_null($rawUser = $this->broker()->getUser(['email' => $user->getRawOriginal('email')]))) + { + return abort(404); + } + + if (!$this->broker()->tokenExists($rawUser, $token)) + { + return abort(404); + } + } + else + { + return abort(404); + } + + return view('auth.reset-password', ['token' => $token, 'email' => $request->email]); + } + + // POST /reset-password + public function reset(Request $request) + { + $request->validate([ + 'token' => ['required'], + 'email' => ['required', 'email'], + 'password' => $this->passwordRules(), + 'password_confirmation' => $this->passwordConfirmationRules() + ]); + + $ciphertext = ''; + if (!is_null($user = User::whereEncrypted('email', '=', $request->email)->first())) + { + $ciphertext = $user->getRawOriginal('email'); + } + + /* $status = */ $this->broker()->reset( + array_merge($request->only('password', 'password_confirmation', 'token'), ['email' => $ciphertext]), + function ($user, $password) use ($request) { + $user->updatePassword($password, $request->ip(), $request->userAgent()); + event(new PasswordReset($user)); + } + ); + + /* + return $status === Password::PASSWORD_RESET + ? redirect()->route('login')->with('status', __($status)) + : back()->withErrors(['email' => [__($status)]]); + */ + // ^^^ Traditionally we would do this, but since we already validated, we can assume that all validation is done. + // Therefore we just go back to login with "your password has been reset." + // Otherwise it will say "invalid email" or something; we don't want to expose if actual emails exist or not. + + return redirect()->route('login')->with('status', __('Your password has successfully been reset, :name!', ['name' => $user->username])); + } + + protected function broker(): mixed + { + return Password::broker(config('fortify.passwords')); + } +} diff --git a/app/Http/Controllers/CatalogController.php b/app/Http/Controllers/CatalogController.php new file mode 100644 index 0000000..d92d64b --- /dev/null +++ b/app/Http/Controllers/CatalogController.php @@ -0,0 +1,13 @@ +get(); + return view('forum.index')->with('categories', $categories); + } + + public function category(Request $request, $id) + { + $category = ForumCategory::where('id', $id)->first(); + $categories = ForumCategory::orderBy('priority', 'desc')->get(); + return view('forum.category')->with(['category' => $category, 'categories' => $categories]); + } + + public function thread(Request $request, $id) + { + $thread = ForumThread::where('id', $id)->first(); + $categories = ForumCategory::orderBy('priority', 'desc')->get(); + return view('forum.thread')->with(['thread' => $thread, 'categories' => $categories]); + } +} diff --git a/app/Http/Controllers/GamesController.php b/app/Http/Controllers/GamesController.php new file mode 100644 index 0000000..025ff89 --- /dev/null +++ b/app/Http/Controllers/GamesController.php @@ -0,0 +1,13 @@ + en_US becomes en_US => English + + if (!isset($locales[$locale])) + { + $locale = config('app.fallback_locale'); + } + + app()->setLocale($locale); + session()->put('locale', $locale); + + return redirect()->back(); + } + + public function document($page) + { + // we can use view()->exists but it's unsafe w/ user input + $documents = ['privacy', 'rules', 'statistics', 'tos']; + if (!in_array($page, $documents)) + { + return abort(404); + } + + return view("document.{$page}"); + } +} diff --git a/app/Http/Controllers/ItemController.php b/app/Http/Controllers/ItemController.php new file mode 100644 index 0000000..aaafa97 --- /dev/null +++ b/app/Http/Controllers/ItemController.php @@ -0,0 +1,25 @@ +canConfigure(), 404); + + return view('item.configure', compact('asset')); + } +} diff --git a/app/Http/Controllers/Roblox/FastFlagController.php b/app/Http/Controllers/Roblox/FastFlagController.php new file mode 100644 index 0000000..457725a --- /dev/null +++ b/app/Http/Controllers/Roblox/FastFlagController.php @@ -0,0 +1,25 @@ +version ?? "2016"; + + if (!in_array($version, self::versions)) { + return abort(400); + } + + $flags = Storage::disk('resources')->get((sprintf('flags/ClientAppSettings/%s.json', $version))); + + return response()->make($flags)->header('Content-Type', 'application/json'); + } +} diff --git a/app/Http/Controllers/Roblox/MiscellaneousScriptController.php b/app/Http/Controllers/Roblox/MiscellaneousScriptController.php new file mode 100644 index 0000000..1a5310e --- /dev/null +++ b/app/Http/Controllers/Roblox/MiscellaneousScriptController.php @@ -0,0 +1,14 @@ +text(ScriptBuilder::from('Gameserver')->sign()); + } +} diff --git a/app/Http/Controllers/Roblox/OnlinePlayController.php b/app/Http/Controllers/Roblox/OnlinePlayController.php new file mode 100644 index 0000000..01488f4 --- /dev/null +++ b/app/Http/Controllers/Roblox/OnlinePlayController.php @@ -0,0 +1,120 @@ +input('placeId'); + $machineAddress = $request->input('server'); + $machinePort = $request->input('serverPort'); + + $parameters = [ + ... ScriptBuilder::defaultParameters(), + 'PlaceID' => -1 + ]; + + // TODO: generate screenshot and video info when placeid parameter is not -1 (@pizzaboxer) + if ($request->has('jobID')) + { + // TODO: we probably won't use job ids for joinscript generation anyway (@pizzaboxer) + // Carrot: why? + + $jobId = $request->input('jobID'); + } + else + { + if (is_numeric($placeId)) + { + $parameters['PlaceID'] = $placeId; + } + + // make sure the machine address given is a local ip + // this probably isn't necessary? eh + if (is_ipv4($machineAddress)) + { + $parameters['MachineAddress'] = $machineAddress; + } + + if (is_port($machinePort)) + { + $parameters['MachinePort'] = $machinePort; + } + } + + /* "ScreenShotInfo":"Crossroads%0d%0aA+fun+game+by+Player%0d%0aBuilt+in+ROBLOX%2c+the+free+online+building+game.+%0d%0ahttp%3a%2f%2fwww.roblox.com%2fCrossroads-place%3fid%3d1818%0d%0aMore+about+this+level%3a%0d%0aThe+classic+ROBLOX+level+is+back!" */ + /* "VideoInfo":"GamesROBLOX, video, free game, online virtual world */ + + $scripts = []; + + switch ($request->route()->getName()) + { + case 'client.online.join': + $scripts[] = 'Join'; + break; + case 'client.online.group-build': + $scripts[] = 'GroupBuild'; + break; + } + + $scripts[] = 'MultiplayerSharedScript'; + + return response()->text(ScriptBuilder::from($scripts)->render($parameters)->sign()); + } + + public function singleplayer(Request $request) + { + $placeId = $request->input('placeId'); + $uploadingTo = $request->input('upload'); + + $parameters = ScriptBuilder::defaultParameters(); + + if (is_numeric($placeId)) + { + $parameters['IsVisit'] = true; + $parameters['PlaceID'] = $placeId; + $parameters['AssetUrl'] = $parameters['BaseUrl'] . "/asset/?id=" . $placeId; + } + + if (Auth::check()) + { + $user = $request->user(); + + $parameters['PlayerName'] = $request->user()->username; + $parameters['PlayerID'] = $request->user()->id; + $parameters['PlayerAppearance'] = $parameters['BaseUrl'] . '/Asset/CharacterFetch.ashx?userId=' . $parameters['PlayerID'] . '&placeId=' . $parameters['PlaceID']; + $parameters['PlayerSSC'] = 'false'; + $parameters['ClientPresenceUrl'] = $parameters['BaseUrl'] . "/Game/ClientPresence.ashx?PlaceID=" . $parameters['PlaceID']; + + if (is_numeric($uploadingTo)) + { + $parameters['UploadUrl'] = $parameters['BaseUrl'] . "/Data/Upload.ashx?assetid=" . $uploadingTo; + } + } + else + { + $parameters['PlayerName'] = 'Guest ' . rand(0, 9999); + $parameters['PlayerAppearance'] = $parameters['BaseUrl'] . '/Asset/CharacterFetch.ashx?userId=1&placeId=' . $parameters['PlaceID']; + } + + $scripts = ['SingleplayerSharedScript']; + + switch ($request->route()->getName()) + { + case 'client.online.visit': + $scripts[] = 'Visit'; + break; + case 'client.online.solo': + $scripts[] = 'PlaySolo'; + break; + } + + return response()->text(ScriptBuilder::from($scripts)->render($parameters)->sign()); + } +} diff --git a/app/Http/Controllers/Roblox/StaticAssetController.php b/app/Http/Controllers/Roblox/StaticAssetController.php new file mode 100644 index 0000000..23d5c56 --- /dev/null +++ b/app/Http/Controllers/Roblox/StaticAssetController.php @@ -0,0 +1,33 @@ +text('0 0 0 0'); + } + + public function chatFilter() + { + return response()->text('True'); + } + + public function keepAlivePinger() + { + // TODO: make this functional? + // supposedly this is to preserve the user's online presence when the client is open + // i'm not entirely sure what the response is supposed to be? archived pages just show 8 (for logged out users) + // but when you're logged it shows a unique number on each request (presumably random? - https://archive.froast.io/forum/32957261) + + return response()->text('8'); + } + + public function respondWithOK() + { + return response()->text('OK'); + } +} diff --git a/app/Http/Controllers/Roblox/StudioController.php b/app/Http/Controllers/Roblox/StudioController.php new file mode 100644 index 0000000..5f1bc12 --- /dev/null +++ b/app/Http/Controllers/Roblox/StudioController.php @@ -0,0 +1,35 @@ +input('PlaceID'); + $parameters = ScriptBuilder::defaultParameters(); + + if (is_numeric($placeId)) + { + $parameters['PlaceID'] = $placeId; + $parameters['AssetUrl'] = $parameters['BaseUrl'] . "/asset/?id=" . $placeId; + $parameters['ClientPresenceUrl'] = $parameters['BaseUrl'] . "/Game/ClientPresence.ashx?PlaceID=" . $placeId . "&LocationType=Studio"; + } + + return response()->text(ScriptBuilder::from(['SingleplayerSharedScript', 'Edit'])->render($parameters)->sign()); + } + + public function studio(Request $request) + { + $parameters = [ + 'BaseUrl' => "http://" . $request->getHost(), + 'StarterScriptID' => 37801172 + ]; + + return response()->text(ScriptBuilder::from('Studio')->render($parameters)->sign()); + } +} diff --git a/app/Http/Controllers/UsersController.php b/app/Http/Controllers/UsersController.php new file mode 100644 index 0000000..2dcd4a8 --- /dev/null +++ b/app/Http/Controllers/UsersController.php @@ -0,0 +1,21 @@ +friends()->count(); + return view('users.profile', compact('user', 'num_friends')); + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php new file mode 100644 index 0000000..647d7f4 --- /dev/null +++ b/app/Http/Kernel.php @@ -0,0 +1,72 @@ + + */ + protected $middleware = [ + \App\Http\Middleware\TrustHosts::class, + \App\Http\Middleware\TrustProxies::class, + \App\Http\Middleware\BlockBannedIpAddresses::class, + \Illuminate\Http\Middleware\HandleCors::class, + \App\Http\Middleware\PreventRequestsDuringMaintenance::class, + \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, + \App\Http\Middleware\TrimStrings::class, + \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, + ]; + + /** + * The application's route middleware groups. + * + * @var array> + */ + protected $middlewareGroups = [ + 'web' => [ + \App\Http\Middleware\EncryptCookies::class, + \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, + \Illuminate\Session\Middleware\StartSession::class, + \Illuminate\Session\Middleware\AuthenticateSession::class, + \Illuminate\View\Middleware\ShareErrorsFromSession::class, + \App\Http\Middleware\VerifyCsrfToken::class, + \Illuminate\Routing\Middleware\SubstituteBindings::class, + \App\Http\Middleware\UpdateCurrentIpAddress::class, + \App\Http\Middleware\Localization::class, + \App\Http\Middleware\IsBanned::class, + \App\Http\Middleware\EnsureEmailIsVerified::class, + ], + + 'api' => [ + 'throttle:api', + \Illuminate\Routing\Middleware\SubstituteBindings::class, + ], + ]; + + /** + * The application's route middleware. + * + * These middleware may be assigned to groups or used individually. + * + * @var array + */ + protected $routeMiddleware = [ + 'admin' => \App\Http\Middleware\AdminGuard::class, + 'auth' => \App\Http\Middleware\Authenticate::class, + 'auth.arbiter' => \App\Http\Middleware\AuthenticateArbiter::class, + 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, + 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, + 'can' => \Illuminate\Auth\Middleware\Authorize::class, + 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, + 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, + 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, + 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, + ]; +} diff --git a/app/Http/Livewire/Account/ModerationHistory.php b/app/Http/Livewire/Account/ModerationHistory.php new file mode 100644 index 0000000..a581fbb --- /dev/null +++ b/app/Http/Livewire/Account/ModerationHistory.php @@ -0,0 +1,41 @@ +may(Users::roleset(), Users::VIEW_BAN_HISTORY), 401); + } + + public function render() + { + $user = Auth::user(); + + $bans = Ban::where('user_id', $user->id)->get(); + $bans = paginate($bans, 15); + + return view('livewire.account.moderation-history', [ + 'bans' => $bans + ]); + } +} diff --git a/app/Http/Livewire/Account/TwoFactorAuthentication.php b/app/Http/Livewire/Account/TwoFactorAuthentication.php new file mode 100644 index 0000000..5f4c91c --- /dev/null +++ b/app/Http/Livewire/Account/TwoFactorAuthentication.php @@ -0,0 +1,34 @@ + ['max:1000'], + ]; + + public function __construct() + { + abort_unless(Auth::check(), 401); + } + + public function mount() + { + $this->blurb = Auth::user()->blurb; + } + + public function updated($property) + { + $this->validateOnly($property); + } + + public function submit() + { + $this->validate(); + + /** @var \App\Models\User */ + $user = Auth::user(); + + if (RateLimiter::tooManyAttempts('update-blurb:' . $user->id, 1)) + { + $wait = RateLimiter::availableIn('update-blurb:' . $user->id); + return $this->addError('blurb', __('Please wait :time before updating your blurb.', ['time' => seconds2human($wait)]));; + } + + RateLimiter::hit('update-blurb:' . $user->id, 300); + + $user->update(['blurb' => $this->blurb]); + + $this->dispatchBrowserEvent('success', __('Your blurb has been updated.')); + } + + public function render() + { + return view('livewire.account.update-blurb'); + } +} diff --git a/app/Http/Livewire/Account/UpdatePassword.php b/app/Http/Livewire/Account/UpdatePassword.php new file mode 100644 index 0000000..d39b512 --- /dev/null +++ b/app/Http/Livewire/Account/UpdatePassword.php @@ -0,0 +1,74 @@ +validateOnly($property); + } + + /** + * @param User $user + * @return array + */ + public function rules(User $user): array + { + return [ + 'current_password' => ['required', new IsCurrentPassword($user)], + 'password' => $this->passwordRules($user->username, $user->email), + 'password_confirmation' => $this->passwordConfirmationRules() + ]; + } + + public function render() + { + return view('livewire.account.update-password'); + } + + public function submit() + { + /** @var \App\Models\User */ + $user = Auth::user(); + + $data = $this->validate($this->rules($user)); + $user->updatePassword($data['password'], Request::ip(), Request::userAgent(), $data['current_password']); + + return redirect()->route('account')->with('status', __('Your password has been updated!')); + } +} diff --git a/app/Http/Livewire/Account/UpdateUsername.php b/app/Http/Livewire/Account/UpdateUsername.php new file mode 100644 index 0000000..6eb20f4 --- /dev/null +++ b/app/Http/Livewire/Account/UpdateUsername.php @@ -0,0 +1,73 @@ +validateOnly($property); + } + + /** + * @param User $user + * @return array + */ + public function rules(User $user): array + { + return [ + 'new_username' => $this->usernameRules('username'), + 'current_password' => ['required', new IsCurrentPassword($user)], + ]; + } + + public function render() + { + return view('livewire.account.update-username'); + } + + public function submit() + { + /** @var \App\Models\User */ + $user = Auth::user(); + $data = $this->validate($this->rules($user)); + + if (!$user->hasEnoughMoney(config('tadah.username_change_cost'))) + { + return $this->dispatchBrowserEvent('alert', __('You do not have enough money to change your username.')); + } + + $user->updateUsername($data['new_username'], Request::ip(), Request::userAgent()); + + return redirect()->route('account')->with('status', __('Your username has been successfully updated!')); + } +} diff --git a/app/Http/Livewire/Admin/ActionLog.php b/app/Http/Livewire/Admin/ActionLog.php new file mode 100644 index 0000000..a68c387 --- /dev/null +++ b/app/Http/Livewire/Admin/ActionLog.php @@ -0,0 +1,50 @@ + ['except' => ''], + ]; + + public function __construct() + { + abort_unless(Auth::check(), 401); + + /** @var \App\Models\User */ + $user = Auth::user(); + abort_unless($user->isSuperAdmin(), 401); + } + + public function updatingSearch() + { + $this->resetPage(); + } + + public function render() + { + $logs = Action::search($this->search)->get()->sortByDesc('created_at'); + + return view('livewire.admin.action-log')->with('logs', paginate($logs, 15)); + } +} diff --git a/app/Http/Livewire/Admin/Alert.php b/app/Http/Livewire/Admin/Alert.php new file mode 100644 index 0000000..56fe863 --- /dev/null +++ b/app/Http/Livewire/Admin/Alert.php @@ -0,0 +1,94 @@ + ['required', 'max:512'], + 'color' => ['required', 'regex:/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/'], + 'expiry' => ['date', 'after:today'], + ]; + } + + public function updated($property) + { + $this->validateOnly($property); + } + + public function __construct() + { + abort_unless(Auth::check(), 401); + + /** @var \App\Models\User */ + $user = Auth::user(); + abort_unless($user->isSuperAdmin(), 401); + } + + public function mount() + { + $this->text = Cache::get('alert')?->text ?? ''; + $this->color = Cache::get('alert')?->color ?? ''; + $this->expiry = Cache::get('expiry')?->expiry->format('m/d/Y') ?? ''; + } + + public function submit() + { + $data = $this->validate(); + + if (!empty($data['expiry'])) + { + Cache::remember('alert', (Carbon::parse($data['expiry'])->timestamp - Carbon::now()->timestamp), function() use ($data) { + return (object) [ + 'text' => $data['text'], + 'color' => $data['color'], + 'expiry' => Carbon::parse($data['expiry']), + ]; + }); + } + else + { + Cache::put('alert', (object) [ + 'text' => $data['text'], + 'color' => $data['color'], + ]); + } + + Action::log(Request::user(), Actions::SiteAlert); + + return $this->dispatchBrowserEvent('reload'); + } + + public function render() + { + return view('livewire.admin.alert'); + } +} diff --git a/app/Http/Livewire/Admin/Ban/IpAddress.php b/app/Http/Livewire/Admin/Ban/IpAddress.php new file mode 100644 index 0000000..ce79109 --- /dev/null +++ b/app/Http/Livewire/Admin/Ban/IpAddress.php @@ -0,0 +1,147 @@ + ['required', 'max:255'], + 'internal_reason' => ['max:255'], + ]; + + public function __construct() + { + abort_unless(Auth::check(), 401); + + /** @var \App\Models\User */ + $user = Auth::user(); + abort_unless($user->may(Users::roleset(), Users::MODERATION_IP_ADDRESS_BAN), 401); + } + + public function updated($property) + { + $this->validateOnly($property); + } + + public function render() + { + return view('livewire.admin.ban.ip-address'); + } + + public function submit() + { + $data = $this->validate(); + $to_ban = []; + + /** + * Identifier whereabout check; + * + * 1. First check if the identifier is a e-mail address by seeing if it contains an '@' character in it. Get the IPs of the users that have this e-mail address and add them to $to_ban. + * 2. If the identifier wasn't an e-mail address, we proceed to check if it is an IPv6 address, by seeing if it contains a period. If it does, return an error. + * 3. If it wasn't an IPv6 address, then we check to see if it is a username (by seeing if it is alphanumeric and less than 20 characters.) If it matches this check but no users exist, we boot them out. We add the IPs of the user to the $to_ban array. + * 4. If it wasn't a username, check if it's an IPv4. If it isn't, boot them out. If it is, add it to $to_ban. + */ + + if (Str::contains($data['identifier'], '@')) + { + if (is_null($users = User::whereEncrypted('email', '=', $data['identifier'])->get())) + { + return $this->addError('identifier', __('No users exist with this e-mail address.')); + } + + foreach ($users as $user) + { + if ($user->isSuperAdmin()) + { + return $this->addError('identifier', __('No users exist with that username.')); + } + + $to_ban[] = $user->register_ip; + $to_ban[] = $user->last_ip; + } + } + elseif (Str::contains($data['identifier'], ':')) + { + return $this->addError('identifier', __('IPv6 addresses are not supported.')); + } + elseif (ctype_alnum($data['identifier'])) + { + if (is_null($user = User::where('username', $data['identifier'])->first()) ) + { + return $this->addError('identifier', __('No users exist with that username.')); + } + + if ($user->isSuperAdmin()) + { + return $this->addError('identifier', __('You may not ban superadmins.')); + } + + $to_ban[] = $user->register_ip; + $to_ban[] = $user->last_ip; + } + else + { + if (!filter_var($data['identifier'], FILTER_VALIDATE_IP)) + { + return $this->addError('identifier', __('Please enter a valid IPv4 address.')); + } + + $to_ban[] = $data['identifier']; + } + + $to_ban = array_unique($to_ban); + + if (in_array(Request::ip(), $to_ban)) + { + return $this->dispatchBrowserEvent('error', __('You cannot ban yourself.')); + } + + $count = 0; + + foreach ($to_ban as $banned_ip) + { + if (!is_null($existing = IpAddressBan::whereEncrypted('ip_address', '=', $banned_ip)->first())) + { + if ($existing->is_active) + { + continue; + } + } + + $count++; + + IpAddressBan::create(array_filter([ + 'ip_address' => $banned_ip, + 'moderator_id' => Request::user()->id, + 'internal_reason' => $data['internal_reason'], + 'criterium' => $data['identifier'] + ], null, ARRAY_FILTER_USE_BOTH)); + Action::log(Request::user(), Actions::AddIPBan); + } + + return $this->dispatchBrowserEvent('success', __(':amount IP(s) have been banned. Please check the ban list to see who got affected.', ['amount' => number_format($count)])); + } +} diff --git a/app/Http/Livewire/Admin/Ban/IpAddressSearch.php b/app/Http/Livewire/Admin/Ban/IpAddressSearch.php new file mode 100644 index 0000000..9acc780 --- /dev/null +++ b/app/Http/Livewire/Admin/Ban/IpAddressSearch.php @@ -0,0 +1,49 @@ +may(Users::roleset(), Users::MODERATION_VIEW_IP_ADDRESS_BAN_LIST), 401); + } + + public function updatingSearch() + { + $this->resetPage(); + } + + public function render() + { + if (empty(trim($this->search))) + { + $bans = IpAddressBan::orderBy('created_at', 'DESC'); + } + else + { + $bans = IpAddressBan::whereEncrypted('ip_address', '=', $this->search); + } + + return view('livewire.admin.ban.ip-address-search')->with('bans', paginate($bans->get(), 15)); + } +} diff --git a/app/Http/Livewire/Admin/Ban/Pardon.php b/app/Http/Livewire/Admin/Ban/Pardon.php new file mode 100644 index 0000000..634ab6a --- /dev/null +++ b/app/Http/Livewire/Admin/Ban/Pardon.php @@ -0,0 +1,71 @@ +may(Users::roleset(), Users::MODERATION_PARDON_BAN), 401); + } + + public function updated($property) + { + $this->validateOnly($property); + } + + /** + * @return array + */ + public function rules(): array + { + return [ + 'username' => ['required', Rule::exists(User::class)], + 'pardon_reason' => ['required', 'max:255'] + ]; + } + + public function render() + { + return view('livewire.admin.ban.pardon'); + } + + public function submit() + { + $data = $this->validate(); + $user = User::where('username', $data['username'])->first(); + + if (!$user->isBanned()) + { + return $this->addError('username', __('This user is not currently banned.')); + } + + Request::user()->pardon($user, $data['pardon_reason']); + Action::log(Request::user(), Actions::PardonedUser, $user); + + return $this->dispatchBrowserEvent('success', __('Successfully pardoned ban for user :username!', ['username' => $user->username])); + } +} diff --git a/app/Http/Livewire/Admin/Ban/PardonIpAddress.php b/app/Http/Livewire/Admin/Ban/PardonIpAddress.php new file mode 100644 index 0000000..6fc62e1 --- /dev/null +++ b/app/Http/Livewire/Admin/Ban/PardonIpAddress.php @@ -0,0 +1,65 @@ + ['required', 'ipv4'], + ]; + + public function __construct() + { + abort_unless(Auth::check(), 401); + + /** @var \App\Models\User */ + $user = Auth::user(); + abort_unless($user->may(Users::roleset(), Users::MODERATION_PARDON_IP_ADDRESS_BAN), 401); + } + + public function updated($property) + { + $this->validateOnly($property); + } + + public function render() + { + return view('livewire.admin.ban.pardon-ip-address'); + } + + public function submit() + { + $data = $this->validate(); + + if (is_null($ban = IpAddressBan::whereEncrypted('ip_address', '=', $data['ip_address'])->where('is_active', true)->first())) + { + return $this->addError('ip_address', __('That IP is not currently banned.')); + } + + Request::user()->pardonIpAddressBan($ban); + Action::log(Request::user(), Actions::RemoveIPBan); + + return $this->dispatchBrowserEvent('success', __('Successfully pardoned ban for IP :ip!', ['ip' => $ban->ip_address])); + } +} diff --git a/app/Http/Livewire/Admin/Ban/Search.php b/app/Http/Livewire/Admin/Ban/Search.php new file mode 100644 index 0000000..747b567 --- /dev/null +++ b/app/Http/Livewire/Admin/Ban/Search.php @@ -0,0 +1,51 @@ + ['except' => ''], + ]; + + public function __construct() + { + abort_unless(Auth::check(), 401); + + /** @var \App\Models\User */ + $user = Auth::user(); + abort_unless($user->may(Users::roleset(), Users::MODERATION_VIEW_BAN_LIST), 401); + } + + public function updatingSearch() + { + $this->resetPage(); + } + + public function render() + { + $bans = Ban::search($this->search)->get(); + + $this->dispatchBrowserEvent('admin-hook-details'); + + return view('livewire.admin.ban.search')->with('bans', paginate($bans, 15)); + } +} diff --git a/app/Http/Livewire/Admin/Ban/User.php b/app/Http/Livewire/Admin/Ban/User.php new file mode 100644 index 0000000..4eb10fb --- /dev/null +++ b/app/Http/Livewire/Admin/Ban/User.php @@ -0,0 +1,165 @@ +may(Users::roleset(), Users::MODERATION_GENERAL_BAN), 401); + } + + /** + * @return array + */ + public function rules(): array + { + return [ + 'username' => ['required', Rule::exists(UserModel::class)], + 'moderator_note' => ['required', 'max:255'], + 'internal_reason' => ['required', 'max:255'], + 'duration_preset' => ['required', Rule::in([0, 1, 2, 3, 4, 5, 6, 7])], + 'offensive_item' => ['nullable'], + 'custom_expiry_date' => ['required_if:duration_preset,6', 'date', 'after:today', 'nullable'], + ]; + } + + public function render() + { + return view('livewire.admin.ban.user'); + } + + public function updated($property) + { + $this->validateOnly($property); + } + + public function submit() + { + $data = $this->validate(); + $user = UserModel::where('username', $data['username'])->first(); + + if ($user->isBanned()) + { + return $this->addError('username', __('That user is already banned.')); + } + + if ($user->username == Request::user()->username) + { + return $this->addError('username', __('You may not moderate yourself.')); + } + + if ($user->isSuperAdmin()) + { + return $this->addError('username', __('You may not moderate superadmins.')); + } + + $is_warning = $data['duration_preset'] == 0; + $is_poison_ban = $data['duration_preset'] == 7; + $expiry_date = null; + + if (!$is_warning && !$is_poison_ban) + { + $expiry_date = match($data['duration_preset']) + { + '1' => Carbon::now()->addDays(1), // 1 day + '2' => Carbon::now()->addDays(3), // 3 days + '3' => Carbon::now()->addDays(7), // 7 days + '4' => Carbon::now()->addDays(14), // 14 days + '5' => null, // Account Deletion + '6' => Carbon::parse($data['custom_expiry_date']) // Custom Date + }; + } + + if ($is_warning) + { + Request::user()->punish($user, [ + 'internal_reason' => $data['internal_reason'], + 'moderator_note' => $data['moderator_note'], + 'offensive_item' => $data['offensive_item'], + 'is_warning' => true, + ]); + + Action::log(Request::user(), Actions::WarnedUser, $user); + } + else + { + $ban = Request::user()->punish($user, [ + 'internal_reason' => $data['internal_reason'], + 'moderator_note' => $data['moderator_note'], + 'offensive_item' => $data['offensive_item'], + 'expiry_date' => $expiry_date, + 'is_appealable' => !empty($this->is_appealable), + ]); + + if (Request::user()->may(Users::roleset(), Users::MODERATION_POISON_BAN) && $is_poison_ban) + { + $user->ban->poison(); + + Action::log(Request::user(), Actions::PoisonBannedUser, $user); + } + else + { + if ($expiry_date) + { + Action::log(Request::user(), Actions::TempBannedUser, $ban); + } + else + { + Action::log(Request::user(), Actions::PermBannedUser, $user); + } + } + } + + return $this->dispatchBrowserEvent('success', __('Successfully punished user :username!', ['username' => $user->username])); + } +} diff --git a/app/Http/Livewire/Admin/GameServer/All.php b/app/Http/Livewire/Admin/GameServer/All.php new file mode 100644 index 0000000..038aca7 --- /dev/null +++ b/app/Http/Livewire/Admin/GameServer/All.php @@ -0,0 +1,62 @@ +may(GameServers::roleset(), GameServers::VIEW), 401); + } + + public function mount($gameServers) + { + $this->game_servers = $gameServers; + } + + /** + * @return array + */ + public function getListeners(): array + { + $listeners = []; + + foreach ($this->game_servers as $game_server) + { + $listeners["echo-private:game-servers.{$game_server->uuid},GameServer\\StateChange"] = '$refresh'; + $listeners["echo-private:game-servers.{$game_server->uuid},GameServer\\NewPlaceJob"] = '$refresh'; + $listeners["echo-private:game-servers.{$game_server->uuid},GameServer\\NewThumbnailJob"] = '$refresh'; + } + + return $listeners; + } + + public function render() + { + $servers = paginate($this->game_servers, 15); + + return view('livewire.admin.game-server.all', compact('servers')); + } +} diff --git a/app/Http/Livewire/Admin/GameServer/Create.php b/app/Http/Livewire/Admin/GameServer/Create.php new file mode 100644 index 0000000..ca85055 --- /dev/null +++ b/app/Http/Livewire/Admin/GameServer/Create.php @@ -0,0 +1,124 @@ +may(GameServers::roleset(), GameServers::CREATE), 401); + } + + public function updated($property) + { + $this->validateOnly($property); + } + + /** + * @return array + */ + public function rules(): array + { + return [ + 'ip_address' => ['required', new IsSiprNameOrIpAddress()], // Rule::unique(GameServer::class) + 'maximum_place_jobs' => ['required', 'integer', 'numeric', 'min:5'], + 'maximum_thumbnail_jobs' => ['required', 'integer', 'numeric', 'min:5'], + 'port' => ['required', 'integer', 'numeric', 'min:0', 'max:65535'], + 'vnc_port' => ['min:0', 'max:65535', 'nullable'], + 'vnc_password' => ['min:0', 'max:512', 'nullable'], + ]; + } + + public function render() + { + return view('livewire.admin.game-server.create'); + } + + public function submit() + { + $data = $this->validate(); + + if (!is_null(GameServer::whereEncrypted('ip_address', '=', $data['ip_address'])->first())) + { + $this->addError('ip_address', __('A game server already exists with that IP address.')); + } + + if (!isset($data['vnc_port']) && !empty($this->has_vnc)) + { + $this->addError('vnc_port', __('Please specify a VNC port.')); + } + + if (!isset($data['vnc_password']) && !empty($this->has_vnc)) + { + $this->addError('vnc_password', __('Please specify a VNC password.')); + } + + if (!$this->getErrorBag()->isEmpty()) + { + return; + } + + $game_server = GameServer::create(array_filter([ + 'uuid' => uuid(), + 'ip_address' => $data['ip_address'], + 'port' => $data['port'], + 'access_key' => GameServer::generateAccessKey(), + 'maximum_place_jobs' => $data['maximum_place_jobs'], + 'maximum_thumbnail_jobs' => $data['maximum_thumbnail_jobs'], + 'has_vnc' => !empty($this->has_vnc), + 'vnc_port' => $data['vnc_port'] ?? null, + 'vnc_password' => $data['vnc_password'] ?? null, + ], null, ARRAY_FILTER_USE_BOTH)); + Action::log(Request::user(), Actions::CreatedGameServer, $game_server); + + return redirect()->route('admin.game-server.view', $game_server->uuid)->with('success', __('Successfully created game server!')); + } +} diff --git a/app/Http/Livewire/Admin/GameServer/Delete.php b/app/Http/Livewire/Admin/GameServer/Delete.php new file mode 100644 index 0000000..822e827 --- /dev/null +++ b/app/Http/Livewire/Admin/GameServer/Delete.php @@ -0,0 +1,49 @@ +gameServer = $gameServer; + } + + public function __construct() + { + abort_unless(Auth::check(), 401); + + /** @var \App\Models\User */ + $user = Auth::user(); + abort_unless($user->may(GameServers::roleset(), GameServers::MANAGE), 401); + } + + public function render() + { + return view('livewire.admin.game-server.delete'); + } + + public function submit() + { + $this->gameServer->delete(); + Action::log(Request::user(), Actions::DeletedGameServer, $this->gameServer); + + return redirect()->route('admin.game-server.all')->with('success', __('Successfully deleted game server!')); + } +} diff --git a/app/Http/Livewire/Admin/GameServer/Manage.php b/app/Http/Livewire/Admin/GameServer/Manage.php new file mode 100644 index 0000000..a70fe28 --- /dev/null +++ b/app/Http/Livewire/Admin/GameServer/Manage.php @@ -0,0 +1,146 @@ +gameServer = $gameServer; + + $this->ip_address = $this->gameServer->ip_address; + $this->maximum_place_jobs = $this->gameServer->maximum_place_jobs; + $this->maximum_thumbnail_jobs = $this->gameServer->maximum_thumbnail_jobs; + $this->port = $this->gameServer->port; + $this->has_vnc = $this->gameServer->has_vnc; + $this->vnc_port = $this->gameServer->vnc_port; + $this->vnc_password = $this->gameServer->vnc_password; + } + + public function updated($property) + { + $this->validateOnly($property); + } + + public function __construct() + { + abort_unless(Auth::check(), 401); + + /** @var \App\Models\User */ + $user = Auth::user(); + abort_unless($user->may(GameServers::roleset(), GameServers::MANAGE), 401); + } + + public function render() + { + return view('livewire.admin.game-server.manage'); + } + + /** + * @return array + */ + public function rules(): array + { + return [ + 'ip_address' => ['required', new IsSiprNameOrIpAddress()], // Rule::unique(GameServer::class) + 'maximum_place_jobs' => ['required', 'integer', 'numeric', 'min:5'], + 'maximum_thumbnail_jobs' => ['required', 'integer', 'numeric', 'min:5'], + 'port' => ['required', 'integer', 'numeric', 'min:0', 'max:65535'], + 'vnc_port' => ['min:0', 'max:65535', 'nullable'], + 'vnc_password' => ['min:0', 'max:512', 'nullable'], + ]; + } + + public function submit() + { + $data = $this->validate(); + + if (is_null($server = GameServer::whereEncrypted('ip_address', '=', $data['ip_address'])->first())) + { + if (!$server->is($this->gameServer)) + { + $this->addError('ip_address', __('A game server already exists with that IP address.')); + } + } + + if (!isset($data['vnc_port']) && !empty($this->has_vnc)) + { + $this->addError('vnc_port', __('Please specify a VNC port.')); + } + + if (!isset($data['vnc_password']) && !empty($this->has_vnc)) + { + $this->addError('vnc_password', __('Please specify a VNC password.')); + } + + if (!$this->getErrorBag()->isEmpty()) + { + return; + } + + $this->gameServer->update(array_filter([ + 'ip_address' => $this->ip_address, + 'maximum_place_jobs' => $this->maximum_place_jobs, + 'maximum_thumbnail_jobs' => $this->maximum_thumbnail_jobs, + 'port' => $this->port, + 'has_vnc' => $this->has_vnc, + 'vnc_port' => $data['vnc_port'] ?? null, + 'vnc_password' => $data['vnc_password'] ?? null, + ], null, ARRAY_FILTER_USE_BOTH)); + Action::log(Request::user(), Actions::ModifiedGameServer, $this->gameServer); + + return $this->dispatchBrowserEvent('success', __('Successfully updated game server!')); + } +} diff --git a/app/Http/Livewire/Admin/User/AssociatedAccounts.php b/app/Http/Livewire/Admin/User/AssociatedAccounts.php new file mode 100644 index 0000000..56b26e4 --- /dev/null +++ b/app/Http/Livewire/Admin/User/AssociatedAccounts.php @@ -0,0 +1,46 @@ +may(Users::roleset(), Users::MODERATION_VIEW_ASSOCIATED_ACCOUNTS), 401); + } + + /** + * @param mixed $accounts + */ + public function mount(mixed $accounts) + { + $this->accounts = $accounts; + } + + public function render() + { + return view('livewire.admin.user.associated-accounts')->with('accounts', $this->accounts->paginate(10)); + } +} diff --git a/app/Http/Livewire/Admin/User/ModerationHistory.php b/app/Http/Livewire/Admin/User/ModerationHistory.php new file mode 100644 index 0000000..3449d85 --- /dev/null +++ b/app/Http/Livewire/Admin/User/ModerationHistory.php @@ -0,0 +1,49 @@ +user = $user; + } + + public function __construct() + { + abort_unless(Auth::check(), 401); + + /** @var \App\Models\User */ + $user = Auth::user(); + abort_unless($user->may(Users::roleset(), Users::MODERATION_VIEW_BAN_HISTORY), 401); + } + + public function render() + { + $bans = Ban::where('user_id', $this->user->id); + + return view('livewire.admin.user.moderation-history')->with('bans', $bans->paginate(15)); + } +} diff --git a/app/Http/Livewire/Auth/Register.php b/app/Http/Livewire/Auth/Register.php new file mode 100644 index 0000000..aa3ce28 --- /dev/null +++ b/app/Http/Livewire/Auth/Register.php @@ -0,0 +1,187 @@ + false, + 'email' => false, + 'password' => false, + 'password_confirmation' => false, + 'key' => false, + 'tos' => false, + 'age' => false, + ]; + + public function __construct() + { + abort_if(Auth::check(), 401); + abort_unless(is_null(PoisonedIpAddress::whereEncrypted('ip_address', '=', Request::ip())->first()), 404); + } + + /** + * @return array + */ + public function rules(): array + { + $rules = [ + 'username' => $this->usernameRules(), + 'email' => $this->emailRules(), + 'password' => $this->passwordRules($this->username, $this->email), + 'password_confirmation' => $this->passwordConfirmationRules(), + 'tos' => ['required', 'min:1'], + 'age' => ['required', 'min:1'], + ]; + + if (config('tadah.invite_keys_required')) + { + $rules['key'] = ['required', 'string', new IsValidInviteKey()]; + } + + return $rules; + } + + public function data() + { + return $this->unwrapDataForValidation($this->prepareForValidation($this->getDataForValidation($this->rules()))); + } + + public function render() + { + $bag = $this->getErrorBag(); + + $icon = function ($field) use ($bag) { + if ($field == 'documents') + { + return match (true) + { + $bag->has('tos') || $bag->has('age') => 'fa-xmark', + !$bag->has('tos') && !$bag->has('age') && $this->input_began['tos'] && $this->input_began['age'] => 'fa-check', + default => 'fa-hyphen' + }; + } + + return match(true) + { + $bag->has($field) && $this->input_began[$field] => 'fa-xmark', + !$bag->has($field) && $this->input_began[$field] => 'fa-check', + default => 'fa-hyphen' + }; + }; + + $status = function ($field) use ($bag) { + return match(true) + { + $bag->has($field) && $this->input_began[$field] => 'is-invalid', + !$bag->has($field) && $this->input_began[$field] && $field != 'tos' && $field != 'age' => 'is-valid', + default => null + }; + }; + + $feedback = function ($field) use ($icon) { + return match($icon($field)) { + 'fa-xmark' => 't_error-feedback', + 'fa-check' => 't_success-feedback', + 'fa-hyphen' => 't_disabled-feedback' + }; + }; + + return view('livewire.auth.register', compact('icon', 'status', 'feedback')); + } + + public function updated($property) + { + if ($property == 'captcha') + { + return; + } + + $this->input_began[$property] = true; + + $validator = validator($this->data(), $this->rules()); + $this->dispatchBrowserEvent('validated', !$validator->fails()); + + $this->validateOnly($property); + } + + public function register() + { + $captchaValidation = validator(['captcha' => $this->captcha], ['captcha' => ['required', recaptchaRuleName()]]); + + if ($captchaValidation->fails()) + { + return $this->dispatchBrowserEvent('fatal', __('The captcha challenge failed. Please try again.')); + } + + $primaryValidation = validator($this->data(), $this->rules()); + if ($primaryValidation->fails()) + { + return $this->dispatchBrowserEvent('fatal', __('An unexpected error occurred. Please try again.')); + } + + if (!is_null(PoisonedIpAddress::whereEncrypted('ip_address', '=', Request::ip())->first())) + { + return abort(404); + } + + User::register($primaryValidation->validated(), Request::ip()); + + return $this->dispatchBrowserEvent('register-complete'); + } +} diff --git a/app/Http/Livewire/Dashboard/BestFriends.php b/app/Http/Livewire/Dashboard/BestFriends.php new file mode 100644 index 0000000..7a53c8b --- /dev/null +++ b/app/Http/Livewire/Dashboard/BestFriends.php @@ -0,0 +1,19 @@ + ['required', 'min:3', 'max:140'], + ]; + + public function __construct() + { + abort_unless(Auth::check(), 401); + } + + public function load() + { + $this->loading = false; + } + + public function share() + { + $this->validate(); + + /** @var \App\Models\User */ + $user = Auth::user(); + $key = ('create-feed-post:' . $user->id); + + if (RateLimiter::tooManyAttempts($key, 1)) + { + $wait = RateLimiter::availableIn($key); + return $this->addError('status', __('Please wait :time before updating your status.', ['time' => seconds2human($wait, true)]));; + } + + RateLimiter::hit('create-feed-post:' . Auth::user()->id, 300); + + $status = Status::create([ + 'content' => $this->status, + 'creator_id' => $user->id + ]); + + $user->updateStatus($status); + } + + public function updated($property) + { + $this->validateOnly($property); + } + + public function render() + { + /** @var \App\Models\User */ + $user = Auth::user(); + $posts = collect([]); + + $this->status = $user->status?->content ?? ''; + + if ($this->loading) + { + return view('livewire.dashboard.feed', compact('posts', 'user')); + } + + // ... merge users own posts + $posts = $posts->merge(Status::where('creator_id', $user->id)->get()); + + // ... merge posts from friends + $friends = $user->friends()->pluck('id')->all(); + $posts = $posts->merge(Status::whereIn('creator_id', $friends)->get()); + + // ... merge posts from groups + // TODO + + // ... sort + $posts = $posts->sortByDesc('id'); + + return view('livewire.dashboard.feed', compact('posts', 'user')); + } +} diff --git a/app/Http/Livewire/Dashboard/RecentlyPlayedGames.php b/app/Http/Livewire/Dashboard/RecentlyPlayedGames.php new file mode 100644 index 0000000..8bd0f11 --- /dev/null +++ b/app/Http/Livewire/Dashboard/RecentlyPlayedGames.php @@ -0,0 +1,19 @@ + 'render']; + + public function __construct() + { + abort_unless(Auth::check(), 401); + } + + public function render() + { + if ($this->selected_type) + { + abort_unless($this->selected_type->isDevelopType(), 401); + + $assets = Asset::where('creator_id', Auth::user()->id) + ->where('creator_type', CreatorType::User->value) + ->where('type', $this->selected_type->value) + ->orderBy('created_at', 'desc') + ->get(); + } + else + { + abort_unless($this->selected_page, 401); + + if ($this->selected_page == DevelopPage::Games) + { + $assets = Universe::where('creator_id', Auth::user()->id) + ->where('creator_type', CreatorType::User->value) + ->orderBy('created_at', 'desc') + ->get(); + } + } + + return view('livewire.develop.assets', [ + 'assets' => paginate($assets, 10), + 'selected_type' => $this->selected_type, + 'selected_page' => $this->selected_page + ]); + } +} diff --git a/app/Http/Livewire/Develop/Create.php b/app/Http/Livewire/Develop/Create.php new file mode 100644 index 0000000..cbaa37c --- /dev/null +++ b/app/Http/Livewire/Develop/Create.php @@ -0,0 +1,185 @@ +selected_type->isDevelopCreatable(), 404); + } + + /** + * @return array + */ + protected function rules(): array + { + return [ + 'asset_name' => ['required', 'min:3', 'max:50'], + 'asset_file' => ['required', ... $this->selected_type->rules()] + ]; + } + + public function upload() + { + $this->validate(); + + if (RateLimiter::tooManyAttempts('create-asset:' . Auth::user()->id, 1)) + { + $wait = RateLimiter::availableIn('create-asset:' . Auth::user()->id); + $this->dispatchBrowserEvent('error', __('Please wait :time before creating a new :asset_type.', ['time' => seconds2human($wait), 'asset_type' => $this->selected_type->fullname()])); + return; + } + + // static thumbnail processing + if (in_array($this->selected_type, [AssetType::TShirt, AssetType::Decal])) + { + try + { + $image = new SimpleImage($this->asset_file->getRealPath()); + } + catch(\Exception $exception) + { + $this->addError('asset_file', __('Failed to process image, it might be corrupted?')); + return; + } + + if ($this->selected_type == AssetType::TShirt) + { + $imageData = new SimpleImage(); + $imageData->fromNew($image->getWidth(), $image->getWidth()); + + $assetThumbnail = new SimpleImage(resource_path('img/tshirt-template.png')); + $assetThumbnail->resize(420, 420); + + // fit the image in a 1:1 canvas, 420x420 max + $imageData->resize($image->getWidth()); + $imageData->overlay($image, 'top'); + if ($image->getWidth() > 420) $imageData->resize(420, 420); + + // image thumbnail must be 420x420 + $imageThumbnail = clone $imageData; + $imageThumbnail->resize(420, 420); + + // asset thumbnail is image thumbnail overlayed onto t-shirt template + $assetThumbnailOverlay = clone $imageThumbnail; + $assetThumbnailOverlay->resize(250, 250); + $assetThumbnail->overlay($assetThumbnailOverlay, 'center', 1); + } + else if ($this->selected_type == AssetType::Decal) + { + // image retains original ratio, original size is retained if under 420x420 + $imageData = clone $image; + $imageData->bestFit(420, 420); + + // image and asset thumbnails are the image resized to 420x420 + $imageThumbnail = clone $image; + $imageThumbnail->resize(420, 420); + $assetThumbnail = clone $imageThumbnail; + } + + $imageData = $imageData->toString(); + $imageThumbnail = $imageThumbnail->toString(); + $assetThumbnail = $assetThumbnail->toString(); + + RateLimiter::hit('create-asset:' . Auth::user()->id, 30); + + $imageAsset = Asset::create([ + 'name' => $this->asset_name, + 'description' => $this->selected_type->fullname() . ' ' . AssetType::Image->name, + 'type' => AssetType::Image->value, + 'creator_id' => Auth::user()->id + ]); + + $imageAsset->initialize($imageData, $imageThumbnail); + + $document = simplexml_load_file(resource_path(sprintf('xml/%s.xml', $this->selected_type->name))); + $document->xpath("//url")[0][0] = sprintf('%s/asset/?id=%d', config('app.url'), $imageAsset->id); + // we need to remove the first line that contains the XML declaration + $assetData = $document->asXML(); + $assetData = preg_replace('/^.+\n/', '', $assetData); + } + else + { + if ($this->selected_type == AssetType::Audio) + { + $assetThumbnail = file_get_contents(resource_path('img/audio.png')); + $assetData = $this->asset_file->get(); + } + + if ($this->selected_type == AssetType::Animation) + { + $assetThumbnail = file_get_contents(resource_path('img/animation.png')); + $assetData = $this->asset_file->get(); + } + + RateLimiter::hit('create-asset:' . Auth::user()->id, 30); + } + + $asset = Asset::create([ + 'name' => $this->asset_name, + 'description' => $this->selected_type->fullname(), + 'type' => $this->selected_type->value, + 'image_id' => $imageAsset->id ?? null, + 'creator_id' => Auth::user()->id + ]); + + $asset->initialize($assetData, $assetThumbnail); + + if (in_array($this->selected_type, [AssetType::TShirt, AssetType::Decal])) + { + Cdn::save($imageData); + Cdn::save($imageThumbnail, 'png'); + } + + Cdn::save($assetData); + Cdn::save($assetThumbnail, 'png'); + + $this->dispatchBrowserEvent('success', __('Successfully created :asset_type.', ["asset_type" => __($this->selected_type->fullname())])); + + $this->emitTo('develop.assets', 'assetCreated'); + } + + public function updated($property) + { + $this->validateOnly($property); + } + + public function render() + { + return view('livewire.develop.create')->with('selected_type', $this->selected_type); + } +} diff --git a/app/Http/Livewire/Develop/Panel.php b/app/Http/Livewire/Develop/Panel.php new file mode 100644 index 0000000..21152ef --- /dev/null +++ b/app/Http/Livewire/Develop/Panel.php @@ -0,0 +1,64 @@ +isDevelopType()) + { + $this->reset('selected_type'); + $this->reset('selected_page'); + } + + $this->selected_type = $type; + $this->selected_page = false; + } + + public function setPage($enum_value) + { + $page = DevelopPage::tryFrom($enum_value); + + if (is_null($page)) + { + $this->reset('selected_type'); + $this->reset('selected_page'); + } + + $this->selected_type = false; + $this->selected_page = $page; + } + + public function render() + { + return view('livewire.develop.panel', [ + 'types' => AssetType::developTypes(), + 'pages' => DevelopPage::developPages(), + 'selected_type' => $this->selected_type, + 'selected_page' => $this->selected_page + ]); + } +} diff --git a/app/Http/Livewire/Forum/Create.php b/app/Http/Livewire/Forum/Create.php new file mode 100644 index 0000000..6c20435 --- /dev/null +++ b/app/Http/Livewire/Forum/Create.php @@ -0,0 +1,13 @@ +thread->id)->orderBy('created_at', 'desc')->get(); + + return view('livewire.forum.replies')->with('replies', paginate($replies, 10)); + } +} \ No newline at end of file diff --git a/app/Http/Livewire/Forum/Thread.php b/app/Http/Livewire/Forum/Thread.php new file mode 100644 index 0000000..cf04244 --- /dev/null +++ b/app/Http/Livewire/Forum/Thread.php @@ -0,0 +1,30 @@ +with('thread', $this->thread); + } + + public function delete() + { + if (Auth::user()->may(Forums::roleset(), Forums::GLOBAL_DELETE_POSTS)) { + $this->thread->delete(); + + return redirect(route('forum')); + } + } +} diff --git a/app/Http/Livewire/Forum/Threads.php b/app/Http/Livewire/Forum/Threads.php new file mode 100644 index 0000000..7cd2111 --- /dev/null +++ b/app/Http/Livewire/Forum/Threads.php @@ -0,0 +1,49 @@ + ['except' => ''], + ]; + + public function render() + { + $threads = []; + + if ($this->search) { + $threads = ForumThread::search($this->search)->get(); + } elseif ($this->category) { + $threads = ForumThread::where('category_id', '=', $this->category->id)->orderBy('updated_at', 'desc')->get(); + } else { + $threads = ForumThread::orderBy('updated_at', 'desc')->get(); + } + + return view('livewire.forum.threads')->with('threads', paginate($threads, 10)); + } +} diff --git a/app/Http/Livewire/Games/Search.php b/app/Http/Livewire/Games/Search.php new file mode 100644 index 0000000..9d96a79 --- /dev/null +++ b/app/Http/Livewire/Games/Search.php @@ -0,0 +1,46 @@ +sort = PlaceSort::tryFrom($enum_value) ?? PlaceSort::MostPopular; + } + + public function setGenre($enum_value) + { + $this->genre = AssetGenre::tryFrom($enum_value) ?? AssetGenre::All; + } + + public function render() + { + return view('livewire.games.search', [ + 'sorts' => PlaceSort::cases(), + 'genres' => AssetGenre::cases(), + 'selected_sort' => $this->sort, + 'selected_genre' => $this->genre + ]); + } +} diff --git a/app/Http/Livewire/Item/Comments.php b/app/Http/Livewire/Item/Comments.php new file mode 100644 index 0000000..3a1489b --- /dev/null +++ b/app/Http/Livewire/Item/Comments.php @@ -0,0 +1,23 @@ +asset->comments_enabled, 404); + } + + public function render() + { + return view('livewire.item.comments'); + } +} diff --git a/app/Http/Livewire/Item/Configure.php b/app/Http/Livewire/Item/Configure.php new file mode 100644 index 0000000..a3a66a2 --- /dev/null +++ b/app/Http/Livewire/Item/Configure.php @@ -0,0 +1,118 @@ + ['required', 'string', 'min:3', 'max:50'], + 'description' => ['required', 'string', 'max:1000'], + 'genre' => [new Enum(AssetGenre::class)], + // 'price' => ['integer', 'min:0', 'max:1000'], + ]; + } + + public function mount() + { + abort_unless($this->asset->canConfigure(), 404); + + $this->name = $this->asset->name; + $this->description = $this->asset->description; + $this->genre = $this->asset->genre->value; + $this->sell = $this->asset->is_for_sale; + $this->price = $this->asset->price; + $this->comments = $this->asset->comments_enabled; + } + + public function updated($property) + { + $this->validateOnly($property); + } + + public function submit() + { + $this->withValidator(function (Validator $validator) { + $validator->sometimes('price', ['required', 'integer', 'min:0', 'max:1000'], function ($input){ + return !is_null($this->sell); + }); + })->validate(); + + $this->asset->name = $this->name; + $this->asset->description = $this->description; + $this->asset->genre = $this->genre; + $this->asset->comments_enabled = $this->comments ?? false; + + if ($this->asset->type->isSellable()) + { + $this->asset->is_for_sale = $this->sell ?? false; + + if ($this->asset->type == AssetType::Model) + { + $this->asset->is_public_domain = $this->asset->is_for_sale; + } + + if ($this->sell && !$this->asset->type->isFree()) + { + $this->asset->price = $this->price; + } + } + + $this->asset->save(); + + $this->dispatchBrowserEvent('success', __('Successfully updated :asset_type.', ["asset_type" => __($this->asset->type->fullname())])); + } + + public function render() + { + $genres = AssetGenre::cases(); + + return view('livewire.item.configure', compact('genres')); + } +} diff --git a/app/Http/Livewire/Layout/SearchBar.php b/app/Http/Livewire/Layout/SearchBar.php new file mode 100644 index 0000000..bdf38c9 --- /dev/null +++ b/app/Http/Livewire/Layout/SearchBar.php @@ -0,0 +1,28 @@ +take(4)->get(); + return $users; + } + + public function render() + { + $users = $this->searchUsers($this->search); + return view('livewire.layout.search-bar')->with('users', $users); + } +} \ No newline at end of file diff --git a/app/Http/Livewire/Users/FriendButton.php b/app/Http/Livewire/Users/FriendButton.php new file mode 100644 index 0000000..cc3cf05 --- /dev/null +++ b/app/Http/Livewire/Users/FriendButton.php @@ -0,0 +1,99 @@ +id, $this->user->id); + + if (!is_null($friendship)) + { + if ($friendship->accepted) + { + $this->dispatchBrowserEvent('error', __('You are already friends with this user.')); + } + else if ($friendship->receiver_id == Auth::user()->id) + { + $this->dispatchBrowserEvent('error', __('You already have an incoming friend request from this user.')); + } + else + { + $this->dispatchBrowserEvent('error', __('You have already sent a friend request to this user.')); + } + + + return; + } + + if (RateLimiter::tooManyAttempts('submit-friend-request:' . Auth::user()->id, 1)) + { + $wait = RateLimiter::availableIn('submit-friend-request:' . Auth::user()->id); + $this->dispatchBrowserEvent('error', __('Please wait :time before sending another friend request.', ['time' => seconds2human($wait)])); + return; + } + + RateLimiter::hit('submit-friend-request:' . Auth::user()->id, 60); + + Friendship::create([ + 'requester_id' => Auth::user()->id, + 'receiver_id' => $this->user->id + ]); + } + + public function accept() + { + $friendship = Friendship::getMutual(Auth::user()->id, $this->user->id); + + if (is_null($friendship) || $friendship->receiver_id != Auth::user()->id) + { + $this->dispatchBrowserEvent('error', __('You don\'t currently have a pending friend request from this user.')); + return; + } + + if ($friendship->accepted) + { + $this->dispatchBrowserEvent('error', __('You are already friends with this user!')); + return; + } + + $friendship->update(['accepted' => true]); + } + + public function revoke() + { + $friendship = Friendship::getMutual(Auth::user()->id, $this->user->id); + + if (is_null($friendship)) + { + $this->dispatchBrowserEvent('error', __('You don\'t have an existing friend connection with this user.')); + return; + } + + $friendship->delete(); + } + + public function render() + { + $user = $this->user; + $friendship = Friendship::getMutual(Auth::user()->id, $this->user->id); + return view('livewire.users.friend-button', compact('user', 'friendship')); + } +} diff --git a/app/Http/Livewire/Users/Search.php b/app/Http/Livewire/Users/Search.php new file mode 100644 index 0000000..e6681b4 --- /dev/null +++ b/app/Http/Livewire/Users/Search.php @@ -0,0 +1,45 @@ + ['except' => ''], + ]; + + public function updatingSearch() + { + $this->resetPage(); + } + + public function render() + { + $users = User::search($this->search)->get(); + if (empty(trim($this->search))) + { + $users = $users->shuffle(); + } + + return view('livewire.users.search')->with('users', paginate($users, 12)); + } +} diff --git a/app/Http/Middleware/AdminGuard.php b/app/Http/Middleware/AdminGuard.php new file mode 100644 index 0000000..cb78486 --- /dev/null +++ b/app/Http/Middleware/AdminGuard.php @@ -0,0 +1,27 @@ +user()->may(Admin::roleset(), Admin::VIEW_PANEL)) + { + return abort(404); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php new file mode 100644 index 0000000..e9860bd --- /dev/null +++ b/app/Http/Middleware/Authenticate.php @@ -0,0 +1,22 @@ +expectsJson()) + { + return route('login'); + } + } +} diff --git a/app/Http/Middleware/AuthenticateArbiter.php b/app/Http/Middleware/AuthenticateArbiter.php new file mode 100644 index 0000000..9e49145 --- /dev/null +++ b/app/Http/Middleware/AuthenticateArbiter.php @@ -0,0 +1,30 @@ +bearerToken())) + { + return abort(404); + } + + $game_server = GameServer::whereEncrypted('access_key', '=', $request->bearerToken())->firstOrFail(); + $request->merge(compact('game_server')); + + return $next($request); + } +} diff --git a/app/Http/Middleware/BlockBannedIpAddresses.php b/app/Http/Middleware/BlockBannedIpAddresses.php new file mode 100644 index 0000000..4764448 --- /dev/null +++ b/app/Http/Middleware/BlockBannedIpAddresses.php @@ -0,0 +1,32 @@ +environment('production')) + { + return $next($request); + } + + if (in_array($request->ip(), Cache::store('octane')->get('banned_ip_addresses') ?? [])) + { + return response()->make('Access Denied', 403); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/EncryptCookies.php b/app/Http/Middleware/EncryptCookies.php new file mode 100644 index 0000000..867695b --- /dev/null +++ b/app/Http/Middleware/EncryptCookies.php @@ -0,0 +1,17 @@ + + */ + protected $except = [ + // + ]; +} diff --git a/app/Http/Middleware/EnsureEmailIsVerified.php b/app/Http/Middleware/EnsureEmailIsVerified.php new file mode 100644 index 0000000..9795b79 --- /dev/null +++ b/app/Http/Middleware/EnsureEmailIsVerified.php @@ -0,0 +1,43 @@ +route()->getName(), $whitelisted)) + { + return $next($request); + } + + if ($request->user() && !$request->user()->hasVerifiedEmail()) + { + return $request->expectsJson() ? abort(403, 'Your email address is not verified.') : redirect()->route('verification.notice'); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/IsBanned.php b/app/Http/Middleware/IsBanned.php new file mode 100644 index 0000000..31b4504 --- /dev/null +++ b/app/Http/Middleware/IsBanned.php @@ -0,0 +1,38 @@ +user()->isBanned() && !in_array(Route::currentRouteName(), $whitelist)) + { + return redirect()->route('account.disabled'); + } + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/Localization.php b/app/Http/Middleware/Localization.php new file mode 100644 index 0000000..a982c3b --- /dev/null +++ b/app/Http/Middleware/Localization.php @@ -0,0 +1,28 @@ + + */ + protected $except = [ + // + ]; +} diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php new file mode 100644 index 0000000..eefa3aa --- /dev/null +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -0,0 +1,34 @@ +check()) + { + return redirect(RouteServiceProvider::HOME); + } + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/ToolGuard.php b/app/Http/Middleware/ToolGuard.php new file mode 100644 index 0000000..d6f515d --- /dev/null +++ b/app/Http/Middleware/ToolGuard.php @@ -0,0 +1,32 @@ +user()->isSuperAdmin()) + { + return abort(404); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/TrimStrings.php b/app/Http/Middleware/TrimStrings.php new file mode 100644 index 0000000..88cadca --- /dev/null +++ b/app/Http/Middleware/TrimStrings.php @@ -0,0 +1,19 @@ + + */ + protected $except = [ + 'current_password', + 'password', + 'password_confirmation', + ]; +} diff --git a/app/Http/Middleware/TrustHosts.php b/app/Http/Middleware/TrustHosts.php new file mode 100644 index 0000000..bf494fe --- /dev/null +++ b/app/Http/Middleware/TrustHosts.php @@ -0,0 +1,20 @@ + + */ + public function hosts(): array + { + return [ + $this->allSubdomainsOfApplicationUrl(), + ]; + } +} diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php new file mode 100644 index 0000000..3dedccf --- /dev/null +++ b/app/Http/Middleware/TrustProxies.php @@ -0,0 +1,28 @@ +|?string + */ + protected $proxies; + + /** + * The headers that should be used to detect proxies. + * + * @var int + */ + protected $headers = + Request::HEADER_X_FORWARDED_FOR | + Request::HEADER_X_FORWARDED_HOST | + Request::HEADER_X_FORWARDED_PORT | + Request::HEADER_X_FORWARDED_PROTO | + Request::HEADER_X_FORWARDED_AWS_ELB; +} diff --git a/app/Http/Middleware/UpdateCurrentIpAddress.php b/app/Http/Middleware/UpdateCurrentIpAddress.php new file mode 100644 index 0000000..eddd626 --- /dev/null +++ b/app/Http/Middleware/UpdateCurrentIpAddress.php @@ -0,0 +1,27 @@ +user()->setLastIpAddress($request->ip()); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php new file mode 100644 index 0000000..9e86521 --- /dev/null +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -0,0 +1,17 @@ + + */ + protected $except = [ + // + ]; +} diff --git a/app/Listeners/GameServer/AppendConsoleOutput.php b/app/Listeners/GameServer/AppendConsoleOutput.php new file mode 100644 index 0000000..c3a0c32 --- /dev/null +++ b/app/Listeners/GameServer/AppendConsoleOutput.php @@ -0,0 +1,19 @@ +game_server->appendToLog('console', [$event->severity, $event->timestamp, $event->output, $event->blur]); + } +} diff --git a/app/Listeners/GameServer/ChangeState.php b/app/Listeners/GameServer/ChangeState.php new file mode 100644 index 0000000..d8901aa --- /dev/null +++ b/app/Listeners/GameServer/ChangeState.php @@ -0,0 +1,19 @@ +game_server->setState($event->state); + } +} diff --git a/app/Listeners/GameServer/Ping.php b/app/Listeners/GameServer/Ping.php new file mode 100644 index 0000000..56fccfb --- /dev/null +++ b/app/Listeners/GameServer/Ping.php @@ -0,0 +1,19 @@ +game_server->ping(); + } +} diff --git a/app/Listeners/SendEmailVerificationNotification.php b/app/Listeners/SendEmailVerificationNotification.php new file mode 100644 index 0000000..029552a --- /dev/null +++ b/app/Listeners/SendEmailVerificationNotification.php @@ -0,0 +1,27 @@ +user instanceof MustVerifyEmail && ! $event->user->hasVerifiedEmail()) + { + $event->user->sendEmailVerificationNotification(); + } + } +} diff --git a/app/Models/Action.php b/app/Models/Action.php new file mode 100644 index 0000000..5a4d826 --- /dev/null +++ b/app/Models/Action.php @@ -0,0 +1,159 @@ + + */ + protected $fillable = [ + 'doer_id', + 'action', + 'target_id' + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'action' => Actions::class + ]; + + /** + * Log an action by an administrator. + * + * @var array + */ + public static function log($user, $action, $target = null) + { + if ($target) { + return self::create([ + 'doer_id' => $user->id, + 'action' => $action->value, + 'target_id' => $target->id + ]); + } else { + return self::create([ + 'doer_id' => $user->id, + 'action' => $action->value + ]); + } + } + + /** + * The person who had done the action. + */ + public function doer() + { + return $this->belongsTo(User::class, 'doer_id'); + } + + /** + * The person who had done the action. + */ + public function target() + { + return $this->belongsTo(User::class, 'action_user_id'); + } + + /** + * Format the localized log string properly. + */ + public function format() + { + $string = __($this->action->text()); + + if ($this->action == Actions::WarnedUser || + $this->action == Actions::PermBannedUser || + $this->action == Actions::PoisonBannedUser || + $this->action == Actions::PardonedUser) { + $user = User::where('id', '=', $this->target_id)->first(); + + if ($user) { + $name = $user->username; + + $string = __($this->action->text(), ['name' => $name]); + } else { + $string = __('Moderated a user.'); + } + } + + if ($this->action == Actions::ChangedUserPermissions) { + $user = User::where('id', '=', $this->target_id)->first(); + + if ($user) { + $name = $user->username; + + $string = __($this->action->text(), ['name' => $name]); + } else { + $string = __('Changed permissions for a user.'); + } + } + + if ($this->action == Actions::TempBannedUser) { + $ban = Ban::where('id', '=', $this->target_id)->first(); + + if ($ban) { + $name = $ban->user->username; + $date = $ban->expiry_date; + + $string = __($this->action->text(), ['name' => $name, 'date' => $date]); + } else { + $string = __('Moderated a user.'); + } + } + + if ($this->action == Actions::CreatedGameServer || + $this->action == Actions::DeletedGameServer || + $this->action == Actions::ModifiedGameServer) { + $gameServer = GameServer::where('id', '=', $this->target_id)->withTrashed()->first(); + + if ($gameServer) { + $ip_address = $gameServer->ip_address; + + $string = __($this->action->text(), ['ip' => $ip_address]); + } else { + $string = __('Modified a game server.'); + } + } + + if ($this->action == Actions::ApprovedAsset || + $this->action == Actions::DeniedAsset || + $this->action == Actions::ModeratedAsset) { + $asset = Asset::where('id', '=', $this->target_id)->withTrashed()->first(); + + if ($asset) { + $name = $asset->name; + $type = $asset->type; + $id = $asset->id; + + $string = __($this->action->text(), ['name' => $name, 'type' => $type, 'id' => $id]); + } else { + $string = __('Modified an asset.'); + } + } + + return $string; + } + + public function toSearchableArray() + { + return [ 'username' => $this->doer->username ]; + } +} diff --git a/app/Models/Asset.php b/app/Models/Asset.php new file mode 100644 index 0000000..1de90fb --- /dev/null +++ b/app/Models/Asset.php @@ -0,0 +1,185 @@ + + */ + protected $fillable = [ + 'name', + 'description', + 'type', + 'genre', + 'version_id', + 'image_id', + 'creator_id', + 'creator_type', + 'is_for_sale', + 'is_public_domain', + 'comments_enabled', + 'moderation', + 'price', + 'gear_attributes', + 'sales', + 'favorites', + 'upvotes', + 'downvotes', + + 'universe_id', + 'max_players', + 'client_version', + 'access', + 'chat_style', + 'is_start_place', + 'is_boosters_club_only', + 'visits' + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'type' => AssetType::class, + 'genre' => AssetGenre::class, + 'creator_type' => CreatorType::class, + ]; + + /** + * Gets the creator of this asset. + */ + public function creator() + { + return $this->belongsTo(User::class, 'creator_id'); + } + + /** + * Gets the current version of this asset. + */ + public function version() + { + return $this->belongsTo(AssetVersion::class, 'version_id'); + } + + /** + * Gets all the versions of this asset. + */ + public function versions() + { + return $this->hasMany(AssetVersion::class, 'asset_id'); + } + + /** + * Gets all the comments of this asset. + */ + public function comments() + { + return $this->hasMany(AssetComment::class, 'asset_id'); + } + + /** + * Gets all the owners of this asset. + */ + public function owners() + { + return $this->hasMany(AssetOwnership::class, 'asset_id'); + } + + /** + * Gets the asset ownership info of the current user. + * + * @return AssetOwnership + */ + public function ownership(): AssetOwnership + { + $userId = Auth::user()->id; + return $this->owners()->where('user_id', $userId)->first(); + } + + /** + * Checks if the current user can configure the asset. + * + * @return bool + */ + public function canConfigure(): bool + { + if ($this->creator_type == CreatorType::User) + { + return $this->creator_id == Auth::user()->id; + } + + return false; + } + + /** + * Initializes the asset on creation. + * + * @param string $file + * @param ?string $thumbnail_icon + */ + public function initialize(string $file, string $thumbnail_icon = null) + { + $this->createVersion($file, $thumbnail_icon); + $this->addOwner(Auth::user()->id); + } + + /** + * Creates a new version of the asset. + * A render request is made if no thumbnail icon is provided. + * + * @param string $file + * @param ?string $thumbnail_icon + * @return AssetVersion + */ + public function createVersion(string $file, string $thumbnail_icon = null): AssetVersion + { + $cdn_file_hash = Cdn::hash($file); + $cdn_thumbnail_icon_hash = Cdn::hash($thumbnail_icon); + + $lastVersion = AssetVersion::select('version')->where('asset_id', $this->id)->orderByDesc('id')->limit(1)->value('version') ?? 0; + + $assetVersion = AssetVersion::create([ + 'asset_id' => $this->id, + 'version' => $lastVersion + 1, + 'cdn_file_hash' => $cdn_file_hash, + 'cdn_thumbnail_icon_hash' => $cdn_thumbnail_icon_hash + ]); + + $this->update(['version_id' => $assetVersion->id]); + + // TODO: request thumbnail render if icon hash is not provided + + return $assetVersion; + } + + /** + * Adds a new owner of the asset. + * + * @param int $user_id + * @return AssetOwnership + */ + public function addOwner(int $user_id): AssetOwnership + { + return AssetOwnership::create([ + 'asset_id' => $this->id, + 'user_id' => $user_id + ]); + } +} diff --git a/app/Models/AssetComment.php b/app/Models/AssetComment.php new file mode 100644 index 0000000..1681cf3 --- /dev/null +++ b/app/Models/AssetComment.php @@ -0,0 +1,38 @@ + + */ + protected $fillable = [ + 'asset_id', + 'creator_id', + 'content' + ]; + + /** + * The asset associated with this comment. + */ + public function asset() + { + return $this->belongsTo(Asset::class, 'asset_id'); + } + + /** + * The user associated with this comment. + */ + public function user() + { + return $this->belongsTo(User::class, 'creator_id'); + } +} diff --git a/app/Models/AssetOwnership.php b/app/Models/AssetOwnership.php new file mode 100644 index 0000000..f89846c --- /dev/null +++ b/app/Models/AssetOwnership.php @@ -0,0 +1,38 @@ + + */ + protected $fillable = [ + 'asset_id', + 'user_id', + 'wearing' + ]; + + /** + * Gets the asset that's owned. + */ + public function asset() + { + return $this->belongsTo(Asset::class, 'asset_id'); + } + + /** + * Gets the user that owns the asset. + */ + public function user() + { + return $this->belongsTo(User::class, 'user_id'); + } +} diff --git a/app/Models/AssetVersion.php b/app/Models/AssetVersion.php new file mode 100644 index 0000000..f6316e4 --- /dev/null +++ b/app/Models/AssetVersion.php @@ -0,0 +1,53 @@ + + */ + protected $fillable = [ + 'asset_id', + 'version', + 'cdn_thumbnail_icon_hash', + 'cdn_thumbnail_widescreen_hash', + 'cdn_file_hash' + ]; + + /** + * The attributes that should be hidden for serialization. + * + * @var array + */ + protected $hidden = [ + 'cdn_thumbnail_icon_hash', + 'cdn_thumbnail_widescreen_hash', + 'cdn_file_hash' + ]; + + /** + * The asset associated with this version. + */ + public function asset() + { + return $this->belongsTo(Asset::class, 'asset_id'); + } + + /** + * The thumbnail of this version. + * + * @param bool $widescreen + * @return string + */ + public function thumbnail(bool $widescreen = false): string + { + return Cdn::getUrl(sprintf('%s.png', $this->cdn_thumbnail_icon_hash), $widescreen); + } +} diff --git a/app/Models/Badge.php b/app/Models/Badge.php new file mode 100644 index 0000000..2090d33 --- /dev/null +++ b/app/Models/Badge.php @@ -0,0 +1,27 @@ + + */ + protected $fillable = [ + 'name', + 'description', + ]; + + /** + * Gets the creator of this badge. + */ + public function creator() + { + return $this->belongsTo(User::class, 'creator'); + } +} diff --git a/app/Models/Ban.php b/app/Models/Ban.php new file mode 100644 index 0000000..df347d8 --- /dev/null +++ b/app/Models/Ban.php @@ -0,0 +1,170 @@ + + */ + protected $fillable = [ + 'moderator_id', + 'user_id', + 'internal_reason', + 'moderator_note', + 'offensive_item', + 'expiry_date', + 'is_appealable', + 'is_poison_ban', + 'patient_zero', + 'is_warning', + 'has_been_pardoned', + 'pardon_internal_reason', + 'pardoner_id', + 'is_active', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'expiry_date' => 'datetime' + ]; + + /** + * Poisons the ban by banning the IP addresses and users of this account and all accounts associated with it. + */ + public function poison() + { + if (count($this->poisonedIpAddresses) != 0) + { + return; + } + + $this->update([ + 'is_poison_ban' => true, + 'patient_zero' => $this->user_id, + ]); + + PoisonedIpAddress::create([ + 'ip_address' => $this->user->register_ip_address, + 'tied_to' => $this->id, + ]); + + PoisonedIpAddress::create([ + 'ip_address' => $this->user->last_ip_address, + 'tied_to' => $this->id, + ]); + + foreach ($this->user->getAssociatedAccounts() as $user) + { + $user->update(['current_ban_id' => $this->id]); + + PoisonedIpAddress::create([ + 'ip_address' => '127.0.0.1', + 'tied_to' => $this->id, + ]); + + PoisonedIpAddress::create([ + 'ip_address' => $user->register_ip, + 'tied_to' => $this->id, + ]); + } + } + + /** + * Unpoisons the ban. + */ + public function cure() + { + if (!$this->is_poison_ban) + { + return; + } + + foreach ($this->poisonedIpAddresses as $ip_address) + { + $ip_address->delete(); + } + + foreach ($this->user->getAssociatedAccounts() as $user) + { + $user->update(['current_ban_id' => null]); + } + } + + /** + * The IP addresses associated with this ban that are not allowed to create an account. + */ + public function poisonedIpAddresses() + { + return $this->hasMany(PoisonedIpAddress::class, 'tied_to', 'id'); + } + + /** + * Lifts the ban. If this is a poison ban, the ban gets cured. + */ + public function lift() + { + $this->update([ + 'is_active' => false + ]); + + $this->user->update([ + 'current_ban_id' => null + ]); + + if ($this->is_poison_ban) + { + $this->cure(); + } + } + + /** + * The user that has been banned. + */ + public function user() + { + return $this->hasOne(User::class, 'id', 'user_id'); + } + + /** + * The moderator that performed this ban. + */ + public function moderator() + { + return $this->hasOne(User::class, 'id', 'moderator_id'); + } + + /** + * The moderator that pardoned this ban (if any.) + */ + public function pardoner() + { + return $this->hasOne(User::class, 'id', 'pardoner_id'); + } + + /** + * The user that was originally poisoned banned associated with this ban. + */ + public function patientZero() + { + return $this->hasOne(User::class, 'id', 'patient_zero'); + } + + public function toSearchableArray() + { + return [ 'username' => $this->user->username ]; + } +} diff --git a/app/Models/ForumCategory.php b/app/Models/ForumCategory.php new file mode 100644 index 0000000..82b32d1 --- /dev/null +++ b/app/Models/ForumCategory.php @@ -0,0 +1,41 @@ + + */ + protected $fillable = [ + 'name', + 'description', + 'priority', + 'color', + 'superadmins_only' + ]; + + /** + * The threads that belong to this category. + */ + public function threads() + { + return $this->hasMany(ForumThread::class, 'category_id'); + } + + /** + * The threads that belong to this category. + */ + public function replies() + { + return $this->hasMany(ForumReply::class, 'category_id'); + } +} diff --git a/app/Models/ForumReply.php b/app/Models/ForumReply.php new file mode 100644 index 0000000..1f1cbac --- /dev/null +++ b/app/Models/ForumReply.php @@ -0,0 +1,36 @@ + + */ + protected $fillable = [ + 'body', + 'author_id', + 'thread_id', + 'stickied' + ]; + + /** + * The author of this thread. + */ + public function author() + { + return $this->belongsTo(User::class, 'author_id'); + } + + public function thread() + { + return $this->belongsTo(ForumThread::class, 'thread_id'); + } +} diff --git a/app/Models/ForumThread.php b/app/Models/ForumThread.php new file mode 100644 index 0000000..5589bd9 --- /dev/null +++ b/app/Models/ForumThread.php @@ -0,0 +1,50 @@ + + */ + protected $fillable = [ + 'title', + 'body', + 'author_id', + 'category_id', + 'stickied', + 'locked', + 'views' + ]; + + /** + * The author of this thread. + */ + public function author() + { + return $this->belongsTo(User::class, 'author_id'); + } + + /** + * The category this thread belongs to. + */ + public function category() + { + return $this->belongsTo(ForumCategory::class, 'category_id'); + } + + /** + * The replies of this thread. + */ + public function replies() + { + return $this->hasMany(ForumReply::class, 'thread_id'); + } +} diff --git a/app/Models/Friendship.php b/app/Models/Friendship.php new file mode 100644 index 0000000..8d54f5f --- /dev/null +++ b/app/Models/Friendship.php @@ -0,0 +1,50 @@ + + */ + protected $fillable = [ + 'requester_id', + 'receiver_id', + 'accepted' + ]; + + /** + * Gets a mutual relationship between two users. + * + * @param int $firstUserId + * @param int $secondUserId + * @return Friendship + */ + public static function getMutual(int $firstUserId, int $secondUserId) + { + return self::whereIn('requester_id', [$firstUserId, $secondUserId])->whereIn('receiver_id', [$firstUserId, $secondUserId])->first(); + } + + /** + * The user that made the friend request. + */ + public function requester() + { + return $this->belongsTo(User::class, 'requester_id'); + } + + /** + * The user that received the friend request. + */ + public function receiver() + { + return $this->belongsTo(User::class, 'receiver_id'); + } +} diff --git a/app/Models/GameServer.php b/app/Models/GameServer.php new file mode 100644 index 0000000..86d1d13 --- /dev/null +++ b/app/Models/GameServer.php @@ -0,0 +1,293 @@ + + */ + protected $fillable = [ + 'uuid', + 'access_key', + 'ip_address', + 'port', + 'maximum_place_jobs', + 'maximum_thumbnail_jobs', + 'is_set_up', + 'has_vnc', + 'vnc_port', + 'vnc_password', + 'friendly_name', + 'utc_offset', + ]; + + /** + * The attributes that should be hidden for serialization. + * + * @var array + */ + protected $hidden = [ + 'access_key', + 'access_key_index', + 'ip_address', + 'ip_address_index', + 'vnc_port', + 'vnc_password', + 'friendly_name', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'access_key' => CipherSweetEncrypted::class, + 'ip_address' => CipherSweetEncrypted::class, + 'vnc_port' => 'encrypted', + 'vnc_password' => 'encrypted', + 'friendly_name' => 'encrypted', + ]; + + /** + * Unformatted log keys for any game server. + * + * @return array + */ + public static array $logKeys = [ + 'console' => 'game_server_logs_%s', + 'ram' => 'game_server_ram_usage_%s', + 'cpu' => 'game_server_cpu_usage_%s', + 'network' => 'game_server_network_usage_%s', + 'access' => 'game_server_access_%s', + 'state' => 'game_server_state_%s', + ]; + + /** + * Gets a log key associated for this game server. + * + * @param string $key + * @return ?string + */ + public function logKey(string $key): ?string + { + if (empty(self::$logKeys[$key])) + { + return null; + } + + return sprintf(self::$logKeys[$key], $this->uuid); + } + + /** + * Initializes all logs keys. + */ + public function initLogKeys() + { + foreach (array_keys(self::$logKeys) as $key) + { + Cache::put($this->logKey($key), null); + } + } + + /** + * Updates the state last ping. + */ + public function ping() + { + Cache::put($this->logKey('state'), [ + 'last_ping' => time(), + 'state' => GameServerState::Online + ]); + } + + /** + * The complete log of this game server. + * + * @param string $key + * @return mixed + */ + public function retrieveCompleteLog(string $key): mixed + { + return Cache::get($this->logKey($key)); + } + + /** + * Appends to one of the log files of this game server. + * + * @param string $key + * @param mixed $message + */ + public function appendToLog(string $key, mixed $message) + { + $lock = Cache::lock($this->logKey($key), 10); + + try + { + $lock->block(5); + + $log = $this->retrieveCompleteLog($key); + if (empty($log)) + { + $log = []; + } + + $timestamp = time(); + + $log['latest'] = $timestamp; + $log[$timestamp] = $message; + + Cache::put($this->logKey($key), $log); + + $lock->release(); + } + finally + { + optional($lock)->release(); + } + } + + /** + * Gets the latest log entry of this game server for a given key. + * + * @param string $key + * @return mixed + */ + public function getLatestLogEntry(string $key): mixed + { + $log = $this->retrieveCompleteLog($key); + + return $log[$log['latest']]; + } + + /** + * Wipes all the logs of this game server. + */ + public function wipeLogs() + { + foreach (array_keys(self::$logKeys) as $key) + { + Cache::forget($this->logKey($key)); + } + + $this->initLogKeys(); + } + + /** + * Wipes a specific log file for this game server. + * + * @param string $key + */ + public function wipeLog(string $key) + { + Cache::forget($this->logKey($key)); + } + + /** + * The places this game server is allowed to access. + * + * @return array + */ + public function allowedPlaces(): array + { + return Cache::get($this->logKey('access')) ?? []; + } + + /** + * Allows this game server to access a place. + * + * @param int $place_id + */ + public function allow(int $place_id) + { + $access = $this->allowedPlaces(); + $access[] = $place_id; + + Cache::store($this->logKey('access')); + } + + /** + * Gets the current state of this game server. + * + * @return GameServerState + */ + public function state(): GameServerState + { + if (is_null($state = Cache::get($this->logKey('state')))) + { + $this->setState(GameServerState::Offline); + return GameServerState::Offline; + } + + if ($state['state'] == GameServerState::Online && (time() - $state['last_ping']) >= 60) + { + $this->setState(GameServerState::Offline); + return GameServerState::Offline; + } + + return $state['state']; + } + + /** + * Sets the current state of this game server. + * + * @param GameServerState $state + */ + public function setState(GameServerState $state) + { + if ($state == GameServerState::Offline) + { + $this->wipeLogs(); + } + + Cache::put($this->logKey('state'), [ + 'last_ping' => time(), + 'state' => $state + ]); + } + + /** + * Gets all running place jobs of this game server. + * + * @return array + */ + public function getRunningPlaceJobs(): array + { + return []; + } + + /** + * Gets all running thumbnail jobs of this game server. + * + * @return array + */ + public function getRunningThumbnailJobs(): array + { + return []; + } + + /** + * Generates a random access key. + * + * @return string + */ + public static function generateAccessKey(): string + { + return bin2hex(random_bytes(32)); + } +} diff --git a/app/Models/InviteKey.php b/app/Models/InviteKey.php new file mode 100644 index 0000000..419a572 --- /dev/null +++ b/app/Models/InviteKey.php @@ -0,0 +1,87 @@ + + */ + protected $fillable = [ + 'creator_id', + 'token', + 'uses', + 'max_uses', + ]; + + /** + * The attributes that should be hidden for serialization. + * + * @var array + */ + protected $hidden = [ + 'token', + 'token_index', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'token' => CipherSweetEncrypted::class, + ]; + + /** + * The creator of this invite key. + */ + public function creator() + { + return $this->belongsTo(User::class, 'creator_id'); + } + + /** + * Uses this invite key once. + */ + public function use() + { + $this->update(['uses' => $this->uses + 1]); + } + + /** + * Whether or not this invite key is valid. + * + * @return bool + */ + public function isValid(): bool + { + return $this->uses < $this->max_uses; + } + + /** + * Generates a new invite key and returns the token for it. + * + * @param int $creator_id + * @param int $max_uses + * @return string + */ + public static function generate(int $creator_id, int $max_uses): string + { + $token = uuid(); + + self::create(compact('creator_id', 'token', 'max_uses')); + + return $token; + } +} diff --git a/app/Models/IpAddressBan.php b/app/Models/IpAddressBan.php new file mode 100644 index 0000000..3523ea4 --- /dev/null +++ b/app/Models/IpAddressBan.php @@ -0,0 +1,77 @@ + + */ + protected $fillable = [ + 'ip_address', + 'moderator_id', + 'criterium', + 'pardoner_id', + 'has_been_pardoned', + 'internal_reason', + 'is_active', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'ip_address' => CipherSweetEncrypted::class, + 'criterium' => 'encrypted', + ]; + + /** + * The event map for the model. + * + * @var array + */ + protected $dispatchesEvents = [ + 'saved' => IpAddressBanModified::class, + 'updated' => IpAddressBanModified::class, + 'deleting' => IpAddressBanModified::class, + 'deleted' => IpAddressBanModified::class, + ]; + + /** + * Gets the moderator of this IP address ban. + */ + public function moderator() + { + return $this->belongsTo(User::class, 'moderator_id'); + } + + /** + * Gets the moderator who pardoned this IP address ban (if any.) + */ + public function pardoner() + { + return $this->belongsTo(User::class, 'pardoner_id'); + } + + /** + * Lifts the IP address ban. + */ + public function lift() + { + $this->update([ + 'is_active' => false + ]); + } +} diff --git a/app/Models/PlaceJob.php b/app/Models/PlaceJob.php new file mode 100644 index 0000000..86a4eea --- /dev/null +++ b/app/Models/PlaceJob.php @@ -0,0 +1,10 @@ + + */ + protected $fillable = [ + 'ip_address', + 'tied_to', + ]; + + /** + * The attributes that should be hidden for serialization. + * + * @var array + */ + protected $hidden = [ + 'ip_address', + 'ip_address_index', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'ip_address' => CipherSweetEncrypted::class, + ]; +} diff --git a/app/Models/Status.php b/app/Models/Status.php new file mode 100644 index 0000000..0f01de0 --- /dev/null +++ b/app/Models/Status.php @@ -0,0 +1,30 @@ + + */ + protected $fillable = [ + 'creator_id', + 'creator_type', + 'content' + ]; + + /** + * The creator of this status. + */ + public function creator() + { + return $this->belongsTo(User::class, 'creator_id'); + } +} diff --git a/app/Models/ThumbnailJob.php b/app/Models/ThumbnailJob.php new file mode 100644 index 0000000..27daac4 --- /dev/null +++ b/app/Models/ThumbnailJob.php @@ -0,0 +1,10 @@ + + */ + protected $fillable = [ + 'creator_id', + 'creator_type', + 'start_place_id', + 'name', + 'version', + 'privileges', + 'privacy', + 'unlisted' + ]; + + /** + * The creator of this universe. + */ + public function creator() + { + return $this->belongsTo(User::class, 'creator_id'); + } + + /** + * The start place of this universe. + */ + public function start_place() + { + return $this->belongsTo(Asset::class, 'start_place_id'); + } +} diff --git a/app/Models/User.php b/app/Models/User.php new file mode 100644 index 0000000..3c92a86 --- /dev/null +++ b/app/Models/User.php @@ -0,0 +1,683 @@ + + */ + protected $fillable = [ + 'username', + 'past_usernames', + 'blurb', + 'email', + 'password', + 'last_ip_address', + 'register_ip_address', + 'activity', + 'current_ban_id', + 'permissions', + 'superadmin', + 'discord_id', + 'current_status_id', + ]; + + /** + * The attributes that should be hidden for serialization. + * + * @var array + */ + protected $hidden = [ + 'email', + 'email_index', + 'password', + 'register_ip_address', + 'register_ip_address_index', + 'last_ip_address', + 'last_ip_address_index', + 'remember_token', + 'discord_id', + 'discord_id_index', + 'discord_linked_at', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'past_usernames' => 'array', + 'email' => CipherSweetEncrypted::class, + 'email_verified_at' => 'datetime', + 'register_ip_address' => CipherSweetEncrypted::class, + 'last_ip_address' => CipherSweetEncrypted::class, + 'activity' => 'array', + 'permissions' => 'array', + 'discord_id' => CipherSweetEncrypted::class, + 'discord_linked_at' => 'datetime', + ]; + + /** + * Sends an account security notification to the email address associated with this account. + * + * @param string $what + * @param string $ip_address + * @param string $userAgent + */ + private function securityNotification(string $what, string $ip_address, string $userAgent) + { + $this->notify(new AccountSecurityNotification( + $what, + $ip_address, + $userAgent, + $this + )); + } + + /** + * Whether or not the user is online on a given place. + * + * @param string $place + * @return bool + */ + public function isOnline(string $place): bool + { + return is_online($this->activity[$place]); + } + + /** + * The timestamp of when the user was last seen on a given place. + * + * @param string $place + * @return int + */ + public function lastSeen(string $place): int + { + return $this->activity[$place]; + } + + /** + * The amount of seconds relative to when the user was last seen on a given place. + * + * @param string $place + * @return int + */ + public function lastSeenRelative(string $place): int + { + return time() - $this->activity[$place]; + } + + /** + * If the user has enough money to perform a given purchase. + * + * @param int $amount + * @return bool + */ + public function hasEnoughMoney(int $amount): bool + { + return true; + } + + /** + * Spends a certain amount of the users account balance on a given item or thing. + * + * @param int $amount + * @param mixed $on + */ + public function spend(int $amount, mixed $on) + { + + } + + /** + * Gets the current Discord account for this user. + * + * @return ?DiscordUser + */ + public function discordAccount(): ?DiscordUser + { + if (is_null($this->discord_id)) + { + return null; + } + + return new DiscordUser($this->discord_id); + } + + /** + * Gets this users current status. + */ + public function status() + { + return $this->hasOne(Status::class, 'creator_id', 'current_status_id'); + } + + /** + * Sets this users current status. + * + * @param Status $status + */ + public function updateStatus(Status $status) + { + $this->update(['current_status_id' => $status->id]); + } + + /** + * Gets the users friends. + * + * @return Collection + */ + public function friends(): Collection + { + return Friendship::where(function ($query) { + $query->where('requester_id', $this->id)->orWhere('receiver_id', $this->id); + })->where('accepted', true)->get(); + } + + /** + * Gets the users incoming friend requests. + * + * @return Collection + */ + public function friendRequests(): Collection + { + return Friendship::where(function ($query) { + $query->Where('receiver_id', $this->id); + })->where('accepted', false)->get(); + } + + /** + * The user's threads. + */ + public function threads() + { + return $this->hasMany(ForumThread::class, 'author_id'); + } + + /** + * The user's replies. + */ + public function replies() + { + return $this->hasMany(ForumReply::class, 'author_id'); + } + + /** + * Updates this user's username. + * + * @param string $new_username + * @param string $ip_address + * @param string $user_agent + */ + public function updateUsername(string $new_username, string $ip_address, string $user_agent) + { + $this->spend(config('tadah.username_change_cost'), sprintf('Username change from %s to %s', $this->username, $new_username)); + + $this->securityNotification( + sprintf('Your username has been changed to **%s** for **%s %s**.', $new_username, config('tadah.username_change_cost'), config('tadah.currency_name')), + $ip_address, + $user_agent + ); + + $history = $this->past_usernames ?? (object) []; + $history[$this->username] = time(); + $this->update(['past_usernames' => $history]); + + $this->update(['username' => $new_username]); + } + + /** + * Updates this user's email address. + * + * @param string $new_email + * @param string $ip_address + * @param string $user_agent + */ + public function updateEmail(string $new_email, string $ip_address, string $user_agent) + { + $this->securityNotification('Your email has been changed to **' . $new_email. '**.', $ip_address, $user_agent); + $this->update(['email' => $new_email, 'email_verified_at' => null]); + } + + /** + * Updates this user's password. + * + * @param string $new_password + * @param string $ip_address + * @param string $user_agent + * @param ?string $current_password + */ + public function updatePassword(string $new_password, string $ip_address, string $user_agent, ?string $current_password = null) + { + $this->securityNotification('Your password has been reset.', $ip_address, $user_agent); + + if (is_null($current_password)) + { + Auth::logoutOtherDevices($current_password); + } + + $this->forceFill([ + 'password' => Hash::make($new_password) + ])->setRememberToken(Str::random(60)); + + $this->save(); + } + + /** + * Whether or not this username has ever changed their username in the past. + * + * @return bool + */ + public function hasChangedUsername(): bool + { + return !empty($this->past_usernames); + } + + /** + * Gets the most recent usernames of this user's username change history. + * + * @param int $amount = 3 + * @return array + */ + public function mostRecentUsernames(int $amount = 3): array + { + if (!$this->hasChangedUsername()) + { + return [ $this->username ]; + } + + // flip it so that it changes from "username" => "timestamp" + $flipped = array_flip($this->past_usernames); + $timestamps = array_keys($flipped); + + // sort the timestamps, so we get the newest usernames first + sort($timestamps); + $chunk = array_slice($timestamps, 0, $amount); + + // now, using the flipped array, access the top timestamps to get our username + $usernames = []; + for ($i = 0; $i < $amount; $i++) + { + if (!isset($chunk[$i])) + { + break; + } + + $usernames[] = $flipped[$chunk[$i]]; + } + + return $usernames; + } + + /** + * Gets the most recent username from the username change history. + * + * @return string + */ + public function mostRecentUsername(): string + { + return $this->mostRecentUsernames(1)[0]; + } + + /** + * Whether or not this user is permitted to do a certain action. + * + * @param string $roleset + * @param int $flag + * @param bool $forget_superadmin = false + * @return bool + */ + public function may(string $roleset, int $flag, bool $forget_superadmin = false): bool + { + return ($this->permissions[$roleset] & $flag) != 0 || (!$forget_superadmin && $this->isSuperAdmin()); + } + + /** + * Allows this user to do something on a specific roleset. + * + * @param string $roleset + * @param int $flag + */ + public function allow(string $roleset, int $flag) + { + $permissions = $this->permissions; + $permissions[$roleset] &= $flag; + + $this->update(['permissions', $permissions]); + } + + /** + * Removes a permission from this user's roleset. + * + * @param string $roleset + * @param int $flag + */ + public function deny(string $roleset, int $flag) + { + $this->allow($roleset, ~$flag); + } + + /** + * Whether or not this user is a superadmin. + * + * @return bool + */ + public function isSuperAdmin(): bool + { + return $this->superadmin === true; + } + + /** + * Whether or not this user is banned. + * + * @return bool + */ + public function isBanned(): bool + { + if (!is_null($this->current_ban_id)) + { + if ($this->ban->is_active) + { + return true; + } + } + + return false; + } + + /** + * The current ban associated with this user (if any.) + */ + public function ban() + { + return $this->belongsTo(Ban::class, 'current_ban_id'); + } + + /** + * Punishes another user. + * + * @param User $user + * @param array $data + */ + public function punish(User $user, array $data) + { + $ban = Ban::create(array_merge([ + 'moderator_id' => $this->id, + 'user_id' => $user->id, + ], $data)); + + $user->update(['current_ban_id' => $ban->id]); + + return $ban; + } + + /** + * Pardons another user. + * + * @param User $user + * @param string $internal_reason + */ + public function pardon(User $user, string $internal_reason) + { + $user->ban->update([ + 'has_been_pardoned' => true, + 'pardoner_id' => $this->id, + 'pardon_internal_reason' => $internal_reason, + ]); + + $user->ban->lift(); + } + + /** + * Pardons an IP address ban. + * + * @param IpAddressBan $ip_address_ban + */ + public function pardonIpAddressBan(IpAddressBan $ip_address_ban) + { + $ip_address_ban->update([ + 'has_been_pardoned' => true, + 'pardoner_id' => $this->id, + ]); + + $ip_address_ban->lift(); + } + + /** + * All associated accounts with this user. + * + * @return mixed + */ + public function getAssociatedAccounts(): mixed + { + return self::whereEncrypted('register_ip_address', '=', $this->register_ip_address) + ->orWhereEncrypted('last_ip_address', '=', $this->last_ip_address); + } + + /** + * Whether or not this user has linked a Discord account yet. + * + * @return bool + */ + public function hasLinkedDiscordAccount(): bool + { + return !is_null($this->discord_id) && !is_null($this->discord_linked_at); + } + + /** + * Whether or not this user has verified their email address. + * + * @return bool + */ + public function hasVerifiedEmail(): bool + { + return !is_null($this->email_verified_at); + } + + /** + * Links a Discord account to this user. + * + * @param int $discord_id + */ + public function linkDiscordAccount(int $discord_id) + { + $this->update([ + 'discord_id' => $discord_id, + 'discord_linked_at' => now() + ]); + } + + /** + * Unlinks the currently linked Discord account. + */ + public function unlinkDiscordAccount() + { + $this->update([ + 'discord_id' => null, + 'discord_linked_at' => null + ]); + } + + /** + * Forcefully sets the permissions object of this user. + * + * @param object|array $permissions + */ + public function forceSetPermissions(object|array $permissions) + { + $this->update(compact('permissions')); + } + + /** + * Sets the last IP address of this user. + * + * @param string $ip_address + */ + public function setLastIpAddress(string $ip_address) + { + $this->update([ + 'last_ip_address' => $ip_address + ]); + } + + /** + * The default activity to be used on any given user. + * + * @return array + */ + public static function defaultActivity(): array + { + $activity = []; + + foreach (['website', 'studio'] as $place) + { + $activity[$place] = time(); + } + + return $activity; + } + + /** + * The default permissions to be used on any given user. + * + * @return array + */ + public static function defaultPermissions(): array + { + $permissions = []; + $rolesets = Roles::allRolesets(); + + foreach ($rolesets as $roleset) + { + $flags = 0; + + switch ($roleset) + { + case Places::roleset(): + $flags |= Places::CREATION; + break; + case SelfHostedServers::roleset(): + $flags |= SelfHostedServers::CREATION; + break; + case Economy::roleset(): + $flags |= Economy::CREATE_ASSETS + | Economy::SELL_ASSETS + | Economy::COMMENTS; + break; + case Users::roleset(): + $flags |= Users::UPDATE_BLURB + | Users::SEND_FRIEND_REQUESTS + | Users::SEND_MESSAGES + | Users::VIEW_BAN_HISTORY; + break; + case Forums::roleset(): + $flags |= Forums::CREATE_THREADS + | Forums::CREATE_REPLIES; + break; + } + + $permissions[$roleset] = $flags; + } + + return $permissions; + } + + /** + * Creates a new user. + * + * @param object|array $input + * @param string $ip_address + * + * @return User + */ + public static function register($input, $ip_address) + { + if (!is_object($input)) + { + $input = (object) $input; + } + + if (config('tadah.invite_keys_required')) + { + if (is_null($input->key)) + { + throw new \Exception('Invite key required'); + } + + $invite_key = InviteKey::whereEncrypted('token', '=', $input->key)->first(); + $invite_key->use(); + } + + $user = self::create([ + 'username' => $input->username, + 'email' => $input->email, + 'password' => Hash::make($input->password), + 'last_ip_address' => $ip_address, + 'register_ip_address' => $ip_address, + 'activity' => self::defaultActivity(), + 'permissions' => self::defaultPermissions(), + ]); + + Auth::login($user); + event(new Registered($user)); + + return $user; + } + + /** + * Create a factory of users for testing + * + * @return \Illuminate\Database\Eloquent\Factories\Factory + */ + protected static function factory() + { + return UserFactory::new(); + } + + /** + * Searchable fields + * + * @return array + */ + public function toSearchableArray() + { + return [ + 'username' => $this->username, + ]; + } +} diff --git a/app/Notifications/AccountSecurityNotification.php b/app/Notifications/AccountSecurityNotification.php new file mode 100644 index 0000000..86f7f87 --- /dev/null +++ b/app/Notifications/AccountSecurityNotification.php @@ -0,0 +1,126 @@ +what = $what; + $this->ip_address = $ip_address; + $this->user_agent = $user_agent; + $this->user = $user; + } + + /** + * The password broker used for account resets. + */ + protected function broker() + { + return Password::broker(config('fortify.passwords')); + } + + /** + * Get the notification's delivery channels. + * + * @param mixed $notifiable + * @return array + */ + public function via(mixed $notifiable): array + { + return ['mail']; + } + + /** + * Get the mail representation of the notification. + * + * @param mixed $notifiable + * @return \Illuminate\Notifications\Messages\MailMessage + */ + public function toMail($notifiable) + { + $token = ''; + + $this->broker()->sendResetLink(['email' => $this->user->getRawOriginal('email')], function ($_, $_token) use (&$token) { + $token = $_token; + }); + + $details = ''; + + if (($location = geolocate($this->ip_address)) !== false) + { + $details = sprintf('This action occurred from %s, %s (IP: %s) on device "%s".', $location->territory, $location->country, $this->ip_address, $this->user_agent); + } + else + { + $details = sprintf('This action occurred from IP "%s" on device "%s".', $this->ip_address, $this->user_agent); + } + + $link = route('password.reset', ['token' => $token]) . '?email=' . urlencode($this->user->email); + + return (new MailMessage) + ->subject('Important Security Notification for ' . $this->user->username) + ->greeting('Hello!') + ->line($this->what) + ->line($details) + ->line('If this wasn\'t you, reset your password now.') + ->action('Reset Password', $link); + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * @return array + */ + public function toArray(mixed $notifiable): array + { + return [ + 'what' => $this->what, + 'ip_address' => $this->ip_address, + 'user_agent' => $this->user_agent, + 'user' => $this->user->id + ]; + } +} diff --git a/app/Proto/AssetType.php b/app/Proto/AssetType.php new file mode 100644 index 0000000..f06ee54 --- /dev/null +++ b/app/Proto/AssetType.php @@ -0,0 +1,73 @@ +Tadah.AssetType + */ +class AssetType +{ + /** + * Generated from protobuf enum CLOTHING = 0; + */ + const CLOTHING = 0; + /** + * Generated from protobuf enum HEAD = 1; + */ + const HEAD = 1; + /** + * Generated from protobuf enum MESH = 2; + */ + const MESH = 2; + /** + * Generated from protobuf enum PLACE = 3; + */ + const PLACE = 3; + /** + * Generated from protobuf enum USER = 4; + */ + const USER = 4; + /** + * Generated from protobuf enum HEADSHOT = 5; + */ + const HEADSHOT = 5; + /** + * Generated from protobuf enum XML = 6; + */ + const XML = 6; + + private static $valueToName = [ + self::CLOTHING => 'CLOTHING', + self::HEAD => 'HEAD', + self::MESH => 'MESH', + self::PLACE => 'PLACE', + self::USER => 'USER', + self::HEADSHOT => 'HEADSHOT', + self::XML => 'XML', + ]; + + public static function name($value) + { + if (!isset(self::$valueToName[$value])) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no name defined for value %s', __CLASS__, $value)); + } + return self::$valueToName[$value]; + } + + + public static function value($name) + { + $const = __CLASS__ . '::' . strtoupper($name); + if (!defined($const)) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no value defined for name %s', __CLASS__, $name)); + } + return constant($const); + } +} + diff --git a/app/Proto/ClientVersion.php b/app/Proto/ClientVersion.php new file mode 100644 index 0000000..5100116 --- /dev/null +++ b/app/Proto/ClientVersion.php @@ -0,0 +1,53 @@ +Tadah.ClientVersion + */ +class ClientVersion +{ + /** + * Generated from protobuf enum NONE = 0; + */ + const NONE = 0; + /** + * Generated from protobuf enum TAIPEI = 2011; + */ + const TAIPEI = 2011; + /** + * Generated from protobuf enum TAMPA = 2016; + */ + const TAMPA = 2016; + + private static $valueToName = [ + self::NONE => 'NONE', + self::TAIPEI => 'TAIPEI', + self::TAMPA => 'TAMPA', + ]; + + public static function name($value) + { + if (!isset(self::$valueToName[$value])) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no name defined for value %s', __CLASS__, $value)); + } + return self::$valueToName[$value]; + } + + + public static function value($name) + { + $const = __CLASS__ . '::' . strtoupper($name); + if (!defined($const)) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no value defined for name %s', __CLASS__, $name)); + } + return constant($const); + } +} + diff --git a/app/Proto/Operation.php b/app/Proto/Operation.php new file mode 100644 index 0000000..def5429 --- /dev/null +++ b/app/Proto/Operation.php @@ -0,0 +1,73 @@ +Tadah.Operation + */ +class Operation +{ + /** + * Generated from protobuf enum OPEN_JOB = 0; + */ + const OPEN_JOB = 0; + /** + * Generated from protobuf enum CLOSE_JOB = 1; + */ + const CLOSE_JOB = 1; + /** + * Generated from protobuf enum EXECUTE_SCRIPT = 2; + */ + const EXECUTE_SCRIPT = 2; + /** + * Generated from protobuf enum RENEW_TAMPA_JOB_LEASE = 3; + */ + const RENEW_TAMPA_JOB_LEASE = 3; + /** + * Generated from protobuf enum CLOSE_ALL_JOBS = 4; + */ + const CLOSE_ALL_JOBS = 4; + /** + * Generated from protobuf enum CLOSE_ALL_TAMPA_PROCESSES = 5; + */ + const CLOSE_ALL_TAMPA_PROCESSES = 5; + /** + * Generated from protobuf enum THUMBNAIL = 6; + */ + const THUMBNAIL = 6; + + private static $valueToName = [ + self::OPEN_JOB => 'OPEN_JOB', + self::CLOSE_JOB => 'CLOSE_JOB', + self::EXECUTE_SCRIPT => 'EXECUTE_SCRIPT', + self::RENEW_TAMPA_JOB_LEASE => 'RENEW_TAMPA_JOB_LEASE', + self::CLOSE_ALL_JOBS => 'CLOSE_ALL_JOBS', + self::CLOSE_ALL_TAMPA_PROCESSES => 'CLOSE_ALL_TAMPA_PROCESSES', + self::THUMBNAIL => 'THUMBNAIL', + ]; + + public static function name($value) + { + if (!isset(self::$valueToName[$value])) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no name defined for value %s', __CLASS__, $value)); + } + return self::$valueToName[$value]; + } + + + public static function value($name) + { + $const = __CLASS__ . '::' . strtoupper($name); + if (!defined($const)) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no value defined for name %s', __CLASS__, $name)); + } + return constant($const); + } +} + diff --git a/app/Proto/Response.php b/app/Proto/Response.php new file mode 100644 index 0000000..6fcffdf --- /dev/null +++ b/app/Proto/Response.php @@ -0,0 +1,139 @@ +Tadah.Response + */ +class Response extends \Google\Protobuf\Internal\Message +{ + /** + * Generated from protobuf field .Tadah.Operation operation = 1; + */ + protected $operation = 0; + /** + * Generated from protobuf field bool success = 2; + */ + protected $success = false; + /** + * Generated from protobuf field string message = 3; + */ + protected $message = ''; + /** + * Generated from protobuf field string data = 4; + */ + protected $data = ''; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int $operation + * @type bool $success + * @type string $message + * @type string $data + * } + */ + public function __construct($data = NULL) { + \GPBMetadata\Resources\Tadah::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field .Tadah.Operation operation = 1; + * @return int + */ + public function getOperation() + { + return $this->operation; + } + + /** + * Generated from protobuf field .Tadah.Operation operation = 1; + * @param int $var + * @return $this + */ + public function setOperation($var) + { + GPBUtil::checkEnum($var, \App\Proto\Operation::class); + $this->operation = $var; + + return $this; + } + + /** + * Generated from protobuf field bool success = 2; + * @return bool + */ + public function getSuccess() + { + return $this->success; + } + + /** + * Generated from protobuf field bool success = 2; + * @param bool $var + * @return $this + */ + public function setSuccess($var) + { + GPBUtil::checkBool($var); + $this->success = $var; + + return $this; + } + + /** + * Generated from protobuf field string message = 3; + * @return string + */ + public function getMessage() + { + return $this->message; + } + + /** + * Generated from protobuf field string message = 3; + * @param string $var + * @return $this + */ + public function setMessage($var) + { + GPBUtil::checkString($var, True); + $this->message = $var; + + return $this; + } + + /** + * Generated from protobuf field string data = 4; + * @return string + */ + public function getData() + { + return $this->data; + } + + /** + * Generated from protobuf field string data = 4; + * @param string $var + * @return $this + */ + public function setData($var) + { + GPBUtil::checkString($var, True); + $this->data = $var; + + return $this; + } + +} + diff --git a/app/Proto/Signal.php b/app/Proto/Signal.php new file mode 100644 index 0000000..fdccc65 --- /dev/null +++ b/app/Proto/Signal.php @@ -0,0 +1,193 @@ +Tadah.Signal + */ +class Signal extends \Google\Protobuf\Internal\Message +{ + /** + * Generated from protobuf field .google.protobuf.Timestamp nonce = 1; + */ + protected $nonce = null; + /** + * Generated from protobuf field string jobId = 2; + */ + protected $jobId = ''; + /** + * Generated from protobuf field .Tadah.Operation operation = 3; + */ + protected $operation = 0; + /** + * Generated from protobuf field .Tadah.ClientVersion version = 4; + */ + protected $version = 0; + /** + * Generated from protobuf field repeated .Tadah.Signal.Place place = 5; + */ + private $place; + /** + * Generated from protobuf field repeated .Tadah.Signal.Thumbnail thumbnail = 6; + */ + private $thumbnail; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type \Google\Protobuf\Timestamp $nonce + * @type string $jobId + * @type int $operation + * @type int $version + * @type \App\Proto\Signal\Place[]|\Google\Protobuf\Internal\RepeatedField $place + * @type \App\Proto\Signal\Thumbnail[]|\Google\Protobuf\Internal\RepeatedField $thumbnail + * } + */ + public function __construct($data = NULL) { + \GPBMetadata\Resources\Tadah::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field .google.protobuf.Timestamp nonce = 1; + * @return \Google\Protobuf\Timestamp + */ + public function getNonce() + { + return $this->nonce; + } + + /** + * Generated from protobuf field .google.protobuf.Timestamp nonce = 1; + * @param \Google\Protobuf\Timestamp $var + * @return $this + */ + public function setNonce($var) + { + GPBUtil::checkMessage($var, \Google\Protobuf\Timestamp::class); + $this->nonce = $var; + + return $this; + } + + /** + * Generated from protobuf field string jobId = 2; + * @return string + */ + public function getJobId() + { + return $this->jobId; + } + + /** + * Generated from protobuf field string jobId = 2; + * @param string $var + * @return $this + */ + public function setJobId($var) + { + GPBUtil::checkString($var, True); + $this->jobId = $var; + + return $this; + } + + /** + * Generated from protobuf field .Tadah.Operation operation = 3; + * @return int + */ + public function getOperation() + { + return $this->operation; + } + + /** + * Generated from protobuf field .Tadah.Operation operation = 3; + * @param int $var + * @return $this + */ + public function setOperation($var) + { + GPBUtil::checkEnum($var, \App\Proto\Operation::class); + $this->operation = $var; + + return $this; + } + + /** + * Generated from protobuf field .Tadah.ClientVersion version = 4; + * @return int + */ + public function getVersion() + { + return $this->version; + } + + /** + * Generated from protobuf field .Tadah.ClientVersion version = 4; + * @param int $var + * @return $this + */ + public function setVersion($var) + { + GPBUtil::checkEnum($var, \App\Proto\ClientVersion::class); + $this->version = $var; + + return $this; + } + + /** + * Generated from protobuf field repeated .Tadah.Signal.Place place = 5; + * @return \Google\Protobuf\Internal\RepeatedField + */ + public function getPlace() + { + return $this->place; + } + + /** + * Generated from protobuf field repeated .Tadah.Signal.Place place = 5; + * @param \App\Proto\Signal\Place[]|\Google\Protobuf\Internal\RepeatedField $var + * @return $this + */ + public function setPlace($var) + { + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \App\Proto\Signal\Place::class); + $this->place = $arr; + + return $this; + } + + /** + * Generated from protobuf field repeated .Tadah.Signal.Thumbnail thumbnail = 6; + * @return \Google\Protobuf\Internal\RepeatedField + */ + public function getThumbnail() + { + return $this->thumbnail; + } + + /** + * Generated from protobuf field repeated .Tadah.Signal.Thumbnail thumbnail = 6; + * @param \App\Proto\Signal\Thumbnail[]|\Google\Protobuf\Internal\RepeatedField $var + * @return $this + */ + public function setThumbnail($var) + { + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \App\Proto\Signal\Thumbnail::class); + $this->thumbnail = $arr; + + return $this; + } + +} + diff --git a/app/Proto/Signal/Place.php b/app/Proto/Signal/Place.php new file mode 100644 index 0000000..633028f --- /dev/null +++ b/app/Proto/Signal/Place.php @@ -0,0 +1,115 @@ +Tadah.Signal.Place + */ +class Place extends \Google\Protobuf\Internal\Message +{ + /** + * Generated from protobuf field uint32 placeId = 1; + */ + protected $placeId = 0; + /** + * Generated from protobuf field string script = 2; + */ + protected $script = ''; + /** + * Generated from protobuf field uint32 expirationInSeconds = 3; + */ + protected $expirationInSeconds = 0; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int $placeId + * @type string $script + * @type int $expirationInSeconds + * } + */ + public function __construct($data = NULL) { + \GPBMetadata\Resources\Tadah::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field uint32 placeId = 1; + * @return int + */ + public function getPlaceId() + { + return $this->placeId; + } + + /** + * Generated from protobuf field uint32 placeId = 1; + * @param int $var + * @return $this + */ + public function setPlaceId($var) + { + GPBUtil::checkUint32($var); + $this->placeId = $var; + + return $this; + } + + /** + * Generated from protobuf field string script = 2; + * @return string + */ + public function getScript() + { + return $this->script; + } + + /** + * Generated from protobuf field string script = 2; + * @param string $var + * @return $this + */ + public function setScript($var) + { + GPBUtil::checkString($var, True); + $this->script = $var; + + return $this; + } + + /** + * Generated from protobuf field uint32 expirationInSeconds = 3; + * @return int + */ + public function getExpirationInSeconds() + { + return $this->expirationInSeconds; + } + + /** + * Generated from protobuf field uint32 expirationInSeconds = 3; + * @param int $var + * @return $this + */ + public function setExpirationInSeconds($var) + { + GPBUtil::checkUint32($var); + $this->expirationInSeconds = $var; + + return $this; + } + +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(Place::class, \App\Proto\Signal_Place::class); + diff --git a/app/Proto/Signal/Thumbnail.php b/app/Proto/Signal/Thumbnail.php new file mode 100644 index 0000000..450c1cf --- /dev/null +++ b/app/Proto/Signal/Thumbnail.php @@ -0,0 +1,115 @@ +Tadah.Signal.Thumbnail + */ +class Thumbnail extends \Google\Protobuf\Internal\Message +{ + /** + * Generated from protobuf field .Tadah.AssetType type = 1; + */ + protected $type = 0; + /** + * Generated from protobuf field uint32 assetId = 2; + */ + protected $assetId = 0; + /** + * Generated from protobuf field string accessKey = 3; + */ + protected $accessKey = ''; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int $type + * @type int $assetId + * @type string $accessKey + * } + */ + public function __construct($data = NULL) { + \GPBMetadata\Resources\Tadah::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field .Tadah.AssetType type = 1; + * @return int + */ + public function getType() + { + return $this->type; + } + + /** + * Generated from protobuf field .Tadah.AssetType type = 1; + * @param int $var + * @return $this + */ + public function setType($var) + { + GPBUtil::checkEnum($var, \App\Proto\AssetType::class); + $this->type = $var; + + return $this; + } + + /** + * Generated from protobuf field uint32 assetId = 2; + * @return int + */ + public function getAssetId() + { + return $this->assetId; + } + + /** + * Generated from protobuf field uint32 assetId = 2; + * @param int $var + * @return $this + */ + public function setAssetId($var) + { + GPBUtil::checkUint32($var); + $this->assetId = $var; + + return $this; + } + + /** + * Generated from protobuf field string accessKey = 3; + * @return string + */ + public function getAccessKey() + { + return $this->accessKey; + } + + /** + * Generated from protobuf field string accessKey = 3; + * @param string $var + * @return $this + */ + public function setAccessKey($var) + { + GPBUtil::checkString($var, True); + $this->accessKey = $var; + + return $this; + } + +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(Thumbnail::class, \App\Proto\Signal_Thumbnail::class); + diff --git a/app/Proto/Signal_Place.php b/app/Proto/Signal_Place.php new file mode 100644 index 0000000..0964ad5 --- /dev/null +++ b/app/Proto/Signal_Place.php @@ -0,0 +1,16 @@ +app->environment('production')) + { + $this->app->register(\Laravel\Telescope\TelescopeServiceProvider::class); + $this->app->register(TelescopeServiceProvider::class); + + $this->app->register(\Laravel\Horizon\HorizonServiceProvider::class); + $this->app->register(HorizonServiceProvider::class); + } + } + + /** + * I'm going to blow my head off + * + * @return void + */ + protected function schema() + { + Blueprint::macro('packed', function ($key) { + return $this->binary($key); + }); + } + + /** + * Bootstrap any application services. + * + * @return void + */ + public function boot() + { + Paginator::useBootstrapFive(); + + Blade::anonymousComponentNamespace('admin/components', 'admin'); + Blade::anonymousComponentNamespace('my/components', 'account'); + + Blade::if('may', function ($roleset, $role) { + /** @var \App\Models\User */ + $user = auth()->user(); + + return $user->may($roleset, $role); + }); + + Response::macro('text', function ($text) { + return Response::make($text, 200, ['Content-Type' => 'text/plain']); + }); + + Response::macro('pack', function ($data) { + return Response::make(msgpack_pack($data), 200, ['Content-Type' => 'application/x-msgpack']); + }); + + schema(); + + if (!app()->runningInConsole() && $this->app->environment('production')) + { + Octane::tick('ip-address-ban-refresher', fn() => IpAddressBanManager::refresh()) + ->seconds(60 * 30) + ->immediate(); + } + } +} diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php new file mode 100644 index 0000000..22b77e6 --- /dev/null +++ b/app/Providers/AuthServiceProvider.php @@ -0,0 +1,30 @@ + + */ + protected $policies = [ + // 'App\Models\Model' => 'App\Policies\ModelPolicy', + ]; + + /** + * Register any authentication / authorization services. + * + * @return void + */ + public function boot() + { + $this->registerPolicies(); + + // + } +} diff --git a/app/Providers/BroadcastServiceProvider.php b/app/Providers/BroadcastServiceProvider.php new file mode 100644 index 0000000..395c518 --- /dev/null +++ b/app/Providers/BroadcastServiceProvider.php @@ -0,0 +1,21 @@ +> + */ + protected $listen = [ + Registered::class => [ + Listeners\SendEmailVerificationNotification::class, + ], + + Events\GameServer\ConsoleOutput::class => [ + Listeners\GameServer\AppendConsoleOutput::class, + ], + + Events\GameServer\ResourceReport::class => [ + Listeners\GameServer\Ping::class + ], + + Events\GameServer\StateChange::class => [ + Listeners\GameServer\ChangeState::class + ], + ]; + + /** + * Register any events for your application. + * + * @return void + */ + public function boot() + { + // + } +} diff --git a/app/Providers/FortifyServiceProvider.php b/app/Providers/FortifyServiceProvider.php new file mode 100644 index 0000000..67458f9 --- /dev/null +++ b/app/Providers/FortifyServiceProvider.php @@ -0,0 +1,89 @@ +email; + + return Limit::perMinute(5)->by($email . $request->ip()); + }); + + RateLimiter::for('two-factor', function (Request $request) { + return Limit::perMinute(5)->by($request->session()->get('login.id')); + }); + + Fortify::authenticateUsing(function (Request $request) { + // I have no idea if Fortify cares about $request so $request->validate isn't used + $validator = validator([recaptchaFieldName() => $request->input(recaptchaFieldName())], [recaptchaFieldName() => ['required', recaptchaRuleName()]]); + if ($validator->fails()) + { + abort(403); + } + + $user = User::where('username', $request->input(config('fortify.username')))->first(); + + if ($user && Hash::check($request->password, $user->password)) + { + return $user; + } + }); + + // Route names : https://github.com/laravel/fortify/blob/1.x/routes/routes.php + // Static functions : https://github.com/laravel/fortify/blob/1.x/src/Fortify.php + Fortify::loginView(function () { + return view('auth.login'); + }); + + Fortify::registerView(function () { + return view('auth.register'); + }); + + Fortify::verifyEmailView(function () { + return view('auth.verify-email'); + }); + + Fortify::requestPasswordResetLinkView(function () { + return view('auth.request-password'); + }); + + Fortify::resetPasswordView(function ($request) { + return view('auth.reset-password', ['request' => $request]); + }); + + Fortify::twoFactorChallengeView(function () { + return view('auth.2fa'); + }); + + Fortify::confirmPasswordView(function () { + return view('auth.confirm-password'); + }); + } +} diff --git a/app/Providers/HorizonServiceProvider.php b/app/Providers/HorizonServiceProvider.php new file mode 100644 index 0000000..d0fc520 --- /dev/null +++ b/app/Providers/HorizonServiceProvider.php @@ -0,0 +1,34 @@ +isSuperAdmin(); + }); + } +} diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php new file mode 100644 index 0000000..f9aacab --- /dev/null +++ b/app/Providers/RouteServiceProvider.php @@ -0,0 +1,57 @@ +configureRateLimiting(); + + $this->routes(function () { + Route::prefix('api') + ->middleware('api') + ->group(base_path('routes/api.php')); + + Route::middleware('web') + ->group(base_path('routes/web.php')); + + Route::prefix('arbiter') + ->group(base_path('routes/arbiter.php')); + + require base_path('routes/roblox.php'); + }); + } + + /** + * Configure the rate limiters for the application. + * + * @return void + */ + protected function configureRateLimiting() + { + RateLimiter::for('api', function (Request $request) { + return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip()); + }); + } +} diff --git a/app/Providers/TelescopeServiceProvider.php b/app/Providers/TelescopeServiceProvider.php new file mode 100644 index 0000000..25fefe8 --- /dev/null +++ b/app/Providers/TelescopeServiceProvider.php @@ -0,0 +1,70 @@ +hideSensitiveRequestDetails(); + + Telescope::filter(function (IncomingEntry $entry) { + if ($this->app->environment('local')) { + return true; + } + + return $entry->isReportableException() || + $entry->isFailedRequest() || + $entry->isFailedJob() || + $entry->isScheduledTask() || + $entry->hasMonitoredTag(); + }); + } + + /** + * Prevent sensitive request details from being logged by Telescope. + * + * @return void + */ + protected function hideSensitiveRequestDetails() + { + if ($this->app->environment('local')) { + return; + } + + Telescope::hideRequestParameters(['_token']); + + Telescope::hideRequestHeaders([ + 'cookie', + 'x-csrf-token', + 'x-xsrf-token', + ]); + } + + /** + * Register the Telescope gate. + * + * This gate determines who can access Telescope in non-local environments. + * + * @return void + */ + protected function gate() + { + Gate::define('viewTelescope', function ($user) { + return $user->isSuperAdmin(); + }); + } +} diff --git a/app/Roblox/Script/Script.php b/app/Roblox/Script/Script.php new file mode 100644 index 0000000..44a24a6 --- /dev/null +++ b/app/Roblox/Script/Script.php @@ -0,0 +1,176 @@ +lua = $lua; + } + + /** + * Renders the script. Note that you may not "un-render" a script. + * + * @param array $parameters + * @return Script + */ + public function render(array $parameters) : Script + { + foreach ($parameters as $key => $value) + { + if (gettype($value) == 'object') + { + $value = $value->name; + } + + $this->lua = str($this)->replace(('{{ ' . $key . ' }}'), (string) $value); + } + + return $this; + } + + /** + * Signs the script. Note that you may not "un-sign" a script. + * + * @param bool $addComment + * @return Script + */ + public function sign($addComment = true): Script + { + $this->signature = signer('roblox')->sign($this); + $this->prepend(str($this->signature)->wrap('%')); + + if ($addComment) + { + $this->prepend('--rbxsig'); + } + + return $this; + } + + /** + * Prepends value to the Lua script. + * + * @param string $code + * @return Script + */ + public function prepend(string $code): Script + { + $this->lua = $code . $this->lua; + + return $this; + } + + /** + * Appends value to the Lua script. + * + * @param string $code + * @return Script + */ + public function append(string $code): Script + { + $this->lua .= $code; + + return $this; + } + + /** + * Converts the script to its ASCII representation. + * + * @return array + */ + public function toAscii(): array + { + return unpack('C*', $this); + } + + /** + * Converts the script to its loadstring form. This is irreversible. + * + * @return Script + */ + public function loadstring(): Script + { + $this->lua = ('loadstring("\\' . implode('\\', $this->toAscii()) . '")()'); + + return $this; + } + + /** + * If this is a loadstring script, this returns the raw Lua code. This is irreversible. + * + * @return Script + * @throws \Exception + */ + public function unpack(): Script + { + if (!str_contains($this, 'loadstring(')) + { + throw new \Exception('Cannot unpack already unpacked script'); + } + + // startPosition gets the position of where "loadstring(" starts, adds length of "loadstring(" to get inside the function, and adds 1 to account for the quotation mark + // endPosition removes all text before the startPosition position and then gets the next occurrence of a ")()" (signifying the end of the function) and removes one to account for the quotation mark and string, then adds startPosition for original length + $startPosition = strpos($this, 'loadstring(') + strlen('loadstring(') + 1; + + if (strpos(substr($this, $startPosition), ')()') === false) + { + throw new \Exception('Malformed loadstring data'); + } + + $endPosition = $startPosition + (strpos(substr($this, $startPosition), ')()') - 1); + $code = substr($this, $startPosition, $endPosition - $startPosition); + + // Parse the code + $code = explode('\\', $code); + $lua = ''; + + array_shift($code); // Remove first empty element (since "\123\456", ['', '123', '456']) + + for ($i = 0; $i < count($code); $i++) + { + if (!is_numeric($code[$i])) + { + throw new \Exception('Malformed loadstring data'); + } + + $lua .= chr($code[$i]); + } + + $this->lua = $lua; + + return $this; + } + + /** + * As a string. + * + * @return string + */ + public function __toString(): string + { + return $this->lua; + } +} diff --git a/app/Roblox/Script/ScriptBuilder.php b/app/Roblox/Script/ScriptBuilder.php new file mode 100644 index 0000000..670b4cd --- /dev/null +++ b/app/Roblox/Script/ScriptBuilder.php @@ -0,0 +1,62 @@ + '', + 'BaseUrl' => config('app.url'), + 'ChatStyle' => ChatStyle::Classic, + 'ClientPresenceUrl' => '', + 'CreatorID' => 0, + 'CreatorType' => 'User', + 'IsTeleport' => 'false', + 'IsTest' => 'true', + 'IsVisit' => 'false', + 'JobID' => '', + 'MachineAddress' => 'localhost', + 'MachinePort' => 53640, + 'OfficialPlace' => false, + 'PlaceID' => 0, + 'PlayerAge' => 0, + 'PlayerAppearance' => '', + 'PlayerID' => 0, + 'PlayerMembership' => 'None', + 'PlayerName' => 'Player', + 'PlayerSSC' => true, + 'PlayerTicket' => '', + 'ScreenshotInfo' => '', + 'VideoInfo' => '', + 'UploadUrl' => '' + ]; + } + + /** + * Creates a script. + * + * @param array|string $scripts + * @return Script + */ + public static function from(array|string $scripts): Script + { + $built = ''; + $scripts = collect($scripts); + + $scripts->each(function ($script) use (&$built) { + $built .= Storage::disk('resources')->get('lua/' . $script . '.lua'); + }); + + return new Script($built); + } +} diff --git a/app/Roles/Admin.php b/app/Roles/Admin.php new file mode 100644 index 0000000..54a71d7 --- /dev/null +++ b/app/Roles/Admin.php @@ -0,0 +1,22 @@ +getConstants(); + } + + /** + * Get all roles in all rolesets. + * + * @return array + */ + public static function allRoles(): array + { + $rolesets = self::allRoleSets(); + $roles = []; + + foreach ($rolesets as $roleset) + { + $roles = array_merge($roles, self::rolesOfRoleset($roleset)); + } + + return $roles; + } +} diff --git a/app/Roles/SelfHostedServers.php b/app/Roles/SelfHostedServers.php new file mode 100644 index 0000000..504c550 --- /dev/null +++ b/app/Roles/SelfHostedServers.php @@ -0,0 +1,37 @@ +path() == '/' ? '/' : '/'.$request->path(); + return preg_match(preg_replace('/$/','i', $route->getCompiled()->getRegex()), rawurldecode($path)); + } +} diff --git a/app/Rules/IsAlphaNumeric.php b/app/Rules/IsAlphaNumeric.php new file mode 100644 index 0000000..ecc0525 --- /dev/null +++ b/app/Rules/IsAlphaNumeric.php @@ -0,0 +1,30 @@ +user->password); + } + + /** + * Get the validation error message. + * + * @return string + */ + public function message(): string + { + return __('Wrong password.'); + } +} diff --git a/app/Rules/IsRobloxXml.php b/app/Rules/IsRobloxXml.php new file mode 100644 index 0000000..c9762a6 --- /dev/null +++ b/app/Rules/IsRobloxXml.php @@ -0,0 +1,53 @@ +hasFile() will not work + // so this is just assuming that the supplied value is an UploadedFile object + + $asset = $value->get(); + + libxml_use_internal_errors(true); + $document = simplexml_load_string($asset); + + if (!$document) + { + // invalid XML + libxml_clear_errors(); + return false; + } + + libxml_use_internal_errors(false); + + // now we just check for some nodes which **should** appear in all XML assets + if (!$document->getName() == 'roblox') return false; + if (count($document->xpath('//External')) < 2) return false; + if (!count($document->xpath('//Item'))) return false; + if (!count($document->xpath('//Properties'))) return false; + + return true; + } + + /** + * Get the validation error message. + * + * @return string + */ + public function message(): string + { + return __('Not a valid Roblox XML asset.'); + } +} diff --git a/app/Rules/IsSiprNameOrIpAddress.php b/app/Rules/IsSiprNameOrIpAddress.php new file mode 100644 index 0000000..bd72c8d --- /dev/null +++ b/app/Rules/IsSiprNameOrIpAddress.php @@ -0,0 +1,39 @@ +first()); + } + + /** + * Get the validation error message. + * + * @return string + */ + public function message(): string + { + return __('That email address is taken.'); + } +} diff --git a/app/Rules/IsValidInviteKey.php b/app/Rules/IsValidInviteKey.php new file mode 100644 index 0000000..a85db39 --- /dev/null +++ b/app/Rules/IsValidInviteKey.php @@ -0,0 +1,38 @@ +first(); + + if ($key && $key->isValid()) + { + return true; + } + + return false; + } + + /** + * Get the validation error message. + * + * @return string + */ + public function message(): string + { + return __('Invalid invite key.'); + } +} diff --git a/app/Rules/IsValidSession.php b/app/Rules/IsValidSession.php new file mode 100644 index 0000000..38eda9e --- /dev/null +++ b/app/Rules/IsValidSession.php @@ -0,0 +1,44 @@ +where('user_id', $this->user->id) + ->where('id', decrypt($value)) + ->first() !== null; + } + + /** + * Get the validation error message. + * + * @return string + */ + public function message(): string + { + return __('Invalid session.'); + } +} diff --git a/app/Signing/Signature.php b/app/Signing/Signature.php new file mode 100644 index 0000000..bf9885e --- /dev/null +++ b/app/Signing/Signature.php @@ -0,0 +1,59 @@ +raw = $signature; + $this->type = $type; + } + + /** + * As a Roblox comment. + * + * @return string + */ + public function asRobloxComment(): string + { + return ('--rbxsig' . str($this)->wrap('%')); + } + + /** + * As a string. + * + * @return string + */ + public function __toString(): string + { + return base64_encode($this->raw); + } +} diff --git a/app/Signing/Signer.php b/app/Signing/Signer.php new file mode 100644 index 0000000..dc1fc36 --- /dev/null +++ b/app/Signing/Signer.php @@ -0,0 +1,73 @@ +type = $type; + + $this->privateKey = $type->getPrivateKey(); + $this->publicKey = $type->getPublicKey(); + } + + /** + * Signs data. + * + * @param string $data + * @return Signature + */ + public function sign(string $data): Signature + { + // $signature appears out of thin air! + openssl_sign($data, $signature, $this->privateKey, $this->type->algorithm()); + + return new Signature($signature, $this->type); + } + + /** + * Verifies data. + * + * @param string $data + * @param string|Signature $signature + */ + public function verify(string $data, string|Signature $signature) + { + if (is_string($signature)) + { + $signature = new Signature($signature, $this->type); + } + + return (bool) openssl_verify($data, $signature->raw, $this->publicKey); + } +} diff --git a/app/Traits/EmailValidationRules.php b/app/Traits/EmailValidationRules.php new file mode 100644 index 0000000..dc21571 --- /dev/null +++ b/app/Traits/EmailValidationRules.php @@ -0,0 +1,16 @@ +title = $title; + $this->fluff = $fluff === 'on' || $fluff === true; + $this->data = $data; + } + + /** + * Get the view / contents that represents the component. + * + * @return \Illuminate\View\View + */ + public function render() + { + $context = [ + 'baseURL' => url('/') + ]; + + // Avoid generated routes + if (Route::has(Route::currentRouteName())) + { + $context['route'] = Route::currentRouteName(); + } + + if (Auth::check()) + { + /** @var \App\Models\User */ + $user = Auth::user(); + + $context['session'] = [ + 'id' => $user->id, + 'heartbeat' => ($user->hasVerifiedEmail() || !config('app.email_verification')) && !$user->isBanned() + ]; + } + + if (!empty($this->data)) + { + $context['data'] = $this->data; + } + + return view('layouts.app', compact('context')); + } +} diff --git a/app/View/Components/AuthLayout.php b/app/View/Components/AuthLayout.php new file mode 100644 index 0000000..39c7bb1 --- /dev/null +++ b/app/View/Components/AuthLayout.php @@ -0,0 +1,31 @@ +cascade(); + } + + return $interval->forHumans(['join' => true]); + } +} + +if (!function_exists('getInboxAddress')) +{ + /** + * Returns the project's mail inbox address. + * + * @return string + */ + function getInboxAddress(): string + { + return 'inbox@' . config('app.base_url'); + } +} + +if (!function_exists('countryCodeToEmoji')) +{ + /** + * Gets the flag emoji for a given country code. + * + * @param string $country_code + * @return string + */ + function countryCodeToEmoji(string $country_code): string + { + $country_code = strtoupper($country_code); + $flag = 0x1F1A5; + + $first = mb_convert_encoding('&#' . (ord($country_code[0]) + $flag) . ';', 'UTF-8', 'HTML-ENTITIES'); + $second = mb_convert_encoding('&#' . (ord($country_code[1]) + $flag) . ';', 'UTF-8', 'HTML-ENTITIES'); + + return $first . $second; + } +} + +if (!function_exists('geolocate')) +{ + /** + * Returns the country name, territory name, country code, and flag for a given IP address. If the IP address could not be successfully geolocated, returns false. + * + * @param string $ip_address + * @return bool|object + */ + function geolocate(string $ip_address): bool|object + { + if (($location = Location::get($ip_address)) !== false) + { + return (object) [ + 'country' => $location->countryName, + 'territory' => $location->regionName, + 'countryCode' => $location->countryCode, + 'flag' => countryCodeToEmoji($location->countryCode) + ]; + } + + return false; + } +} + +if (!function_exists('agent')) +{ + /** + * Returns a new Agent for a given user agent string. + * + * @param string $user_agent + * @return \App\Helpers\Agent + */ + function agent(string $user_agent): Agent + { + return new Agent(null, $user_agent); + } +} + +if (!function_exists('is_online')) +{ + /** + * Checks if a given timestamp is "online". + * + * @param int $timestamp + * @return bool + */ + function is_online(int $timestamp): bool + { + return time() - $timestamp <= 60; + } +} + +if (!function_exists('active_link')) +{ + /** + * Returns whether or not to highlight a route in the navigation bar by comparing the current request route. + * + * @param string $route + * @param int $segment + * @return bool + */ + function active_link(string $route, int $segment = 1): bool + { + return request()->segment($segment) == $route; + } +} + +if (!function_exists('paginate')) +{ + /** + * Paginates a given collection. + * + * @param \Illuminate\Support\Collection $collection + * @param int $show_per_page + * + * @return \Illuminate\Pagination\LengthAwarePaginator + */ + function paginate(Collection $collection, int $show_per_page): LengthAwarePaginator + { + return PaginationTransformer::paginate($collection, $show_per_page); + } +} + +if (!function_exists('safe_define')) +{ + /** + * Safely defines a constant by checking if it exists in the first place. + * + * @param string $key + * @param mixed $value + */ + function safe_define(string $key, mixed $value) + { + if (!defined($key)) + { + define($key, $value); + } + } +} + +if (!function_exists('sha256')) +{ + /** + * Returns a SHA256 checksum of given data. + * + * @param mixed $data + * @return string + */ + function sha256(mixed $data): string + { + return hash('sha256', $data); + } +} + +if (!function_exists('sha512')) +{ + /** + * Returns a SHA512 checksum of given data. + * + * @param mixed $data + * @return string + */ + function sha512(mixed $data): string + { + return hash('sha512', $data); + } +} + +if (!function_exists('uuid')) +{ + /** + * Returns a new randomly generated UUID. + * + * @return string + */ + function uuid(): string + { + return Str::uuid()->toString(); + } +} + +if (!function_exists('signer')) +{ + /** + * Acquires a signer. + * + * @param SignatureType|string $type + * @return Signer + */ + function signer(SignatureType|string $type): Signer + { + if (is_string($type)) + { + $type = SignatureType::tryFrom($type) ?? SignatureType::Roblox; + } + + return new Signer($type); + } +} + +if (!function_exists('is_base64')) +{ + /** + * Determines if a string is base64 or not. + * + * @param mixed $data + * @return bool + */ + function is_base64($data): bool + { + return base64_encode(base64_decode($data, true)) === $data; + } +} + +if (!function_exists('is_ipv4')) +{ + /** + * Determines if a string is a valid IPv4 address. + * + * @param mixed $data + * @return bool + */ + function is_ipv4(mixed $data): bool + { + return filter_var($data, FILTER_VALIDATE_IP) && !filter_var($data, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE); + } +} + +if (!function_exists('is_port')) +{ + /** + * Determines if a port is a valid port. + * + * @param mixed $data + * @return bool + */ + function is_port(mixed $data):bool + { + return is_numeric($data) && $data > 0 && $data < 65536; + } +} diff --git a/artisan b/artisan new file mode 100644 index 0000000..67a3329 --- /dev/null +++ b/artisan @@ -0,0 +1,53 @@ +#!/usr/bin/env php +make(Illuminate\Contracts\Console\Kernel::class); + +$status = $kernel->handle( + $input = new Symfony\Component\Console\Input\ArgvInput, + new Symfony\Component\Console\Output\ConsoleOutput +); + +/* +|-------------------------------------------------------------------------- +| Shutdown The Application +|-------------------------------------------------------------------------- +| +| Once Artisan has finished running, we will fire off the shutdown events +| so that any final work may be done by the application before we shut +| down the process. This is the last thing to happen to the request. +| +*/ + +$kernel->terminate($input, $status); + +exit($status); diff --git a/bootstrap/app.php b/bootstrap/app.php new file mode 100644 index 0000000..037e17d --- /dev/null +++ b/bootstrap/app.php @@ -0,0 +1,55 @@ +singleton( + Illuminate\Contracts\Http\Kernel::class, + App\Http\Kernel::class +); + +$app->singleton( + Illuminate\Contracts\Console\Kernel::class, + App\Console\Kernel::class +); + +$app->singleton( + Illuminate\Contracts\Debug\ExceptionHandler::class, + App\Exceptions\Handler::class +); + +/* +|-------------------------------------------------------------------------- +| Return The Application +|-------------------------------------------------------------------------- +| +| This script returns the application instance. The instance is given to +| the calling script so we can separate the building of the instances +| from the actual running of the application and sending responses. +| +*/ + +return $app; diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/bootstrap/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..eae0de9 --- /dev/null +++ b/composer.json @@ -0,0 +1,103 @@ +{ + "name": "tadah/web", + "type": "project", + "description": "The Tadah Website", + "license": "AGPL-3.0", + "require": { + "php": "^8.1", + "arandilopez/laravel-profane": "dev-tadah as 0.5.0", + "biscolab/laravel-recaptcha": "^5.4", + "bjorn-voesten/ciphersweet-for-laravel": "dev-tadah as 1.3.0", + "claviska/simpleimage": "^3.7", + "google/protobuf": "^3.21", + "guzzlehttp/guzzle": "^7.4", + "http-interop/http-factory-guzzle": "^1.2", + "jenssegers/agent": "^2.6", + "laravel/fortify": "^1.13", + "laravel/framework": "^9.24", + "laravel/horizon": "^5.9", + "laravel/octane": "^1.3", + "laravel/scout": "^9.4", + "laravel/socialite": "^5.5", + "laravel/telescope": "^4.9", + "laravel/tinker": "^2.7", + "livewire/livewire": "^2.10", + "martinbean/socialite-discord-provider": "dev-tadah as 1.2.0", + "meilisearch/meilisearch-php": "^0.24", + "olssonm/laravel-zxcvbn": "dev-tadah as 4.5", + "propaganistas/laravel-disposable-email": "^2.1", + "pusher/pusher-php-server": "^7.0", + "spatie/color": "^1.5", + "stevebauman/location": "^6.5" + }, + "require-dev": { + "barryvdh/laravel-debugbar": "^3.7", + "fakerphp/faker": "^1.20", + "laravel/sail": "^1.15", + "nunomaduro/collision": "^6.2", + "nunomaduro/larastan": "^2.1", + "spatie/laravel-ignition": "^1.3" + }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/tadah-foss/ciphersweet-for-laravel.git" + }, + { + "type": "vcs", + "url": "https://github.com/tadah-foss/laravel-profane.git" + }, + { + "type": "vcs", + "url": "https://github.com/tadah-foss/laravel-zxcvbn.git" + }, + { + "type": "vcs", + "url": "https://github.com/tadah-foss/socialite-discord-provider.git" + } + ], + + "autoload": { + "psr-4": { + "App\\": "app/", + "Database\\Factories\\": "database/factories/", + "Database\\Seeders\\": "database/seeders/" + }, + "files": [ + "app\\helpers.php" + ] + }, + "extra": { + "laravel": { + "dont-discover": [ + "laravel/telescope" + ] + } + }, + "scripts": { + "post-autoload-dump": [ + "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", + "@php artisan package:discover --ansi" + ], + "post-update-cmd": [ + "@php artisan vendor:publish --tag=laravel-assets --ansi --force" + ], + "post-root-package-install": [ + "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" + ], + "post-create-project-cmd": [ + "@php artisan key:generate --ansi" + ] + }, + "config": { + "optimize-autoloader": true, + "preferred-install": "dist", + "sort-packages": true, + "platform": { + "ext-pcntl": "8.1", + "ext-posix": "8.1" + } + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..b29cce8 --- /dev/null +++ b/composer.lock @@ -0,0 +1,9472 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "08204a59226ddd2d94ebcfd25d509f53", + "packages": [ + { + "name": "arandilopez/laravel-profane", + "version": "dev-tadah", + "source": { + "type": "git", + "url": "https://github.com/tadah-foss/laravel-profane.git", + "reference": "13bdf8e99920ded2aa6e112d7f22eb0737842321" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tadah-foss/laravel-profane/zipball/13bdf8e99920ded2aa6e112d7f22eb0737842321", + "reference": "13bdf8e99920ded2aa6e112d7f22eb0737842321", + "shasum": "" + }, + "require": { + "illuminate/support": ">=5.2|^6.0|^7.0|^8.0|^9.0" + }, + "require-dev": { + "mockery/mockery": "^1.3", + "phpunit/phpunit": "^8.0|^8.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "LaravelProfane\\ProfaneServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "LaravelProfane\\": "src/", + "LaravelProfaneTests\\": "tests/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Arandi Lopez", + "email": "arandilopez.93@gmail.com" + } + ], + "description": "Laravel Profanity Valitador", + "support": { + "source": "https://github.com/tadah-foss/laravel-profane/tree/tadah" + }, + "time": "2022-08-12T22:33:47+00:00" + }, + { + "name": "bacon/bacon-qr-code", + "version": "2.0.7", + "source": { + "type": "git", + "url": "https://github.com/Bacon/BaconQrCode.git", + "reference": "d70c840f68657ce49094b8d91f9ee0cc07fbf66c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/d70c840f68657ce49094b8d91f9ee0cc07fbf66c", + "reference": "d70c840f68657ce49094b8d91f9ee0cc07fbf66c", + "shasum": "" + }, + "require": { + "dasprid/enum": "^1.0.3", + "ext-iconv": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phly/keep-a-changelog": "^2.1", + "phpunit/phpunit": "^7 | ^8 | ^9", + "spatie/phpunit-snapshot-assertions": "^4.2.9", + "squizlabs/php_codesniffer": "^3.4" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "type": "library", + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "BaconQrCode is a QR code generator for PHP.", + "homepage": "https://github.com/Bacon/BaconQrCode", + "support": { + "issues": "https://github.com/Bacon/BaconQrCode/issues", + "source": "https://github.com/Bacon/BaconQrCode/tree/2.0.7" + }, + "time": "2022-03-14T02:02:36+00:00" + }, + { + "name": "biscolab/laravel-recaptcha", + "version": "v5.4.0", + "source": { + "type": "git", + "url": "https://github.com/biscolab/laravel-recaptcha.git", + "reference": "1bab726402d5376553a439b88a0faa07e84488fd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/biscolab/laravel-recaptcha/zipball/1bab726402d5376553a439b88a0faa07e84488fd", + "reference": "1bab726402d5376553a439b88a0faa07e84488fd", + "shasum": "" + }, + "require": { + "illuminate/routing": "^7.0|^8.0|^9.0", + "illuminate/support": "^7.0|^8.0|^9.0", + "php": "^7.3|^8.0" + }, + "require-dev": { + "orchestra/testbench": "5.*|6.*|^7.0", + "phpunit/phpunit": "^9.1" + }, + "suggest": { + "biscolab/laravel-authlog": "It allows to handle logged-in users and force log-out if needed" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Biscolab\\ReCaptcha\\ReCaptchaServiceProvider" + ], + "aliases": { + "ReCaptcha": "Biscolab\\ReCaptcha\\Facades\\ReCaptcha" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Biscolab\\ReCaptcha\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roberto Belotti", + "email": "roby.belotti@gmail.com", + "homepage": "https://biscolab.com", + "role": "Developer" + } + ], + "description": "Simple and painless Google reCAPTCHA package for Laravel framework", + "homepage": "https://biscolab.com/laravel-recaptcha", + "keywords": [ + "captcha", + "laravel", + "recaptcha", + "validation" + ], + "support": { + "issues": "https://github.com/biscolab/laravel-recaptcha/issues", + "source": "https://github.com/biscolab/laravel-recaptcha/tree/v5.4.0" + }, + "time": "2022-05-07T12:52:46+00:00" + }, + { + "name": "bjeavons/zxcvbn-php", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/bjeavons/zxcvbn-php.git", + "reference": "994928ae5b17ecff8baa2406832d37bdf01116c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bjeavons/zxcvbn-php/zipball/994928ae5b17ecff8baa2406832d37bdf01116c0", + "reference": "994928ae5b17ecff8baa2406832d37bdf01116c0", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.2 | ^8.0 | ^8.1", + "symfony/polyfill-mbstring": ">=1.3.1" + }, + "require-dev": { + "php-coveralls/php-coveralls": "*", + "phpunit/phpunit": "^8.5", + "squizlabs/php_codesniffer": "3.*" + }, + "suggest": { + "ext-gmp": "Required for optimized binomial calculations (also requires PHP >= 7.3)" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZxcvbnPhp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "See contributors", + "homepage": "https://github.com/bjeavons/zxcvbn-php" + } + ], + "description": "Realistic password strength estimation PHP library based on Zxcvbn JS", + "homepage": "https://github.com/bjeavons/zxcvbn-php", + "keywords": [ + "password", + "zxcvbn" + ], + "support": { + "issues": "https://github.com/bjeavons/zxcvbn-php/issues", + "source": "https://github.com/bjeavons/zxcvbn-php/tree/1.3.1" + }, + "time": "2021-12-21T18:37:02+00:00" + }, + { + "name": "bjorn-voesten/ciphersweet-for-laravel", + "version": "dev-tadah", + "source": { + "type": "git", + "url": "https://github.com/tadah-foss/ciphersweet-for-laravel.git", + "reference": "a72393c71ee28def05eae25fc0995732f4233899" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tadah-foss/ciphersweet-for-laravel/zipball/a72393c71ee28def05eae25fc0995732f4233899", + "reference": "a72393c71ee28def05eae25fc0995732f4233899", + "shasum": "" + }, + "require": { + "illuminate/config": "^9.0", + "illuminate/database": "^9.0", + "illuminate/support": "^9.0", + "paragonie/ciphersweet": "^3.0", + "php": "^8.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "BjornVoesten\\CipherSweet\\CipherSweetServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "BjornVoesten\\CipherSweet\\": "src/", + "BjornVoesten\\CipherSweet\\Seeds\\": "database/seeds/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bjorn Voesten", + "email": "bjorn-voesten@live.nl" + } + ], + "support": { + "source": "https://github.com/tadah-foss/ciphersweet-for-laravel/tree/tadah" + }, + "time": "2022-08-12T23:07:27+00:00" + }, + { + "name": "brick/math", + "version": "0.10.2", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "459f2781e1a08d52ee56b0b1444086e038561e3f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/459f2781e1a08d52ee56b0b1444086e038561e3f", + "reference": "459f2781e1a08d52ee56b0b1444086e038561e3f", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^9.0", + "vimeo/psalm": "4.25.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "brick", + "math" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.10.2" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2022-08-10T22:54:19+00:00" + }, + { + "name": "claviska/simpleimage", + "version": "3.7.0", + "source": { + "type": "git", + "url": "https://github.com/claviska/SimpleImage.git", + "reference": "abd15ced313c7b8041d7d73d8d2398b4f2510cf1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/claviska/SimpleImage/zipball/abd15ced313c7b8041d7d73d8d2398b4f2510cf1", + "reference": "abd15ced313c7b8041d7d73d8d2398b4f2510cf1", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "league/color-extractor": "0.3.*", + "php": ">=5.6.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "claviska": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Cory LaViska", + "homepage": "http://www.abeautifulsite.net/", + "role": "Developer" + } + ], + "description": "A PHP class that makes working with images as simple as possible.", + "support": { + "issues": "https://github.com/claviska/SimpleImage/issues", + "source": "https://github.com/claviska/SimpleImage/tree/3.7.0" + }, + "funding": [ + { + "url": "https://github.com/claviska", + "type": "github" + } + ], + "time": "2022-07-05T13:18:44+00:00" + }, + { + "name": "clue/stream-filter", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/clue/stream-filter.git", + "reference": "d6169430c7731d8509da7aecd0af756a5747b78e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clue/stream-filter/zipball/d6169430c7731d8509da7aecd0af756a5747b78e", + "reference": "d6169430c7731d8509da7aecd0af756a5747b78e", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "Clue\\StreamFilter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "A simple and modern approach to stream filtering in PHP", + "homepage": "https://github.com/clue/php-stream-filter", + "keywords": [ + "bucket brigade", + "callback", + "filter", + "php_user_filter", + "stream", + "stream_filter_append", + "stream_filter_register" + ], + "support": { + "issues": "https://github.com/clue/stream-filter/issues", + "source": "https://github.com/clue/stream-filter/tree/v1.6.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-02-21T13:15:14+00:00" + }, + { + "name": "composer/ca-bundle", + "version": "1.3.3", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "30897edbfb15e784fe55587b4f73ceefd3c4d98c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/30897edbfb15e784fe55587b4f73ceefd3c4d98c", + "reference": "30897edbfb15e784fe55587b4f73ceefd3c4d98c", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.55", + "psr/log": "^1.0", + "symfony/phpunit-bridge": "^4.2 || ^5", + "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/ca-bundle/issues", + "source": "https://github.com/composer/ca-bundle/tree/1.3.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-07-20T07:14:26+00:00" + }, + { + "name": "dasprid/enum", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/DASPRiD/Enum.git", + "reference": "5abf82f213618696dda8e3bf6f64dd042d8542b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/5abf82f213618696dda8e3bf6f64dd042d8542b2", + "reference": "5abf82f213618696dda8e3bf6f64dd042d8542b2", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "^7 | ^8 | ^9", + "squizlabs/php_codesniffer": "^3.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "PHP 7.1 enum implementation", + "keywords": [ + "enum", + "map" + ], + "support": { + "issues": "https://github.com/DASPRiD/Enum/issues", + "source": "https://github.com/DASPRiD/Enum/tree/1.0.3" + }, + "time": "2020-10-02T16:03:48+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "0992cc19268b259a39e86f296da5f0677841f42c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/0992cc19268b259a39e86f296da5f0677841f42c", + "reference": "0992cc19268b259a39e86f296da5f0677841f42c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^3.14" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.1" + }, + "time": "2021-08-13T13:06:58+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89", + "reference": "8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^8.2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "vimeo/psalm": "^4.10" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" + } + ], + "time": "2021-10-22T20:16:43+00:00" + }, + { + "name": "doctrine/lexer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/1.2.3" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2022-02-28T11:07:21+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.3.1", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-webmozart-assert": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.1" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2022-01-18T15:43:28+00:00" + }, + { + "name": "egulias/email-validator", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "f88dcf4b14af14a98ad96b14b2b317969eab6715" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/f88dcf4b14af14a98ad96b14b2b317969eab6715", + "reference": "f88dcf4b14af14a98ad96b14b2b317969eab6715", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1.2", + "php": ">=7.2", + "symfony/polyfill-intl-idn": "^1.15" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^8.5.8|^9.3.3", + "vimeo/psalm": "^4" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/3.2.1" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2022-06-18T20:57:19+00:00" + }, + { + "name": "facade/ignition-contracts", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/facade/ignition-contracts.git", + "reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/facade/ignition-contracts/zipball/3c921a1cdba35b68a7f0ccffc6dffc1995b18267", + "reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^v2.15.8", + "phpunit/phpunit": "^9.3.11", + "vimeo/psalm": "^3.17.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Facade\\IgnitionContracts\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://flareapp.io", + "role": "Developer" + } + ], + "description": "Solution contracts for Ignition", + "homepage": "https://github.com/facade/ignition-contracts", + "keywords": [ + "contracts", + "flare", + "ignition" + ], + "support": { + "issues": "https://github.com/facade/ignition-contracts/issues", + "source": "https://github.com/facade/ignition-contracts/tree/1.0.2" + }, + "time": "2020-10-16T08:27:54+00:00" + }, + { + "name": "fruitcake/php-cors", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/fruitcake/php-cors.git", + "reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/58571acbaa5f9f462c9c77e911700ac66f446d4e", + "reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "symfony/http-foundation": "^4.4|^5.4|^6" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" + } + ], + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "homepage": "https://github.com/fruitcake/php-cors", + "keywords": [ + "cors", + "laravel", + "symfony" + ], + "support": { + "issues": "https://github.com/fruitcake/php-cors/issues", + "source": "https://github.com/fruitcake/php-cors/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2022-02-20T15:07:15+00:00" + }, + { + "name": "geoip2/geoip2", + "version": "v2.13.0", + "source": { + "type": "git", + "url": "git@github.com:maxmind/GeoIP2-php.git", + "reference": "6a41d8fbd6b90052bc34dff3b4252d0f88067b23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/6a41d8fbd6b90052bc34dff3b4252d0f88067b23", + "reference": "6a41d8fbd6b90052bc34dff3b4252d0f88067b23", + "shasum": "" + }, + "require": { + "ext-json": "*", + "maxmind-db/reader": "~1.8", + "maxmind/web-service-common": "~0.8", + "php": ">=7.2" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "3.*", + "phpstan/phpstan": "*", + "phpunit/phpunit": "^8.0 || ^9.0", + "squizlabs/php_codesniffer": "3.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "GeoIp2\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Gregory J. Oschwald", + "email": "goschwald@maxmind.com", + "homepage": "https://www.maxmind.com/" + } + ], + "description": "MaxMind GeoIP2 PHP API", + "homepage": "https://github.com/maxmind/GeoIP2-php", + "keywords": [ + "IP", + "geoip", + "geoip2", + "geolocation", + "maxmind" + ], + "time": "2022-08-05T20:32:58+00:00" + }, + { + "name": "google/protobuf", + "version": "v3.21.5", + "source": { + "type": "git", + "url": "https://github.com/protocolbuffers/protobuf-php.git", + "reference": "70649d33d2b6e8fd0db6d9b6fffc7f46f01f1438" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/70649d33d2b6e8fd0db6d9b6fffc7f46f01f1438", + "reference": "70649d33d2b6e8fd0db6d9b6fffc7f46f01f1438", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": ">=5.0.0" + }, + "suggest": { + "ext-bcmath": "Need to support JSON deserialization" + }, + "type": "library", + "autoload": { + "psr-4": { + "Google\\Protobuf\\": "src/Google/Protobuf", + "GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "proto library for PHP", + "homepage": "https://developers.google.com/protocol-buffers/", + "keywords": [ + "proto" + ], + "support": { + "source": "https://github.com/protocolbuffers/protobuf-php/tree/v3.21.5" + }, + "time": "2022-08-09T19:53:56+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/a878d45c1914464426dc94da61c9e1d36ae262a8", + "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.28 || ^9.5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2022-07-30T15:56:11+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.4.5", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/1dd98b0564cb3f6bd16ce683cb755f94c10fbd82", + "reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5", + "guzzlehttp/psr7": "^1.9 || ^2.4", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "ext-curl": "*", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.5 || ^9.3.5", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.4-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.4.5" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2022-06-20T22:16:13+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/fe752aedc9fd8fcca3fe7ad05d419d32998a06da", + "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.5.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2021-10-22T20:56:57+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "13388f00956b1503577598873fffb5ae994b5737" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/13388f00956b1503577598873fffb5ae994b5737", + "reference": "13388f00956b1503577598873fffb5ae994b5737", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.4.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2022-06-20T21:43:11+00:00" + }, + { + "name": "http-interop/http-factory-guzzle", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/http-interop/http-factory-guzzle.git", + "reference": "8f06e92b95405216b237521cc64c804dd44c4a81" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/http-interop/http-factory-guzzle/zipball/8f06e92b95405216b237521cc64c804dd44c4a81", + "reference": "8f06e92b95405216b237521cc64c804dd44c4a81", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "^1.7||^2.0", + "php": ">=7.3", + "psr/http-factory": "^1.0" + }, + "provide": { + "psr/http-factory-implementation": "^1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "guzzlehttp/psr7": "Includes an HTTP factory starting in version 2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Factory\\Guzzle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "An HTTP Factory using Guzzle PSR7", + "keywords": [ + "factory", + "http", + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/http-interop/http-factory-guzzle/issues", + "source": "https://github.com/http-interop/http-factory-guzzle/tree/1.2.0" + }, + "time": "2021-07-21T13:50:14+00:00" + }, + { + "name": "jaybizzle/crawler-detect", + "version": "v1.2.111", + "source": { + "type": "git", + "url": "https://github.com/JayBizzle/Crawler-Detect.git", + "reference": "d572ed4a65a70a2d2871dc5137c9c5b7e69745ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/d572ed4a65a70a2d2871dc5137c9c5b7e69745ab", + "reference": "d572ed4a65a70a2d2871dc5137c9c5b7e69745ab", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8|^5.5|^6.5|^9.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Jaybizzle\\CrawlerDetect\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Beech", + "email": "m@rkbee.ch", + "role": "Developer" + } + ], + "description": "CrawlerDetect is a PHP class for detecting bots/crawlers/spiders via the user agent", + "homepage": "https://github.com/JayBizzle/Crawler-Detect/", + "keywords": [ + "crawler", + "crawler detect", + "crawler detector", + "crawlerdetect", + "php crawler detect" + ], + "support": { + "issues": "https://github.com/JayBizzle/Crawler-Detect/issues", + "source": "https://github.com/JayBizzle/Crawler-Detect/tree/v1.2.111" + }, + "time": "2022-03-15T22:19:01+00:00" + }, + { + "name": "jenssegers/agent", + "version": "v2.6.4", + "source": { + "type": "git", + "url": "https://github.com/jenssegers/agent.git", + "reference": "daa11c43729510b3700bc34d414664966b03bffe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jenssegers/agent/zipball/daa11c43729510b3700bc34d414664966b03bffe", + "reference": "daa11c43729510b3700bc34d414664966b03bffe", + "shasum": "" + }, + "require": { + "jaybizzle/crawler-detect": "^1.2", + "mobiledetect/mobiledetectlib": "^2.7.6", + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5.0|^6.0|^7.0" + }, + "suggest": { + "illuminate/support": "Required for laravel service providers" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "laravel": { + "providers": [ + "Jenssegers\\Agent\\AgentServiceProvider" + ], + "aliases": { + "Agent": "Jenssegers\\Agent\\Facades\\Agent" + } + } + }, + "autoload": { + "psr-4": { + "Jenssegers\\Agent\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jens Segers", + "homepage": "https://jenssegers.com" + } + ], + "description": "Desktop/mobile user agent parser with support for Laravel, based on Mobiledetect", + "homepage": "https://github.com/jenssegers/agent", + "keywords": [ + "Agent", + "browser", + "desktop", + "laravel", + "mobile", + "platform", + "user agent", + "useragent" + ], + "support": { + "issues": "https://github.com/jenssegers/agent/issues", + "source": "https://github.com/jenssegers/agent/tree/v2.6.4" + }, + "funding": [ + { + "url": "https://github.com/jenssegers", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/jenssegers/agent", + "type": "tidelift" + } + ], + "time": "2020-06-13T08:05:20+00:00" + }, + { + "name": "laminas/laminas-diactoros", + "version": "2.14.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-diactoros.git", + "reference": "6cb35f61913f06b2c91075db00f67cfd78869e28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6cb35f61913f06b2c91075db00f67cfd78869e28", + "reference": "6cb35f61913f06b2c91075db00f67cfd78869e28", + "shasum": "" + }, + "require": { + "php": "^7.3 || ~8.0.0 || ~8.1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0" + }, + "conflict": { + "phpspec/prophecy": "<1.9.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-curl": "*", + "ext-dom": "*", + "ext-gd": "*", + "ext-libxml": "*", + "http-interop/http-factory-tests": "^0.9.0", + "laminas/laminas-coding-standard": "~2.3.0", + "php-http/psr7-integration-tests": "^1.1.1", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psalm/plugin-phpunit": "^0.17.0", + "vimeo/psalm": "^4.24.0" + }, + "type": "library", + "extra": { + "laminas": { + "config-provider": "Laminas\\Diactoros\\ConfigProvider", + "module": "Laminas\\Diactoros" + } + }, + "autoload": { + "files": [ + "src/functions/create_uploaded_file.php", + "src/functions/marshal_headers_from_sapi.php", + "src/functions/marshal_method_from_sapi.php", + "src/functions/marshal_protocol_version_from_sapi.php", + "src/functions/marshal_uri_from_sapi.php", + "src/functions/normalize_server.php", + "src/functions/normalize_uploaded_files.php", + "src/functions/parse_cookie_header.php", + "src/functions/create_uploaded_file.legacy.php", + "src/functions/marshal_headers_from_sapi.legacy.php", + "src/functions/marshal_method_from_sapi.legacy.php", + "src/functions/marshal_protocol_version_from_sapi.legacy.php", + "src/functions/marshal_uri_from_sapi.legacy.php", + "src/functions/normalize_server.legacy.php", + "src/functions/normalize_uploaded_files.legacy.php", + "src/functions/parse_cookie_header.legacy.php" + ], + "psr-4": { + "Laminas\\Diactoros\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "PSR HTTP Message implementations", + "homepage": "https://laminas.dev", + "keywords": [ + "http", + "laminas", + "psr", + "psr-17", + "psr-7" + ], + "support": { + "chat": "https://laminas.dev/chat", + "docs": "https://docs.laminas.dev/laminas-diactoros/", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-diactoros/issues", + "rss": "https://github.com/laminas/laminas-diactoros/releases.atom", + "source": "https://github.com/laminas/laminas-diactoros" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2022-07-28T12:23:48+00:00" + }, + { + "name": "laravel/fortify", + "version": "v1.13.3", + "source": { + "type": "git", + "url": "https://github.com/laravel/fortify.git", + "reference": "cde06120605b8bb038142b03425c67fc97d047d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/fortify/zipball/cde06120605b8bb038142b03425c67fc97d047d1", + "reference": "cde06120605b8bb038142b03425c67fc97d047d1", + "shasum": "" + }, + "require": { + "bacon/bacon-qr-code": "^2.0", + "ext-json": "*", + "illuminate/support": "^8.82|^9.0", + "php": "^7.3|^8.0", + "pragmarx/google2fa": "^7.0|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^6.0|^7.0", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Fortify\\FortifyServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Fortify\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Backend controllers and scaffolding for Laravel authentication.", + "keywords": [ + "auth", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/fortify/issues", + "source": "https://github.com/laravel/fortify" + }, + "time": "2022-08-15T15:08:17+00:00" + }, + { + "name": "laravel/framework", + "version": "v9.25.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/framework.git", + "reference": "e8af8c2212e3717757ea7f459a655a2e9e771109" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/framework/zipball/e8af8c2212e3717757ea7f459a655a2e9e771109", + "reference": "e8af8c2212e3717757ea7f459a655a2e9e771109", + "shasum": "" + }, + "require": { + "doctrine/inflector": "^2.0", + "dragonmantank/cron-expression": "^3.1", + "egulias/email-validator": "^3.1", + "ext-mbstring": "*", + "ext-openssl": "*", + "fruitcake/php-cors": "^1.2", + "laravel/serializable-closure": "^1.0", + "league/commonmark": "^2.2", + "league/flysystem": "^3.0.16", + "monolog/monolog": "^2.0", + "nesbot/carbon": "^2.53.1", + "nunomaduro/termwind": "^1.13", + "php": "^8.0.2", + "psr/container": "^1.1.1|^2.0.1", + "psr/log": "^1.0|^2.0|^3.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "ramsey/uuid": "^4.2.2", + "symfony/console": "^6.0.3", + "symfony/error-handler": "^6.0", + "symfony/finder": "^6.0", + "symfony/http-foundation": "^6.0", + "symfony/http-kernel": "^6.0", + "symfony/mailer": "^6.0", + "symfony/mime": "^6.0", + "symfony/process": "^6.0", + "symfony/routing": "^6.0", + "symfony/var-dumper": "^6.0", + "tijsverkoyen/css-to-inline-styles": "^2.2.2", + "vlucas/phpdotenv": "^5.4.1", + "voku/portable-ascii": "^2.0" + }, + "conflict": { + "tightenco/collect": "<5.5.33" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0" + }, + "replace": { + "illuminate/auth": "self.version", + "illuminate/broadcasting": "self.version", + "illuminate/bus": "self.version", + "illuminate/cache": "self.version", + "illuminate/collections": "self.version", + "illuminate/conditionable": "self.version", + "illuminate/config": "self.version", + "illuminate/console": "self.version", + "illuminate/container": "self.version", + "illuminate/contracts": "self.version", + "illuminate/cookie": "self.version", + "illuminate/database": "self.version", + "illuminate/encryption": "self.version", + "illuminate/events": "self.version", + "illuminate/filesystem": "self.version", + "illuminate/hashing": "self.version", + "illuminate/http": "self.version", + "illuminate/log": "self.version", + "illuminate/macroable": "self.version", + "illuminate/mail": "self.version", + "illuminate/notifications": "self.version", + "illuminate/pagination": "self.version", + "illuminate/pipeline": "self.version", + "illuminate/queue": "self.version", + "illuminate/redis": "self.version", + "illuminate/routing": "self.version", + "illuminate/session": "self.version", + "illuminate/support": "self.version", + "illuminate/testing": "self.version", + "illuminate/translation": "self.version", + "illuminate/validation": "self.version", + "illuminate/view": "self.version" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.198.1", + "doctrine/dbal": "^2.13.3|^3.1.4", + "fakerphp/faker": "^1.9.2", + "guzzlehttp/guzzle": "^7.2", + "league/flysystem-aws-s3-v3": "^3.0", + "league/flysystem-ftp": "^3.0", + "league/flysystem-sftp-v3": "^3.0", + "mockery/mockery": "^1.4.4", + "orchestra/testbench-core": "^7.1", + "pda/pheanstalk": "^4.0", + "phpstan/phpstan": "^1.4.7", + "phpunit/phpunit": "^9.5.8", + "predis/predis": "^1.1.9|^2.0", + "symfony/cache": "^6.0" + }, + "suggest": { + "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", + "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.198.1).", + "brianium/paratest": "Required to run tests in parallel (^6.0).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.13.3|^3.1.4).", + "ext-bcmath": "Required to use the multiple_of validation rule.", + "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", + "ext-memcached": "Required to use the memcache cache driver.", + "ext-pcntl": "Required to use all features of the queue worker.", + "ext-posix": "Required to use all features of the queue worker.", + "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0).", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", + "filp/whoops": "Required for friendly error pages in development (^2.14.3).", + "guzzlehttp/guzzle": "Required to use the HTTP Client and the ping methods on schedules (^7.2).", + "laravel/tinker": "Required to use the tinker console command (^2.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", + "mockery/mockery": "Required to use mocking (^1.4.4).", + "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^4.0).", + "phpunit/phpunit": "Required to use assertions and run tests (^9.5.8).", + "predis/predis": "Required to use the predis connector (^1.1.9|^2.0).", + "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", + "symfony/cache": "Required to PSR-6 cache bridge (^6.0).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^6.0).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^6.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.0).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.0).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "files": [ + "src/Illuminate/Collections/helpers.php", + "src/Illuminate/Events/functions.php", + "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Support/helpers.php" + ], + "psr-4": { + "Illuminate\\": "src/Illuminate/", + "Illuminate\\Support\\": [ + "src/Illuminate/Macroable/", + "src/Illuminate/Collections/", + "src/Illuminate/Conditionable/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Laravel Framework.", + "homepage": "https://laravel.com", + "keywords": [ + "framework", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-08-16T16:36:05+00:00" + }, + { + "name": "laravel/horizon", + "version": "v5.10.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/horizon.git", + "reference": "8cbdf156dbbc146be5527d0c5fae185a3d31fff0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/horizon/zipball/8cbdf156dbbc146be5527d0c5fae185a3d31fff0", + "reference": "8cbdf156dbbc146be5527d0c5fae185a3d31fff0", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcntl": "*", + "ext-posix": "*", + "illuminate/contracts": "^8.17|^9.0", + "illuminate/queue": "^8.17|^9.0", + "illuminate/support": "^8.17|^9.0", + "nesbot/carbon": "^2.17", + "php": "^7.3|^8.0", + "ramsey/uuid": "^4.0", + "symfony/error-handler": "^5.0|^6.0", + "symfony/process": "^5.0|^6.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^6.0|^7.0", + "phpunit/phpunit": "^9.0", + "predis/predis": "^1.1|^2.0" + }, + "suggest": { + "ext-redis": "Required to use the Redis PHP driver.", + "predis/predis": "Required when not using the Redis PHP driver (^1.1|^2.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Horizon\\HorizonServiceProvider" + ], + "aliases": { + "Horizon": "Laravel\\Horizon\\Horizon" + } + } + }, + "autoload": { + "psr-4": { + "Laravel\\Horizon\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Dashboard and code-driven configuration for Laravel queues.", + "keywords": [ + "laravel", + "queue" + ], + "support": { + "issues": "https://github.com/laravel/horizon/issues", + "source": "https://github.com/laravel/horizon/tree/v5.10.0" + }, + "time": "2022-08-11T17:05:00+00:00" + }, + { + "name": "laravel/octane", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/octane.git", + "reference": "93dfdb57e721bceaf495bbe1c87d5d852d10e16b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/octane/zipball/93dfdb57e721bceaf495bbe1c87d5d852d10e16b", + "reference": "93dfdb57e721bceaf495bbe1c87d5d852d10e16b", + "shasum": "" + }, + "require": { + "laminas/laminas-diactoros": "^2.5", + "laravel/framework": "^8.81|^9.0", + "laravel/serializable-closure": "^1.0", + "nesbot/carbon": "^2.60", + "php": "^8.0", + "symfony/psr-http-message-bridge": "^2.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.2", + "mockery/mockery": "^1.4", + "nunomaduro/collision": "^5.10|^6.0", + "orchestra/testbench": "^6.16|^7.0", + "phpunit/phpunit": "^9.3", + "spiral/roadrunner": "^2.8.2" + }, + "bin": [ + "bin/roadrunner-worker", + "bin/swoole-server" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Octane\\OctaneServiceProvider" + ], + "aliases": { + "Octane": "Laravel\\Octane\\Facades\\Octane" + } + } + }, + "autoload": { + "psr-4": { + "Laravel\\Octane\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Supercharge your Laravel application's performance.", + "keywords": [ + "laravel", + "octane", + "roadrunner", + "swoole" + ], + "support": { + "issues": "https://github.com/laravel/octane/issues", + "source": "https://github.com/laravel/octane" + }, + "time": "2022-08-02T15:44:43+00:00" + }, + { + "name": "laravel/scout", + "version": "v9.4.10", + "source": { + "type": "git", + "url": "https://github.com/laravel/scout.git", + "reference": "45c7222ccd8f5d8ee069a85deeef799b7dcd79fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/scout/zipball/45c7222ccd8f5d8ee069a85deeef799b7dcd79fa", + "reference": "45c7222ccd8f5d8ee069a85deeef799b7dcd79fa", + "shasum": "" + }, + "require": { + "illuminate/bus": "^8.0|^9.0", + "illuminate/contracts": "^8.0|^9.0", + "illuminate/database": "^8.0|^9.0", + "illuminate/http": "^8.0|^9.0", + "illuminate/pagination": "^8.0|^9.0", + "illuminate/queue": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "php": "^7.3|^8.0" + }, + "require-dev": { + "meilisearch/meilisearch-php": "^0.19", + "mockery/mockery": "^1.0", + "orchestra/testbench": "^6.17|^7.0", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "algolia/algoliasearch-client-php": "Required to use the Algolia engine (^3.2).", + "meilisearch/meilisearch-php": "Required to use the MeiliSearch engine (^0.23)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Scout\\ScoutServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Scout\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Scout provides a driver based solution to searching your Eloquent models.", + "keywords": [ + "algolia", + "laravel", + "search" + ], + "support": { + "issues": "https://github.com/laravel/scout/issues", + "source": "https://github.com/laravel/scout" + }, + "time": "2022-07-19T14:34:57+00:00" + }, + { + "name": "laravel/serializable-closure", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "09f0e9fb61829f628205b7c94906c28740ff9540" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/09f0e9fb61829f628205b7c94906c28740ff9540", + "reference": "09f0e9fb61829f628205b7c94906c28740ff9540", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "pestphp/pest": "^1.18", + "phpstan/phpstan": "^0.12.98", + "symfony/var-dumper": "^5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2022-05-16T17:09:47+00:00" + }, + { + "name": "laravel/socialite", + "version": "v5.5.4", + "source": { + "type": "git", + "url": "https://github.com/laravel/socialite.git", + "reference": "3eec261bf83690dd85812587457f093e3156dca6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/socialite/zipball/3eec261bf83690dd85812587457f093e3156dca6", + "reference": "3eec261bf83690dd85812587457f093e3156dca6", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0", + "illuminate/http": "^6.0|^7.0|^8.0|^9.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0", + "league/oauth1-client": "^1.10.1", + "php": "^7.2|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^4.0|^5.0|^6.0|^7.0", + "phpunit/phpunit": "^8.0|^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Socialite\\SocialiteServiceProvider" + ], + "aliases": { + "Socialite": "Laravel\\Socialite\\Facades\\Socialite" + } + } + }, + "autoload": { + "psr-4": { + "Laravel\\Socialite\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.", + "homepage": "https://laravel.com", + "keywords": [ + "laravel", + "oauth" + ], + "support": { + "issues": "https://github.com/laravel/socialite/issues", + "source": "https://github.com/laravel/socialite" + }, + "time": "2022-08-08T13:27:06+00:00" + }, + { + "name": "laravel/telescope", + "version": "v4.9.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/telescope.git", + "reference": "0368468e9f6d804032d18c009ed19c226572e6c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/telescope/zipball/0368468e9f6d804032d18c009ed19c226572e6c6", + "reference": "0368468e9f6d804032d18c009ed19c226572e6c6", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel/framework": "^8.37|^9.0", + "php": "^7.3|^8.0", + "symfony/var-dumper": "^5.0|^6.0" + }, + "require-dev": { + "ext-gd": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "orchestra/testbench": "^6.0|^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Telescope\\TelescopeServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Telescope\\": "src/", + "Laravel\\Telescope\\Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Mohamed Said", + "email": "mohamed@laravel.com" + } + ], + "description": "An elegant debug assistant for the Laravel framework.", + "keywords": [ + "debugging", + "laravel", + "monitoring" + ], + "support": { + "issues": "https://github.com/laravel/telescope/issues", + "source": "https://github.com/laravel/telescope/tree/v4.9.2" + }, + "time": "2022-08-08T19:54:18+00:00" + }, + { + "name": "laravel/tinker", + "version": "v2.7.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/tinker.git", + "reference": "dff39b661e827dae6e092412f976658df82dbac5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/tinker/zipball/dff39b661e827dae6e092412f976658df82dbac5", + "reference": "dff39b661e827dae6e092412f976658df82dbac5", + "shasum": "" + }, + "require": { + "illuminate/console": "^6.0|^7.0|^8.0|^9.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0", + "php": "^7.2.5|^8.0", + "psy/psysh": "^0.10.4|^0.11.1", + "symfony/var-dumper": "^4.3.4|^5.0|^6.0" + }, + "require-dev": { + "mockery/mockery": "~1.3.3|^1.4.2", + "phpunit/phpunit": "^8.5.8|^9.3.3" + }, + "suggest": { + "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Tinker\\TinkerServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Tinker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Powerful REPL for the Laravel framework.", + "keywords": [ + "REPL", + "Tinker", + "laravel", + "psysh" + ], + "support": { + "issues": "https://github.com/laravel/tinker/issues", + "source": "https://github.com/laravel/tinker/tree/v2.7.2" + }, + "time": "2022-03-23T12:38:24+00:00" + }, + { + "name": "league/color-extractor", + "version": "0.3.2", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/color-extractor.git", + "reference": "837086ec60f50c84c611c613963e4ad2e2aec806" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/color-extractor/zipball/837086ec60f50c84c611c613963e4ad2e2aec806", + "reference": "837086ec60f50c84c611c613963e4ad2e2aec806", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "php": ">=5.4.0" + }, + "replace": { + "matthecat/colorextractor": "*" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2", + "phpunit/phpunit": "~5" + }, + "type": "library", + "autoload": { + "psr-4": { + "": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mathieu Lechat", + "email": "math.lechat@gmail.com", + "homepage": "http://matthecat.com", + "role": "Developer" + } + ], + "description": "Extract colors from an image as a human would do.", + "homepage": "https://github.com/thephpleague/color-extractor", + "keywords": [ + "color", + "extract", + "human", + "image", + "palette" + ], + "support": { + "issues": "https://github.com/thephpleague/color-extractor/issues", + "source": "https://github.com/thephpleague/color-extractor/tree/master" + }, + "time": "2016-12-15T09:30:02+00:00" + }, + { + "name": "league/commonmark", + "version": "2.3.5", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "84d74485fdb7074f4f9dd6f02ab957b1de513257" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/84d74485fdb7074f4f9dd6f02ab957b1de513257", + "reference": "84d74485fdb7074f4f9dd6f02ab957b1de513257", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.30.0", + "commonmark/commonmark.js": "0.30.0", + "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3 | ^6.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0", + "unleashedtech/php-coding-standard": "^3.1.1", + "vimeo/psalm": "^4.24.0" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.4-dev" + } + }, + "autoload": { + "psr-4": { + "League\\CommonMark\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], + "support": { + "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2022-07-29T10:59:45+00:00" + }, + { + "name": "league/config", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.90", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2021-08-14T12:15:32+00:00" + }, + { + "name": "league/flysystem", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "81aea9e5217084c7850cd36e1587ee4aad721c6b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/81aea9e5217084c7850cd36e1587ee4aad721c6b", + "reference": "81aea9e5217084c7850cd36e1587ee4aad721c6b", + "shasum": "" + }, + "require": { + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "symfony/http-client": "<5.2" + }, + "require-dev": { + "async-aws/s3": "^1.5", + "async-aws/simple-s3": "^1.0", + "aws/aws-sdk-php": "^3.198.1", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "microsoft/azure-storage-blob": "^1.1", + "phpseclib/phpseclib": "^2.0", + "phpstan/phpstan": "^0.12.26", + "phpunit/phpunit": "^9.5.11", + "sabre/dav": "^4.3.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "File storage abstraction for PHP", + "keywords": [ + "WebDAV", + "aws", + "cloud", + "file", + "files", + "filesystem", + "filesystems", + "ftp", + "s3", + "sftp", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/3.2.1" + }, + "funding": [ + { + "url": "https://offset.earth/frankdejonge", + "type": "custom" + }, + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2022-08-14T20:48:34+00:00" + }, + { + "name": "league/mime-type-detection", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd", + "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2022-04-17T13:12:02+00:00" + }, + { + "name": "league/oauth1-client", + "version": "v1.10.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth1-client.git", + "reference": "d6365b901b5c287dd41f143033315e2f777e1167" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/d6365b901b5c287dd41f143033315e2f777e1167", + "reference": "d6365b901b5c287dd41f143033315e2f777e1167", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-openssl": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "guzzlehttp/psr7": "^1.7|^2.0", + "php": ">=7.1||>=8.0" + }, + "require-dev": { + "ext-simplexml": "*", + "friendsofphp/php-cs-fixer": "^2.17", + "mockery/mockery": "^1.3.3", + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5||9.5" + }, + "suggest": { + "ext-simplexml": "For decoding XML-based responses." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev", + "dev-develop": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "League\\OAuth1\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Corlett", + "email": "bencorlett@me.com", + "homepage": "http://www.webcomm.com.au", + "role": "Developer" + } + ], + "description": "OAuth 1.0 Client Library", + "keywords": [ + "Authentication", + "SSO", + "authorization", + "bitbucket", + "identity", + "idp", + "oauth", + "oauth1", + "single sign on", + "trello", + "tumblr", + "twitter" + ], + "support": { + "issues": "https://github.com/thephpleague/oauth1-client/issues", + "source": "https://github.com/thephpleague/oauth1-client/tree/v1.10.1" + }, + "time": "2022-04-15T14:02:14+00:00" + }, + { + "name": "livewire/livewire", + "version": "v2.10.7", + "source": { + "type": "git", + "url": "https://github.com/livewire/livewire.git", + "reference": "fa0441bf82f1674beecb3a8ad8a4ae428736ed18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/livewire/livewire/zipball/fa0441bf82f1674beecb3a8ad8a4ae428736ed18", + "reference": "fa0441bf82f1674beecb3a8ad8a4ae428736ed18", + "shasum": "" + }, + "require": { + "illuminate/database": "^7.0|^8.0|^9.0", + "illuminate/support": "^7.0|^8.0|^9.0", + "illuminate/validation": "^7.0|^8.0|^9.0", + "league/mime-type-detection": "^1.9", + "php": "^7.2.5|^8.0", + "symfony/http-kernel": "^5.0|^6.0" + }, + "require-dev": { + "calebporzio/sushi": "^2.1", + "laravel/framework": "^7.0|^8.0|^9.0", + "mockery/mockery": "^1.3.1", + "orchestra/testbench": "^5.0|^6.0|^7.0", + "orchestra/testbench-dusk": "^5.2|^6.0|^7.0", + "phpunit/phpunit": "^8.4|^9.0", + "psy/psysh": "@stable" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Livewire\\LivewireServiceProvider" + ], + "aliases": { + "Livewire": "Livewire\\Livewire" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Livewire\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Caleb Porzio", + "email": "calebporzio@gmail.com" + } + ], + "description": "A front-end framework for Laravel.", + "support": { + "issues": "https://github.com/livewire/livewire/issues", + "source": "https://github.com/livewire/livewire/tree/v2.10.7" + }, + "funding": [ + { + "url": "https://github.com/livewire", + "type": "github" + } + ], + "time": "2022-08-08T13:52:53+00:00" + }, + { + "name": "martinbean/socialite-discord-provider", + "version": "dev-tadah", + "source": { + "type": "git", + "url": "https://github.com/tadah-foss/socialite-discord-provider.git", + "reference": "29049b92ca124ea8a679420b2c547bf6888d005b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tadah-foss/socialite-discord-provider/zipball/29049b92ca124ea8a679420b2c547bf6888d005b", + "reference": "29049b92ca124ea8a679420b2c547bf6888d005b", + "shasum": "" + }, + "require": { + "facade/ignition-contracts": "^1.0", + "laravel/socialite": "^4.0|^5.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "MartinBean\\Laravel\\Socialite\\DiscordServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "MartinBean\\Laravel\\Socialite\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Martin Bean", + "email": "martin@martinbean.co.uk", + "homepage": "https://martinbean.co.uk" + } + ], + "description": "A Discord provider for Laravel Socialite.", + "keywords": [ + "discord", + "laravel", + "oauth", + "socialite" + ], + "support": { + "issues": "https://github.com/martinbean/socialite-discord-provider/issues", + "source": "https://github.com/martinbean/socialite-discord-provider" + }, + "time": "2022-08-12T22:43:44+00:00" + }, + { + "name": "maxmind-db/reader", + "version": "v1.11.0", + "source": { + "type": "git", + "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git", + "reference": "b1f3c0699525336d09cc5161a2861268d9f2ae5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/b1f3c0699525336d09cc5161a2861268d9f2ae5b", + "reference": "b1f3c0699525336d09cc5161a2861268d9f2ae5b", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "conflict": { + "ext-maxminddb": "<1.10.1,>=2.0.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "3.*", + "php-coveralls/php-coveralls": "^2.1", + "phpstan/phpstan": "*", + "phpunit/phpcov": ">=6.0.0", + "phpunit/phpunit": ">=8.0.0,<10.0.0", + "squizlabs/php_codesniffer": "3.*" + }, + "suggest": { + "ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", + "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", + "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups" + }, + "type": "library", + "autoload": { + "psr-4": { + "MaxMind\\Db\\": "src/MaxMind/Db" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Gregory J. Oschwald", + "email": "goschwald@maxmind.com", + "homepage": "https://www.maxmind.com/" + } + ], + "description": "MaxMind DB Reader API", + "homepage": "https://github.com/maxmind/MaxMind-DB-Reader-php", + "keywords": [ + "database", + "geoip", + "geoip2", + "geolocation", + "maxmind" + ], + "support": { + "issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues", + "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.11.0" + }, + "time": "2021-10-18T15:23:10+00:00" + }, + { + "name": "maxmind/web-service-common", + "version": "v0.9.0", + "source": { + "type": "git", + "url": "https://github.com/maxmind/web-service-common-php.git", + "reference": "4dc5a3e8df38aea4ca3b1096cee3a038094e9b53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/4dc5a3e8df38aea4ca3b1096cee3a038094e9b53", + "reference": "4dc5a3e8df38aea4ca3b1096cee3a038094e9b53", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0.3", + "ext-curl": "*", + "ext-json": "*", + "php": ">=7.2" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "3.*", + "phpstan/phpstan": "*", + "phpunit/phpunit": "^8.0 || ^9.0", + "squizlabs/php_codesniffer": "3.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "MaxMind\\Exception\\": "src/Exception", + "MaxMind\\WebService\\": "src/WebService" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Gregory Oschwald", + "email": "goschwald@maxmind.com" + } + ], + "description": "Internal MaxMind Web Service API", + "homepage": "https://github.com/maxmind/web-service-common-php", + "support": { + "issues": "https://github.com/maxmind/web-service-common-php/issues", + "source": "https://github.com/maxmind/web-service-common-php/tree/v0.9.0" + }, + "time": "2022-03-28T17:43:20+00:00" + }, + { + "name": "meilisearch/meilisearch-php", + "version": "v0.24.2", + "source": { + "type": "git", + "url": "https://github.com/meilisearch/meilisearch-php.git", + "reference": "7f7b350480bce4bc80efc9a613a820261a96ef8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/meilisearch/meilisearch-php/zipball/7f7b350480bce4bc80efc9a613a820261a96ef8b", + "reference": "7f7b350480bce4bc80efc9a613a820261a96ef8b", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.4 || ^8.0", + "php-http/client-common": "^2.0", + "php-http/discovery": "^1.7", + "php-http/httplug": "^2.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "guzzlehttp/guzzle": "^7.1", + "http-interop/http-factory-guzzle": "^1.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "guzzlehttp/guzzle": "Use Guzzle ^7 as HTTP client", + "http-interop/http-factory-guzzle": "Factory for guzzlehttp/guzzle" + }, + "type": "library", + "autoload": { + "psr-4": { + "MeiliSearch\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Clementine Urquizar", + "email": "clementine@meilisearch.com" + } + ], + "description": "PHP wrapper for the Meilisearch API", + "keywords": [ + "api", + "client", + "instant", + "meilisearch", + "php", + "search" + ], + "support": { + "issues": "https://github.com/meilisearch/meilisearch-php/issues", + "source": "https://github.com/meilisearch/meilisearch-php/tree/v0.24.2" + }, + "time": "2022-08-16T15:18:17+00:00" + }, + { + "name": "mobiledetect/mobiledetectlib", + "version": "2.8.39", + "source": { + "type": "git", + "url": "https://github.com/serbanghita/Mobile-Detect.git", + "reference": "0fd6753003fc870f6e229bae869cc1337c99bc45" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/0fd6753003fc870f6e229bae869cc1337c99bc45", + "reference": "0fd6753003fc870f6e229bae869cc1337c99bc45", + "shasum": "" + }, + "require": { + "php": ">=5.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.35||~5.7" + }, + "type": "library", + "autoload": { + "psr-0": { + "Detection": "namespaced/" + }, + "classmap": [ + "Mobile_Detect.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Serban Ghita", + "email": "serbanghita@gmail.com", + "homepage": "http://mobiledetect.net", + "role": "Developer" + } + ], + "description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.", + "homepage": "https://github.com/serbanghita/Mobile-Detect", + "keywords": [ + "detect mobile devices", + "mobile", + "mobile detect", + "mobile detector", + "php mobile detect" + ], + "support": { + "issues": "https://github.com/serbanghita/Mobile-Detect/issues", + "source": "https://github.com/serbanghita/Mobile-Detect/tree/2.8.39" + }, + "time": "2022-02-17T19:24:25+00:00" + }, + { + "name": "monolog/monolog", + "version": "2.8.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "720488632c590286b88b80e62aa3d3d551ad4a50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/720488632c590286b88b80e62aa3d3d551ad4a50", + "reference": "720488632c590286b88b80e62aa3d3d551ad4a50", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2", + "guzzlehttp/guzzle": "^7.4", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "phpspec/prophecy": "^1.15", + "phpstan/phpstan": "^0.12.91", + "phpunit/phpunit": "^8.5.14", + "predis/predis": "^1.1 || ^2.0", + "rollbar/rollbar": "^1.3 || ^2 || ^3", + "ruflin/elastica": "^7", + "swiftmailer/swiftmailer": "^5.3|^6.0", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/2.8.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2022-07-24T11:55:47+00:00" + }, + { + "name": "nesbot/carbon", + "version": "2.61.0", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "bdf4f4fe3a3eac4de84dbec0738082a862c68ba6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bdf4f4fe3a3eac4de84dbec0738082a862c68ba6", + "reference": "bdf4f4fe3a3eac4de84dbec0738082a862c68ba6", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1.8 || ^8.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php80": "^1.16", + "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "doctrine/dbal": "^2.0 || ^3.0", + "doctrine/orm": "^2.7", + "friendsofphp/php-cs-fixer": "^3.0", + "kylekatarnls/multi-tester": "^2.0", + "ondrejmirtes/better-reflection": "*", + "phpmd/phpmd": "^2.9", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.99 || ^1.7.14", + "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", + "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", + "squizlabs/php_codesniffer": "^3.4" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-3.x": "3.x-dev", + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbon.nesbot.com/docs", + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, + "funding": [ + { + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" + } + ], + "time": "2022-08-06T12:41:24+00:00" + }, + { + "name": "nette/schema", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/9a39cef03a5b34c7de64f551538cbba05c2be5df", + "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df", + "shasum": "" + }, + "require": { + "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0", + "php": ">=7.1 <8.2" + }, + "require-dev": { + "nette/tester": "^2.3 || ^2.4", + "phpstan/phpstan-nette": "^0.12", + "tracy/tracy": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.2.2" + }, + "time": "2021-10-15T11:40:02+00:00" + }, + { + "name": "nette/utils", + "version": "v3.2.7", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "0af4e3de4df9f1543534beab255ccf459e7a2c99" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/0af4e3de4df9f1543534beab255ccf459e7a2c99", + "reference": "0af4e3de4df9f1543534beab255ccf459e7a2c99", + "shasum": "" + }, + "require": { + "php": ">=7.2 <8.2" + }, + "conflict": { + "nette/di": "<3.0.6" + }, + "require-dev": { + "nette/tester": "~2.0", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v3.2.7" + }, + "time": "2022-01-24T11:29:14+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.14.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" + }, + "time": "2022-05-31T20:59:12+00:00" + }, + { + "name": "nunomaduro/termwind", + "version": "v1.14.0", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "10065367baccf13b6e30f5e9246fa4f63a79eb1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/10065367baccf13b6e30f5e9246fa4f63a79eb1d", + "reference": "10065367baccf13b6e30f5e9246fa4f63a79eb1d", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.0", + "symfony/console": "^5.3.0|^6.0.0" + }, + "require-dev": { + "ergebnis/phpstan-rules": "^1.0.", + "illuminate/console": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "laravel/pint": "^1.0.0", + "pestphp/pest": "^1.21.0", + "pestphp/pest-plugin-mock": "^1.0", + "phpstan/phpstan": "^1.4.6", + "phpstan/phpstan-strict-rules": "^1.1.0", + "symfony/var-dumper": "^5.2.7|^6.0.0", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Termwind\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Its like Tailwind CSS, but for the console.", + "keywords": [ + "cli", + "console", + "css", + "package", + "php", + "style" + ], + "support": { + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v1.14.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", + "type": "github" + } + ], + "time": "2022-08-01T11:03:24+00:00" + }, + { + "name": "olssonm/laravel-zxcvbn", + "version": "dev-tadah", + "source": { + "type": "git", + "url": "https://github.com/tadah-foss/laravel-zxcvbn.git", + "reference": "3e6deadefbd86fc33e915d28df32336d5d03952f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tadah-foss/laravel-zxcvbn/zipball/3e6deadefbd86fc33e915d28df32336d5d03952f", + "reference": "3e6deadefbd86fc33e915d28df32336d5d03952f", + "shasum": "" + }, + "require": { + "bjeavons/zxcvbn-php": "^1.2", + "illuminate/support": "^7.0|^8.0|^9.0", + "php": "^7.3|^8.0" + }, + "require-dev": { + "orchestra/testbench": ">=4.0", + "phpunit/phpunit": "^8.0|^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + }, + "laravel": { + "providers": [ + "Olssonm\\Zxcvbn\\ZxcvbnServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Olssonm\\Zxcvbn\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Olssonm\\Zxcvbn\\Test\\": "tests/" + } + }, + "scripts": { + "test": [ + "phpunit" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marcus Olsson", + "email": "contact@marcusolsson.me", + "homepage": "https://marcusolsson.me" + } + ], + "description": "Implementation of the zxcvbn project by @dropbox for Laravel. Uses zxcvbn-php by @bjeavons.", + "homepage": "https://github.com/olssonm/laravel-zxcvbn", + "keywords": [ + "laravel", + "olssonm", + "passwords", + "security", + "staple horse battery", + "validation", + "zxcvbn" + ], + "support": { + "source": "https://github.com/tadah-foss/laravel-zxcvbn/tree/tadah" + }, + "time": "2022-08-12T22:17:28+00:00" + }, + { + "name": "paragonie/ciphersweet", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/paragonie/ciphersweet.git", + "reference": "2e4606e8553ce7fcc9390753dfd6ead4a6f90f27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/ciphersweet/zipball/2e4606e8553ce7fcc9390753dfd6ead4a6f90f27", + "reference": "2e4606e8553ce7fcc9390753dfd6ead4a6f90f27", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-openssl": "*", + "paragonie/constant_time_encoding": "^1.0.4|^2", + "paragonie/sodium_compat": ">= 1.17 <2", + "php": "^5.5|^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^4|^5|^6|^7|^8|^9" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\CipherSweet\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com" + } + ], + "description": "Searchable field-level encryption library for CRM software", + "keywords": [ + "FIPS 140-2", + "crm", + "cryptography", + "encrypt", + "encryption", + "field-level encryption", + "libsodium", + "searchable encryption" + ], + "support": { + "issues": "https://github.com/paragonie/ciphersweet/issues", + "source": "https://github.com/paragonie/ciphersweet/tree/v3.2.1" + }, + "time": "2022-05-21T17:49:17+00:00" + }, + { + "name": "paragonie/constant_time_encoding", + "version": "v2.6.3", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "58c3f47f650c94ec05a151692652a868995d2938" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", + "reference": "58c3f47f650c94ec05a151692652a868995d2938", + "shasum": "" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2022-06-14T06:56:20+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, + { + "name": "paragonie/sodium_compat", + "version": "v1.17.1", + "source": { + "type": "git", + "url": "https://github.com/paragonie/sodium_compat.git", + "reference": "ac994053faac18d386328c91c7900f930acadf1e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/ac994053faac18d386328c91c7900f930acadf1e", + "reference": "ac994053faac18d386328c91c7900f930acadf1e", + "shasum": "" + }, + "require": { + "paragonie/random_compat": ">=1", + "php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^3|^4|^5|^6|^7|^8|^9" + }, + "suggest": { + "ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.", + "ext-sodium": "PHP >= 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security." + }, + "type": "library", + "autoload": { + "files": [ + "autoload.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com" + }, + { + "name": "Frank Denis", + "email": "jedisct1@pureftpd.org" + } + ], + "description": "Pure PHP implementation of libsodium; uses the PHP extension if it exists", + "keywords": [ + "Authentication", + "BLAKE2b", + "ChaCha20", + "ChaCha20-Poly1305", + "Chapoly", + "Curve25519", + "Ed25519", + "EdDSA", + "Edwards-curve Digital Signature Algorithm", + "Elliptic Curve Diffie-Hellman", + "Poly1305", + "Pure-PHP cryptography", + "RFC 7748", + "RFC 8032", + "Salpoly", + "Salsa20", + "X25519", + "XChaCha20-Poly1305", + "XSalsa20-Poly1305", + "Xchacha20", + "Xsalsa20", + "aead", + "cryptography", + "ecdh", + "elliptic curve", + "elliptic curve cryptography", + "encryption", + "libsodium", + "php", + "public-key cryptography", + "secret-key cryptography", + "side-channel resistant" + ], + "support": { + "issues": "https://github.com/paragonie/sodium_compat/issues", + "source": "https://github.com/paragonie/sodium_compat/tree/v1.17.1" + }, + "time": "2022-03-23T19:32:04+00:00" + }, + { + "name": "php-http/client-common", + "version": "2.5.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/client-common.git", + "reference": "d135751167d57e27c74de674d6a30cef2dc8e054" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/client-common/zipball/d135751167d57e27c74de674d6a30cef2dc8e054", + "reference": "d135751167d57e27c74de674d6a30cef2dc8e054", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/httplug": "^2.0", + "php-http/message": "^1.6", + "php-http/message-factory": "^1.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0", + "symfony/options-resolver": "~4.0.15 || ~4.1.9 || ^4.2.1 || ^5.0 || ^6.0", + "symfony/polyfill-php80": "^1.17" + }, + "require-dev": { + "doctrine/instantiator": "^1.1", + "guzzlehttp/psr7": "^1.4", + "nyholm/psr7": "^1.2", + "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", + "phpspec/prophecy": "^1.10.2", + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3" + }, + "suggest": { + "ext-json": "To detect JSON responses with the ContentTypePlugin", + "ext-libxml": "To detect XML responses with the ContentTypePlugin", + "php-http/cache-plugin": "PSR-6 Cache plugin", + "php-http/logger-plugin": "PSR-3 Logger plugin", + "php-http/stopwatch-plugin": "Symfony Stopwatch plugin" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Client\\Common\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Common HTTP Client implementations and tools for HTTPlug", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "common", + "http", + "httplug" + ], + "support": { + "issues": "https://github.com/php-http/client-common/issues", + "source": "https://github.com/php-http/client-common/tree/2.5.0" + }, + "time": "2021-11-26T15:01:24+00:00" + }, + { + "name": "php-http/discovery", + "version": "1.14.3", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "31d8ee46d0215108df16a8527c7438e96a4d7735" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/31d8ee46d0215108df16a8527c7438e96a4d7735", + "reference": "31d8ee46d0215108df16a8527c7438e96a4d7735", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0" + }, + "require-dev": { + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1" + }, + "suggest": { + "php-http/message": "Allow to use Guzzle, Diactoros or Slim Framework factories" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds installed HTTPlug implementations and PSR-7 message factories", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.14.3" + }, + "time": "2022-07-11T14:04:40+00:00" + }, + { + "name": "php-http/httplug", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/httplug.git", + "reference": "f640739f80dfa1152533976e3c112477f69274eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/httplug/zipball/f640739f80dfa1152533976e3c112477f69274eb", + "reference": "f640739f80dfa1152533976e3c112477f69274eb", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/promise": "^1.1", + "psr/http-client": "^1.0", + "psr/http-message": "^1.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.1", + "phpspec/phpspec": "^5.1 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eric GELOEN", + "email": "geloen.eric@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "HTTPlug, the HTTP client abstraction for PHP", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "http" + ], + "support": { + "issues": "https://github.com/php-http/httplug/issues", + "source": "https://github.com/php-http/httplug/tree/2.3.0" + }, + "time": "2022-02-21T09:52:22+00:00" + }, + { + "name": "php-http/message", + "version": "1.13.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/message.git", + "reference": "7886e647a30a966a1a8d1dad1845b71ca8678361" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/message/zipball/7886e647a30a966a1a8d1dad1845b71ca8678361", + "reference": "7886e647a30a966a1a8d1dad1845b71ca8678361", + "shasum": "" + }, + "require": { + "clue/stream-filter": "^1.5", + "php": "^7.1 || ^8.0", + "php-http/message-factory": "^1.0.2", + "psr/http-message": "^1.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.6", + "ext-zlib": "*", + "guzzlehttp/psr7": "^1.0", + "laminas/laminas-diactoros": "^2.0", + "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", + "slim/slim": "^3.0" + }, + "suggest": { + "ext-zlib": "Used with compressor/decompressor streams", + "guzzlehttp/psr7": "Used with Guzzle PSR-7 Factories", + "laminas/laminas-diactoros": "Used with Diactoros Factories", + "slim/slim": "Used with Slim Framework PSR-7 implementation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "files": [ + "src/filters.php" + ], + "psr-4": { + "Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "HTTP Message related tools", + "homepage": "http://php-http.org", + "keywords": [ + "http", + "message", + "psr-7" + ], + "support": { + "issues": "https://github.com/php-http/message/issues", + "source": "https://github.com/php-http/message/tree/1.13.0" + }, + "time": "2022-02-11T13:41:14+00:00" + }, + { + "name": "php-http/message-factory", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-http/message-factory.git", + "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/message-factory/zipball/a478cb11f66a6ac48d8954216cfed9aa06a501a1", + "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Factory interfaces for PSR-7 HTTP Message", + "homepage": "http://php-http.org", + "keywords": [ + "factory", + "http", + "message", + "stream", + "uri" + ], + "support": { + "issues": "https://github.com/php-http/message-factory/issues", + "source": "https://github.com/php-http/message-factory/tree/master" + }, + "time": "2015-12-19T14:08:53+00:00" + }, + { + "name": "php-http/promise", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/promise.git", + "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/promise/zipball/4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", + "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.3.2", + "phpspec/phpspec": "^5.1.2 || ^6.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joel Wurtz", + "email": "joel.wurtz@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Promise used for asynchronous HTTP requests", + "homepage": "http://httplug.io", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/php-http/promise/issues", + "source": "https://github.com/php-http/promise/tree/1.1.0" + }, + "time": "2020-07-07T09:29:14+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", + "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8", + "phpunit/phpunit": "^8.5.28 || ^9.5.21" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2022-07-30T15:51:26+00:00" + }, + { + "name": "pragmarx/google2fa", + "version": "v8.0.1", + "source": { + "type": "git", + "url": "https://github.com/antonioribeiro/google2fa.git", + "reference": "80c3d801b31fe165f8fe99ea085e0a37834e1be3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/80c3d801b31fe165f8fe99ea085e0a37834e1be3", + "reference": "80c3d801b31fe165f8fe99ea085e0a37834e1be3", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1.0|^2.0", + "php": "^7.1|^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.18", + "phpunit/phpunit": "^7.5.15|^8.5|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "PragmaRX\\Google2FA\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antonio Carlos Ribeiro", + "email": "acr@antoniocarlosribeiro.com", + "role": "Creator & Designer" + } + ], + "description": "A One Time Password Authentication package, compatible with Google Authenticator.", + "keywords": [ + "2fa", + "Authentication", + "Two Factor Authentication", + "google2fa" + ], + "support": { + "issues": "https://github.com/antonioribeiro/google2fa/issues", + "source": "https://github.com/antonioribeiro/google2fa/tree/v8.0.1" + }, + "time": "2022-06-13T21:57:56+00:00" + }, + { + "name": "propaganistas/laravel-disposable-email", + "version": "2.1.21", + "source": { + "type": "git", + "url": "https://github.com/Propaganistas/Laravel-Disposable-Email.git", + "reference": "535bbff459d94f1dd6565b6d250f0df7985c38df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Propaganistas/Laravel-Disposable-Email/zipball/535bbff459d94f1dd6565b6d250f0df7985c38df", + "reference": "535bbff459d94f1dd6565b6d250f0df7985c38df", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/cache": "^6.0|^7.0|^8.0|^9.0", + "illuminate/config": "^6.0|^7.0|^8.0|^9.0", + "illuminate/console": "^6.0|^7.0|^8.0|^9.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0", + "illuminate/validation": "^6.0|^7.0|^8.0|^9.0", + "php": "^7.1|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.3.3|^1.4.2", + "orchestra/testbench": "*", + "phpunit/phpunit": "*" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Propaganistas\\LaravelDisposableEmail\\DisposableEmailServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Propaganistas\\LaravelDisposableEmail\\": "src/", + "Propaganistas\\LaravelDisposableEmail\\Tests\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Propaganistas", + "email": "Propaganistas@users.noreply.github.com" + } + ], + "description": "Disposable email validator", + "keywords": [ + "disposable", + "email", + "laravel", + "mail", + "temporary", + "throwaway", + "validator" + ], + "support": { + "issues": "https://github.com/Propaganistas/Laravel-Disposable-Email/issues", + "source": "https://github.com/Propaganistas/Laravel-Disposable-Email/tree/2.1.21" + }, + "time": "2022-07-01T02:07:38+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/master" + }, + "time": "2020-06-29T06:28:15+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, + "time": "2019-04-30T12:38:16+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "psy/psysh", + "version": "v0.11.8", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "f455acf3645262ae389b10e9beba0c358aa6994e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/f455acf3645262ae389b10e9beba0c358aa6994e", + "reference": "f455acf3645262ae389b10e9beba0c358aa6994e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^4.0 || ^3.1", + "php": "^8.0 || ^7.0.8", + "symfony/console": "^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", + "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.11.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "support": { + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.11.8" + }, + "time": "2022-07-28T14:25:11+00:00" + }, + { + "name": "pusher/pusher-php-server", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/pusher/pusher-http-php.git", + "reference": "af3eeaefc0c7959f5b3852f0a4dd5547245d33df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pusher/pusher-http-php/zipball/af3eeaefc0c7959f5b3852f0a4dd5547245d33df", + "reference": "af3eeaefc0c7959f5b3852f0a4dd5547245d33df", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "guzzlehttp/guzzle": "^7.2", + "paragonie/sodium_compat": "^1.6", + "php": "^7.3|^8.0", + "psr/log": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "overtrue/phplint": "^2.3", + "phpunit/phpunit": "^8.5|^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "Pusher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Library for interacting with the Pusher REST API", + "keywords": [ + "events", + "messaging", + "php-pusher-server", + "publish", + "push", + "pusher", + "real time", + "real-time", + "realtime", + "rest", + "trigger" + ], + "support": { + "issues": "https://github.com/pusher/pusher-http-php/issues", + "source": "https://github.com/pusher/pusher-http-php/tree/7.0.2" + }, + "time": "2021-12-07T13:09:00+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "ramsey/collection", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/cccc74ee5e328031b15640b51056ee8d3bb66c0a", + "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8", + "symfony/polyfill-php81": "^1.23" + }, + "require-dev": { + "captainhook/captainhook": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "ergebnis/composer-normalize": "^2.6", + "fakerphp/faker": "^1.5", + "hamcrest/hamcrest-php": "^2", + "jangregor/phpstan-prophecy": "^0.8", + "mockery/mockery": "^1.3", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1", + "phpstan/phpstan": "^0.12.32", + "phpstan/phpstan-mockery": "^0.12.5", + "phpstan/phpstan-phpunit": "^0.12.11", + "phpunit/phpunit": "^8.5 || ^9", + "psy/psysh": "^0.10.4", + "slevomat/coding-standard": "^6.3", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/1.2.2" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "time": "2021-10-10T03:01:02+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.4.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "373f7bacfcf3de038778ff27dcce5672ddbf4c8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/373f7bacfcf3de038778ff27dcce5672ddbf4c8a", + "reference": "373f7bacfcf3de038778ff27dcce5672ddbf4c8a", + "shasum": "" + }, + "require": { + "brick/math": "^0.8 || ^0.9 || ^0.10", + "ext-ctype": "*", + "ext-json": "*", + "php": "^8.0", + "ramsey/collection": "^1.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.8", + "ergebnis/composer-normalize": "^2.15", + "mockery/mockery": "^1.3", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", + "php-mock/php-mock-mockery": "^1.3", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-mockery": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^8.5 || ^9", + "slevomat/coding-standard": "^7.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.9" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-ctype": "Enables faster processing of character classification using ctype functions.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.4.0" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" + } + ], + "time": "2022-08-05T17:58:37+00:00" + }, + { + "name": "spatie/color", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/spatie/color.git", + "reference": "d6e9b2766d8e24aab835e414248728762bd63530" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/color/zipball/d6e9b2766d8e24aab835e414248728762bd63530", + "reference": "d6e9b2766d8e24aab835e414248728762bd63530", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5||^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Color\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sebastian De Deyne", + "email": "sebastian@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A little library to handle color conversions", + "homepage": "https://github.com/spatie/color", + "keywords": [ + "color", + "conversion", + "rgb", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/color/issues", + "source": "https://github.com/spatie/color/tree/1.5.2" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-06-24T21:50:06+00:00" + }, + { + "name": "stevebauman/location", + "version": "v6.5.0", + "source": { + "type": "git", + "url": "https://github.com/stevebauman/location.git", + "reference": "8ceac08537058138071534d49b17556cae2b656e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/stevebauman/location/zipball/8ceac08537058138071534d49b17556cae2b656e", + "reference": "8ceac08537058138071534d49b17556cae2b656e", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "geoip2/geoip2": "^2.0", + "illuminate/support": "^5.0|^6.0|^7.0|^8.0|^9.0", + "php": ">=7.3" + }, + "require-dev": { + "mockery/mockery": "~0.9|^1.0", + "orchestra/testbench": "~3.2|~4.0|^6.0|^7.0", + "pestphp/pest": "^1.21" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Stevebauman\\Location\\LocationServiceProvider" + ], + "aliases": { + "Location": "Stevebauman\\Location\\Facades\\Location" + } + } + }, + "autoload": { + "psr-4": { + "Stevebauman\\Location\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Steve Bauman", + "email": "steven_bauman@outlook.com" + } + ], + "description": "Retrieve a user's location by their IP Address", + "keywords": [ + "IP", + "geo", + "geo-location", + "geoip", + "laravel", + "location", + "php" + ], + "support": { + "issues": "https://github.com/stevebauman/location/issues", + "source": "https://github.com/stevebauman/location/tree/v6.5.0" + }, + "time": "2022-05-12T13:11:31+00:00" + }, + { + "name": "symfony/console", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "43fcb5c5966b43c56bcfa481368d90d748936ab8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/43fcb5c5966b43c56bcfa481368d90d748936ab8", + "reference": "43fcb5c5966b43c56bcfa481368d90d748936ab8", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.4|^6.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/lock": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-22T14:17:57+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "0dd5e36b80e1de97f8f74ed7023ac2b837a36443" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/0dd5e36b80e1de97f8f74ed7023ac2b837a36443", + "reference": "0dd5e36b80e1de97f8f74ed7023ac2b837a36443", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Converts CSS selectors to XPath expressions", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-06-27T17:24:16+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-02-25T11:15:52+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "736e42db3fd586d91820355988698e434e1d8419" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/736e42db3fd586d91820355988698e434e1d8419", + "reference": "736e42db3fd586d91820355988698e434e1d8419", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^5.4|^6.0" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" + }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-29T07:42:06+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v6.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "a0449a7ad7daa0f7c0acd508259f80544ab5a347" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a0449a7ad7daa0f7c0acd508259f80544ab5a347", + "reference": "a0449a7ad7daa0f7c0acd508259f80544ab5a347", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2|^3" + }, + "conflict": { + "symfony/dependency-injection": "<5.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^5.4|^6.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v6.1.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-05T16:51:07+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "02ff5eea2f453731cfbc6bc215e456b781480448" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/02ff5eea2f453731cfbc6bc215e456b781480448", + "reference": "02ff5eea2f453731cfbc6bc215e456b781480448", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-02-25T11:15:52+00:00" + }, + { + "name": "symfony/finder", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "39696bff2c2970b3779a5cac7bf9f0b88fc2b709" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/39696bff2c2970b3779a5cac7bf9f0b88fc2b709", + "reference": "39696bff2c2970b3779a5cac7bf9f0b88fc2b709", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-29T07:42:06+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "b03712c93759a81fc243ecc18ec4637958afebdb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/b03712c93759a81fc243ecc18ec4637958afebdb", + "reference": "b03712c93759a81fc243ecc18ec4637958afebdb", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.1" + }, + "require-dev": { + "predis/predis": "~1.0", + "symfony/cache": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/mime": "^5.4|^6.0" + }, + "suggest": { + "symfony/mime": "To use the file extension guesser" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-27T15:50:51+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "0692bc185a1dbb54864686a1fc6785667279da70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/0692bc185a1dbb54864686a1fc6785667279da70", + "reference": "0692bc185a1dbb54864686a1fc6785667279da70", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/error-handler": "^6.1", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<5.4", + "symfony/cache": "<5.4", + "symfony/config": "<6.1", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<6.1", + "symfony/doctrine-bridge": "<5.4", + "symfony/form": "<5.4", + "symfony/http-client": "<5.4", + "symfony/mailer": "<5.4", + "symfony/messenger": "<5.4", + "symfony/translation": "<5.4", + "symfony/twig-bridge": "<5.4", + "symfony/validator": "<5.4", + "twig/twig": "<2.13" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^5.4|^6.0", + "symfony/config": "^6.1", + "symfony/console": "^5.4|^6.0", + "symfony/css-selector": "^5.4|^6.0", + "symfony/dependency-injection": "^6.1", + "symfony/dom-crawler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-client-contracts": "^1.1|^2|^3", + "symfony/process": "^5.4|^6.0", + "symfony/routing": "^5.4|^6.0", + "symfony/stopwatch": "^5.4|^6.0", + "symfony/translation": "^5.4|^6.0", + "symfony/translation-contracts": "^1.1|^2|^3", + "symfony/uid": "^5.4|^6.0", + "twig/twig": "^2.13|^3.0.4" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a structured process for converting a Request into a Response", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-29T12:59:10+00:00" + }, + { + "name": "symfony/mailer", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "b2db228a93278863d1567f90d7caf26922dbfede" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/b2db228a93278863d1567f90d7caf26922dbfede", + "reference": "b2db228a93278863d1567f90d7caf26922dbfede", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3", + "php": ">=8.1", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/mime": "^5.4|^6.0", + "symfony/service-contracts": "^1.1|^2|^3" + }, + "conflict": { + "symfony/http-kernel": "<5.4" + }, + "require-dev": { + "symfony/http-client-contracts": "^1.1|^2|^3", + "symfony/messenger": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-27T15:50:51+00:00" + }, + { + "name": "symfony/mime", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "9c0247994fc6584da8591ba64b2bffaace9df87d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/9c0247994fc6584da8591ba64b2bffaace9df87d", + "reference": "9c0247994fc6584da8591ba64b2bffaace9df87d", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<5.4" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/property-access": "^5.4|^6.0", + "symfony/property-info": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-20T13:46:29+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v6.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "a3016f5442e28386ded73c43a32a5b68586dd1c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a3016f5442e28386ded73c43a32a5b68586dd1c4", + "reference": "a3016f5442e28386ded73c43a32a5b68586dd1c4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.1|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v6.1.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-02-25T11:15:52+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "433d05519ce6990bf3530fba6957499d327395c2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", + "reference": "433d05519ce6990bf3530fba6957499d327395c2", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/59a8d271f00dd0e4c2e518104cc7963f655a1aa8", + "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-intl-normalizer": "^1.10", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "219aa369ceff116e673852dce47c3a41794c14bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", + "reference": "219aa369ceff116e673852dce47c3a41794c14bd", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2", + "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-10T07:21:04+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/process", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "a6506e99cfad7059b1ab5cab395854a0a0c21292" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/a6506e99cfad7059b1ab5cab395854a0a0c21292", + "reference": "a6506e99cfad7059b1ab5cab395854a0a0c21292", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-06-27T17:24:16+00:00" + }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v2.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "22b37c8a3f6b5d94e9cdbd88e1270d96e2f97b34" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/22b37c8a3f6b5d94e9cdbd88e1270d96e2f97b34", + "reference": "22b37c8a3f6b5d94e9cdbd88e1270d96e2f97b34", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0", + "symfony/http-foundation": "^4.4 || ^5.0 || ^6.0" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "psr/log": "^1.1 || ^2 || ^3", + "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0", + "symfony/config": "^4.4 || ^5.0 || ^6.0", + "symfony/event-dispatcher": "^4.4 || ^5.0 || ^6.0", + "symfony/framework-bundle": "^4.4 || ^5.0 || ^6.0", + "symfony/http-kernel": "^4.4 || ^5.0 || ^6.0", + "symfony/phpunit-bridge": "^5.4@dev || ^6.0" + }, + "suggest": { + "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-main": "2.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/symfony/psr-http-message-bridge/issues", + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.1.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-05T13:13:39+00:00" + }, + { + "name": "symfony/routing", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "ef9108b3a88045b7546e808fb404ddb073dd35ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/ef9108b3a88045b7546e808fb404ddb073dd35ea", + "reference": "ef9108b3a88045b7546e808fb404ddb073dd35ea", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "conflict": { + "doctrine/annotations": "<1.12", + "symfony/config": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/yaml": "<5.4" + }, + "require-dev": { + "doctrine/annotations": "^1.12", + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "symfony/config": "For using the all-in-one router or any loader", + "symfony/expression-language": "For using expression matching", + "symfony/http-foundation": "For using a Symfony Request object", + "symfony/yaml": "For using the YAML loader" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Maps an HTTP request to a set of configuration variables", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "support": { + "source": "https://github.com/symfony/routing/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-20T15:00:40+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "925e713fe8fcacf6bc05e936edd8dd5441a21239" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/925e713fe8fcacf6bc05e936edd8dd5441a21239", + "reference": "925e713fe8fcacf6bc05e936edd8dd5441a21239", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-30T19:18:58+00:00" + }, + { + "name": "symfony/string", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "f35241f45c30bcd9046af2bb200a7086f70e1d6b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/f35241f45c30bcd9046af2bb200a7086f70e1d6b", + "reference": "f35241f45c30bcd9046af2bb200a7086f70e1d6b", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.0" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-27T15:50:51+00:00" + }, + { + "name": "symfony/translation", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "b042e16087d298d08c1f013ff505d16c12a3b1be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/b042e16087d298d08c1f013ff505d16c12a3b1be", + "reference": "b042e16087d298d08c1f013ff505d16c12a3b1be", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.3|^3.0" + }, + "conflict": { + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-client-contracts": "^1.1|^2.0|^3.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/intl": "^5.4|^6.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^5.4|^6.0", + "symfony/service-contracts": "^1.1.2|^2|^3", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-20T13:46:29+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "606be0f48e05116baef052f7f3abdb345c8e02cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/606be0f48e05116baef052f7f3abdb345c8e02cc", + "reference": "606be0f48e05116baef052f7f3abdb345c8e02cc", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "suggest": { + "symfony/translation-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-06-27T17:24:16+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "d5a5e44a2260c5eb5e746bf4f1fbd12ee6ceb427" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/d5a5e44a2260c5eb5e746bf4f1fbd12ee6ceb427", + "reference": "d5a5e44a2260c5eb5e746bf4f1fbd12ee6ceb427", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.3", + "symfony/console": "<5.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/uid": "^5.4|^6.0", + "twig/twig": "^2.13|^3.0.4" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-20T13:46:29+00:00" + }, + { + "name": "tijsverkoyen/css-to-inline-styles", + "version": "2.2.4", + "source": { + "type": "git", + "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", + "reference": "da444caae6aca7a19c0c140f68c6182e337d5b1c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/da444caae6aca7a19c0c140f68c6182e337d5b1c", + "reference": "da444caae6aca7a19c0c140f68c6182e337d5b1c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": "^5.5 || ^7.0 || ^8.0", + "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "TijsVerkoyen\\CssToInlineStyles\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "css_to_inline_styles@verkoyen.eu", + "role": "Developer" + } + ], + "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", + "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "support": { + "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.4" + }, + "time": "2021-12-08T09:12:39+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.4.1", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/264dce589e7ce37a7ba99cb901eed8249fbec92f", + "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.0.2", + "php": "^7.1.3 || ^8.0", + "phpoption/phpoption": "^1.8", + "symfony/polyfill-ctype": "^1.23", + "symfony/polyfill-mbstring": "^1.23.1", + "symfony/polyfill-php80": "^1.23.1" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "ext-filter": "*", + "phpunit/phpunit": "^7.5.20 || ^8.5.21 || ^9.5.10" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.4-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.4.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2021-12-12T23:22:04+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "b56450eed252f6801410d810c8e1727224ae0743" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b56450eed252f6801410d810c8e1727224ae0743", + "reference": "b56450eed252f6801410d810c8e1727224ae0743", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + }, + "suggest": { + "ext-intl": "Use Intl for transliterator_transliterate() support" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Moelleken", + "homepage": "http://www.moelleken.org/" + } + ], + "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", + "homepage": "https://github.com/voku/portable-ascii", + "keywords": [ + "ascii", + "clean", + "php" + ], + "support": { + "issues": "https://github.com/voku/portable-ascii/issues", + "source": "https://github.com/voku/portable-ascii/tree/2.0.1" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-ascii", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2022-03-08T17:03:00+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + } + ], + "packages-dev": [ + { + "name": "barryvdh/laravel-debugbar", + "version": "v3.7.0", + "source": { + "type": "git", + "url": "https://github.com/barryvdh/laravel-debugbar.git", + "reference": "3372ed65e6d2039d663ed19aa699956f9d346271" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/3372ed65e6d2039d663ed19aa699956f9d346271", + "reference": "3372ed65e6d2039d663ed19aa699956f9d346271", + "shasum": "" + }, + "require": { + "illuminate/routing": "^7|^8|^9", + "illuminate/session": "^7|^8|^9", + "illuminate/support": "^7|^8|^9", + "maximebf/debugbar": "^1.17.2", + "php": ">=7.2.5", + "symfony/finder": "^5|^6" + }, + "require-dev": { + "mockery/mockery": "^1.3.3", + "orchestra/testbench-dusk": "^5|^6|^7", + "phpunit/phpunit": "^8.5|^9.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.6-dev" + }, + "laravel": { + "providers": [ + "Barryvdh\\Debugbar\\ServiceProvider" + ], + "aliases": { + "Debugbar": "Barryvdh\\Debugbar\\Facades\\Debugbar" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Barryvdh\\Debugbar\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" + } + ], + "description": "PHP Debugbar integration for Laravel", + "keywords": [ + "debug", + "debugbar", + "laravel", + "profiler", + "webprofiler" + ], + "support": { + "issues": "https://github.com/barryvdh/laravel-debugbar/issues", + "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.7.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2022-07-11T09:26:42+00:00" + }, + { + "name": "composer/class-map-generator", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/class-map-generator.git", + "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/class-map-generator/zipball/1e1cb2b791facb2dfe32932a7718cf2571187513", + "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513", + "shasum": "" + }, + "require": { + "composer/pcre": "^2 || ^3", + "php": "^7.2 || ^8.0", + "symfony/finder": "^4.4 || ^5.3 || ^6" + }, + "require-dev": { + "phpstan/phpstan": "^1.6", + "phpstan/phpstan-deprecation-rules": "^1", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/filesystem": "^5.4 || ^6", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\ClassMapGenerator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Utilities to scan PHP code and generate class maps.", + "keywords": [ + "classmap" + ], + "support": { + "issues": "https://github.com/composer/class-map-generator/issues", + "source": "https://github.com/composer/class-map-generator/tree/1.0.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-06-19T11:31:27+00:00" + }, + { + "name": "composer/pcre", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd", + "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.0.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-02-25T20:21:48+00:00" + }, + { + "name": "fakerphp/faker", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/FakerPHP/Faker.git", + "reference": "37f751c67a5372d4e26353bd9384bc03744ec77b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/37f751c67a5372d4e26353bd9384bc03744ec77b", + "reference": "37f751c67a5372d4e26353bd9384bc03744ec77b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "conflict": { + "fzaninotto/faker": "*" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "doctrine/persistence": "^1.3 || ^2.0", + "ext-intl": "*", + "symfony/phpunit-bridge": "^4.4 || ^5.2" + }, + "suggest": { + "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", + "ext-curl": "Required by Faker\\Provider\\Image to download images.", + "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", + "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", + "ext-mbstring": "Required for multibyte Unicode string functionality." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "v1.20-dev" + } + }, + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "support": { + "issues": "https://github.com/FakerPHP/Faker/issues", + "source": "https://github.com/FakerPHP/Faker/tree/v1.20.0" + }, + "time": "2022-07-20T13:12:54+00:00" + }, + { + "name": "filp/whoops", + "version": "2.14.5", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", + "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", + "shasum": "" + }, + "require": { + "php": "^5.5.9 || ^7.0 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "mockery/mockery": "^0.9 || ^1.0", + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.14.5" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2022-01-07T12:00:00+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "shasum": "" + }, + "require": { + "php": "^5.3|^7.0|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + }, + "time": "2020-07-09T08:09:16+00:00" + }, + { + "name": "laravel/sail", + "version": "v1.15.4", + "source": { + "type": "git", + "url": "https://github.com/laravel/sail.git", + "reference": "853dea1fa866a52a93beccc4e5affdc49b98e7d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sail/zipball/853dea1fa866a52a93beccc4e5affdc49b98e7d5", + "reference": "853dea1fa866a52a93beccc4e5affdc49b98e7d5", + "shasum": "" + }, + "require": { + "illuminate/console": "^8.0|^9.0", + "illuminate/contracts": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "php": "^7.3|^8.0" + }, + "bin": [ + "bin/sail" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Sail\\SailServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Docker files for running a basic Laravel application.", + "keywords": [ + "docker", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/sail/issues", + "source": "https://github.com/laravel/sail" + }, + "time": "2022-08-17T13:17:15+00:00" + }, + { + "name": "maximebf/debugbar", + "version": "v1.18.0", + "source": { + "type": "git", + "url": "https://github.com/maximebf/php-debugbar.git", + "reference": "0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6", + "reference": "0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6", + "shasum": "" + }, + "require": { + "php": "^7.1|^8", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^2.6|^3|^4|^5|^6" + }, + "require-dev": { + "phpunit/phpunit": "^7.5.20 || ^9.4.2", + "twig/twig": "^1.38|^2.7|^3.0" + }, + "suggest": { + "kriswallsmith/assetic": "The best way to manage assets", + "monolog/monolog": "Log using Monolog", + "predis/predis": "Redis storage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "DebugBar\\": "src/DebugBar/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Maxime Bouroumeau-Fuseau", + "email": "maxime.bouroumeau@gmail.com", + "homepage": "http://maximebf.com" + }, + { + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" + } + ], + "description": "Debug bar in the browser for php application", + "homepage": "https://github.com/maximebf/php-debugbar", + "keywords": [ + "debug", + "debugbar" + ], + "support": { + "issues": "https://github.com/maximebf/php-debugbar/issues", + "source": "https://github.com/maximebf/php-debugbar/tree/v1.18.0" + }, + "time": "2021-12-27T18:49:48+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "c10a5f6e06fc2470ab1822fa13fa2a7380f8fbac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/c10a5f6e06fc2470ab1822fa13fa2a7380f8fbac", + "reference": "c10a5f6e06fc2470ab1822fa13fa2a7380f8fbac", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": "^7.3 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "issues": "https://github.com/mockery/mockery/issues", + "source": "https://github.com/mockery/mockery/tree/1.5.0" + }, + "time": "2022-01-20T13:18:17+00:00" + }, + { + "name": "nunomaduro/collision", + "version": "v6.2.1", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/collision.git", + "reference": "5f058f7e39278b701e455b3c82ec5298cf001d89" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/5f058f7e39278b701e455b3c82ec5298cf001d89", + "reference": "5f058f7e39278b701e455b3c82ec5298cf001d89", + "shasum": "" + }, + "require": { + "facade/ignition-contracts": "^1.0.2", + "filp/whoops": "^2.14.5", + "php": "^8.0.0", + "symfony/console": "^6.0.2" + }, + "require-dev": { + "brianium/paratest": "^6.4.1", + "laravel/framework": "^9.7", + "laravel/pint": "^0.2.1", + "nunomaduro/larastan": "^1.0.2", + "nunomaduro/mock-final-classes": "^1.1.0", + "orchestra/testbench": "^7.3.0", + "phpunit/phpunit": "^9.5.11" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "6.x-dev" + }, + "laravel": { + "providers": [ + "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "NunoMaduro\\Collision\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Cli error handling for console/command-line PHP applications.", + "keywords": [ + "artisan", + "cli", + "command-line", + "console", + "error", + "handling", + "laravel", + "laravel-zero", + "php", + "symfony" + ], + "support": { + "issues": "https://github.com/nunomaduro/collision/issues", + "source": "https://github.com/nunomaduro/collision" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2022-06-27T16:11:16+00:00" + }, + { + "name": "nunomaduro/larastan", + "version": "v2.1.12", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/larastan.git", + "reference": "65cfc54fa195e509c2e2be119761552017d22a56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/larastan/zipball/65cfc54fa195e509c2e2be119761552017d22a56", + "reference": "65cfc54fa195e509c2e2be119761552017d22a56", + "shasum": "" + }, + "require": { + "composer/class-map-generator": "^1.0", + "composer/pcre": "^3.0", + "ext-json": "*", + "illuminate/console": "^9", + "illuminate/container": "^9", + "illuminate/contracts": "^9", + "illuminate/database": "^9", + "illuminate/http": "^9", + "illuminate/pipeline": "^9", + "illuminate/support": "^9", + "mockery/mockery": "^1.4.4", + "php": "^8.0.2", + "phpmyadmin/sql-parser": "^5.5", + "phpstan/phpstan": "^1.8.1" + }, + "require-dev": { + "nikic/php-parser": "^4.13.2", + "orchestra/testbench": "^7.0.0", + "phpunit/phpunit": "^9.5.11" + }, + "suggest": { + "orchestra/testbench": "Using Larastan for analysing a package needs Testbench" + }, + "type": "phpstan-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "NunoMaduro\\Larastan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan wrapper for Laravel", + "keywords": [ + "PHPStan", + "code analyse", + "code analysis", + "larastan", + "laravel", + "package", + "php", + "static analysis" + ], + "support": { + "issues": "https://github.com/nunomaduro/larastan/issues", + "source": "https://github.com/nunomaduro/larastan/tree/v2.1.12" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/canvural", + "type": "github" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2022-07-17T15:23:33+00:00" + }, + { + "name": "phpmyadmin/sql-parser", + "version": "5.5.0", + "source": { + "type": "git", + "url": "https://github.com/phpmyadmin/sql-parser.git", + "reference": "8ab99cd0007d880f49f5aa1807033dbfa21b1cb5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/8ab99cd0007d880f49f5aa1807033dbfa21b1cb5", + "reference": "8ab99cd0007d880f49f5aa1807033dbfa21b1cb5", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "symfony/polyfill-mbstring": "^1.3" + }, + "conflict": { + "phpmyadmin/motranslator": "<3.0" + }, + "require-dev": { + "phpmyadmin/coding-standard": "^3.0", + "phpmyadmin/motranslator": "^4.0 || ^5.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.2", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/php-code-coverage": "*", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "^0.16.1", + "vimeo/psalm": "^4.11", + "zumba/json-serializer": "^3.0" + }, + "suggest": { + "ext-mbstring": "For best performance", + "phpmyadmin/motranslator": "Translate messages to your favorite locale" + }, + "bin": [ + "bin/highlight-query", + "bin/lint-query", + "bin/tokenize-query" + ], + "type": "library", + "autoload": { + "psr-4": { + "PhpMyAdmin\\SqlParser\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "The phpMyAdmin Team", + "email": "developers@phpmyadmin.net", + "homepage": "https://www.phpmyadmin.net/team/" + } + ], + "description": "A validating SQL lexer and parser with a focus on MySQL dialect.", + "homepage": "https://github.com/phpmyadmin/sql-parser", + "keywords": [ + "analysis", + "lexer", + "parser", + "sql" + ], + "support": { + "issues": "https://github.com/phpmyadmin/sql-parser/issues", + "source": "https://github.com/phpmyadmin/sql-parser" + }, + "time": "2021-12-09T04:31:52+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.8.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c53312ecc575caf07b0e90dee43883fdf90ca67c", + "reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/1.8.2" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpstan", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2022-07-20T09:57:31+00:00" + }, + { + "name": "spatie/backtrace", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/backtrace.git", + "reference": "4ee7d41aa5268107906ea8a4d9ceccde136dbd5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/4ee7d41aa5268107906ea8a4d9ceccde136dbd5b", + "reference": "4ee7d41aa5268107906ea8a4d9ceccde136dbd5b", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "ext-json": "*", + "phpunit/phpunit": "^9.3", + "symfony/var-dumper": "^5.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Backtrace\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van de Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A better backtrace", + "homepage": "https://github.com/spatie/backtrace", + "keywords": [ + "Backtrace", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/backtrace/issues", + "source": "https://github.com/spatie/backtrace/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2021-11-09T10:57:15+00:00" + }, + { + "name": "spatie/flare-client-php", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/flare-client-php.git", + "reference": "b1b974348750925b717fa8c8b97a0db0d1aa40ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/b1b974348750925b717fa8c8b97a0db0d1aa40ca", + "reference": "b1b974348750925b717fa8c8b97a0db0d1aa40ca", + "shasum": "" + }, + "require": { + "illuminate/pipeline": "^8.0|^9.0", + "php": "^8.0", + "spatie/backtrace": "^1.2", + "symfony/http-foundation": "^5.0|^6.0", + "symfony/mime": "^5.2|^6.0", + "symfony/process": "^5.2|^6.0", + "symfony/var-dumper": "^5.2|^6.0" + }, + "require-dev": { + "dms/phpunit-arraysubset-asserts": "^0.3.0", + "pestphp/pest": "^1.20", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "spatie/phpunit-snapshot-assertions": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.1.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\FlareClient\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Send PHP errors to Flare", + "homepage": "https://github.com/spatie/flare-client-php", + "keywords": [ + "exception", + "flare", + "reporting", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/flare-client-php/issues", + "source": "https://github.com/spatie/flare-client-php/tree/1.3.0" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-08-08T10:10:20+00:00" + }, + { + "name": "spatie/ignition", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/ignition.git", + "reference": "997363fbcce809b1e55f571997d49017f9c623d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/ignition/zipball/997363fbcce809b1e55f571997d49017f9c623d9", + "reference": "997363fbcce809b1e55f571997d49017f9c623d9", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "monolog/monolog": "^2.0", + "php": "^8.0", + "spatie/flare-client-php": "^1.1", + "symfony/console": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "require-dev": { + "mockery/mockery": "^1.4", + "pestphp/pest": "^1.20", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "symfony/process": "^5.4|^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Spatie\\Ignition\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Spatie", + "email": "info@spatie.be", + "role": "Developer" + } + ], + "description": "A beautiful error page for PHP applications.", + "homepage": "https://flareapp.io/ignition", + "keywords": [ + "error", + "flare", + "laravel", + "page" + ], + "support": { + "docs": "https://flareapp.io/docs/ignition-for-laravel/introduction", + "forum": "https://twitter.com/flareappio", + "issues": "https://github.com/spatie/ignition/issues", + "source": "https://github.com/spatie/ignition" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-05-16T13:16:07+00:00" + }, + { + "name": "spatie/laravel-ignition", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-ignition.git", + "reference": "fe37a0eafe6ea040804255c70e9808af13314f87" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/fe37a0eafe6ea040804255c70e9808af13314f87", + "reference": "fe37a0eafe6ea040804255c70e9808af13314f87", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "illuminate/support": "^8.77|^9.0", + "monolog/monolog": "^2.3", + "php": "^8.0", + "spatie/flare-client-php": "^1.0.1", + "spatie/ignition": "^1.2.4", + "symfony/console": "^5.0|^6.0", + "symfony/var-dumper": "^5.0|^6.0" + }, + "require-dev": { + "filp/whoops": "^2.14", + "livewire/livewire": "^2.8|dev-develop", + "mockery/mockery": "^1.4", + "nunomaduro/larastan": "^1.0", + "orchestra/testbench": "^6.23|^7.0", + "pestphp/pest": "^1.20", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "spatie/laravel-ray": "^1.27" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\LaravelIgnition\\IgnitionServiceProvider" + ], + "aliases": { + "Flare": "Spatie\\LaravelIgnition\\Facades\\Flare" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\LaravelIgnition\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Spatie", + "email": "info@spatie.be", + "role": "Developer" + } + ], + "description": "A beautiful error page for Laravel applications.", + "homepage": "https://flareapp.io/ignition", + "keywords": [ + "error", + "flare", + "laravel", + "page" + ], + "support": { + "docs": "https://flareapp.io/docs/ignition-for-laravel/introduction", + "forum": "https://twitter.com/flareappio", + "issues": "https://github.com/spatie/laravel-ignition/issues", + "source": "https://github.com/spatie/laravel-ignition" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-06-17T06:28:57+00:00" + } + ], + "aliases": [ + { + "package": "arandilopez/laravel-profane", + "version": "dev-tadah", + "alias": "0.5.0", + "alias_normalized": "0.5.0.0" + }, + { + "package": "bjorn-voesten/ciphersweet-for-laravel", + "version": "dev-tadah", + "alias": "1.3.0", + "alias_normalized": "1.3.0.0" + }, + { + "package": "martinbean/socialite-discord-provider", + "version": "dev-tadah", + "alias": "1.2.0", + "alias_normalized": "1.2.0.0" + }, + { + "package": "olssonm/laravel-zxcvbn", + "version": "dev-tadah", + "alias": "4.5", + "alias_normalized": "4.5.0.0" + } + ], + "minimum-stability": "dev", + "stability-flags": { + "arandilopez/laravel-profane": 20, + "bjorn-voesten/ciphersweet-for-laravel": 20, + "martinbean/socialite-discord-provider": 20, + "olssonm/laravel-zxcvbn": 20 + }, + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": "^8.1" + }, + "platform-dev": [], + "platform-overrides": { + "ext-pcntl": "8.1", + "ext-posix": "8.1" + }, + "plugin-api-version": "2.2.0" +} diff --git a/config/app.php b/config/app.php new file mode 100644 index 0000000..d54098b --- /dev/null +++ b/config/app.php @@ -0,0 +1,217 @@ + env('APP_NAME', 'Laravel'), + + /* + |-------------------------------------------------------------------------- + | Application Environment + |-------------------------------------------------------------------------- + | + | This value determines the "environment" your application is currently + | running in. This may determine how you prefer to configure various + | services the application utilizes. Set this in your ".env" file. + | + */ + + 'env' => env('APP_ENV', 'production'), + + /* + |-------------------------------------------------------------------------- + | Application Debug Mode + |-------------------------------------------------------------------------- + | + | When your application is in debug mode, detailed error messages with + | stack traces will be shown on every error that occurs within your + | application. If disabled, a simple generic error page is shown. + | + */ + + 'debug' => (bool) env('APP_DEBUG', false), + + /* + |-------------------------------------------------------------------------- + | Application URL + |-------------------------------------------------------------------------- + | + | This URL is used by the console to properly generate URLs when using + | the Artisan command line tool. You should set this to the root of + | your application so that it is used when running Artisan tasks. + | + */ + + 'base_url' => parse_url(env('APP_URL', 'http://localhost'))['host'], + 'url' => env('APP_URL', 'http://localhost'), + + 'asset_url' => env('ASSET_URL', null), + + /* + |-------------------------------------------------------------------------- + | Application Timezone + |-------------------------------------------------------------------------- + | + | Here you may specify the default timezone for your application, which + | will be used by the PHP date and date-time functions. We have gone + | ahead and set this to a sensible default for you out of the box. + | + */ + + 'timezone' => env('APP_TIMEZONE', 'UTC'), + + 'email_verification' => (bool) env('EMAIL_VERIFICATION', false), + + /* + |-------------------------------------------------------------------------- + | Application Locale Configuration + |-------------------------------------------------------------------------- + | + | The application locale determines the default locale that will be used + | by the translation service provider. You are free to set this value + | to any of the locales which will be supported by the application. + | + */ + + 'locale' => 'en_US', + + 'available_locales' => [ + 'English' => 'en_US', + ], + + 'country_flags' => [ + 'en_US' => "us", + ], + + /* + |-------------------------------------------------------------------------- + | Application Fallback Locale + |-------------------------------------------------------------------------- + | + | The fallback locale determines the locale to use when the current one + | is not available. You may change the value to correspond to any of + | the language folders that are provided through your application. + | + */ + + 'fallback_locale' => 'en_US', + + /* + |-------------------------------------------------------------------------- + | Faker Locale + |-------------------------------------------------------------------------- + | + | This locale will be used by the Faker PHP library when generating fake + | data for your database seeds. For example, this will be used to get + | localized telephone numbers, street address information and more. + | + */ + + 'faker_locale' => 'en_US', + + /* + |-------------------------------------------------------------------------- + | Encryption Key + |-------------------------------------------------------------------------- + | + | This key is used by the Illuminate encrypter service and should be set + | to a random, 32 character string, otherwise these encrypted strings + | will not be safe. Please do this before deploying an application! + | + */ + + 'key' => env('APP_KEY'), + + 'cipher' => 'AES-256-CBC', + + /* + |-------------------------------------------------------------------------- + | Autoloaded Service Providers + |-------------------------------------------------------------------------- + | + | The service providers listed here will be automatically loaded on the + | request to your application. Feel free to add your own services to + | this array to grant expanded functionality to your applications. + | + */ + + 'providers' => [ + + /* + * Laravel Framework Service Providers... + */ + Illuminate\Auth\AuthServiceProvider::class, + Illuminate\Broadcasting\BroadcastServiceProvider::class, + Illuminate\Bus\BusServiceProvider::class, + Illuminate\Cache\CacheServiceProvider::class, + Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, + Illuminate\Cookie\CookieServiceProvider::class, + Illuminate\Database\DatabaseServiceProvider::class, + Illuminate\Encryption\EncryptionServiceProvider::class, + Illuminate\Filesystem\FilesystemServiceProvider::class, + Illuminate\Foundation\Providers\FoundationServiceProvider::class, + Illuminate\Hashing\HashServiceProvider::class, + Illuminate\Mail\MailServiceProvider::class, + Illuminate\Notifications\NotificationServiceProvider::class, + Illuminate\Pagination\PaginationServiceProvider::class, + Illuminate\Pipeline\PipelineServiceProvider::class, + Illuminate\Queue\QueueServiceProvider::class, + Illuminate\Redis\RedisServiceProvider::class, + Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, + Illuminate\Session\SessionServiceProvider::class, + Illuminate\Translation\TranslationServiceProvider::class, + Illuminate\Validation\ValidationServiceProvider::class, + Illuminate\View\ViewServiceProvider::class, + + /* + * Package Service Providers... + */ + + /* + * Application Service Providers... + */ + App\Providers\AppServiceProvider::class, + App\Providers\FortifyServiceProvider::class, + App\Providers\AuthServiceProvider::class, + App\Providers\BroadcastServiceProvider::class, + App\Providers\EventServiceProvider::class, + App\Providers\RouteServiceProvider::class, + App\Providers\TelescopeServiceProvider::class, + ], + + /* + |-------------------------------------------------------------------------- + | Class Aliases + |-------------------------------------------------------------------------- + | + | This array of class aliases will be registered when this application + | is started. However, feel free to register as many as you wish as + | the aliases are "lazy" loaded so they don't hinder performance. + | + */ + + 'aliases' => Facade::defaultAliases()->merge([ + 'Admin' => App\Roles\Admin::class, + 'Economy' => App\Roles\Economy::class, + 'Forums' => App\Roles\Forums::class, + 'GameServers' => App\Roles\GameServers::class, + 'Places' => App\Roles\Places::class, + 'SelfHostedServers' => App\Roles\SelfHostedServers::class, + 'Users' => App\Roles\Users::class, + 'GameServerState' => App\Enums\GameServerState::class, + 'ArbiterLogSeverity' => App\Enums\ArbiterLogSeverity::class, + ])->toArray(), + +]; diff --git a/config/auth.php b/config/auth.php new file mode 100644 index 0000000..d8c6cee --- /dev/null +++ b/config/auth.php @@ -0,0 +1,111 @@ + [ + 'guard' => 'web', + 'passwords' => 'users', + ], + + /* + |-------------------------------------------------------------------------- + | Authentication Guards + |-------------------------------------------------------------------------- + | + | Next, you may define every authentication guard for your application. + | Of course, a great default configuration has been defined for you + | here which uses session storage and the Eloquent user provider. + | + | All authentication drivers have a user provider. This defines how the + | users are actually retrieved out of your database or other storage + | mechanisms used by this application to persist your user's data. + | + | Supported: "session" + | + */ + + 'guards' => [ + 'web' => [ + 'driver' => 'session', + 'provider' => 'users', + ], + ], + + /* + |-------------------------------------------------------------------------- + | User Providers + |-------------------------------------------------------------------------- + | + | All authentication drivers have a user provider. This defines how the + | users are actually retrieved out of your database or other storage + | mechanisms used by this application to persist your user's data. + | + | If you have multiple user tables or models you may configure multiple + | sources which represent each model / table. These sources may then + | be assigned to any extra authentication guards you have defined. + | + | Supported: "database", "eloquent" + | + */ + + 'providers' => [ + 'users' => [ + 'driver' => 'eloquent', + 'model' => App\Models\User::class, + ], + + // 'users' => [ + // 'driver' => 'database', + // 'table' => 'users', + // ], + ], + + /* + |-------------------------------------------------------------------------- + | Resetting Passwords + |-------------------------------------------------------------------------- + | + | You may specify multiple password reset configurations if you have more + | than one user table or model in the application and you want to have + | separate password reset settings based on the specific user types. + | + | The expire time is the number of minutes that each reset token will be + | considered valid. This security feature keeps tokens short-lived so + | they have less time to be guessed. You may change this as needed. + | + */ + + 'passwords' => [ + 'users' => [ + 'provider' => 'users', + 'table' => 'password_resets', + 'expire' => 60, + 'throttle' => 60, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Password Confirmation Timeout + |-------------------------------------------------------------------------- + | + | Here you may define the amount of seconds before a password confirmation + | times out and the user is prompted to re-enter their password via the + | confirmation screen. By default, the timeout lasts for three hours. + | + */ + + 'password_timeout' => 10800, + +]; diff --git a/config/broadcasting.php b/config/broadcasting.php new file mode 100644 index 0000000..dca0e6b --- /dev/null +++ b/config/broadcasting.php @@ -0,0 +1,70 @@ + env('BROADCAST_DRIVER', 'null'), + + /* + |-------------------------------------------------------------------------- + | Broadcast Connections + |-------------------------------------------------------------------------- + | + | Here you may define all of the broadcast connections that will be used + | to broadcast events to other systems or over websockets. Samples of + | each available type of connection are provided inside this array. + | + */ + + 'connections' => [ + + 'pusher' => [ + 'driver' => 'pusher', + 'key' => env('PUSHER_APP_KEY', 'app-key'), + 'secret' => env('PUSHER_APP_SECRET', 'app-secret'), + 'app_id' => env('PUSHER_APP_ID', 'app-id'), + 'options' => [ + 'host' => env('PUSHER_HOST', 'soketi'), + 'port' => env('PUSHER_PORT', 6001), + 'scheme' => env('PUSHER_SCHEME', 'http'), + 'encrypted' => true, + 'useTLS' => env('PUSHER_SCHEME') === 'https', + ], + 'client_options' => [ + // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html + ], + ], + + 'ably' => [ + 'driver' => 'ably', + 'key' => env('ABLY_KEY'), + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + ], + + 'log' => [ + 'driver' => 'log', + ], + + 'null' => [ + 'driver' => 'null', + ], + + ], + +]; diff --git a/config/cache.php b/config/cache.php new file mode 100644 index 0000000..985b381 --- /dev/null +++ b/config/cache.php @@ -0,0 +1,110 @@ + 'redis', + + /* + |-------------------------------------------------------------------------- + | Cache Stores + |-------------------------------------------------------------------------- + | + | Here you may define all of the cache "stores" for your application as + | well as their drivers. You may even define multiple stores for the + | same cache driver to group types of items stored in your caches. + | + | Supported drivers: "apc", "array", "database", "file", + | "memcached", "redis", "dynamodb", "octane", "null" + | + */ + + 'stores' => [ + + 'apc' => [ + 'driver' => 'apc', + ], + + 'array' => [ + 'driver' => 'array', + 'serialize' => false, + ], + + 'database' => [ + 'driver' => 'database', + 'table' => 'cache', + 'connection' => null, + 'lock_connection' => null, + ], + + 'file' => [ + 'driver' => 'file', + 'path' => storage_path('framework/cache/data'), + ], + + 'memcached' => [ + 'driver' => 'memcached', + 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), + 'sasl' => [ + env('MEMCACHED_USERNAME'), + env('MEMCACHED_PASSWORD'), + ], + 'options' => [ + // Memcached::OPT_CONNECT_TIMEOUT => 2000, + ], + 'servers' => [ + [ + 'host' => env('MEMCACHED_HOST', '127.0.0.1'), + 'port' => env('MEMCACHED_PORT', 11211), + 'weight' => 100, + ], + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'cache', + 'lock_connection' => 'default', + ], + + 'dynamodb' => [ + 'driver' => 'dynamodb', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), + 'endpoint' => env('DYNAMODB_ENDPOINT'), + ], + + 'octane' => [ + 'driver' => 'octane', + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Cache Key Prefix + |-------------------------------------------------------------------------- + | + | When utilizing a RAM based store such as APC or Memcached, there might + | be other applications utilizing the same cache. So, we'll specify a + | value to get prefixed to all our keys so we can avoid collisions. + | + */ + + 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'), + +]; diff --git a/config/ciphersweet.php b/config/ciphersweet.php new file mode 100644 index 0000000..ac5972f --- /dev/null +++ b/config/ciphersweet.php @@ -0,0 +1,21 @@ + env('CIPHERSWEET_KEY'), + + /* + * You may specify which encryption algorithm has to be used + * to encrypt all attributes. + * + * Supported: "modern", "fips" + */ + 'crypto' => env('CIPHERSWEET_CRYPTO', 'modern'), + +]; \ No newline at end of file diff --git a/config/cors.php b/config/cors.php new file mode 100644 index 0000000..558369d --- /dev/null +++ b/config/cors.php @@ -0,0 +1,34 @@ + ['api/*'], + + 'allowed_methods' => ['*'], + + 'allowed_origins' => ['*'], + + 'allowed_origins_patterns' => [], + + 'allowed_headers' => ['*'], + + 'exposed_headers' => [], + + 'max_age' => 0, + + 'supports_credentials' => false, + +]; diff --git a/config/database.php b/config/database.php new file mode 100644 index 0000000..0faebae --- /dev/null +++ b/config/database.php @@ -0,0 +1,147 @@ + env('DB_CONNECTION', 'mysql'), + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | Here are each of the database connections setup for your application. + | Of course, examples of configuring each database platform that is + | supported by Laravel is shown below to make development simple. + | + | + | All database work in Laravel is done through the PHP PDO facilities + | so make sure you have the driver for your particular database of + | choice installed on your machine before you begin development. + | + */ + + 'connections' => [ + + 'sqlite' => [ + 'driver' => 'sqlite', + 'url' => env('DATABASE_URL'), + 'database' => env('DB_DATABASE', database_path('database.sqlite')), + 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => 'utf8mb4', + 'collation' => 'utf8mb4_unicode_ci', + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => 'utf8', + 'prefix' => '', + 'prefix_indexes' => true, + 'search_path' => 'public', + 'sslmode' => 'prefer', + ], + + 'sqlsrv' => [ + 'driver' => 'sqlsrv', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '1433'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => 'utf8', + 'prefix' => '', + 'prefix_indexes' => true, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Migration Repository Table + |-------------------------------------------------------------------------- + | + | This table keeps track of all the migrations that have already run for + | your application. Using this information, we can determine which of + | the migrations on disk haven't actually been run in the database. + | + */ + + 'migrations' => 'migrations', + + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store that also + | provides a richer body of commands than a typical key-value system + | such as APC or Memcached. Laravel makes it easy to dig right in. + | + */ + + 'redis' => [ + + 'client' => env('REDIS_CLIENT', 'phpredis'), + + 'options' => [ + 'cluster' => env('REDIS_CLUSTER', 'redis'), + 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), + ], + + 'default' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_DB', '0'), + ], + + 'cache' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_CACHE_DB', '1'), + ], + + ], + +]; diff --git a/config/disposable-email.php b/config/disposable-email.php new file mode 100644 index 0000000..3537d7f --- /dev/null +++ b/config/disposable-email.php @@ -0,0 +1,70 @@ + 'https://cdn.jsdelivr.net/gh/disposable/disposable-email-domains@master/domains.json', + + /* + |-------------------------------------------------------------------------- + | Fetch class + |-------------------------------------------------------------------------- + | + | The class responsible for fetching the contents of the source url. + | The default implementation makes use of file_get_contents and + | json_decode and will probably suffice for most applications. + | + | If your application has different needs (e.g. behind a proxy) then you + | can define a custom fetch class here that carries out the fetching. + | Your custom class should implement the Fetcher contract. + | + */ + + 'fetcher' => \Propaganistas\LaravelDisposableEmail\Fetcher\DefaultFetcher::class, + + /* + |-------------------------------------------------------------------------- + | Storage Path + |-------------------------------------------------------------------------- + | + | The location where the retrieved domains list should be stored locally. + | The path should be accessible and writable by the web server. A good + | place for storing the list is in the framework's own storage path. + | + */ + + 'storage' => storage_path('framework/disposable_domains.json'), + + /* + |-------------------------------------------------------------------------- + | Cache Configuration + |-------------------------------------------------------------------------- + | + | Here you may define whether the disposable domains list should be cached. + | If you disable caching or when the cache is empty, the list will be + | fetched from local storage instead. + | + | You can optionally specify an alternate cache connection or modify the + | cache key as desired. + | + */ + + 'cache' => [ + 'enabled' => true, + 'store' => 'default', + 'key' => 'disposable_email.domains', + ], + +]; diff --git a/config/filesystems.php b/config/filesystems.php new file mode 100644 index 0000000..9f851de --- /dev/null +++ b/config/filesystems.php @@ -0,0 +1,86 @@ + env('FILESYSTEM_DISK', 'local'), + + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Here you may configure as many filesystem "disks" as you wish, and you + | may even configure multiple disks of the same driver. Defaults have + | been setup for each driver as an example of the required options. + | + | Supported Drivers: "local", "ftp", "sftp", "s3" + | + */ + + 'disks' => [ + + 'local' => [ + 'driver' => 'local', + 'root' => storage_path('app'), + ], + + 'resources' => [ + 'driver' => 'local', + 'root' => resource_path(), + ], + + 'public' => [ + 'driver' => 'local', + 'root' => storage_path('app/public'), + 'url' => env('APP_URL').'/storage', + 'visibility' => 'public', + ], + + 'content' => [ + 'driver' => 'local', + 'root' => storage_path('app/content'), + 'url' => env('APP_URL').'/content', + 'visibility' => 'public', + ], + + 's3' => [ + 'driver' => 's3', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION'), + 'bucket' => env('AWS_BUCKET'), + 'url' => env('AWS_URL'), + 'endpoint' => env('AWS_ENDPOINT'), + 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Symbolic Links + |-------------------------------------------------------------------------- + | + | Here you may configure the symbolic links that will be created when the + | `storage:link` Artisan command is executed. The array keys should be + | the locations of the links and the values should be their targets. + | + */ + + 'links' => [ + public_path('storage') => storage_path('app/public'), + public_path('content') => storage_path('app/content') + ], + +]; diff --git a/config/fortify.php b/config/fortify.php new file mode 100644 index 0000000..7bd766b --- /dev/null +++ b/config/fortify.php @@ -0,0 +1,143 @@ + 'web', + + /* + |-------------------------------------------------------------------------- + | Fortify Password Broker + |-------------------------------------------------------------------------- + | + | Here you may specify which password broker Fortify can use when a user + | is resetting their password. This configured value should match one + | of your password brokers setup in your "auth" configuration file. + | + */ + + 'passwords' => 'users', + + /* + |-------------------------------------------------------------------------- + | Username / Email + |-------------------------------------------------------------------------- + | + | This value defines which model attribute should be considered as your + | application's "username" field. Typically, this might be the email + | address of the users but you are free to change this value here. + | + | Out of the box, Fortify expects forgot password and reset password + | requests to have a field named 'email'. If the application uses + | another name for the field you may define it below as needed. + | + */ + + 'username' => 'username', + + 'email' => 'email', + + /* + |-------------------------------------------------------------------------- + | Home Path + |-------------------------------------------------------------------------- + | + | Here you may configure the path where users will get redirected during + | authentication or password reset when the operations are successful + | and the user is authenticated. You are free to change this value. + | + */ + + 'home' => RouteServiceProvider::HOME, + + /* + |-------------------------------------------------------------------------- + | Fortify Routes Prefix / Subdomain + |-------------------------------------------------------------------------- + | + | Here you may specify which prefix Fortify will assign to all the routes + | that it registers with the application. If necessary, you may change + | subdomain under which all of the Fortify routes will be available. + | + */ + + 'prefix' => '', + + 'domain' => null, + + /* + |-------------------------------------------------------------------------- + | Fortify Routes Middleware + |-------------------------------------------------------------------------- + | + | Here you may specify which middleware Fortify will assign to the routes + | that it registers with the application. If necessary, you may change + | these middleware but typically this provided default is preferred. + | + */ + + 'middleware' => ['web'], + + /* + |-------------------------------------------------------------------------- + | Rate Limiting + |-------------------------------------------------------------------------- + | + | By default, Fortify will throttle logins to five requests per minute for + | every email and IP address combination. However, if you would like to + | specify a custom rate limiter to call then you may specify it here. + | + */ + + 'limiters' => [ + 'login' => 'login', + 'two-factor' => 'two-factor', + ], + + /* + |-------------------------------------------------------------------------- + | Register View Routes + |-------------------------------------------------------------------------- + | + | Here you may specify if the routes returning views should be disabled as + | you may not need them when building your own application. This may be + | especially true if you're writing a custom single-page application. + | + */ + + 'views' => true, + + /* + |-------------------------------------------------------------------------- + | Features + |-------------------------------------------------------------------------- + | + | Some of the Fortify features are optional. You may disable the features + | by removing them from this array. You're free to only remove some of + | these features or you can even remove all of these if you need to. + | + */ + + 'features' => [ + Features::registration(), + Features::resetPasswords(), + Features::emailVerification(), + Features::twoFactorAuthentication([ + 'confirmPassword' => true, + ]), + ], + +]; diff --git a/config/hashing.php b/config/hashing.php new file mode 100644 index 0000000..3a75e20 --- /dev/null +++ b/config/hashing.php @@ -0,0 +1,52 @@ + 'argon2id', + + /* + |-------------------------------------------------------------------------- + | Bcrypt Options + |-------------------------------------------------------------------------- + | + | Here you may specify the configuration options that should be used when + | passwords are hashed using the Bcrypt algorithm. This will allow you + | to control the amount of time it takes to hash the given password. + | + */ + + 'bcrypt' => [ + 'rounds' => env('BCRYPT_ROUNDS', 10), + ], + + /* + |-------------------------------------------------------------------------- + | Argon Options + |-------------------------------------------------------------------------- + | + | Here you may specify the configuration options that should be used when + | passwords are hashed using the Argon algorithm. These will allow you + | to control the amount of time it takes to hash the given password. + | + */ + + 'argon' => [ + 'memory' => 65536, + 'threads' => 1, + 'time' => 4, + ], + +]; diff --git a/config/horizon.php b/config/horizon.php new file mode 100644 index 0000000..15e6b98 --- /dev/null +++ b/config/horizon.php @@ -0,0 +1,203 @@ + env('HORIZON_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | Horizon Path + |-------------------------------------------------------------------------- + | + | This is the URI path where Horizon will be accessible from. Feel free + | to change this path to anything you like. Note that the URI will not + | affect the paths of its internal API that aren't exposed to users. + | + */ + + 'path' => env('HORIZON_PATH', 'horizon'), + + /* + |-------------------------------------------------------------------------- + | Horizon Redis Connection + |-------------------------------------------------------------------------- + | + | This is the name of the Redis connection where Horizon will store the + | meta information required for it to function. It includes the list + | of supervisors, failed jobs, job metrics, and other information. + | + */ + + 'use' => 'default', + + /* + |-------------------------------------------------------------------------- + | Horizon Redis Prefix + |-------------------------------------------------------------------------- + | + | This prefix will be used when storing all Horizon data in Redis. You + | may modify the prefix when you are running multiple installations + | of Horizon on the same server so that they don't have problems. + | + */ + + 'prefix' => env( + 'HORIZON_PREFIX', + Str::slug(env('APP_NAME', 'laravel'), '_').'_horizon:' + ), + + /* + |-------------------------------------------------------------------------- + | Horizon Route Middleware + |-------------------------------------------------------------------------- + | + | These middleware will get attached onto each Horizon route, giving you + | the chance to add your own middleware to this list or change any of + | the existing middleware. Or, you can simply stick with this list. + | + */ + + 'middleware' => [ + 'web', + Authorize::class, + ToolGuard::class + ], + + /* + |-------------------------------------------------------------------------- + | Queue Wait Time Thresholds + |-------------------------------------------------------------------------- + | + | This option allows you to configure when the LongWaitDetected event + | will be fired. Every connection / queue combination may have its + | own, unique threshold (in seconds) before this event is fired. + | + */ + + 'waits' => [ + 'redis:default' => 60, + ], + + /* + |-------------------------------------------------------------------------- + | Job Trimming Times + |-------------------------------------------------------------------------- + | + | Here you can configure for how long (in minutes) you desire Horizon to + | persist the recent and failed jobs. Typically, recent jobs are kept + | for one hour while all failed jobs are stored for an entire week. + | + */ + + 'trim' => [ + 'recent' => 60, + 'pending' => 60, + 'completed' => 60, + 'recent_failed' => 10080, + 'failed' => 10080, + 'monitored' => 10080, + ], + + /* + |-------------------------------------------------------------------------- + | Metrics + |-------------------------------------------------------------------------- + | + | Here you can configure how many snapshots should be kept to display in + | the metrics graph. This will get used in combination with Horizon's + | `horizon:snapshot` schedule to define how long to retain metrics. + | + */ + + 'metrics' => [ + 'trim_snapshots' => [ + 'job' => 24, + 'queue' => 24, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Fast Termination + |-------------------------------------------------------------------------- + | + | When this option is enabled, Horizon's "terminate" command will not + | wait on all of the workers to terminate unless the --wait option + | is provided. Fast termination can shorten deployment delay by + | allowing a new instance of Horizon to start while the last + | instance will continue to terminate each of its workers. + | + */ + + 'fast_termination' => false, + + /* + |-------------------------------------------------------------------------- + | Memory Limit (MB) + |-------------------------------------------------------------------------- + | + | This value describes the maximum amount of memory the Horizon master + | supervisor may consume before it is terminated and restarted. For + | configuring these limits on your workers, see the next section. + | + */ + + 'memory_limit' => 64, + + /* + |-------------------------------------------------------------------------- + | Queue Worker Configuration + |-------------------------------------------------------------------------- + | + | Here you may define the queue worker settings used by your application + | in all environments. These supervisors and settings handle all your + | queued jobs and will be provisioned by Horizon during deployment. + | + */ + + 'defaults' => [ + 'supervisor-1' => [ + 'connection' => 'redis', + 'queue' => ['default'], + 'balance' => 'auto', + 'maxProcesses' => 1, + 'maxTime' => 0, + 'maxJobs' => 0, + 'memory' => 128, + 'tries' => 1, + 'timeout' => 60, + 'nice' => 0, + ], + ], + + 'environments' => [ + 'production' => [ + 'supervisor-1' => [ + 'maxProcesses' => 10, + 'balanceMaxShift' => 1, + 'balanceCooldown' => 3, + ], + ], + + 'local' => [ + 'supervisor-1' => [ + 'maxProcesses' => 3, + ], + ], + ], +]; diff --git a/config/livewire.php b/config/livewire.php new file mode 100644 index 0000000..59f8d5c --- /dev/null +++ b/config/livewire.php @@ -0,0 +1,158 @@ + 'App\\Http\\Livewire', + + /* + |-------------------------------------------------------------------------- + | View Path + |-------------------------------------------------------------------------- + | + | This value sets the path for Livewire component views. This affects + | file manipulation helper commands like `artisan make:livewire`. + | + */ + + 'view_path' => resource_path('views/livewire'), + + /* + |-------------------------------------------------------------------------- + | Layout + |-------------------------------------------------------------------------- + | The default layout view that will be used when rendering a component via + | Route::get('/some-endpoint', SomeComponent::class);. In this case the + | the view returned by SomeComponent will be wrapped in "layouts.app" + | + */ + + 'layout' => 'layouts.app', + + /* + |-------------------------------------------------------------------------- + | Livewire Assets URL + |-------------------------------------------------------------------------- + | + | This value sets the path to Livewire JavaScript assets, for cases where + | your app's domain root is not the correct path. By default, Livewire + | will load its JavaScript assets from the app's "relative root". + | + | Examples: "/assets", "myurl.com/app". + | + */ + + 'asset_url' => null, + + /* + |-------------------------------------------------------------------------- + | Livewire App URL + |-------------------------------------------------------------------------- + | + | This value should be used if livewire assets are served from CDN. + | Livewire will communicate with an app through this url. + | + | Examples: "https://my-app.com", "myurl.com/app". + | + */ + + 'app_url' => null, + + /* + |-------------------------------------------------------------------------- + | Livewire Endpoint Middleware Group + |-------------------------------------------------------------------------- + | + | This value sets the middleware group that will be applied to the main + | Livewire "message" endpoint (the endpoint that gets hit everytime + | a Livewire component updates). It is set to "web" by default. + | + */ + + 'middleware_group' => 'web', + + /* + |-------------------------------------------------------------------------- + | Livewire Temporary File Uploads Endpoint Configuration + |-------------------------------------------------------------------------- + | + | Livewire handles file uploads by storing uploads in a temporary directory + | before the file is validated and stored permanently. All file uploads + | are directed to a global endpoint for temporary storage. The config + | items below are used for customizing the way the endpoint works. + | + */ + + 'temporary_file_upload' => [ + 'disk' => null, // Example: 'local', 's3' Default: 'default' + 'rules' => null, // Example: ['file', 'mimes:png,jpg'] Default: ['required', 'file', 'max:12288'] (12MB) + 'directory' => null, // Example: 'tmp' Default 'livewire-tmp' + 'middleware' => null, // Example: 'throttle:5,1' Default: 'throttle:60,1' + 'preview_mimes' => [ // Supported file types for temporary pre-signed file URLs. + 'png', 'gif', 'bmp', 'svg', 'wav', 'mp4', + 'mov', 'avi', 'wmv', 'mp3', 'm4a', + 'jpg', 'jpeg', 'mpga', 'webp', 'wma', + ], + 'max_upload_time' => 5, // Max duration (in minutes) before an upload gets invalidated. + ], + + /* + |-------------------------------------------------------------------------- + | Manifest File Path + |-------------------------------------------------------------------------- + | + | This value sets the path to the Livewire manifest file. + | The default should work for most cases (which is + | "/bootstrap/cache/livewire-components.php"), but for specific + | cases like when hosting on Laravel Vapor, it could be set to a different value. + | + | Example: for Laravel Vapor, it would be "/tmp/storage/bootstrap/cache/livewire-components.php". + | + */ + + 'manifest_path' => null, + + /* + |-------------------------------------------------------------------------- + | Back Button Cache + |-------------------------------------------------------------------------- + | + | This value determines whether the back button cache will be used on pages + | that contain Livewire. By disabling back button cache, it ensures that + | the back button shows the correct state of components, instead of + | potentially stale, cached data. + | + | Setting it to "false" (default) will disable back button cache. + | + */ + + 'back_button_cache' => false, + + /* + |-------------------------------------------------------------------------- + | Render On Redirect + |-------------------------------------------------------------------------- + | + | This value determines whether Livewire will render before it's redirected + | or not. Setting it to "false" (default) will mean the render method is + | skipped when redirecting. And "true" will mean the render method is + | run before redirecting. Browsers bfcache can store a potentially + | stale view if render is skipped on redirect. + | + */ + + 'render_on_redirect' => false, + +]; diff --git a/config/logging.php b/config/logging.php new file mode 100644 index 0000000..fefe088 --- /dev/null +++ b/config/logging.php @@ -0,0 +1,119 @@ + env('LOG_CHANNEL', 'stack'), + + /* + |-------------------------------------------------------------------------- + | Deprecations Log Channel + |-------------------------------------------------------------------------- + | + | This option controls the log channel that should be used to log warnings + | regarding deprecated PHP and library features. This allows you to get + | your application ready for upcoming major versions of dependencies. + | + */ + + 'deprecations' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), + + /* + |-------------------------------------------------------------------------- + | Log Channels + |-------------------------------------------------------------------------- + | + | Here you may configure the log channels for your application. Out of + | the box, Laravel uses the Monolog PHP logging library. This gives + | you a variety of powerful log handlers / formatters to utilize. + | + | Available Drivers: "single", "daily", "slack", "syslog", + | "errorlog", "monolog", + | "custom", "stack" + | + */ + + 'channels' => [ + 'stack' => [ + 'driver' => 'stack', + 'channels' => ['single'], + 'ignore_exceptions' => false, + ], + + 'single' => [ + 'driver' => 'single', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + ], + + 'daily' => [ + 'driver' => 'daily', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + 'days' => 14, + ], + + 'slack' => [ + 'driver' => 'slack', + 'url' => env('LOG_SLACK_WEBHOOK_URL'), + 'username' => 'Laravel Log', + 'emoji' => ':boom:', + 'level' => env('LOG_LEVEL', 'critical'), + ], + + 'papertrail' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class), + 'handler_with' => [ + 'host' => env('PAPERTRAIL_URL'), + 'port' => env('PAPERTRAIL_PORT'), + 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), + ], + ], + + 'stderr' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => StreamHandler::class, + 'formatter' => env('LOG_STDERR_FORMATTER'), + 'with' => [ + 'stream' => 'php://stderr', + ], + ], + + 'syslog' => [ + 'driver' => 'syslog', + 'level' => env('LOG_LEVEL', 'debug'), + ], + + 'errorlog' => [ + 'driver' => 'errorlog', + 'level' => env('LOG_LEVEL', 'debug'), + ], + + 'null' => [ + 'driver' => 'monolog', + 'handler' => NullHandler::class, + ], + + 'emergency' => [ + 'path' => storage_path('logs/laravel.log'), + ], + ], + +]; diff --git a/config/mail.php b/config/mail.php new file mode 100644 index 0000000..87b6fe3 --- /dev/null +++ b/config/mail.php @@ -0,0 +1,117 @@ + env('MAIL_MAILER', 'smtp'), + + /* + |-------------------------------------------------------------------------- + | Mailer Configurations + |-------------------------------------------------------------------------- + | + | Here you may configure all of the mailers used by your application plus + | their respective settings. Several examples have been configured for + | you and you are free to add your own as your application requires. + | + | Laravel supports a variety of mail "transport" drivers to be used while + | sending an e-mail. You will specify which one you are using for your + | mailers below. You are free to add additional mailers as required. + | + | Supported: "smtp", "sendmail", "mailgun", "ses", + | "postmark", "log", "array", "failover" + | + */ + + 'mailers' => [ + 'smtp' => [ + 'transport' => 'smtp', + 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), + 'port' => env('MAIL_PORT', 587), + 'encryption' => env('MAIL_ENCRYPTION', 'tls'), + 'username' => env('MAIL_USERNAME'), + 'password' => env('MAIL_PASSWORD'), + 'timeout' => null, + ], + + 'ses' => [ + 'transport' => 'ses', + ], + + 'mailgun' => [ + 'transport' => 'mailgun', + ], + + 'postmark' => [ + 'transport' => 'postmark', + ], + + 'sendmail' => [ + 'transport' => 'sendmail', + 'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -t -i'), + ], + + 'log' => [ + 'transport' => 'log', + 'channel' => env('MAIL_LOG_CHANNEL'), + ], + + 'array' => [ + 'transport' => 'array', + ], + + 'failover' => [ + 'transport' => 'failover', + 'mailers' => [ + 'smtp', + 'log', + ], + ], + ], + + /* + |-------------------------------------------------------------------------- + | Global "From" Address + |-------------------------------------------------------------------------- + | + | You may wish for all e-mails sent by your application to be sent from + | the same address. Here, you may specify a name and address that is + | used globally for all e-mails that are sent by your application. + | + */ + + 'from' => [ + 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), + 'name' => env('MAIL_FROM_NAME', 'Example'), + ], + + /* + |-------------------------------------------------------------------------- + | Markdown Mail Settings + |-------------------------------------------------------------------------- + | + | If you are using Markdown based email rendering, you may configure your + | theme and component paths here, allowing you to customize the design + | of the emails. Or, you may simply stick with the Laravel defaults! + | + */ + + 'markdown' => [ + 'theme' => 'default', + + 'paths' => [ + resource_path('views/vendor/mail'), + ], + ], + +]; diff --git a/config/octane.php b/config/octane.php new file mode 100644 index 0000000..4a957a1 --- /dev/null +++ b/config/octane.php @@ -0,0 +1,221 @@ + env('OCTANE_SERVER', 'roadrunner'), + + /* + |-------------------------------------------------------------------------- + | Force HTTPS + |-------------------------------------------------------------------------- + | + | When this configuration value is set to "true", Octane will inform the + | framework that all absolute links must be generated using the HTTPS + | protocol. Otherwise your links may be generated using plain HTTP. + | + */ + + 'https' => env('OCTANE_HTTPS', false), + + /* + |-------------------------------------------------------------------------- + | Octane Listeners + |-------------------------------------------------------------------------- + | + | All of the event listeners for Octane's events are defined below. These + | listeners are responsible for resetting your application's state for + | the next request. You may even add your own listeners to the list. + | + */ + + 'listeners' => [ + WorkerStarting::class => [ + EnsureUploadedFilesAreValid::class, + EnsureUploadedFilesCanBeMoved::class, + ], + + RequestReceived::class => [ + ...Octane::prepareApplicationForNextOperation(), + ...Octane::prepareApplicationForNextRequest(), + // + ], + + RequestHandled::class => [ + // + ], + + RequestTerminated::class => [ + // FlushUploadedFiles::class, + ], + + TaskReceived::class => [ + ...Octane::prepareApplicationForNextOperation(), + // + ], + + TaskTerminated::class => [ + // + ], + + TickReceived::class => [ + ...Octane::prepareApplicationForNextOperation(), + // + ], + + TickTerminated::class => [ + // + ], + + OperationTerminated::class => [ + FlushTemporaryContainerInstances::class, + // DisconnectFromDatabases::class, + // CollectGarbage::class, + ], + + WorkerErrorOccurred::class => [ + ReportException::class, + StopWorkerIfNecessary::class, + ], + + WorkerStopping::class => [ + // + ], + ], + + /* + |-------------------------------------------------------------------------- + | Warm / Flush Bindings + |-------------------------------------------------------------------------- + | + | The bindings listed below will either be pre-warmed when a worker boots + | or they will be flushed before every new request. Flushing a binding + | will force the container to resolve that binding again when asked. + | + */ + + 'warm' => [ + ...Octane::defaultServicesToWarm(), + ], + + 'flush' => [ + \Barryvdh\Debugbar\LaravelDebugbar::class, + ], + + /* + |-------------------------------------------------------------------------- + | Octane Cache Table + |-------------------------------------------------------------------------- + | + | While using Swoole, you may leverage the Octane cache, which is powered + | by a Swoole table. You may set the maximum number of rows as well as + | the number of bytes per row using the configuration options below. + | + */ + + 'cache' => [ + 'rows' => 1000, + 'bytes' => 10000, + ], + + /* + |-------------------------------------------------------------------------- + | Octane Swoole Tables + |-------------------------------------------------------------------------- + | + | While using Swoole, you may define additional tables as required by the + | application. These tables can be used to store data that needs to be + | quickly accessed by other workers on the particular Swoole server. + | + */ + + 'tables' => [ + 'example:1000' => [ + 'name' => 'string:1000', + 'votes' => 'int', + ], + ], + + /* + |-------------------------------------------------------------------------- + | File Watching + |-------------------------------------------------------------------------- + | + | The following list of files and directories will be watched when using + | the --watch option offered by Octane. If any of the directories and + | files are changed, Octane will automatically reload your workers. + | + */ + + 'watch' => [ + 'app', + 'bootstrap', + 'config', + 'database', + 'public/**/*.php', + 'resources/**/*.php', + 'routes', + 'composer.lock', + '.env', + ], + + /* + |-------------------------------------------------------------------------- + | Garbage Collection Threshold + |-------------------------------------------------------------------------- + | + | When executing long-lived PHP scripts such as Octane, memory can build + | up before being cleared by PHP. You can force Octane to run garbage + | collection if your application consumes this amount of megabytes. + | + */ + + 'garbage' => 50, + + /* + |-------------------------------------------------------------------------- + | Maximum Execution Time + |-------------------------------------------------------------------------- + | + | The following setting configures the maximum execution time for requests + | being handled by Octane. You may set this value to 0 to indicate that + | there isn't a specific time limit on Octane request execution time. + | + */ + + 'max_execution_time' => 30, + +]; diff --git a/config/parsedown.php b/config/parsedown.php new file mode 100644 index 0000000..6ad6641 --- /dev/null +++ b/config/parsedown.php @@ -0,0 +1,38 @@ +` tags. + * + * @see https://github.com/erusev/parsedown/wiki/Usage + */ + 'breaks_enabled' => false, + + /** + * Tells the `parsedown()` helper and the `@parsedown` **Blade** directive if the user input should be inline parsed by default. + * + * @see https://github.com/erusev/parsedown/wiki/Usage + */ + 'inline' => false, + + /** + * Tells **Parsedown** if it should escape **HTML** in trusted input. This method isn't safe from XSS! + * + * @see https://github.com/erusev/parsedown#escaping-html + */ + 'markup_escaped' => false, + + /** + * Tells **Parsedown** if it needs to process untrusted user-input. + * + * @see https://github.com/erusev/parsedown#security + */ + 'safe_mode' => true, + + /** + * Tells **Parsedown** if it should automatically convert urls into anchor tags. + * + * @see https://github.com/erusev/parsedown/wiki/Usage + */ + 'urls_linked' => true, +]; \ No newline at end of file diff --git a/config/queue.php b/config/queue.php new file mode 100644 index 0000000..25ea5a8 --- /dev/null +++ b/config/queue.php @@ -0,0 +1,93 @@ + env('QUEUE_CONNECTION', 'sync'), + + /* + |-------------------------------------------------------------------------- + | Queue Connections + |-------------------------------------------------------------------------- + | + | Here you may configure the connection information for each server that + | is used by your application. A default configuration has been added + | for each back-end shipped with Laravel. You are free to add more. + | + | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | + */ + + 'connections' => [ + + 'sync' => [ + 'driver' => 'sync', + ], + + 'database' => [ + 'driver' => 'database', + 'table' => 'jobs', + 'queue' => 'default', + 'retry_after' => 90, + 'after_commit' => false, + ], + + 'beanstalkd' => [ + 'driver' => 'beanstalkd', + 'host' => 'localhost', + 'queue' => 'default', + 'retry_after' => 90, + 'block_for' => 0, + 'after_commit' => false, + ], + + 'sqs' => [ + 'driver' => 'sqs', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), + 'queue' => env('SQS_QUEUE', 'default'), + 'suffix' => env('SQS_SUFFIX'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'after_commit' => false, + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + 'queue' => env('REDIS_QUEUE', 'default'), + 'retry_after' => 90, + 'block_for' => null, + 'after_commit' => false, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Failed Queue Jobs + |-------------------------------------------------------------------------- + | + | These options configure the behavior of failed queue job logging so you + | can control which database and table are used to store the jobs that + | have failed. You may change them to any database / table you wish. + | + */ + + 'failed' => [ + 'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'), + 'database' => env('DB_CONNECTION', 'mysql'), + 'table' => 'failed_jobs', + ], + +]; diff --git a/config/recaptcha.php b/config/recaptcha.php new file mode 100644 index 0000000..2e131dc --- /dev/null +++ b/config/recaptcha.php @@ -0,0 +1,179 @@ + env('RECAPTCHA_SITE_KEY', ''), + + /** + * + * The secret key + * get secret key @ www.google.com/recaptcha/admin + * + */ + 'api_secret_key' => env('RECAPTCHA_SECRET_KEY', ''), + + /** + * + * ReCATCHA version + * Supported: "v2", "invisible", "v3", + * + * get more info @ https://developers.google.com/recaptcha/docs/versions + * + */ + 'version' => 'invisible', + + /** + * + * The curl timout in seconds to validate a recaptcha token + * @since v3.5.0 + * + */ + 'curl_timeout' => 10, + + /** + * + * IP addresses for which validation will be skipped + * IP/CIDR netmask eg. 127.0.0.0/24, also 127.0.0.1 is accepted and /32 assumed + * + */ + 'skip_ip' => env('RECAPTCHA_SKIP_IP', []), + + /** + * + * Default route called to check the Google reCAPTCHA token + * @since v3.2.0 + * + */ + 'default_validation_route' => 'biscolab-recaptcha/validate', + + /** + * + * The name of the parameter used to send Google reCAPTCHA token to verify route + * @since v3.2.0 + * + */ + 'default_token_parameter_name' => 'token', + + /** + * + * The default Google reCAPTCHA language code + * It has no effect with v3 + * @see https://developers.google.com/recaptcha/docs/language + * @since v3.6.0 + * + */ + 'default_language' => null, + + /** + * + * The default form ID. Only for "invisible" reCAPTCHA + * @since v4.0.0 + * + */ + 'default_form_id' => 'biscolab-recaptcha-invisible-form', + + /** + * + * Deferring the render can be achieved by specifying your onload callback function and adding parameters to the JavaScript resource. + * It has no effect with v3 and invisible + * @see https://developers.google.com/recaptcha/docs/display#explicit_render + * @since v4.0.0 + * Supported true, false + * + */ + 'explicit' => false, + + /** + * + * Set API domain. You can use "www.recaptcha.net" in case "www.google.com" is not accessible. + * (no check will be made on the entered value) + * @see https://developers.google.com/recaptcha/docs/faq#can-i-use-recaptcha-globally + * @since v4.3.0 + * Default 'www.google.com' (ReCaptchaBuilder::DEFAULT_RECAPTCHA_API_DOMAIN) + * + */ + 'api_domain' => 'www.google.com', + + /** + * + * Set `true` when the error message must be null + * @since v5.1.0 + * Default false + * + */ + 'empty_message' => false, + + /** + * + * Set either the error message or the errom message translation key + * @since v5.1.0 + * Default 'validation.recaptcha' + * + */ + 'error_message_key' => 'validation.recaptcha', + + /** + * + * g-recaptcha tag attributes and grecaptcha.render parameters (v2 only) + * @see https://developers.google.com/recaptcha/docs/display#render_param + * @since v4.0.0 + */ + 'tag_attributes' => [ + + /** + * The color theme of the widget. + * Supported "light", "dark" + */ + 'theme' => 'light', + + /** + * The size of the widget. + * Supported "normal", "compact" + */ + 'size' => 'normal', + + /** + * The tabindex of the widget and challenge. + * If other elements in your page use tabindex, it should be set to make user navigation easier. + */ + 'tabindex' => 0, + + /** + * The name of your callback function, executed when the user submits a successful response. + * The g-recaptcha-response token is passed to your callback. + * DO NOT SET "biscolabOnloadCallback" + */ + 'callback' => null, + + /** + * The name of your callback function, executed when the reCAPTCHA response expires and the user needs to re-verify. + * DO NOT SET "biscolabOnloadCallback" + */ + 'expired-callback' => null, + + /** + * The name of your callback function, executed when reCAPTCHA encounters an error (usually network connectivity) and cannot continue until connectivity is restored. + * If you specify a function here, you are responsible for informing the user that they should retry. + * DO NOT SET "biscolabOnloadCallback" + */ + 'error-callback' => null, + ] +]; diff --git a/config/scout.php b/config/scout.php new file mode 100644 index 0000000..5c8b7d2 --- /dev/null +++ b/config/scout.php @@ -0,0 +1,137 @@ + env('SCOUT_DRIVER', 'algolia'), + + /* + |-------------------------------------------------------------------------- + | Index Prefix + |-------------------------------------------------------------------------- + | + | Here you may specify a prefix that will be applied to all search index + | names used by Scout. This prefix may be useful if you have multiple + | "tenants" or applications sharing the same search infrastructure. + | + */ + + 'prefix' => env('SCOUT_PREFIX', ''), + + /* + |-------------------------------------------------------------------------- + | Queue Data Syncing + |-------------------------------------------------------------------------- + | + | This option allows you to control if the operations that sync your data + | with your search engines are queued. When this is set to "true" then + | all automatic data syncing will get queued for better performance. + | + */ + + 'queue' => env('SCOUT_QUEUE', false), + + /* + |-------------------------------------------------------------------------- + | Database Transactions + |-------------------------------------------------------------------------- + | + | This configuration option determines if your data will only be synced + | with your search indexes after every open database transaction has + | been committed, thus preventing any discarded data from syncing. + | + */ + + 'after_commit' => false, + + /* + |-------------------------------------------------------------------------- + | Chunk Sizes + |-------------------------------------------------------------------------- + | + | These options allow you to control the maximum chunk size when you are + | mass importing data into the search engine. This allows you to fine + | tune each of these chunk sizes based on the power of the servers. + | + */ + + 'chunk' => [ + 'searchable' => 500, + 'unsearchable' => 500, + ], + + /* + |-------------------------------------------------------------------------- + | Soft Deletes + |-------------------------------------------------------------------------- + | + | This option allows to control whether to keep soft deleted records in + | the search indexes. Maintaining soft deleted records can be useful + | if your application still needs to search for the records later. + | + */ + + 'soft_delete' => false, + + /* + |-------------------------------------------------------------------------- + | Identify User + |-------------------------------------------------------------------------- + | + | This option allows you to control whether to notify the search engine + | of the user performing the search. This is sometimes useful if the + | engine supports any analytics based on this application's users. + | + | Supported engines: "algolia" + | + */ + + 'identify' => env('SCOUT_IDENTIFY', false), + + /* + |-------------------------------------------------------------------------- + | Algolia Configuration + |-------------------------------------------------------------------------- + | + | Here you may configure your Algolia settings. Algolia is a cloud hosted + | search engine which works great with Scout out of the box. Just plug + | in your application ID and admin API key to get started searching. + | + */ + + 'algolia' => [ + 'id' => env('ALGOLIA_APP_ID', ''), + 'secret' => env('ALGOLIA_SECRET', ''), + ], + + /* + |-------------------------------------------------------------------------- + | MeiliSearch Configuration + |-------------------------------------------------------------------------- + | + | Here you may configure your MeiliSearch settings. MeiliSearch is an open + | source search engine with minimal configuration. Below, you can state + | the host and key information for your own MeiliSearch installation. + | + | See: https://docs.meilisearch.com/guides/advanced_guides/configuration.html + | + */ + + 'meilisearch' => [ + 'host' => env('MEILISEARCH_HOST', 'http://localhost:7700'), + 'key' => env('MEILISEARCH_KEY', null), + ], + +]; diff --git a/config/services.php b/config/services.php new file mode 100644 index 0000000..c06b79a --- /dev/null +++ b/config/services.php @@ -0,0 +1,39 @@ + [ + 'domain' => env('MAILGUN_DOMAIN'), + 'secret' => env('MAILGUN_SECRET'), + 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), + ], + + 'postmark' => [ + 'token' => env('POSTMARK_TOKEN'), + ], + + 'ses' => [ + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + ], + + 'discord' => [ + 'client_id' => env('DISCORD_CLIENT_ID'), + 'client_secret' => env('DISCORD_CLIENT_SECRET'), + 'redirect' => '/my/discord/callback', + ], + +]; diff --git a/config/session.php b/config/session.php new file mode 100644 index 0000000..8fed97c --- /dev/null +++ b/config/session.php @@ -0,0 +1,201 @@ + env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => env('SESSION_CONNECTION'), + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | While using one of the framework's cache driven session backends you may + | list a cache store that should be used for these sessions. This value + | must match with one of the application's configured cache "stores". + | + | Affects: "apc", "dynamodb", "memcached", "redis" + | + */ + + 'store' => env('SESSION_STORE'), + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ + + 'cookie' => env( + 'SESSION_COOKIE', + Str::slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN'), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you when it can't be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE'), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | will set this value to "lax" since this is a secure default value. + | + | Supported: "lax", "strict", "none", null + | + */ + + 'same_site' => 'lax', + +]; diff --git a/config/tadah.php b/config/tadah.php new file mode 100644 index 0000000..c3fda54 --- /dev/null +++ b/config/tadah.php @@ -0,0 +1,17 @@ + (bool) env('USERS_CREATE_INVITE_KEYS', true), + 'user_invite_key_cost' => 100, + 'user_maximum_keys_in_window' => 2, // for ex. 2 keys every x days + 'user_invite_key_cooldown' => 7, // in days + + 'invite_keys_required' => (bool)env('REQUIRE_INVITE_KEYS', false), + 'currency_name' => Str::plural('Token'), + 'currency_name_singular' => 'Token', + 'discord_required' => (bool)env('USERS_DISCORD_REQUIRED', true), + 'username_change_cost' => 0, +]; diff --git a/config/telescope.php b/config/telescope.php new file mode 100644 index 0000000..629c070 --- /dev/null +++ b/config/telescope.php @@ -0,0 +1,176 @@ + env('TELESCOPE_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | Telescope Path + |-------------------------------------------------------------------------- + | + | This is the URI path where Telescope will be accessible from. Feel free + | to change this path to anything you like. Note that the URI will not + | affect the paths of its internal API that aren't exposed to users. + | + */ + + 'path' => env('TELESCOPE_PATH', 'telescope'), + + /* + |-------------------------------------------------------------------------- + | Telescope Storage Driver + |-------------------------------------------------------------------------- + | + | This configuration options determines the storage driver that will + | be used to store Telescope's data. In addition, you may set any + | custom options as needed by the particular driver you choose. + | + */ + + 'driver' => env('TELESCOPE_DRIVER', 'database'), + + 'storage' => [ + 'database' => [ + 'connection' => env('DB_CONNECTION', 'mysql'), + 'chunk' => 1000, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Telescope Master Switch + |-------------------------------------------------------------------------- + | + | This option may be used to disable all Telescope watchers regardless + | of their individual configuration, which simply provides a single + | and convenient way to enable or disable Telescope data storage. + | + */ + + 'enabled' => env('TELESCOPE_ENABLED', true), + + /* + |-------------------------------------------------------------------------- + | Telescope Route Middleware + |-------------------------------------------------------------------------- + | + | These middleware will be assigned to every Telescope route, giving you + | the chance to add your own middleware to this list or change any of + | the existing middleware. Or, you can simply stick with this list. + | + */ + + 'middleware' => [ + 'web', + Authorize::class, + ToolGuard::class, + ], + + /* + |-------------------------------------------------------------------------- + | Allowed / Ignored Paths & Commands + |-------------------------------------------------------------------------- + | + | The following array lists the URI paths and Artisan commands that will + | not be watched by Telescope. In addition to this list, some Laravel + | commands, like migrations and queue commands, are always ignored. + | + */ + + 'only_paths' => [ + // 'api/*' + ], + + 'ignore_paths' => [ + 'nova-api*', + ], + + 'ignore_commands' => [ + // + ], + + /* + |-------------------------------------------------------------------------- + | Telescope Watchers + |-------------------------------------------------------------------------- + | + | The following array lists the "watchers" that will be registered with + | Telescope. The watchers gather the application's profile data when + | a request or task is executed. Feel free to customize this list. + | + */ + + 'watchers' => [ + Watchers\BatchWatcher::class => env('TELESCOPE_BATCH_WATCHER', true), + Watchers\CacheWatcher::class => env('TELESCOPE_CACHE_WATCHER', true), + Watchers\ClientRequestWatcher::class => env('TELESCOPE_CLIENT_REQUEST_WATCHER', true), + + Watchers\CommandWatcher::class => [ + 'enabled' => env('TELESCOPE_COMMAND_WATCHER', true), + 'ignore' => [], + ], + + Watchers\DumpWatcher::class => [ + 'enabled' => env('TELESCOPE_DUMP_WATCHER', true), + 'always' => env('TELESCOPE_DUMP_WATCHER_ALWAYS', false), + ], + + Watchers\EventWatcher::class => [ + 'enabled' => env('TELESCOPE_EVENT_WATCHER', true), + 'ignore' => [], + ], + + Watchers\ExceptionWatcher::class => env('TELESCOPE_EXCEPTION_WATCHER', true), + + Watchers\GateWatcher::class => [ + 'enabled' => env('TELESCOPE_GATE_WATCHER', true), + 'ignore_abilities' => [], + 'ignore_packages' => true, + ], + + Watchers\JobWatcher::class => env('TELESCOPE_JOB_WATCHER', true), + Watchers\LogWatcher::class => env('TELESCOPE_LOG_WATCHER', true), + Watchers\MailWatcher::class => env('TELESCOPE_MAIL_WATCHER', true), + + Watchers\ModelWatcher::class => [ + 'enabled' => env('TELESCOPE_MODEL_WATCHER', true), + 'events' => ['eloquent.*'], + 'hydrations' => true, + ], + + Watchers\NotificationWatcher::class => env('TELESCOPE_NOTIFICATION_WATCHER', true), + + Watchers\QueryWatcher::class => [ + 'enabled' => env('TELESCOPE_QUERY_WATCHER', true), + 'ignore_packages' => true, + 'slow' => 100, + ], + + Watchers\RedisWatcher::class => env('TELESCOPE_REDIS_WATCHER', true), + + Watchers\RequestWatcher::class => [ + 'enabled' => env('TELESCOPE_REQUEST_WATCHER', true), + 'size_limit' => env('TELESCOPE_RESPONSE_SIZE_LIMIT', 64), + 'ignore_status_codes' => [], + ], + + Watchers\ScheduleWatcher::class => env('TELESCOPE_SCHEDULE_WATCHER', true), + Watchers\ViewWatcher::class => env('TELESCOPE_VIEW_WATCHER', true), + ], +]; diff --git a/config/view.php b/config/view.php new file mode 100644 index 0000000..22b8a18 --- /dev/null +++ b/config/view.php @@ -0,0 +1,36 @@ + [ + resource_path('views'), + ], + + /* + |-------------------------------------------------------------------------- + | Compiled View Path + |-------------------------------------------------------------------------- + | + | This option determines where all the compiled Blade templates will be + | stored for your application. Typically, this is within the storage + | directory. However, as usual, you are free to change this value. + | + */ + + 'compiled' => env( + 'VIEW_COMPILED_PATH', + realpath(storage_path('framework/views')) + ), + +]; diff --git a/database/.gitignore b/database/.gitignore new file mode 100644 index 0000000..9b19b93 --- /dev/null +++ b/database/.gitignore @@ -0,0 +1 @@ +*.sqlite* diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php new file mode 100644 index 0000000..0507a01 --- /dev/null +++ b/database/factories/UserFactory.php @@ -0,0 +1,31 @@ + + */ +class UserFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition() + { + return [ + 'username' => $this->faker->userName(), + 'email' => $this->faker->unique()->safeEmail(), + 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', + 'last_ip_address' => '127.0.0.1', + 'register_ip_address' => '127.0.0.1', + 'activity' => User::defaultActivity(), + 'permissions' => User::defaultPermissions() + ]; + } +} diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php new file mode 100644 index 0000000..5ec2fa9 --- /dev/null +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -0,0 +1,52 @@ +id(); + $table->string('username', 20)->unique(); + $table->packed('past_usernames')->nullable(); + $table->string('blurb', 1000)->default(''); + $table->text('email')->nullable(); + $table->tinyText('email_index')->nullable(); + $table->timestamp('email_verified_at')->nullable(); + $table->string('password'); + $table->text('last_ip_address')->nullable(); + $table->tinyText('last_ip_address_index')->nullable(); + $table->text('register_ip_address')->nullable(); + $table->tinyText('register_ip_address_index')->nullable(); + $table->bigInteger('current_ban_id')->nullable(); + $table->packed('activity'); + $table->packed('permissions'); + $table->boolean('superadmin')->default(false); + $table->text('discord_id')->nullable(); + $table->tinyText('discord_id_index')->nullable(); + $table->timestamp('discord_linked_at')->nullable(); + $table->boolean('two_factor_confirmed')->after('two_factor_recovery_codes')->default(false); + $table->bigInteger('current_status_id')->nullable(); + $table->rememberToken(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('users'); + } +}; diff --git a/database/migrations/2014_10_12_100000_create_password_resets_table.php b/database/migrations/2014_10_12_100000_create_password_resets_table.php new file mode 100644 index 0000000..fcacb80 --- /dev/null +++ b/database/migrations/2014_10_12_100000_create_password_resets_table.php @@ -0,0 +1,32 @@ +string('email')->index(); + $table->string('token'); + $table->timestamp('created_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('password_resets'); + } +}; diff --git a/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php b/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php new file mode 100644 index 0000000..d2237fc --- /dev/null +++ b/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php @@ -0,0 +1,38 @@ +text('two_factor_secret') + ->after('password') + ->nullable(); + + $table->text('two_factor_recovery_codes') + ->after('two_factor_secret') + ->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('two_factor_secret', 'two_factor_recovery_codes'); + }); + } +}; diff --git a/database/migrations/2019_08_19_000000_create_failed_jobs_table.php b/database/migrations/2019_08_19_000000_create_failed_jobs_table.php new file mode 100644 index 0000000..1719198 --- /dev/null +++ b/database/migrations/2019_08_19_000000_create_failed_jobs_table.php @@ -0,0 +1,36 @@ +id(); + $table->string('uuid')->unique(); + $table->text('connection'); + $table->text('queue'); + $table->longText('payload'); + $table->longText('exception'); + $table->timestamp('failed_at')->useCurrent(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('failed_jobs'); + } +}; diff --git a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php new file mode 100644 index 0000000..fd235f8 --- /dev/null +++ b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php @@ -0,0 +1,36 @@ +id(); + $table->morphs('tokenable'); + $table->string('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('personal_access_tokens'); + } +}; diff --git a/database/migrations/2022_01_09_205316_create_game_servers_table.php b/database/migrations/2022_01_09_205316_create_game_servers_table.php new file mode 100644 index 0000000..f25f37c --- /dev/null +++ b/database/migrations/2022_01_09_205316_create_game_servers_table.php @@ -0,0 +1,46 @@ +id(); + $table->text('uuid'); + $table->text('access_key'); + $table->tinyText('access_key_index'); + $table->text('ip_address'); + $table->tinyText('ip_address_index'); + $table->bigInteger('port')->default(64989); + $table->bigInteger('maximum_place_jobs'); + $table->bigInteger('maximum_thumbnail_jobs'); + $table->boolean('is_set_up')->default(false); + $table->boolean('has_vnc')->default(true); + $table->text('vnc_port')->nullable(); + $table->text('vnc_password')->nullable(); + $table->text('friendly_name')->nullable(); + $table->string('utc_offset')->nullable(); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('game_servers'); + } +}; diff --git a/database/migrations/2022_01_09_205341_create_badges_table.php b/database/migrations/2022_01_09_205341_create_badges_table.php new file mode 100644 index 0000000..e72115e --- /dev/null +++ b/database/migrations/2022_01_09_205341_create_badges_table.php @@ -0,0 +1,37 @@ +id(); + $table->string('name', 100)->default('New Badge'); + $table->string('description', 2000)->default('Earn this badge from my game.'); + $table->bigInteger('creator_id'); + $table->bigInteger('game_id'); + $table->boolean('awardable')->default(0); + $table->boolean('approved')->default(0); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('badges'); + } +}; diff --git a/database/migrations/2022_01_09_205414_create_place_jobs_table.php b/database/migrations/2022_01_09_205414_create_place_jobs_table.php new file mode 100644 index 0000000..796a063 --- /dev/null +++ b/database/migrations/2022_01_09_205414_create_place_jobs_table.php @@ -0,0 +1,33 @@ +id(); + $table->string('game_server_uuid'); + $table->string('place_id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('place_jobs'); + } +}; diff --git a/database/migrations/2022_02_13_073348_create_invite_keys_table.php b/database/migrations/2022_02_13_073348_create_invite_keys_table.php new file mode 100644 index 0000000..908d11c --- /dev/null +++ b/database/migrations/2022_02_13_073348_create_invite_keys_table.php @@ -0,0 +1,37 @@ +id(); + $table->text('token'); + $table->text('token_index'); + $table->bigInteger('creator_id'); + $table->integer('uses')->default(0); + $table->integer('max_uses'); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('invite_keys'); + } +}; diff --git a/database/migrations/2022_02_19_063207_create_sessions_table.php b/database/migrations/2022_02_19_063207_create_sessions_table.php new file mode 100644 index 0000000..c455537 --- /dev/null +++ b/database/migrations/2022_02_19_063207_create_sessions_table.php @@ -0,0 +1,35 @@ +string('id')->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->string('ip_address', 45)->nullable(); + $table->text('user_agent')->nullable(); + $table->text('payload'); + $table->integer('last_activity')->index(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('sessions'); + } +}; diff --git a/database/migrations/2022_03_06_004335_create_bans_table.php b/database/migrations/2022_03_06_004335_create_bans_table.php new file mode 100644 index 0000000..e6f0c69 --- /dev/null +++ b/database/migrations/2022_03_06_004335_create_bans_table.php @@ -0,0 +1,45 @@ +id(); + $table->timestamps(); + $table->string('moderator_id'); + $table->string('user_id'); + $table->string('internal_reason'); + $table->string('moderator_note'); + $table->text('offensive_item')->nullable(); + $table->dateTime('expiry_date')->nullable(); + $table->boolean('is_appealable')->default(true); + $table->boolean('is_poison_ban')->default(false); + $table->string('patient_zero')->nullable(); + $table->boolean('is_warning')->default(false); + $table->boolean('has_been_pardoned')->default(false); + $table->string('pardon_internal_reason')->nullable(); + $table->string('pardoner_id')->nullable(); + $table->boolean('is_active')->default(true); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('bans'); + } +}; diff --git a/database/migrations/2022_03_06_074551_create_ip_address_bans_table.php b/database/migrations/2022_03_06_074551_create_ip_address_bans_table.php new file mode 100644 index 0000000..40db355 --- /dev/null +++ b/database/migrations/2022_03_06_074551_create_ip_address_bans_table.php @@ -0,0 +1,39 @@ +id(); + $table->text('ip_address'); + $table->tinyText('ip_address_index'); + $table->text('criterium'); + $table->bigInteger('moderator_id'); + $table->bigInteger('pardoner_id')->nullable(); + $table->string('internal_reason', 255)->nullable(); + $table->boolean('is_active')->default(true); + $table->boolean('has_been_pardoned')->default(false); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('ip_address_bans'); + } +}; diff --git a/database/migrations/2022_03_14_224312_create_poisoned_ip_addresses.php b/database/migrations/2022_03_14_224312_create_poisoned_ip_addresses.php new file mode 100644 index 0000000..ad73a81 --- /dev/null +++ b/database/migrations/2022_03_14_224312_create_poisoned_ip_addresses.php @@ -0,0 +1,34 @@ +id(); + $table->text('ip_address'); + $table->tinyText('ip_address_index'); + $table->bigInteger('tied_to'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('poisoned_ip_addresses'); + } +}; diff --git a/database/migrations/2022_03_20_025917_create_thumbnail_jobs_table.php b/database/migrations/2022_03_20_025917_create_thumbnail_jobs_table.php new file mode 100644 index 0000000..6752871 --- /dev/null +++ b/database/migrations/2022_03_20_025917_create_thumbnail_jobs_table.php @@ -0,0 +1,32 @@ +id(); + $table->string('game_server_uuid'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('thumbnail_jobs'); + } +}; diff --git a/database/migrations/2022_03_26_044913_create_job_batches_table.php b/database/migrations/2022_03_26_044913_create_job_batches_table.php new file mode 100644 index 0000000..226e640 --- /dev/null +++ b/database/migrations/2022_03_26_044913_create_job_batches_table.php @@ -0,0 +1,39 @@ +string('id')->primary(); + $table->string('name'); + $table->integer('total_jobs'); + $table->integer('pending_jobs'); + $table->integer('failed_jobs'); + $table->text('failed_job_ids'); + $table->mediumText('options')->nullable(); + $table->integer('cancelled_at')->nullable(); + $table->integer('created_at'); + $table->integer('finished_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('job_batches'); + } +}; diff --git a/database/migrations/2022_04_12_154421_create_statuses_table.php b/database/migrations/2022_04_12_154421_create_statuses_table.php new file mode 100644 index 0000000..dbf5fb6 --- /dev/null +++ b/database/migrations/2022_04_12_154421_create_statuses_table.php @@ -0,0 +1,37 @@ +id(); + $table->bigInteger('creator_id'); + $table->bigInteger('creator_type')->default(CreatorType::User->value); + $table->bigInteger('group_id')->nullable(); + $table->string('content', 140); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('statuses'); + } +}; diff --git a/database/migrations/2022_04_12_224438_create_assets_table.php b/database/migrations/2022_04_12_224438_create_assets_table.php new file mode 100644 index 0000000..b362458 --- /dev/null +++ b/database/migrations/2022_04_12_224438_create_assets_table.php @@ -0,0 +1,64 @@ +id(); + $table->string('name', 50); + $table->string('description', 1000); + $table->bigInteger('type'); + $table->bigInteger('genre')->default(AssetGenre::All->value); + $table->bigInteger('version_id')->default(1); + $table->bigInteger('image_id')->nullable(); + $table->bigInteger('creator_id'); + $table->bigInteger('creator_type')->default(CreatorType::User->value); + $table->bigInteger('moderation')->default(AssetModeration::Pending->value); + $table->boolean('is_for_sale')->default(false); + $table->boolean('is_public_domain')->default(true); + $table->boolean('comments_enabled')->default(true); + $table->bigInteger('price')->default(0); + $table->bigInteger('gear_attributes')->default(0); + $table->bigInteger('sales')->default(0); + $table->bigInteger('favorites')->default(0); + $table->bigInteger('upvotes')->default(0); + $table->bigInteger('downvotes')->default(0); + + $table->bigInteger('universe_id')->nullable(); + $table->bigInteger('max_players')->default(16)->nullable(); + $table->bigInteger('client_version')->nullable(); + $table->bigInteger('access')->default(PlaceAccess::Everyone->value)->nullable(); + $table->bigInteger('chat_style')->default(ChatStyle::Classic->value)->nullable(); + $table->boolean('is_start_place')->default(false)->nullable(); + $table->boolean('is_boosters_club_only')->default(false)->nullable(); + $table->bigInteger('visits')->default(0)->nullable(); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('assets'); + } +}; diff --git a/database/migrations/2022_04_13_095641_create_asset_versions_table.php b/database/migrations/2022_04_13_095641_create_asset_versions_table.php new file mode 100644 index 0000000..2a0ae8c --- /dev/null +++ b/database/migrations/2022_04_13_095641_create_asset_versions_table.php @@ -0,0 +1,36 @@ +id(); + $table->bigInteger('asset_id'); + $table->bigInteger('version'); + $table->string('cdn_thumbnail_icon_hash')->nullable(); + $table->string('cdn_thumbnail_widescreen_hash')->nullable(); + $table->string('cdn_file_hash'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('asset_versions'); + } +}; diff --git a/database/migrations/2022_04_13_095721_create_universes_table.php b/database/migrations/2022_04_13_095721_create_universes_table.php new file mode 100644 index 0000000..e5d2b5c --- /dev/null +++ b/database/migrations/2022_04_13_095721_create_universes_table.php @@ -0,0 +1,48 @@ +id(); + $table->bigInteger('creator_id'); + $table->bigInteger('creator_type')->default(CreatorType::User->value); + $table->bigInteger('start_place_id')->nullable(); + $table->string('name')->default('My Game'); + $table->bigInteger('version'); + + $table->packed('privileges'); + /** + * { "owner": user_id, "allowed_editors": [user_id1, user_id2, user_id3, group_id1] } + * "owner" can transfer to anyone + * "owner" has full privileges + */ + + $table->integer('privacy')->default(0); // 0: Public. 1: Private for owner only. 2: Private, but all friends of owner is allowed + $table->boolean('unlisted')->default(false); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('universes'); + } +}; diff --git a/database/migrations/2022_04_13_100911_create_asset_comments_table.php b/database/migrations/2022_04_13_100911_create_asset_comments_table.php new file mode 100644 index 0000000..5dce634 --- /dev/null +++ b/database/migrations/2022_04_13_100911_create_asset_comments_table.php @@ -0,0 +1,35 @@ +id(); + $table->bigInteger('asset_id'); + $table->bigInteger('creator_id'); + $table->string('content', 140); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('asset_comments'); + } +}; diff --git a/database/migrations/2022_04_13_101743_create_asset_ownerships_table.php b/database/migrations/2022_04_13_101743_create_asset_ownerships_table.php new file mode 100644 index 0000000..b228f3a --- /dev/null +++ b/database/migrations/2022_04_13_101743_create_asset_ownerships_table.php @@ -0,0 +1,35 @@ +id(); + $table->bigInteger('asset_id'); + $table->bigInteger('user_id'); + $table->boolean('wearing')->default(false); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('asset_ownerships'); + } +}; diff --git a/database/migrations/2022_04_16_080833_create_friendships_table.php b/database/migrations/2022_04_16_080833_create_friendships_table.php new file mode 100644 index 0000000..0fb80a1 --- /dev/null +++ b/database/migrations/2022_04_16_080833_create_friendships_table.php @@ -0,0 +1,35 @@ +id(); + $table->bigInteger('requester_id'); + $table->bigInteger('receiver_id'); + $table->boolean('accepted')->default(false); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('friendships'); + } +}; diff --git a/database/migrations/2022_07_02_101148_create_actions_table.php b/database/migrations/2022_07_02_101148_create_actions_table.php new file mode 100644 index 0000000..78e93cd --- /dev/null +++ b/database/migrations/2022_07_02_101148_create_actions_table.php @@ -0,0 +1,34 @@ +id(); + $table->bigInteger('doer_id'); + $table->bigInteger('action'); + $table->bigInteger('target_id')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('actions'); + } +}; diff --git a/database/migrations/2022_07_02_135149_create_forum_threads_table.php b/database/migrations/2022_07_02_135149_create_forum_threads_table.php new file mode 100644 index 0000000..14d4f8d --- /dev/null +++ b/database/migrations/2022_07_02_135149_create_forum_threads_table.php @@ -0,0 +1,39 @@ +id(); + $table->string('title', 100); + $table->string('body', 10000); + $table->bigInteger('author_id'); + $table->bigInteger('category_id'); + $table->boolean('stickied')->default(false); + $table->boolean('locked')->default(false); + $table->bigInteger('views')->default(0); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('forum_threads'); + } +}; diff --git a/database/migrations/2022_07_02_135209_create_forum_replies_table.php b/database/migrations/2022_07_02_135209_create_forum_replies_table.php new file mode 100644 index 0000000..b69178d --- /dev/null +++ b/database/migrations/2022_07_02_135209_create_forum_replies_table.php @@ -0,0 +1,37 @@ +id(); + $table->timestamps(); + $table->string('body', 10000); + $table->bigInteger('author_id'); + $table->bigInteger('thread_id'); + $table->bigInteger('category_id'); + $table->boolean('stickied')->default(false); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('forum_replies'); + } +}; diff --git a/database/migrations/2022_07_02_135303_create_forum_categories_table.php b/database/migrations/2022_07_02_135303_create_forum_categories_table.php new file mode 100644 index 0000000..1d90605 --- /dev/null +++ b/database/migrations/2022_07_02_135303_create_forum_categories_table.php @@ -0,0 +1,37 @@ +id(); + $table->string('name', 50); + $table->string('description', 400); + $table->bigInteger('priority')->unique(); + $table->string('color', 10)->default('#000000'); + $table->boolean('restricted')->default(false); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('forum_categories'); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php new file mode 100644 index 0000000..ce9c864 --- /dev/null +++ b/database/seeders/DatabaseSeeder.php @@ -0,0 +1,19 @@ +create(); + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d7dd9a6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,107 @@ +# For more information: https://laravel.com/docs/sail +version: '3' +services: + laravel.test: + build: + context: ./docker + dockerfile: Dockerfile + args: + WWWGROUP: '${WWWGROUP}' + extra_hosts: + - 'host.docker.internal:host-gateway' + ports: + - '${APP_PORT:-80}:80' + environment: + WWWUSER: '${WWWUSER}' + LARAVEL_SAIL: 1 + XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}' + XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}' + volumes: + - '.:/var/www/html' + networks: + - sail + depends_on: + - pgsql + - redis + - meilisearch + - selenium + - soketi + pgsql: + image: 'postgres:13' + ports: + - '${FORWARD_DB_PORT:-5432}:5432' + environment: + PGPASSWORD: '${DB_PASSWORD:-secret}' + POSTGRES_DB: '${DB_DATABASE}' + POSTGRES_USER: '${DB_USERNAME}' + POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}' + volumes: + - 'sail-pgsql:/var/lib/postgresql/data' + networks: + - sail + healthcheck: + test: ["CMD", "pg_isready", "-q", "-d", "${DB_DATABASE}", "-U", "${DB_USERNAME}"] + retries: 3 + timeout: 5s + redis: + image: 'redis:alpine' + ports: + - '${FORWARD_REDIS_PORT:-6379}:6379' + volumes: + - 'sail-redis:/data' + networks: + - sail + healthcheck: + test: ["CMD", "redis-cli", "ping"] + retries: 3 + timeout: 5s + meilisearch: + image: 'getmeili/meilisearch:latest' + ports: + - '${FORWARD_MEILISEARCH_PORT:-7700}:7700' + volumes: + - 'sail-meilisearch:/data.ms' + networks: + - sail + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--spider", "http://localhost:7700/health"] + retries: 3 + timeout: 5s + mailhog: + image: 'mailhog/mailhog:latest' + environment: + MEILI_MASTER_KEY: ${MEILISEARCH_KEY} + ports: + - '${FORWARD_MAILHOG_PORT:-1025}:1025' + - '${FORWARD_MAILHOG_DASHBOARD_PORT:-8025}:8025' + networks: + - sail + soketi: + image: 'quay.io/soketi/soketi:latest-16-alpine' + environment: + DEBUG: '1' + METRICS_SERVER_PORT: '9601' + DEFAULT_APP_ID: ${PUSHER_APP_ID} + DEFAULT_APP_KEY: ${PUSHER_APP_KEY} + DEFAULT_APP_SECRET: ${PUSHER_APP_SECRET} + ports: + - '${SOKETI_PORT:-6001}:6001' + - '${SOKETI_METRICS_SERVER_PORT:-9601}:9601' + networks: + - sail + selenium: + image: 'selenium/standalone-chrome' + volumes: + - '/dev/shm:/dev/shm' + networks: + - sail +networks: + sail: + driver: bridge +volumes: + sail-pgsql: + driver: local + sail-redis: + driver: local + sail-meilisearch: + driver: local diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..0277709 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,63 @@ +FROM ubuntu:22.04 + +LABEL maintainer="Taylor Otwell" + +ARG WWWGROUP +ARG NODE_VERSION=16 +ARG POSTGRES_VERSION=14 + +WORKDIR /var/www/html + +ENV DEBIAN_FRONTEND noninteractive +ENV TZ=UTC + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN apt-get update \ + && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python2 \ + && mkdir -p ~/.gnupg \ + && chmod 600 ~/.gnupg \ + && echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf \ + && echo "keyserver hkp://keyserver.ubuntu.com:80" >> ~/.gnupg/dirmngr.conf \ + && gpg --recv-key 0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c \ + && gpg --export 0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c > /usr/share/keyrings/ppa_ondrej_php.gpg \ + && echo "deb [signed-by=/usr/share/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu jammy main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \ + && apt-get update \ + && apt-get install -y php8.1-cli php8.1-dev \ + php8.1-pgsql php8.1-sqlite3 php8.1-gd \ + php8.1-curl \ + php8.1-imap php8.1-mysql php8.1-mbstring \ + php8.1-xml php8.1-zip php8.1-bcmath php8.1-soap \ + php8.1-intl php8.1-readline \ + php8.1-ldap \ + php8.1-msgpack php8.1-igbinary php8.1-redis php8.1-swoole \ + php8.1-memcached php8.1-pcov php8.1-xdebug \ + && php -r "readfile('https://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \ + && curl -sLS https://deb.nodesource.com/setup_$NODE_VERSION.x | bash - \ + && apt-get install -y nodejs \ + && npm install -g npm \ + && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarn.gpg >/dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/pgdg.gpg >/dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt jammy-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && apt-get install -y yarn \ + && apt-get install -y mysql-client \ + && apt-get install -y postgresql-client-$POSTGRES_VERSION \ + && apt-get -y autoremove \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.1 + +RUN groupadd --force -g $WWWGROUP sail +RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail + +COPY start-container /usr/local/bin/start-container +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY php.ini /etc/php/8.1/cli/conf.d/99-sail.ini +RUN chmod +x /usr/local/bin/start-container + +EXPOSE 8000 + +ENTRYPOINT ["start-container"] diff --git a/docker/php.ini b/docker/php.ini new file mode 100644 index 0000000..ae5ccd6 --- /dev/null +++ b/docker/php.ini @@ -0,0 +1,4 @@ +[PHP] +post_max_size = 100M +upload_max_filesize = 100M +variables_order = EGPCS diff --git a/docker/release/Dockerfile b/docker/release/Dockerfile new file mode 100644 index 0000000..b732f12 --- /dev/null +++ b/docker/release/Dockerfile @@ -0,0 +1,90 @@ +FROM phpswoole/php8.1-alpine +WORKDIR /var/www/html + +# Basic +RUN apk update && pecl update-channels +RUN apk add bash supervisor tzdata curl supervisor zip unzip + +# Timezone +ENV TZ=$APP_TIMEZONE +RUN apk add tzdata +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +# Install essential build tools for NPM assets + PHP extensions +RUN apk add \ + autoconf \ + g++ \ + gcc \ + git \ + libpng \ + make \ + nodejs \ + yarn + +# Install build tools for PHP extensions only +RUN apk add \ + bzip2-dev \ + curl-dev \ + icu-dev \ + libfreetype6-dev \ + libjpeg-turbo-dev \ + libpng-dev \ + libwebp-dev \ + libxpm-dev \ + libzip-dev \ + oniguruma-dev \ + openssl-dev \ + zlib-dev + +# Install PHP extensions +RUN pecl install msgpack-stable && docker-php-ext-enable msgpack && \ + pecl install redis-stable && docker-php-ext-enable redis && \ + && docker-php-ext-configure gd --with-freetype --with-jpeg && docker-php-ext-install gd && docker-php-ext-enable gd \ + && docker-php-ext-install -j$(nproc) bz2 && docker-php-ext-enable bz2 \ + && docker-php-ext-install -j$(nproc) curl && docker-php-ext-enable curl \ + && docker-php-ext-install -j$(nproc) intl && docker-php-ext-enable intl \ + && docker-php-ext-install -j$(nproc) mbstring && docker-php-ext-enable mbstring \ + && docker-php-ext-install -j$(nproc) pdo pdo_pgsql && docker-php-ext-enable pdo pg_sql \ + && docker-php-ext-install -j$(nproc) xml && docker-php-ext-enable xml \ + && docker-php-ext-install -j$(nproc) zip && docker-php-ext-enable zip + +# Clear out the junk +RUN apk add \ + bzip2-dev \ + curl-dev \ + icu-dev \ + libfreetype6-dev \ + libjpeg-turbo-dev \ + libpng-dev \ + libwebp-dev \ + libxpm-dev \ + libzip-dev \ + oniguruma-dev \ + openssl-dev \ + zlib-dev + +RUN rm -rf /var/cache/apk/* && /tmp/* + +# Entrypoint +RUN (delgroup www-data || true) \ + && addgroup -g 82 -S www-data \ + && adduser -u 82 -D -S -G www-data www-data + +RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.1 +COPY start-container /usr/local/bin/start-container +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY php.ini /etc/php/8.1/cli/conf.d/99-tadah.ini + +# Add our source directory +ADD . . + +# Build NPM assets and install composer +RUN npm run production \ + && composer install --no-ansi --no-dev --no-interaction --no-plugins --no-progress --no-scripts --optimize-autoloader + +# Delete artifacts +RUN rm webpack.mix.js package* composer* + +# Run +EXPOSE 80 +ENTRYPOINT [ "start-container" ] diff --git a/docker/release/php.ini b/docker/release/php.ini new file mode 100644 index 0000000..0c5fc8e --- /dev/null +++ b/docker/release/php.ini @@ -0,0 +1,34 @@ +[PHP] +post_max_size = 100M +upload_max_filesize = 100M +variables_order = GPCS +short_open_tag = Off +precision = 14 +output_buffering = 4096 +zlib.output_compression = Off +implicit_flush = Off +serialize_precision = -1 +zend.enable_gc = On +zend.exception_ignore_args = On +expose_php = Off +error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT +display_errors = Off +display_startup_errors = Off +log_errors = On +ignore_repeated_errors = Off +ignore_repeated_source = Off +report_memleaks = On +variables_order = "GPCS" +request_order = "GP" +register_argc_argv = Off +auto_globals_jit = On +default_mimetype = "text/html" +default_charset = "UTF-8" +doc_root = +user_dir = +enable_dl = Off +file_uploads = On +max_file_uploads = 20 +allow_url_fopen = On +allow_url_include = Off +default_socket_timeout = 60 diff --git a/docker/release/start-container b/docker/release/start-container new file mode 100644 index 0000000..65f147f --- /dev/null +++ b/docker/release/start-container @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +if [ ! -z "$WWWUSER" ]; then + usermod -u $WWWUSER www-data +fi + +if [ ! -d /.composer ]; then + mkdir /.composer +fi + +chmod -R ugo+rw /.composer + +if [ $# -gt 0 ]; then + exec gosu $WWWUSER "$@" +else + /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/docker/release/supervisord.conf b/docker/release/supervisord.conf new file mode 100644 index 0000000..a080fd0 --- /dev/null +++ b/docker/release/supervisord.conf @@ -0,0 +1,26 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:php] +command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --host=0.0.0.0 --port=80 +user=www-data +autostart=true +autorestart=true +stdout_logfile=/var/log/php-stdout.log +stdout_logfile_maxbytes=0 +stderr_logfile=/var/log/php-stderr.log +stderr_logfile_maxbytes=0 + +[program:laravel-worker] +command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan queue:work redis --max-time=3600 --timeout=20 +user=www-data +autostart=true +autorestart=true +numprocs=32 +stdout_logfile=/var/log/laravel-worker-stdout.log +stdout_logfile_maxbytes=0 +stdout_logfile=/var/log/laravel-worker-stderr.log +stderr_logfile_maxbytes=0 diff --git a/docker/start-container b/docker/start-container new file mode 100644 index 0000000..dc1ade8 --- /dev/null +++ b/docker/start-container @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +if [ ! -z "$WWWUSER" ]; then + usermod -u $WWWUSER sail +fi + +if [ ! -d /.composer ]; then + mkdir /.composer +fi + +chmod -R ugo+rw /.composer + +if [ $# -gt 0 ]; then + exec gosu $WWWUSER "$@" +else + /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/docker/supervisord.conf b/docker/supervisord.conf new file mode 100644 index 0000000..812142b --- /dev/null +++ b/docker/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:php] +command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80 +user=sail +environment=LARAVEL_SAIL="1" +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/lang/en_US.json b/lang/en_US.json new file mode 100644 index 0000000..577680d --- /dev/null +++ b/lang/en_US.json @@ -0,0 +1,7 @@ +{ + "The :attribute must contain at least one letter.": "The :attribute must contain at least one letter.", + "The :attribute must contain at least one number.": "The :attribute must contain at least one number.", + "The :attribute must contain at least one symbol.": "The :attribute must contain at least one symbol.", + "The :attribute must contain at least one uppercase and one lowercase letter.": "The :attribute must contain at least one uppercase and one lowercase letter.", + "The given :attribute has appeared in a data leak. Please choose a different :attribute.": "The given :attribute has appeared in a data leak. Please choose a different :attribute." +} diff --git a/lang/en_US/auth.php b/lang/en_US/auth.php new file mode 100644 index 0000000..6598e2c --- /dev/null +++ b/lang/en_US/auth.php @@ -0,0 +1,20 @@ + 'These credentials do not match our records.', + 'password' => 'The provided password is incorrect.', + 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', + +]; diff --git a/lang/en_US/pagination.php b/lang/en_US/pagination.php new file mode 100644 index 0000000..d481411 --- /dev/null +++ b/lang/en_US/pagination.php @@ -0,0 +1,19 @@ + '« Previous', + 'next' => 'Next »', + +]; diff --git a/lang/en_US/passwords.php b/lang/en_US/passwords.php new file mode 100644 index 0000000..59e7455 --- /dev/null +++ b/lang/en_US/passwords.php @@ -0,0 +1,22 @@ + 'Your password has been reset!', + 'sent' => 'If you provided an email address associated with a valid account, an email has been sent to that address containing the password reset link.', + 'throttled' => 'Please wait before retrying.', + 'token' => 'This password reset token is invalid.', + 'user' => "We can't find a user with that email address.", + +]; diff --git a/lang/en_US/validation.php b/lang/en_US/validation.php new file mode 100644 index 0000000..8ff2e92 --- /dev/null +++ b/lang/en_US/validation.php @@ -0,0 +1,164 @@ + 'The :attribute must be accepted.', + 'accepted_if' => 'The :attribute must be accepted when :other is :value.', + 'active_url' => 'The :attribute is not a valid URL.', + 'after' => 'The :attribute must be a date after :date.', + 'after_or_equal' => 'The :attribute must be a date after or equal to :date.', + 'alpha' => 'The :attribute must only contain letters.', + 'alpha_dash' => 'The :attribute must only contain letters, numbers, dashes and underscores.', + 'alpha_num' => 'The :attribute must only contain letters and numbers.', + 'array' => 'The :attribute must be an array.', + 'before' => 'The :attribute must be a date before :date.', + 'before_or_equal' => 'The :attribute must be a date before or equal to :date.', + 'between' => [ + 'numeric' => 'The :attribute must be between :min and :max.', + 'file' => 'The :attribute must be between :min and :max kilobytes.', + 'string' => 'The :attribute must be between :min and :max characters.', + 'array' => 'The :attribute must have between :min and :max items.', + ], + 'boolean' => 'The :attribute field must be true or false.', + 'confirmed' => 'The :attribute confirmation does not match.', + 'current_password' => 'The password is incorrect.', + 'date' => 'The :attribute is not a valid date.', + 'date_equals' => 'The :attribute must be a date equal to :date.', + 'date_format' => 'The :attribute does not match the format :format.', + 'declined' => 'The :attribute must be declined.', + 'declined_if' => 'The :attribute must be declined when :other is :value.', + 'different' => 'The :attribute and :other must be different.', + 'digits' => 'The :attribute must be :digits digits.', + 'digits_between' => 'The :attribute must be between :min and :max digits.', + 'dimensions' => 'The :attribute has invalid image dimensions.', + 'distinct' => 'The :attribute field has a duplicate value.', + 'email' => 'The :attribute must be a valid email address.', + 'ends_with' => 'The :attribute must end with one of the following: :values.', + 'enum' => 'The selected :attribute is invalid.', + 'exists' => 'The selected :attribute is invalid.', + 'file' => 'The :attribute must be a file.', + 'filled' => 'The :attribute field must have a value.', + 'gt' => [ + 'numeric' => 'The :attribute must be greater than :value.', + 'file' => 'The :attribute must be greater than :value kilobytes.', + 'string' => 'The :attribute must be greater than :value characters.', + 'array' => 'The :attribute must have more than :value items.', + ], + 'gte' => [ + 'numeric' => 'The :attribute must be greater than or equal to :value.', + 'file' => 'The :attribute must be greater than or equal to :value kilobytes.', + 'string' => 'The :attribute must be greater than or equal to :value characters.', + 'array' => 'The :attribute must have :value items or more.', + ], + 'image' => 'The :attribute must be an image.', + 'in' => 'The selected :attribute is invalid.', + 'indisposable' => 'Disposable email addresses are not allowed.', + 'in_array' => 'The :attribute field does not exist in :other.', + 'integer' => 'The :attribute must be an integer.', + 'ip' => 'The :attribute must be a valid IP address.', + 'ipv4' => 'The :attribute must be a valid IPv4 address.', + 'ipv6' => 'The :attribute must be a valid IPv6 address.', + 'json' => 'The :attribute must be a valid JSON string.', + 'lt' => [ + 'numeric' => 'The :attribute must be less than :value.', + 'file' => 'The :attribute must be less than :value kilobytes.', + 'string' => 'The :attribute must be less than :value characters.', + 'array' => 'The :attribute must have less than :value items.', + ], + 'lte' => [ + 'numeric' => 'The :attribute must be less than or equal to :value.', + 'file' => 'The :attribute must be less than or equal to :value kilobytes.', + 'string' => 'The :attribute must be less than or equal to :value characters.', + 'array' => 'The :attribute must not have more than :value items.', + ], + 'mac_address' => 'The :attribute must be a valid MAC address.', + 'max' => [ + 'numeric' => 'The :attribute must not be greater than :max.', + 'file' => 'The :attribute must not be greater than :max kilobytes.', + 'string' => 'The :attribute must not be greater than :max characters.', + 'array' => 'The :attribute must not have more than :max items.', + ], + 'mimes' => 'The :attribute must be a file of type: :values.', + 'mimetypes' => 'The :attribute must be a file of type: :values.', + 'min' => [ + 'numeric' => 'The :attribute must be at least :min.', + 'file' => 'The :attribute must be at least :min kilobytes.', + 'string' => 'The :attribute must be at least :min characters.', + 'array' => 'The :attribute must have at least :min items.', + ], + 'multiple_of' => 'The :attribute must be a multiple of :value.', + 'not_in' => 'The selected :attribute is invalid.', + 'not_regex' => 'The :attribute format is invalid.', + 'numeric' => 'The :attribute must be a number.', + 'password' => 'The password is incorrect.', + 'present' => 'The :attribute field must be present.', + 'prohibited' => 'The :attribute field is prohibited.', + 'prohibited_if' => 'The :attribute field is prohibited when :other is :value.', + 'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.', + 'prohibits' => 'The :attribute field prohibits :other from being present.', + 'regex' => 'The :attribute format is invalid.', + 'required' => 'The :attribute field is required.', + 'required_array_keys' => 'The :attribute field must contain entries for: :values.', + 'required_if' => 'The :attribute field is required when :other is :value.', + 'required_unless' => 'The :attribute field is required unless :other is in :values.', + 'required_with' => 'The :attribute field is required when :values is present.', + 'required_with_all' => 'The :attribute field is required when :values are present.', + 'required_without' => 'The :attribute field is required when :values is not present.', + 'required_without_all' => 'The :attribute field is required when none of :values are present.', + 'same' => 'The :attribute and :other must match.', + 'size' => [ + 'numeric' => 'The :attribute must be :size.', + 'file' => 'The :attribute must be :size kilobytes.', + 'string' => 'The :attribute must be :size characters.', + 'array' => 'The :attribute must contain :size items.', + ], + 'starts_with' => 'The :attribute must start with one of the following: :values.', + 'string' => 'The :attribute must be a string.', + 'timezone' => 'The :attribute must be a valid timezone.', + 'unique' => 'The :attribute has already been taken.', + 'uploaded' => 'The :attribute failed to upload.', + 'url' => 'The :attribute must be a valid URL.', + 'uuid' => 'The :attribute must be a valid UUID.', + + /* + |-------------------------------------------------------------------------- + | Custom Validation Language Lines + |-------------------------------------------------------------------------- + | + | Here you may specify custom validation messages for attributes using the + | convention "attribute.rule" to name the lines. This makes it quick to + | specify a specific custom language line for a given attribute rule. + | + */ + + 'custom' => [ + 'attribute-name' => [ + 'rule-name' => 'custom-message', + ], + ], + + /* + |-------------------------------------------------------------------------- + | Custom Validation Attributes + |-------------------------------------------------------------------------- + | + | The following language lines are used to swap our attribute placeholder + | with something more reader friendly such as "E-Mail Address" instead + | of "email". This simply helps us make our message more expressive. + | + */ + + 'attributes' => [], + +]; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..8a07db1 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,12417 @@ +{ + "name": "web", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "dependencies": { + "@popperjs/core": "^2.11.6", + "@ryangjchandler/alpine-clipboard": "^2.2.0", + "alpinejs": "^3.10.3", + "axios": "^0.27.2", + "bootstrap": "^5.2.0", + "chart.js": "^3.9.1", + "jquery": "^3.6.0", + "jquery.waitforimages": "^2.4.0", + "laravel-echo": "^1.13.1", + "laravel-mix": "^6.0.49", + "pusher-js": "^7.3.0", + "resolve-url-loader": "^5.0.0", + "sass": "^1.54.4", + "sass-loader": "^13.0.2", + "showdown": "^2.1.0", + "vanillajs-datepicker": "^1.2.0", + "xss": "^1.0.13" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.18.13", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.18.13", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.13", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-module-transforms": "^7.18.9", + "@babel/helpers": "^7.18.9", + "@babel/parser": "^7.18.13", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.18.13", + "@babel/types": "^7.18.13", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.18.13", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.13", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-explode-assignable-expression": "^7.18.6", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.18.8", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.20.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.18.13", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "regexpu-core": "^5.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.3.2", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { + "version": "6.3.0", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-explode-assignable-expression": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.18.6", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.18.9", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.18.10", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.18.6", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.18.11", + "license": "MIT", + "dependencies": { + "@babel/helper-function-name": "^7.18.9", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.18.11", + "@babel/types": "^7.18.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.18.13", + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.18.10", + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-static-block": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.18.8", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.18.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-remap-async-to-generator": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.18.13", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.18.8", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-module-transforms": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-validator-identifier": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.18.8", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "regenerator-transform": "^0.15.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.18.10", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.9", + "babel-plugin-polyfill-corejs2": "^0.3.2", + "babel-plugin-polyfill-corejs3": "^0.5.3", + "babel-plugin-polyfill-regenerator": "^0.4.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.0", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.18.10", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.18.10", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.18.8", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.18.10", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-dynamic-import": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-json-strings": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", + "@babel/plugin-proposal-numeric-separator": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.18.9", + "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.18.6", + "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-block-scoped-functions": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.18.9", + "@babel/plugin-transform-classes": "^7.18.9", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.18.9", + "@babel/plugin-transform-dotall-regex": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", + "@babel/plugin-transform-exponentiation-operator": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", + "@babel/plugin-transform-member-expression-literals": "^7.18.6", + "@babel/plugin-transform-modules-amd": "^7.18.6", + "@babel/plugin-transform-modules-commonjs": "^7.18.6", + "@babel/plugin-transform-modules-systemjs": "^7.18.9", + "@babel/plugin-transform-modules-umd": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.18.6", + "@babel/plugin-transform-new-target": "^7.18.6", + "@babel/plugin-transform-object-super": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.18.8", + "@babel/plugin-transform-property-literals": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-reserved-words": "^7.18.6", + "@babel/plugin-transform-shorthand-properties": "^7.18.6", + "@babel/plugin-transform-spread": "^7.18.9", + "@babel/plugin-transform-sticky-regex": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-regex": "^7.18.6", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.18.10", + "babel-plugin-polyfill-corejs2": "^0.3.2", + "babel-plugin-polyfill-corejs3": "^0.5.3", + "babel-plugin-polyfill-regenerator": "^0.4.0", + "core-js-compat": "^3.22.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.0", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.18.9", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.18.10", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.18.13", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.13", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.18.13", + "@babel/types": "^7.18.13", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.18.13", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.18.6", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.2", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.15", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "license": "MIT" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.6", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@ryangjchandler/alpine-clipboard": { + "version": "2.2.0", + "license": "MIT" + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "license": "ISC", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.1.19", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.18.0", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.10", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/clean-css": { + "version": "4.2.5", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "source-map": "^0.6.0" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.3.5", + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.4.6", + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.4", + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "0.0.51", + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "4.17.13", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.30", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/http-proxy": { + "version": "1.17.9", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/imagemin": { + "version": "8.0.0", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/imagemin-gifsicle": { + "version": "7.0.1", + "license": "MIT", + "dependencies": { + "@types/imagemin": "*" + } + }, + "node_modules/@types/imagemin-mozjpeg": { + "version": "8.0.1", + "license": "MIT", + "dependencies": { + "@types/imagemin": "*" + } + }, + "node_modules/@types/imagemin-optipng": { + "version": "5.2.1", + "license": "MIT", + "dependencies": { + "@types/imagemin": "*" + } + }, + "node_modules/@types/imagemin-svgo": { + "version": "8.0.1", + "license": "MIT", + "dependencies": { + "@types/imagemin": "*", + "@types/svgo": "^1" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "3.0.1", + "license": "MIT" + }, + "node_modules/@types/minimatch": { + "version": "5.1.0", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "18.7.13", + "license": "MIT" + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "license": "MIT" + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "license": "MIT" + }, + "node_modules/@types/serve-index": { + "version": "1.9.1", + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.0", + "license": "MIT", + "dependencies": { + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.33", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/svgo": { + "version": "1.3.6", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.5.3", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.1.5", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.1.5" + } + }, + "node_modules/@vue/shared": { + "version": "3.1.5", + "license": "MIT" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.1", + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.1", + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.1", + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "1.2.0", + "license": "MIT", + "peerDependencies": { + "webpack": "4.x.x || 5.x.x", + "webpack-cli": "4.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "1.5.0", + "license": "MIT", + "dependencies": { + "envinfo": "^7.7.3" + }, + "peerDependencies": { + "webpack-cli": "4.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "1.7.0", + "license": "MIT", + "peerDependencies": { + "webpack-cli": "4.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "license": "Apache-2.0" + }, + "node_modules/accepts": { + "version": "1.3.8", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.8.0", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.8.0", + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.11.0", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/alpinejs": { + "version": "3.10.3", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "~3.1.1" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/array-union": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "license": "MIT" + }, + "node_modules/assert": { + "version": "1.5.0", + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1", + "util": "0.10.3" + } + }, + "node_modules/assert/node_modules/inherits": { + "version": "2.0.1", + "license": "ISC" + }, + "node_modules/assert/node_modules/util": { + "version": "0.10.3", + "license": "MIT", + "dependencies": { + "inherits": "2.0.1" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.8", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.21.3", + "caniuse-lite": "^1.0.30001373", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axios": { + "version": "0.27.2", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/babel-loader": { + "version": "8.2.5", + "license": "MIT", + "dependencies": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "engines": { + "node": ">= 8.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "license": "MIT", + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.3.2", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.2", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.0", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.5.3", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.2", + "core-js-compat": "^3.21.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.4.0", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/batch": { + "version": "0.6.1", + "license": "MIT" + }, + "node_modules/big.js": { + "version": "5.2.2", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/bn.js": { + "version": "5.2.1", + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.20.0", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.0.13", + "license": "MIT", + "dependencies": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/bootstrap": { + "version": "5.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "license": "MIT", + "peerDependencies": { + "@popperjs/core": "^2.11.5" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.1", + "license": "ISC", + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.0", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/browserify-sign/node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "license": "MIT", + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserslist": { + "version": "4.21.3", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001370", + "electron-to-chromium": "^1.4.202", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.5" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "4.9.2", + "license": "MIT", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "license": "MIT" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "license": "MIT" + }, + "node_modules/bytes": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001383", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/charenc": { + "version": "0.0.2", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/chart.js": { + "version": "3.9.1", + "license": "MIT" + }, + "node_modules/chokidar": { + "version": "3.5.3", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/clean-css": { + "version": "5.3.1", + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/cli-table3": { + "version": "0.6.2", + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/collect.js": { + "version": "4.34.3", + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/colord": { + "version": "2.9.3", + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.19", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/compressible": { + "version": "2.0.18", + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/concat": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "commander": "^2.9.0" + }, + "bin": { + "concat": "bin/concat" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/concat/node_modules/commander": { + "version": "2.20.3", + "license": "MIT" + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "2.15.3", + "license": "MIT" + }, + "node_modules/console-browserify": { + "version": "1.2.0" + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/content-type": { + "version": "1.0.4", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.25.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.21.3", + "semver": "7.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat/node_modules/semver": { + "version": "7.0.0", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "7.0.1", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "license": "MIT" + }, + "node_modules/create-hash": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "license": "MIT", + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/css-declaration-sorter": { + "version": "6.3.0", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-loader": { + "version": "5.2.7", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.15", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^3.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.27.0 || ^5.0.0" + } + }, + "node_modules/css-loader/node_modules/schema-utils": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select/node_modules/domhandler": { + "version": "4.3.1", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/css-tree": { + "version": "1.1.3", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssfilter": { + "version": "0.0.10", + "license": "MIT" + }, + "node_modules/cssnano": { + "version": "5.1.13", + "license": "MIT", + "dependencies": { + "cssnano-preset-default": "^5.2.12", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-preset-default": { + "version": "5.2.12", + "license": "MIT", + "dependencies": { + "css-declaration-sorter": "^6.3.0", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.0", + "postcss-convert-values": "^5.1.2", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.6", + "postcss-merge-rules": "^5.1.2", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.3", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.0", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.0", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-utils": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "license": "MIT", + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "license": "BSD-2-Clause", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.1.4", + "license": "MIT", + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/des.js": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "license": "MIT" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/dns-packet": { + "version": "5.4.0", + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/domhandler": { + "version": "4.3.1", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domain-browser": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "3.3.0", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.0.1" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/domutils/node_modules/domhandler": { + "version": "4.3.1", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dotenv": { + "version": "10.0.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=10" + } + }, + "node_modules/dotenv-expand": { + "version": "5.1.0", + "license": "BSD-2-Clause" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.230", + "license": "ISC" + }, + "node_modules/elliptic": { + "version": "6.5.4", + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.10.0", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envinfo": { + "version": "7.8.1", + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-module-lexer": { + "version": "0.9.3", + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.18.1", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.10.3", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/express/node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.13.0", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/file-type": { + "version": "12.4.2", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.1", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.2.0", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.3", + "license": "Unlicense" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.2", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "license": "BSD-2-Clause" + }, + "node_modules/globals": { + "version": "11.12.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "10.0.2", + "license": "MIT", + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "license": "ISC" + }, + "node_modules/growly": { + "version": "1.3.0", + "license": "MIT" + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/has": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.0", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hash-base/node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/hash-sum": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/hash.js": { + "version": "1.1.7", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.3.3", + "license": "MIT" + }, + "node_modules/html-loader": { + "version": "1.3.2", + "license": "MIT", + "dependencies": { + "html-minifier-terser": "^5.1.1", + "htmlparser2": "^4.1.0", + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/html-loader/node_modules/schema-utils": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/html-minifier-terser": { + "version": "5.1.1", + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.1", + "clean-css": "^4.2.3", + "commander": "^4.1.1", + "he": "^1.2.0", + "param-case": "^3.0.3", + "relateurl": "^0.2.7", + "terser": "^4.6.3" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/html-minifier-terser/node_modules/clean-css": { + "version": "4.2.4", + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "4.1.1", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/html-minifier-terser/node_modules/terser": { + "version": "4.8.1", + "license": "BSD-2-Clause", + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/html-minifier-terser/node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "2.1.0", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.2.0", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/imagemin": { + "version": "7.0.1", + "license": "MIT", + "dependencies": { + "file-type": "^12.0.0", + "globby": "^10.0.0", + "graceful-fs": "^4.2.2", + "junk": "^3.1.0", + "make-dir": "^3.0.0", + "p-pipe": "^3.0.0", + "replace-ext": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/img-loader": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "loader-utils": "^1.1.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "imagemin": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/img-loader/node_modules/json5": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/img-loader/node_modules/loader-utils": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/immutable": { + "version": "4.1.0", + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "license": "ISC" + }, + "node_modules/interpret": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ipaddr.js": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.10.0", + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jquery": { + "version": "3.6.0", + "license": "MIT" + }, + "node_modules/jquery.waitforimages": { + "version": "2.4.0", + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.1", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/junk": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/klona": { + "version": "2.0.5", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/laravel-echo": { + "version": "1.13.1", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/laravel-mix": { + "version": "6.0.49", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.15.8", + "@babel/plugin-proposal-object-rest-spread": "^7.15.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.15.8", + "@babel/preset-env": "^7.15.8", + "@babel/runtime": "^7.15.4", + "@types/babel__core": "^7.1.16", + "@types/clean-css": "^4.2.5", + "@types/imagemin-gifsicle": "^7.0.1", + "@types/imagemin-mozjpeg": "^8.0.1", + "@types/imagemin-optipng": "^5.2.1", + "@types/imagemin-svgo": "^8.0.0", + "autoprefixer": "^10.4.0", + "babel-loader": "^8.2.3", + "chalk": "^4.1.2", + "chokidar": "^3.5.2", + "clean-css": "^5.2.4", + "cli-table3": "^0.6.0", + "collect.js": "^4.28.5", + "commander": "^7.2.0", + "concat": "^1.0.3", + "css-loader": "^5.2.6", + "cssnano": "^5.0.8", + "dotenv": "^10.0.0", + "dotenv-expand": "^5.1.0", + "file-loader": "^6.2.0", + "fs-extra": "^10.0.0", + "glob": "^7.2.0", + "html-loader": "^1.3.2", + "imagemin": "^7.0.1", + "img-loader": "^4.0.0", + "lodash": "^4.17.21", + "md5": "^2.3.0", + "mini-css-extract-plugin": "^1.6.2", + "node-libs-browser": "^2.2.1", + "postcss-load-config": "^3.1.0", + "postcss-loader": "^6.2.0", + "semver": "^7.3.5", + "strip-ansi": "^6.0.0", + "style-loader": "^2.0.0", + "terser": "^5.9.0", + "terser-webpack-plugin": "^5.2.4", + "vue-style-loader": "^4.1.3", + "webpack": "^5.60.0", + "webpack-cli": "^4.9.1", + "webpack-dev-server": "^4.7.3", + "webpack-merge": "^5.8.0", + "webpack-notifier": "^1.14.1", + "webpackbar": "^5.0.0-3", + "yargs": "^17.2.1" + }, + "bin": { + "laravel-mix": "bin/cli.js", + "mix": "bin/cli.js" + }, + "engines": { + "node": ">=12.14.0" + }, + "peerDependencies": { + "@babel/core": "^7.15.8", + "@babel/plugin-proposal-object-rest-spread": "^7.15.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.15.8", + "@babel/preset-env": "^7.15.8", + "postcss": "^8.3.11", + "webpack": "^5.60.0", + "webpack-cli": "^4.9.1" + } + }, + "node_modules/lilconfig": { + "version": "2.0.6", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "license": "MIT" + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "license": "MIT" + }, + "node_modules/lower-case": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/md5": { + "version": "2.3.0", + "license": "BSD-3-Clause", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mdn-data": { + "version": "2.0.14", + "license": "CC0-1.0" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.4.7", + "license": "Unlicense", + "dependencies": { + "fs-monkey": "^1.0.3" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "license": "MIT" + }, + "node_modules/mime": { + "version": "1.6.0", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "1.6.2", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0", + "webpack-sources": "^1.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.4.0 || ^5.0.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "license": "ISC" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.4", + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "license": "MIT" + }, + "node_modules/no-case": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-libs-browser": { + "version": "2.2.1", + "license": "MIT", + "dependencies": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, + "node_modules/node-notifier": { + "version": "9.0.1", + "license": "MIT", + "dependencies": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.3.0", + "which": "^2.0.2" + } + }, + "node_modules/node-releases": { + "version": "2.0.6", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.0", + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "license": "MIT" + }, + "node_modules/p-limit": { + "version": "2.3.0", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-pipe": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "license": "(MIT AND Zlib)" + }, + "node_modules/param-case": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "license": "ISC", + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-browserify": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "license": "MIT", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss": { + "version": "8.4.16", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-calc": { + "version": "8.2.4", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-colormin": { + "version": "5.3.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-convert-values": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "browserslist": "^4.20.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-comments": { + "version": "5.1.2", + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "5.1.0", + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-empty": { + "version": "5.1.1", + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "5.1.0", + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-load-config": { + "version": "3.1.4", + "license": "MIT", + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-loader": { + "version": "6.2.1", + "license": "MIT", + "dependencies": { + "cosmiconfig": "^7.0.0", + "klona": "^2.0.5", + "semver": "^7.3.5" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "5.1.6", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-merge-rules": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "5.1.1", + "license": "MIT", + "dependencies": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-params": { + "version": "5.1.3", + "license": "MIT", + "dependencies": { + "browserslist": "^4.16.6", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "5.2.1", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.0.0", + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "5.1.0", + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "5.1.1", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "5.1.1", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-string": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.16.6", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-url": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "5.1.1", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-ordered-values": { + "version": "5.1.3", + "license": "MIT", + "dependencies": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "5.1.1", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "license": "MIT" + }, + "node_modules/pretty-time": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/process": { + "version": "0.11.10", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "1.4.1", + "license": "MIT" + }, + "node_modules/pusher-js": { + "version": "7.4.0", + "license": "MIT", + "dependencies": { + "@types/node": "^14.14.31", + "tweetnacl": "^1.0.3" + } + }, + "node_modules/pusher-js/node_modules/@types/node": { + "version": "14.18.26", + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.10.3", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/string_decoder": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.7.1", + "license": "MIT", + "dependencies": { + "resolve": "^1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.0.1", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "license": "MIT" + }, + "node_modules/regenerator-transform": { + "version": "0.15.0", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-parser": { + "version": "2.2.11", + "license": "MIT" + }, + "node_modules/regexpu-core": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.0.1", + "regjsgen": "^0.6.0", + "regjsparser": "^0.8.2", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.6.0", + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.8.4", + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/replace-ext": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.1", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url-loader": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.54.5", + "license": "MIT", + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/sass-loader": { + "version": "13.0.2", + "license": "MIT", + "dependencies": { + "klona": "^2.0.4", + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + } + } + }, + "node_modules/schema-utils": { + "version": "2.7.1", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.3.7", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "license": "MIT" + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "license": "ISC" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "license": "ISC" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "license": "MIT", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "license": "ISC" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shellwords": { + "version": "0.1.1", + "license": "MIT" + }, + "node_modules/showdown": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "commander": "^9.0.0" + }, + "bin": { + "showdown": "bin/showdown.js" + }, + "funding": { + "type": "individual", + "url": "https://www.paypal.me/tiviesantos" + } + }, + "node_modules/showdown/node_modules/commander": { + "version": "9.4.0", + "license": "MIT", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "license": "ISC" + }, + "node_modules/slash": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.6.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/spdy-transport/node_modules/readable-stream": { + "version": "3.6.0", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/stable": { + "version": "0.1.8", + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.2.1", + "license": "MIT" + }, + "node_modules/stream-browserify": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-http": { + "version": "2.8.3", + "license": "MIT", + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/string-width": { + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/style-loader": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/style-loader/node_modules/schema-utils": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/stylehacks": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.16.6", + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svgo": { + "version": "2.8.0", + "license": "MIT", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.15.0", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.5", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.14", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "terser": "^5.14.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "license": "MIT" + }, + "node_modules/thunky": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/timers-browserify": { + "version": "2.0.12", + "license": "MIT", + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-arraybuffer": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tslib": { + "version": "2.4.0", + "license": "0BSD" + }, + "node_modules/tty-browserify": { + "version": "0.0.0", + "license": "MIT" + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "license": "Unlicense" + }, + "node_modules/type-is": { + "version": "1.6.18", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.5", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/url": { + "version": "0.11.0", + "license": "MIT", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "license": "MIT" + }, + "node_modules/util": { + "version": "0.11.1", + "license": "MIT", + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.3", + "license": "ISC" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vanillajs-datepicker": { + "version": "1.2.0", + "license": "MIT" + }, + "node_modules/vary": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "license": "MIT" + }, + "node_modules/vue-style-loader": { + "version": "4.1.3", + "license": "MIT", + "dependencies": { + "hash-sum": "^1.0.2", + "loader-utils": "^1.0.2" + } + }, + "node_modules/vue-style-loader/node_modules/json5": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/vue-style-loader/node_modules/loader-utils": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webpack": { + "version": "5.74.0", + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.10.0", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "4.10.0", + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.2.0", + "@webpack-cli/info": "^1.5.0", + "@webpack-cli/serve": "^1.7.0", + "colorette": "^2.0.14", + "commander": "^7.0.0", + "cross-spawn": "^7.0.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "@webpack-cli/migrate": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.3", + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv": { + "version": "8.11.0", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.10.0", + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.1", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.0.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.4.2" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.11.0", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-server/node_modules/ajv-keywords": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-merge": { + "version": "5.8.0", + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-notifier": { + "version": "1.15.0", + "license": "ISC", + "dependencies": { + "node-notifier": "^9.0.0", + "strip-ansi": "^6.0.0" + }, + "peerDependencies": { + "@types/webpack": ">4.41.31" + }, + "peerDependenciesMeta": { + "@types/webpack": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "1.4.3", + "license": "MIT", + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack/node_modules/webpack-sources": { + "version": "3.2.3", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpackbar": { + "version": "5.0.2", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "consola": "^2.15.3", + "pretty-time": "^1.1.0", + "std-env": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "webpack": "3 || 4 || 5" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.8.1", + "license": "MIT", + "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/xss": { + "version": "1.0.14", + "license": "MIT", + "dependencies": { + "commander": "^2.20.3", + "cssfilter": "0.0.10" + }, + "bin": { + "xss": "bin/xss" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/xss/node_modules/commander": { + "version": "2.20.3", + "license": "MIT" + }, + "node_modules/xtend": { + "version": "4.0.2", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.2", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "17.5.1", + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "license": "ISC", + "engines": { + "node": ">=12" + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.18.6", + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.18.13" + }, + "@babel/core": { + "version": "7.18.13", + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.13", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-module-transforms": "^7.18.9", + "@babel/helpers": "^7.18.9", + "@babel/parser": "^7.18.13", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.18.13", + "@babel/types": "^7.18.13", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0" + } + } + }, + "@babel/generator": { + "version": "7.18.13", + "requires": { + "@babel/types": "^7.18.13", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.18.9", + "requires": { + "@babel/helper-explode-assignable-expression": "^7.18.6", + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.18.9", + "requires": { + "@babel/compat-data": "^7.18.8", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.20.2", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0" + } + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.18.13", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.18.6", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "regexpu-core": "^5.1.0" + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.3.2", + "requires": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "dependencies": { + "semver": { + "version": "6.3.0" + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9" + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.18.6", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-function-name": { + "version": "7.18.9", + "requires": { + "@babel/template": "^7.18.6", + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.18.9", + "requires": { + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.18.9", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.18.9" + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.18.9", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-replace-supers": { + "version": "7.18.9", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-simple-access": { + "version": "7.18.6", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.18.9", + "requires": { + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.18.10" + }, + "@babel/helper-validator-identifier": { + "version": "7.18.6" + }, + "@babel/helper-validator-option": { + "version": "7.18.6" + }, + "@babel/helper-wrap-function": { + "version": "7.18.11", + "requires": { + "@babel/helper-function-name": "^7.18.9", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.18.11", + "@babel/types": "^7.18.10" + } + }, + "@babel/helpers": { + "version": "7.18.9", + "requires": { + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3" + }, + "has-flag": { + "version": "3.0.0" + }, + "supports-color": { + "version": "5.5.0", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.18.13" + }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.18.9", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.18.9" + } + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.18.10", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-proposal-class-static-block": { + "version": "7.18.6", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" + } + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.18.9", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.18.9", + "requires": { + "@babel/compat-data": "^7.18.8", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.18.8" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.18.9", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.18.6", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-import-assertions": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.18.6", + "requires": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-remap-async-to-generator": "^7.18.6" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.18.9", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.18.9", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.18.9", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.18.13", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.18.6", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.18.9", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.18.6", + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.18.8", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.18.9", + "requires": { + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.18.9", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.18.6", + "requires": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.18.6", + "requires": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.18.9", + "requires": { + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-module-transforms": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-validator-identifier": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.18.6", + "requires": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.18.6", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.18.8", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "regenerator-transform": "^0.15.0" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.18.10", + "requires": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.9", + "babel-plugin-polyfill-corejs2": "^0.3.2", + "babel-plugin-polyfill-corejs3": "^0.5.3", + "babel-plugin-polyfill-regenerator": "^0.4.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0" + } + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.18.9", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.18.6", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.18.9", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.18.10", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.18.6", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/preset-env": { + "version": "7.18.10", + "requires": { + "@babel/compat-data": "^7.18.8", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.18.10", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-dynamic-import": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-json-strings": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", + "@babel/plugin-proposal-numeric-separator": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.18.9", + "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.18.6", + "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-block-scoped-functions": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.18.9", + "@babel/plugin-transform-classes": "^7.18.9", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.18.9", + "@babel/plugin-transform-dotall-regex": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", + "@babel/plugin-transform-exponentiation-operator": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", + "@babel/plugin-transform-member-expression-literals": "^7.18.6", + "@babel/plugin-transform-modules-amd": "^7.18.6", + "@babel/plugin-transform-modules-commonjs": "^7.18.6", + "@babel/plugin-transform-modules-systemjs": "^7.18.9", + "@babel/plugin-transform-modules-umd": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.18.6", + "@babel/plugin-transform-new-target": "^7.18.6", + "@babel/plugin-transform-object-super": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.18.8", + "@babel/plugin-transform-property-literals": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-reserved-words": "^7.18.6", + "@babel/plugin-transform-shorthand-properties": "^7.18.6", + "@babel/plugin-transform-spread": "^7.18.9", + "@babel/plugin-transform-sticky-regex": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-regex": "^7.18.6", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.18.10", + "babel-plugin-polyfill-corejs2": "^0.3.2", + "babel-plugin-polyfill-corejs3": "^0.5.3", + "babel-plugin-polyfill-regenerator": "^0.4.0", + "core-js-compat": "^3.22.1", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0" + } + } + }, + "@babel/preset-modules": { + "version": "0.1.5", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/runtime": { + "version": "7.18.9", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.18.10", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + } + }, + "@babel/traverse": { + "version": "7.18.13", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.13", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.18.13", + "@babel/types": "^7.18.13", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.18.13", + "requires": { + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.18.6", + "to-fast-properties": "^2.0.0" + } + }, + "@colors/colors": { + "version": "1.5.0", + "optional": true + }, + "@discoveryjs/json-ext": { + "version": "0.5.7" + }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0" + }, + "@jridgewell/set-array": { + "version": "1.1.2" + }, + "@jridgewell/source-map": { + "version": "0.3.2", + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.15", + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@leichtgewicht/ip-codec": { + "version": "2.0.4" + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5" + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@popperjs/core": { + "version": "2.11.6" + }, + "@ryangjchandler/alpine-clipboard": { + "version": "2.2.0" + }, + "@trysound/sax": { + "version": "0.2.0" + }, + "@types/babel__core": { + "version": "7.1.19", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.4", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.18.0", + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/body-parser": { + "version": "1.19.2", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/bonjour": { + "version": "3.5.10", + "requires": { + "@types/node": "*" + } + }, + "@types/clean-css": { + "version": "4.2.5", + "requires": { + "@types/node": "*", + "source-map": "^0.6.0" + } + }, + "@types/connect": { + "version": "3.4.35", + "requires": { + "@types/node": "*" + } + }, + "@types/connect-history-api-fallback": { + "version": "1.3.5", + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "@types/eslint": { + "version": "8.4.6", + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.4", + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "0.0.51" + }, + "@types/express": { + "version": "4.17.13", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.30", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "@types/glob": { + "version": "7.2.0", + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/http-proxy": { + "version": "1.17.9", + "requires": { + "@types/node": "*" + } + }, + "@types/imagemin": { + "version": "8.0.0", + "requires": { + "@types/node": "*" + } + }, + "@types/imagemin-gifsicle": { + "version": "7.0.1", + "requires": { + "@types/imagemin": "*" + } + }, + "@types/imagemin-mozjpeg": { + "version": "8.0.1", + "requires": { + "@types/imagemin": "*" + } + }, + "@types/imagemin-optipng": { + "version": "5.2.1", + "requires": { + "@types/imagemin": "*" + } + }, + "@types/imagemin-svgo": { + "version": "8.0.1", + "requires": { + "@types/imagemin": "*", + "@types/svgo": "^1" + } + }, + "@types/json-schema": { + "version": "7.0.11" + }, + "@types/mime": { + "version": "3.0.1" + }, + "@types/minimatch": { + "version": "5.1.0" + }, + "@types/node": { + "version": "18.7.13" + }, + "@types/parse-json": { + "version": "4.0.0" + }, + "@types/qs": { + "version": "6.9.7" + }, + "@types/range-parser": { + "version": "1.2.4" + }, + "@types/retry": { + "version": "0.12.0" + }, + "@types/serve-index": { + "version": "1.9.1", + "requires": { + "@types/express": "*" + } + }, + "@types/serve-static": { + "version": "1.15.0", + "requires": { + "@types/mime": "*", + "@types/node": "*" + } + }, + "@types/sockjs": { + "version": "0.3.33", + "requires": { + "@types/node": "*" + } + }, + "@types/svgo": { + "version": "1.3.6" + }, + "@types/ws": { + "version": "8.5.3", + "requires": { + "@types/node": "*" + } + }, + "@vue/reactivity": { + "version": "3.1.5", + "requires": { + "@vue/shared": "3.1.5" + } + }, + "@vue/shared": { + "version": "3.1.5" + }, + "@webassemblyjs/ast": { + "version": "1.11.1", + "requires": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1" + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.1" + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.1" + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1" + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.1", + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.1", + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.1" + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.1", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "1.2.0", + "requires": {} + }, + "@webpack-cli/info": { + "version": "1.5.0", + "requires": { + "envinfo": "^7.7.3" + } + }, + "@webpack-cli/serve": { + "version": "1.7.0", + "requires": {} + }, + "@xtuc/ieee754": { + "version": "1.2.0" + }, + "@xtuc/long": { + "version": "4.2.2" + }, + "accepts": { + "version": "1.3.8", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.8.0" + }, + "acorn-import-assertions": { + "version": "1.8.0", + "requires": {} + }, + "adjust-sourcemap-loader": { + "version": "4.0.0", + "requires": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + } + }, + "ajv": { + "version": "6.12.6", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-formats": { + "version": "2.1.1", + "requires": { + "ajv": "^8.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.11.0", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0" + } + } + }, + "ajv-keywords": { + "version": "3.5.2", + "requires": {} + }, + "alpinejs": { + "version": "3.10.3", + "requires": { + "@vue/reactivity": "~3.1.1" + } + }, + "ansi-html-community": { + "version": "0.0.8" + }, + "ansi-regex": { + "version": "5.0.1" + }, + "ansi-styles": { + "version": "4.3.0", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "array-flatten": { + "version": "2.1.2" + }, + "array-union": { + "version": "2.1.0" + }, + "asn1.js": { + "version": "5.4.1", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0" + } + } + }, + "assert": { + "version": "1.5.0", + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1" + }, + "util": { + "version": "0.10.3", + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "asynckit": { + "version": "0.4.0" + }, + "autoprefixer": { + "version": "10.4.8", + "requires": { + "browserslist": "^4.21.3", + "caniuse-lite": "^1.0.30001373", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + } + }, + "axios": { + "version": "0.27.2", + "requires": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "babel-loader": { + "version": "8.2.5", + "requires": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.3.2", + "requires": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.2", + "semver": "^6.1.1" + }, + "dependencies": { + "semver": { + "version": "6.3.0" + } + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.5.3", + "requires": { + "@babel/helper-define-polyfill-provider": "^0.3.2", + "core-js-compat": "^3.21.0" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.4.0", + "requires": { + "@babel/helper-define-polyfill-provider": "^0.3.2" + } + }, + "balanced-match": { + "version": "1.0.2" + }, + "base64-js": { + "version": "1.5.1" + }, + "batch": { + "version": "0.6.1" + }, + "big.js": { + "version": "5.2.2" + }, + "binary-extensions": { + "version": "2.2.0" + }, + "bn.js": { + "version": "5.2.1" + }, + "body-parser": { + "version": "1.20.0", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2" + }, + "debug": { + "version": "2.6.9", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0" + } + } + }, + "bonjour-service": { + "version": "1.0.13", + "requires": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "boolbase": { + "version": "1.0.0" + }, + "bootstrap": { + "version": "5.2.0", + "requires": {} + }, + "brace-expansion": { + "version": "1.1.11", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0" + }, + "browserify-aes": { + "version": "1.2.0", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.2.1", + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1" + } + } + }, + "browserify-zlib": { + "version": "0.2.0", + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.21.3", + "requires": { + "caniuse-lite": "^1.0.30001370", + "electron-to-chromium": "^1.4.202", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.5" + } + }, + "buffer": { + "version": "4.9.2", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.2" + }, + "buffer-xor": { + "version": "1.0.3" + }, + "builtin-status-codes": { + "version": "3.0.0" + }, + "bytes": { + "version": "3.0.0" + }, + "call-bind": { + "version": "1.0.2", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0" + }, + "camel-case": { + "version": "4.1.2", + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "caniuse-api": { + "version": "3.0.0", + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001383" + }, + "chalk": { + "version": "4.1.2", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "charenc": { + "version": "0.0.2" + }, + "chart.js": { + "version": "3.9.1" + }, + "chokidar": { + "version": "3.5.3", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "chrome-trace-event": { + "version": "1.0.3" + }, + "cipher-base": { + "version": "1.0.4", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "clean-css": { + "version": "5.3.1", + "requires": { + "source-map": "~0.6.0" + } + }, + "cli-table3": { + "version": "0.6.2", + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + } + }, + "cliui": { + "version": "7.0.4", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone-deep": { + "version": "4.0.1", + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "collect.js": { + "version": "4.34.3" + }, + "color-convert": { + "version": "2.0.1", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4" + }, + "colord": { + "version": "2.9.3" + }, + "colorette": { + "version": "2.0.19" + }, + "combined-stream": { + "version": "1.0.8", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "7.2.0" + }, + "commondir": { + "version": "1.0.1" + }, + "compressible": { + "version": "2.0.18", + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0" + } + } + }, + "concat": { + "version": "1.0.3", + "requires": { + "commander": "^2.9.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3" + } + } + }, + "concat-map": { + "version": "0.0.1" + }, + "connect-history-api-fallback": { + "version": "2.0.0" + }, + "consola": { + "version": "2.15.3" + }, + "console-browserify": { + "version": "1.2.0" + }, + "constants-browserify": { + "version": "1.0.0" + }, + "content-disposition": { + "version": "0.5.4", + "requires": { + "safe-buffer": "5.2.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1" + } + } + }, + "content-type": { + "version": "1.0.4" + }, + "convert-source-map": { + "version": "1.8.0", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.5.0" + }, + "cookie-signature": { + "version": "1.0.6" + }, + "core-js-compat": { + "version": "3.25.0", + "requires": { + "browserslist": "^4.21.3", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0" + } + } + }, + "core-util-is": { + "version": "1.0.3" + }, + "cosmiconfig": { + "version": "7.0.1", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "create-ecdh": { + "version": "4.0.4", + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0" + } + } + }, + "create-hash": { + "version": "1.2.0", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "7.0.3", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypt": { + "version": "0.0.2" + }, + "crypto-browserify": { + "version": "3.12.0", + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "css-declaration-sorter": { + "version": "6.3.0", + "requires": {} + }, + "css-loader": { + "version": "5.2.7", + "requires": { + "icss-utils": "^5.1.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.15", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^3.0.0", + "semver": "^7.3.5" + }, + "dependencies": { + "schema-utils": { + "version": "3.1.1", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "css-select": { + "version": "4.3.0", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "dependencies": { + "domhandler": { + "version": "4.3.1", + "requires": { + "domelementtype": "^2.2.0" + } + } + } + }, + "css-tree": { + "version": "1.1.3", + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + } + }, + "css-what": { + "version": "6.1.0" + }, + "cssesc": { + "version": "3.0.0" + }, + "cssfilter": { + "version": "0.0.10" + }, + "cssnano": { + "version": "5.1.13", + "requires": { + "cssnano-preset-default": "^5.2.12", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + } + }, + "cssnano-preset-default": { + "version": "5.2.12", + "requires": { + "css-declaration-sorter": "^6.3.0", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.0", + "postcss-convert-values": "^5.1.2", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.6", + "postcss-merge-rules": "^5.1.2", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.3", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.0", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.0", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + } + }, + "cssnano-utils": { + "version": "3.1.0", + "requires": {} + }, + "csso": { + "version": "4.2.0", + "requires": { + "css-tree": "^1.1.2" + } + }, + "debug": { + "version": "4.3.4", + "requires": { + "ms": "2.1.2" + } + }, + "default-gateway": { + "version": "6.0.3", + "requires": { + "execa": "^5.0.0" + } + }, + "define-lazy-prop": { + "version": "2.0.0" + }, + "define-properties": { + "version": "1.1.4", + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "delayed-stream": { + "version": "1.0.0" + }, + "depd": { + "version": "2.0.0" + }, + "des.js": { + "version": "1.0.1", + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.2.0" + }, + "detect-node": { + "version": "2.1.0" + }, + "diffie-hellman": { + "version": "5.0.3", + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0" + } + } + }, + "dir-glob": { + "version": "3.0.1", + "requires": { + "path-type": "^4.0.0" + } + }, + "dns-equal": { + "version": "1.0.0" + }, + "dns-packet": { + "version": "5.4.0", + "requires": { + "@leichtgewicht/ip-codec": "^2.0.1" + } + }, + "dom-serializer": { + "version": "1.4.1", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "dependencies": { + "domhandler": { + "version": "4.3.1", + "requires": { + "domelementtype": "^2.2.0" + } + } + } + }, + "domain-browser": { + "version": "1.2.0" + }, + "domelementtype": { + "version": "2.3.0" + }, + "domhandler": { + "version": "3.3.0", + "requires": { + "domelementtype": "^2.0.1" + } + }, + "domutils": { + "version": "2.8.0", + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "dependencies": { + "domhandler": { + "version": "4.3.1", + "requires": { + "domelementtype": "^2.2.0" + } + } + } + }, + "dot-case": { + "version": "3.0.4", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "dotenv": { + "version": "10.0.0" + }, + "dotenv-expand": { + "version": "5.1.0" + }, + "ee-first": { + "version": "1.1.1" + }, + "electron-to-chromium": { + "version": "1.4.230" + }, + "elliptic": { + "version": "6.5.4", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0" + } + } + }, + "emoji-regex": { + "version": "8.0.0" + }, + "emojis-list": { + "version": "3.0.0" + }, + "encodeurl": { + "version": "1.0.2" + }, + "enhanced-resolve": { + "version": "5.10.0", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "entities": { + "version": "2.2.0" + }, + "envinfo": { + "version": "7.8.1" + }, + "error-ex": { + "version": "1.3.2", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-module-lexer": { + "version": "0.9.3" + }, + "escalade": { + "version": "3.1.1" + }, + "escape-html": { + "version": "1.0.3" + }, + "escape-string-regexp": { + "version": "1.0.5" + }, + "eslint-scope": { + "version": "5.1.1", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.3.0", + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0" + } + } + }, + "estraverse": { + "version": "4.3.0" + }, + "esutils": { + "version": "2.0.3" + }, + "etag": { + "version": "1.8.1" + }, + "eventemitter3": { + "version": "4.0.7" + }, + "events": { + "version": "3.3.0" + }, + "evp_bytestokey": { + "version": "1.0.3", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "5.1.1", + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "express": { + "version": "4.18.1", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.10.3", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1" + }, + "debug": { + "version": "2.6.9", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0" + }, + "safe-buffer": { + "version": "5.2.1" + } + } + }, + "fast-deep-equal": { + "version": "3.1.3" + }, + "fast-glob": { + "version": "3.2.11", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0" + }, + "fastest-levenshtein": { + "version": "1.0.16" + }, + "fastq": { + "version": "1.13.0", + "requires": { + "reusify": "^1.0.4" + } + }, + "faye-websocket": { + "version": "0.11.4", + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "file-loader": { + "version": "6.2.0", + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "3.1.1", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "file-type": { + "version": "12.4.2" + }, + "fill-range": { + "version": "7.0.1", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0" + } + } + }, + "find-cache-dir": { + "version": "3.3.2", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "follow-redirects": { + "version": "1.15.1" + }, + "form-data": { + "version": "4.0.0", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.2.0" + }, + "fraction.js": { + "version": "4.2.0" + }, + "fresh": { + "version": "0.5.2" + }, + "fs-extra": { + "version": "10.1.0", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs-monkey": { + "version": "1.0.3" + }, + "fs.realpath": { + "version": "1.0.0" + }, + "function-bind": { + "version": "1.1.1" + }, + "gensync": { + "version": "1.0.0-beta.2" + }, + "get-caller-file": { + "version": "2.0.5" + }, + "get-intrinsic": { + "version": "1.1.2", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-stream": { + "version": "6.0.1" + }, + "glob": { + "version": "7.2.3", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "requires": { + "is-glob": "^4.0.1" + } + }, + "glob-to-regexp": { + "version": "0.4.1" + }, + "globals": { + "version": "11.12.0" + }, + "globby": { + "version": "10.0.2", + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.10" + }, + "growly": { + "version": "1.3.0" + }, + "handle-thing": { + "version": "2.0.1" + }, + "has": { + "version": "1.0.3", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0" + }, + "has-property-descriptors": { + "version": "1.0.0", + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3" + }, + "hash-base": { + "version": "3.1.0", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1" + } + } + }, + "hash-sum": { + "version": "1.0.2" + }, + "hash.js": { + "version": "1.1.7", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0" + }, + "hmac-drbg": { + "version": "1.0.1", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hpack.js": { + "version": "2.1.6", + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "html-entities": { + "version": "2.3.3" + }, + "html-loader": { + "version": "1.3.2", + "requires": { + "html-minifier-terser": "^5.1.1", + "htmlparser2": "^4.1.0", + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "3.1.1", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "html-minifier-terser": { + "version": "5.1.1", + "requires": { + "camel-case": "^4.1.1", + "clean-css": "^4.2.3", + "commander": "^4.1.1", + "he": "^1.2.0", + "param-case": "^3.0.3", + "relateurl": "^0.2.7", + "terser": "^4.6.3" + }, + "dependencies": { + "clean-css": { + "version": "4.2.4", + "requires": { + "source-map": "~0.6.0" + } + }, + "commander": { + "version": "4.1.1" + }, + "terser": { + "version": "4.8.1", + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "commander": { + "version": "2.20.3" + } + } + } + } + }, + "htmlparser2": { + "version": "4.1.0", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + }, + "http-deceiver": { + "version": "1.2.7" + }, + "http-errors": { + "version": "2.0.0", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "http-parser-js": { + "version": "0.5.8" + }, + "http-proxy": { + "version": "1.18.1", + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "2.0.6", + "requires": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + } + }, + "https-browserify": { + "version": "1.0.0" + }, + "human-signals": { + "version": "2.1.0" + }, + "iconv-lite": { + "version": "0.4.24", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-utils": { + "version": "5.1.0", + "requires": {} + }, + "ieee754": { + "version": "1.2.1" + }, + "ignore": { + "version": "5.2.0" + }, + "imagemin": { + "version": "7.0.1", + "requires": { + "file-type": "^12.0.0", + "globby": "^10.0.0", + "graceful-fs": "^4.2.2", + "junk": "^3.1.0", + "make-dir": "^3.0.0", + "p-pipe": "^3.0.0", + "replace-ext": "^1.0.0" + } + }, + "img-loader": { + "version": "4.0.0", + "requires": { + "loader-utils": "^1.1.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, + "immutable": { + "version": "4.1.0" + }, + "import-fresh": { + "version": "3.3.0", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-local": { + "version": "3.1.0", + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4" + }, + "interpret": { + "version": "2.2.0" + }, + "ipaddr.js": { + "version": "2.0.1" + }, + "is-arrayish": { + "version": "0.2.1" + }, + "is-binary-path": { + "version": "2.1.0", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "1.1.6" + }, + "is-core-module": { + "version": "2.10.0", + "requires": { + "has": "^1.0.3" + } + }, + "is-docker": { + "version": "2.2.1" + }, + "is-extglob": { + "version": "2.1.1" + }, + "is-fullwidth-code-point": { + "version": "3.0.0" + }, + "is-glob": { + "version": "4.0.3", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0" + }, + "is-plain-obj": { + "version": "3.0.0" + }, + "is-plain-object": { + "version": "2.0.4", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-stream": { + "version": "2.0.1" + }, + "is-wsl": { + "version": "2.2.0", + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0" + }, + "isexe": { + "version": "2.0.0" + }, + "isobject": { + "version": "3.0.1" + }, + "jest-worker": { + "version": "27.5.1", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jquery": { + "version": "3.6.0" + }, + "jquery.waitforimages": { + "version": "2.4.0" + }, + "js-tokens": { + "version": "4.0.0" + }, + "jsesc": { + "version": "2.5.2" + }, + "json-parse-even-better-errors": { + "version": "2.3.1" + }, + "json-schema-traverse": { + "version": "0.4.1" + }, + "json5": { + "version": "2.2.1" + }, + "jsonfile": { + "version": "6.1.0", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "junk": { + "version": "3.1.0" + }, + "kind-of": { + "version": "6.0.3" + }, + "klona": { + "version": "2.0.5" + }, + "laravel-echo": { + "version": "1.13.1" + }, + "laravel-mix": { + "version": "6.0.49", + "requires": { + "@babel/core": "^7.15.8", + "@babel/plugin-proposal-object-rest-spread": "^7.15.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.15.8", + "@babel/preset-env": "^7.15.8", + "@babel/runtime": "^7.15.4", + "@types/babel__core": "^7.1.16", + "@types/clean-css": "^4.2.5", + "@types/imagemin-gifsicle": "^7.0.1", + "@types/imagemin-mozjpeg": "^8.0.1", + "@types/imagemin-optipng": "^5.2.1", + "@types/imagemin-svgo": "^8.0.0", + "autoprefixer": "^10.4.0", + "babel-loader": "^8.2.3", + "chalk": "^4.1.2", + "chokidar": "^3.5.2", + "clean-css": "^5.2.4", + "cli-table3": "^0.6.0", + "collect.js": "^4.28.5", + "commander": "^7.2.0", + "concat": "^1.0.3", + "css-loader": "^5.2.6", + "cssnano": "^5.0.8", + "dotenv": "^10.0.0", + "dotenv-expand": "^5.1.0", + "file-loader": "^6.2.0", + "fs-extra": "^10.0.0", + "glob": "^7.2.0", + "html-loader": "^1.3.2", + "imagemin": "^7.0.1", + "img-loader": "^4.0.0", + "lodash": "^4.17.21", + "md5": "^2.3.0", + "mini-css-extract-plugin": "^1.6.2", + "node-libs-browser": "^2.2.1", + "postcss-load-config": "^3.1.0", + "postcss-loader": "^6.2.0", + "semver": "^7.3.5", + "strip-ansi": "^6.0.0", + "style-loader": "^2.0.0", + "terser": "^5.9.0", + "terser-webpack-plugin": "^5.2.4", + "vue-style-loader": "^4.1.3", + "webpack": "^5.60.0", + "webpack-cli": "^4.9.1", + "webpack-dev-server": "^4.7.3", + "webpack-merge": "^5.8.0", + "webpack-notifier": "^1.14.1", + "webpackbar": "^5.0.0-3", + "yargs": "^17.2.1" + } + }, + "lilconfig": { + "version": "2.0.6" + }, + "lines-and-columns": { + "version": "1.2.4" + }, + "loader-runner": { + "version": "4.3.0" + }, + "loader-utils": { + "version": "2.0.2", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "locate-path": { + "version": "5.0.0", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21" + }, + "lodash.debounce": { + "version": "4.0.8" + }, + "lodash.memoize": { + "version": "4.1.2" + }, + "lodash.uniq": { + "version": "4.5.0" + }, + "lower-case": { + "version": "2.0.2", + "requires": { + "tslib": "^2.0.3" + } + }, + "lru-cache": { + "version": "6.0.0", + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0" + } + } + }, + "md5": { + "version": "2.3.0", + "requires": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "md5.js": { + "version": "1.3.5", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mdn-data": { + "version": "2.0.14" + }, + "media-typer": { + "version": "0.3.0" + }, + "memfs": { + "version": "3.4.7", + "requires": { + "fs-monkey": "^1.0.3" + } + }, + "merge-descriptors": { + "version": "1.0.1" + }, + "merge-stream": { + "version": "2.0.0" + }, + "merge2": { + "version": "1.4.1" + }, + "methods": { + "version": "1.1.2" + }, + "micromatch": { + "version": "4.0.5", + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "miller-rabin": { + "version": "4.0.1", + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0" + } + } + }, + "mime": { + "version": "1.6.0" + }, + "mime-db": { + "version": "1.52.0" + }, + "mime-types": { + "version": "2.1.35", + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "2.1.0" + }, + "mini-css-extract-plugin": { + "version": "1.6.2", + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0", + "webpack-sources": "^1.1.0" + }, + "dependencies": { + "schema-utils": { + "version": "3.1.1", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "minimalistic-assert": { + "version": "1.0.1" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1" + }, + "minimatch": { + "version": "3.1.2", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6" + }, + "ms": { + "version": "2.1.2" + }, + "multicast-dns": { + "version": "7.2.5", + "requires": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + } + }, + "nanoid": { + "version": "3.3.4" + }, + "negotiator": { + "version": "0.6.3" + }, + "neo-async": { + "version": "2.6.2" + }, + "no-case": { + "version": "3.0.4", + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node-forge": { + "version": "1.3.1" + }, + "node-libs-browser": { + "version": "2.2.1", + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, + "node-notifier": { + "version": "9.0.1", + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.3.0", + "which": "^2.0.2" + } + }, + "node-releases": { + "version": "2.0.6" + }, + "normalize-path": { + "version": "3.0.0" + }, + "normalize-range": { + "version": "0.1.2" + }, + "normalize-url": { + "version": "6.1.0" + }, + "npm-run-path": { + "version": "4.0.1", + "requires": { + "path-key": "^3.0.0" + } + }, + "nth-check": { + "version": "2.1.1", + "requires": { + "boolbase": "^1.0.0" + } + }, + "object-assign": { + "version": "4.1.1" + }, + "object-inspect": { + "version": "1.12.2" + }, + "object-keys": { + "version": "1.1.1" + }, + "object.assign": { + "version": "4.1.4", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "obuf": { + "version": "1.1.2" + }, + "on-finished": { + "version": "2.4.1", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2" + }, + "once": { + "version": "1.4.0", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "8.4.0", + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, + "os-browserify": { + "version": "0.3.0" + }, + "p-limit": { + "version": "2.3.0", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-pipe": { + "version": "3.1.0" + }, + "p-retry": { + "version": "4.6.2", + "requires": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + } + }, + "p-try": { + "version": "2.2.0" + }, + "pako": { + "version": "1.0.11" + }, + "param-case": { + "version": "3.0.4", + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "parent-module": { + "version": "1.0.1", + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.6", + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-json": { + "version": "5.2.0", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parseurl": { + "version": "1.3.3" + }, + "pascal-case": { + "version": "3.1.2", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-browserify": { + "version": "0.0.1" + }, + "path-exists": { + "version": "4.0.0" + }, + "path-is-absolute": { + "version": "1.0.1" + }, + "path-key": { + "version": "3.1.1" + }, + "path-parse": { + "version": "1.0.7" + }, + "path-to-regexp": { + "version": "0.1.7" + }, + "path-type": { + "version": "4.0.0" + }, + "pbkdf2": { + "version": "3.1.2", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picocolors": { + "version": "1.0.0" + }, + "picomatch": { + "version": "2.3.1" + }, + "pkg-dir": { + "version": "4.2.0", + "requires": { + "find-up": "^4.0.0" + } + }, + "postcss": { + "version": "8.4.16", + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "postcss-calc": { + "version": "8.2.4", + "requires": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-colormin": { + "version": "5.3.0", + "requires": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-convert-values": { + "version": "5.1.2", + "requires": { + "browserslist": "^4.20.3", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-discard-comments": { + "version": "5.1.2", + "requires": {} + }, + "postcss-discard-duplicates": { + "version": "5.1.0", + "requires": {} + }, + "postcss-discard-empty": { + "version": "5.1.1", + "requires": {} + }, + "postcss-discard-overridden": { + "version": "5.1.0", + "requires": {} + }, + "postcss-load-config": { + "version": "3.1.4", + "requires": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + } + }, + "postcss-loader": { + "version": "6.2.1", + "requires": { + "cosmiconfig": "^7.0.0", + "klona": "^2.0.5", + "semver": "^7.3.5" + } + }, + "postcss-merge-longhand": { + "version": "5.1.6", + "requires": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.0" + } + }, + "postcss-merge-rules": { + "version": "5.1.2", + "requires": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-minify-font-values": { + "version": "5.1.0", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-gradients": { + "version": "5.1.1", + "requires": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-params": { + "version": "5.1.3", + "requires": { + "browserslist": "^4.16.6", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-selectors": { + "version": "5.2.1", + "requires": { + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-modules-extract-imports": { + "version": "3.0.0", + "requires": {} + }, + "postcss-modules-local-by-default": { + "version": "4.0.0", + "requires": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "3.0.0", + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-modules-values": { + "version": "4.0.0", + "requires": { + "icss-utils": "^5.0.0" + } + }, + "postcss-normalize-charset": { + "version": "5.1.0", + "requires": {} + }, + "postcss-normalize-display-values": { + "version": "5.1.0", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-positions": { + "version": "5.1.1", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "5.1.1", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-string": { + "version": "5.1.0", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "5.1.0", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-unicode": { + "version": "5.1.0", + "requires": { + "browserslist": "^4.16.6", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-url": { + "version": "5.1.0", + "requires": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-whitespace": { + "version": "5.1.1", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-ordered-values": { + "version": "5.1.3", + "requires": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-reduce-initial": { + "version": "5.1.0", + "requires": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "5.1.0", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-selector-parser": { + "version": "6.0.10", + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-svgo": { + "version": "5.1.0", + "requires": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + } + }, + "postcss-unique-selectors": { + "version": "5.1.1", + "requires": { + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-value-parser": { + "version": "4.2.0" + }, + "pretty-time": { + "version": "1.1.0" + }, + "process": { + "version": "0.11.10" + }, + "process-nextick-args": { + "version": "2.0.1" + }, + "proxy-addr": { + "version": "2.0.7", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "dependencies": { + "ipaddr.js": { + "version": "1.9.1" + } + } + }, + "public-encrypt": { + "version": "4.0.3", + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0" + } + } + }, + "punycode": { + "version": "1.4.1" + }, + "pusher-js": { + "version": "7.4.0", + "requires": { + "@types/node": "^14.14.31", + "tweetnacl": "^1.0.3" + }, + "dependencies": { + "@types/node": { + "version": "14.18.26" + } + } + }, + "qs": { + "version": "6.10.3", + "requires": { + "side-channel": "^1.0.4" + } + }, + "querystring": { + "version": "0.2.0" + }, + "querystring-es3": { + "version": "0.2.1" + }, + "queue-microtask": { + "version": "1.2.3" + }, + "randombytes": { + "version": "2.1.0", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1" + }, + "raw-body": { + "version": "2.5.1", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2" + } + } + }, + "readable-stream": { + "version": "2.3.7", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "string_decoder": { + "version": "1.1.1", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "readdirp": { + "version": "3.6.0", + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.7.1", + "requires": { + "resolve": "^1.9.0" + } + }, + "regenerate": { + "version": "1.4.2" + }, + "regenerate-unicode-properties": { + "version": "10.0.1", + "requires": { + "regenerate": "^1.4.2" + } + }, + "regenerator-runtime": { + "version": "0.13.9" + }, + "regenerator-transform": { + "version": "0.15.0", + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regex-parser": { + "version": "2.2.11" + }, + "regexpu-core": { + "version": "5.1.0", + "requires": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.0.1", + "regjsgen": "^0.6.0", + "regjsparser": "^0.8.2", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" + } + }, + "regjsgen": { + "version": "0.6.0" + }, + "regjsparser": { + "version": "0.8.4", + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0" + } + } + }, + "relateurl": { + "version": "0.2.7" + }, + "replace-ext": { + "version": "1.0.1" + }, + "require-directory": { + "version": "2.1.1" + }, + "require-from-string": { + "version": "2.0.2" + }, + "requires-port": { + "version": "1.0.0" + }, + "resolve": { + "version": "1.22.1", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0" + } + } + }, + "resolve-from": { + "version": "4.0.0" + }, + "resolve-url-loader": { + "version": "5.0.0", + "requires": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + } + }, + "retry": { + "version": "0.13.1" + }, + "reusify": { + "version": "1.0.4" + }, + "rimraf": { + "version": "3.0.2", + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-parallel": { + "version": "1.2.0", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-buffer": { + "version": "5.1.2" + }, + "safer-buffer": { + "version": "2.1.2" + }, + "sass": { + "version": "1.54.5", + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, + "sass-loader": { + "version": "13.0.2", + "requires": { + "klona": "^2.0.4", + "neo-async": "^2.6.2" + } + }, + "schema-utils": { + "version": "2.7.1", + "requires": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + } + }, + "select-hose": { + "version": "2.0.0" + }, + "selfsigned": { + "version": "2.0.1", + "requires": { + "node-forge": "^1" + } + }, + "semver": { + "version": "7.3.7", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "send": { + "version": "0.18.0", + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0" + } + } + }, + "ms": { + "version": "2.1.3" + } + } + }, + "serialize-javascript": { + "version": "6.0.0", + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2" + }, + "http-errors": { + "version": "1.6.3", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3" + }, + "ms": { + "version": "2.0.0" + }, + "setprototypeof": { + "version": "1.1.0" + }, + "statuses": { + "version": "1.5.0" + } + } + }, + "serve-static": { + "version": "1.15.0", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "setimmediate": { + "version": "1.0.5" + }, + "setprototypeof": { + "version": "1.2.0" + }, + "sha.js": { + "version": "2.4.11", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallow-clone": { + "version": "3.0.1", + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0" + }, + "shellwords": { + "version": "0.1.1" + }, + "showdown": { + "version": "2.1.0", + "requires": { + "commander": "^9.0.0" + }, + "dependencies": { + "commander": { + "version": "9.4.0" + } + } + }, + "side-channel": { + "version": "1.0.4", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.7" + }, + "slash": { + "version": "3.0.0" + }, + "sockjs": { + "version": "0.3.24", + "requires": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "source-list-map": { + "version": "2.0.1" + }, + "source-map": { + "version": "0.6.1" + }, + "source-map-js": { + "version": "1.0.2" + }, + "source-map-support": { + "version": "0.5.21", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spdy": { + "version": "4.0.2", + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + } + }, + "spdy-transport": { + "version": "3.0.0", + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "stable": { + "version": "0.1.8" + }, + "statuses": { + "version": "2.0.1" + }, + "std-env": { + "version": "3.2.1" + }, + "stream-browserify": { + "version": "2.0.2", + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.8.3", + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "string_decoder": { + "version": "1.3.0", + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1" + } + } + }, + "string-width": { + "version": "4.2.3", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-final-newline": { + "version": "2.0.0" + }, + "style-loader": { + "version": "2.0.0", + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "3.1.1", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "stylehacks": { + "version": "5.1.0", + "requires": { + "browserslist": "^4.16.6", + "postcss-selector-parser": "^6.0.4" + } + }, + "supports-color": { + "version": "7.2.0", + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0" + }, + "svgo": { + "version": "2.8.0", + "requires": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + } + }, + "tapable": { + "version": "2.2.1" + }, + "terser": { + "version": "5.15.0", + "requires": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "commander": { + "version": "2.20.3" + } + } + }, + "terser-webpack-plugin": { + "version": "5.3.5", + "requires": { + "@jridgewell/trace-mapping": "^0.3.14", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "terser": "^5.14.1" + }, + "dependencies": { + "schema-utils": { + "version": "3.1.1", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "thunky": { + "version": "1.1.0" + }, + "timers-browserify": { + "version": "2.0.12", + "requires": { + "setimmediate": "^1.0.4" + } + }, + "to-arraybuffer": { + "version": "1.0.1" + }, + "to-fast-properties": { + "version": "2.0.0" + }, + "to-regex-range": { + "version": "5.0.1", + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1" + }, + "tslib": { + "version": "2.4.0" + }, + "tty-browserify": { + "version": "0.0.0" + }, + "tweetnacl": { + "version": "1.0.3" + }, + "type-is": { + "version": "1.6.18", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "2.0.0" + }, + "unicode-match-property-ecmascript": { + "version": "2.0.0", + "requires": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "2.0.0" + }, + "unicode-property-aliases-ecmascript": { + "version": "2.0.0" + }, + "universalify": { + "version": "2.0.0" + }, + "unpipe": { + "version": "1.0.0" + }, + "update-browserslist-db": { + "version": "1.0.5", + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "uri-js": { + "version": "4.4.1", + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1" + } + } + }, + "url": { + "version": "0.11.0", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2" + } + } + }, + "util": { + "version": "0.11.1", + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3" + } + } + }, + "util-deprecate": { + "version": "1.0.2" + }, + "utils-merge": { + "version": "1.0.1" + }, + "uuid": { + "version": "8.3.2" + }, + "vanillajs-datepicker": { + "version": "1.2.0" + }, + "vary": { + "version": "1.1.2" + }, + "vm-browserify": { + "version": "1.1.2" + }, + "vue-style-loader": { + "version": "4.1.3", + "requires": { + "hash-sum": "^1.0.2", + "loader-utils": "^1.0.2" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, + "watchpack": { + "version": "2.4.0", + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "wbuf": { + "version": "1.7.3", + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "webpack": { + "version": "5.74.0", + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.10.0", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "dependencies": { + "schema-utils": { + "version": "3.1.1", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "webpack-sources": { + "version": "3.2.3" + } + } + }, + "webpack-cli": { + "version": "4.10.0", + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.2.0", + "@webpack-cli/info": "^1.5.0", + "@webpack-cli/serve": "^1.7.0", + "colorette": "^2.0.14", + "commander": "^7.0.0", + "cross-spawn": "^7.0.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "webpack-merge": "^5.7.3" + } + }, + "webpack-dev-middleware": { + "version": "5.3.3", + "requires": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.11.0", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0" + }, + "schema-utils": { + "version": "4.0.0", + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + } + } + } + }, + "webpack-dev-server": { + "version": "4.10.0", + "requires": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.1", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.0.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.4.2" + }, + "dependencies": { + "ajv": { + "version": "8.11.0", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0" + }, + "schema-utils": { + "version": "4.0.0", + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + } + } + } + }, + "webpack-merge": { + "version": "5.8.0", + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + } + }, + "webpack-notifier": { + "version": "1.15.0", + "requires": { + "node-notifier": "^9.0.0", + "strip-ansi": "^6.0.0" + } + }, + "webpack-sources": { + "version": "1.4.3", + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "webpackbar": { + "version": "5.0.2", + "requires": { + "chalk": "^4.1.0", + "consola": "^2.15.3", + "pretty-time": "^1.1.0", + "std-env": "^3.0.1" + } + }, + "websocket-driver": { + "version": "0.7.4", + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4" + }, + "which": { + "version": "2.0.2", + "requires": { + "isexe": "^2.0.0" + } + }, + "wildcard": { + "version": "2.0.0" + }, + "wrap-ansi": { + "version": "7.0.0", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2" + }, + "ws": { + "version": "8.8.1", + "requires": {} + }, + "xss": { + "version": "1.0.14", + "requires": { + "commander": "^2.20.3", + "cssfilter": "0.0.10" + }, + "dependencies": { + "commander": { + "version": "2.20.3" + } + } + }, + "xtend": { + "version": "4.0.2" + }, + "y18n": { + "version": "5.0.8" + }, + "yallist": { + "version": "4.0.0" + }, + "yaml": { + "version": "1.10.2" + }, + "yargs": { + "version": "17.5.1", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + } + }, + "yargs-parser": { + "version": "21.1.1" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..43856d3 --- /dev/null +++ b/package.json @@ -0,0 +1,30 @@ +{ + "scripts": { + "dev": "npm run development", + "development": "mix", + "watch": "mix watch", + "watch-poll": "mix watch -- --watch-options-poll=1000", + "hot": "mix watch --hot", + "prod": "npm run production", + "production": "mix --production" + }, + "dependencies": { + "@popperjs/core": "^2.11.6", + "@ryangjchandler/alpine-clipboard": "^2.2.0", + "alpinejs": "^3.10.3", + "axios": "^0.27.2", + "bootstrap": "^5.2.0", + "chart.js": "^3.9.1", + "jquery": "^3.6.0", + "jquery.waitforimages": "^2.4.0", + "laravel-echo": "^1.13.1", + "laravel-mix": "^6.0.49", + "pusher-js": "^7.3.0", + "resolve-url-loader": "^5.0.0", + "sass": "^1.54.4", + "sass-loader": "^13.0.2", + "showdown": "^2.1.0", + "vanillajs-datepicker": "^1.2.0", + "xss": "^1.0.13" + } +} diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..c8f55a6 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,13 @@ +includes: +- ./vendor/nunomaduro/larastan/extension.neon + +parameters: + paths: + - app + - bootstrap + - config + - database + - routes + level: 0 + checkOctaneCompatibility: true + checkModelProperties: true diff --git a/public/content b/public/content new file mode 100644 index 0000000..4e1391e --- /dev/null +++ b/public/content @@ -0,0 +1 @@ +/var/www/html/storage/app/content \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..21b472a734e767e620e88fde840dd518f1b0e5fd GIT binary patch literal 4286 zcmeIzYfuwc6bJB|*CyE{Y{EN%Kq6F#g336kpdB1idr8iipaZ)tyT!w zhi_|Vd~~qITE}TCDx#M1D%PSBosO{Yq(VuEKOrO%VT-(o*uLw9zpL}=($#qW{(rs$D=9uf!6-YO;um4v zfY`cd6~&Lr5c9J#D1HvgMavL_2IZ14gUzPVC%7hTRfu3OL%|-jkD>0DE2;Bk8t+H@ zHA*;uy+cazgHwLe{dHbAJT!A>}<8wt;@Q60wkGXat)&OTPw+fwh3&61p&Gw3_hp5O22_a3vil=bhKqi|n zApCVw;eqne1~{)(LUjP`at3QZwRr4>xW;*$S11vXTmebh9TD15GfWHT@OsbUGv+}% z_TrGob+|U)l?upu0U5G2P<8WcYy{Nc^Yxut*5f>mT{KuVvVwDJn$$eQXWoCGTWA5< zL=j=Jg8Jf{vBRNWr-a%dc`tnCYl9VTXX~^I8S1|b=VKG*m&k9;sp(%eKF9WW9~KTnbD0phI5{$iKTKO*+P-XU0PpjL;Ntfpl9Ghn5s)S)~9%9 zHifCk#i2f)mg3Ya!+ev3P+OIf<5d%);qowlxD??Fmm<3vu)6qR^{f0T%3p#wWqF!Z zrVtWV3C&wk5%U6Ei3^A3=m2OQ5eUsAS?XS+)b=YeK~c!lQk;8b3K1z5lc+uV0Q=>n z7-$)zg_f})UB-n%OPsF9Z}IwNE#q|L>clY4dHpArviTAsE%T-;Yo^D-^(m2XZSv4A zQzGCRYby3!49BidkD{(84e!6qfR9a>i$o;~QOHISFJzO1S9)Ze0dCA03pZwtgd4L) z^_q=iml$hxtbRf^A;I{!BcxD3m}0?zqg@kR`EsF;i4mXK7Zz~mfZqGwkx_d1BW)U( z=f$CTFsF|1HQzPvtcnY7I~eAB`%t)F>(S_-&u_gsG1|E_k$3y8gaK`Y&EG5_yb=ZV z>8TlUa4T&J{GJ>OmW*VuES(0Hw-XUoc8sju%!{YO&9uob>>SII#9HgJBqbV9K6^6z z?BVzS)r#>WEY|F~kIf4wfn`-P+{rOQ>zbG0PNv%{IPR;vkLR?mo_!zBjc;8un^S%s zA>!&KsZnhu>BlT9XEgtsI_Y8ShJ|3up9}Va6tEYjfUR)e)ACcyw!FC)YM1oK+fYp!}5 zkFELhA3BPc?st|hmpDwz-O~r9e(NP7U(@`gs!-p5el|{mE5-ygvBxhszPcdEdbcdy zJ+s5HJ=2JYb7z)&`k>S&ogL&b zuGD^XTcUGUPJwf0c3vO3I7aL8ojcZzM}wX}C>Qa3k)AsMeP4uuCqxX7T?ANJMJNIL fZlM6gjRDx`CdP9JD}e=W8*zM}2R$C+xXCS8sFTK|h*A?+>eMA{#pJUhdmvZF+17xLa?+QeCD&COy_egn^*(^Bu8dVJIK5n`f` zNyprjlqnNky+%&VfSw=kFVF}NZ?l%?c%B1OW@Kc#I^Pn&^D&W>=TdK*Jn`z4$)ul6 zd3)k!Ow3FR{occe_nD;kzjfk_Da+d)iWaZxWa7R`yKPp6Z{X%)@%kV}JYt^_m5r=g z)jVhARX25tI4XS{8X+HhzO}dIp40qg^V5#r=3|~c#o^AOf6d3uPs?D3@cws4@0NJY zxT#mThzw|MHs#IbG8o=&Alj}AcfI_@P+(^bYQgSW>C>6(j0Da|;EV*$NZ^bF z&Pd>l1kOm{j0FCdNg!O(WvnzZL#W_hA*E7-?_5AFX3GkhECte4&K7UETYAc9IZFbi zmvq1*?t+Uv%LJLB_}S4Wz+7VD%rJ8<_wgo>@D}rwS!>pq=gj+rx0_58X>K#~&7J0c zlWM};QZiZ6&fH4OBtBE@xGE`<7i6z|An!{Z_kH;0`r$GOaI_P?ij2P*EYHer-WJOo zd0f0?sZ1ip`6j|lhvHS{A+wzFuOr)XYIO42E5FH`GJ$%QO1*q8-wAUcbFCR=#!8q8 zH)G6O=1uraGBIS**+y4td*UiJ_AKDUBy2f}B_Y|>OFXipTl_1Ky)$;fi za^Hy@Kb6;It86!&(3f;#3T3~1B45h4@{@eRl<8Ai>T~%)ew25h`XVxTLki3}l8t5z zF%j~s+$nc}Q(NRjiGP1zERUjn2{PzEBvC4zWwAt42D4OJG(_vvG9y%d5pnT0nY^x+ z4_YF@K(8eG@7dx5^>@*wb=2fxo>WTz^t#8L(2O(JnThm(Iq3dK6K`%ecbN<`A6h3$ zJ0@Sr_eka!q@bKPf+Bc6D&HZ^Uy<5A`~6{Q;`0kFCUTtnK3l#`$oL07Ix$^oI=V~! z^RIG|1vTv{F1zLGDWje;^i#y!QuM8cPor!hUeJna+V6APujMk9bmAitAk)V5GJyeELgFECh6G&}uCH^YfMBra!IyljvDyYjLIgI>{A)7~Jk!+NW#-H9Z z!j|tS8D*yyxlAsgm-xsLq*;xm4-#K5U&|hzs<1S@-Ra9oWSWO26m*`FbV{`2c0JGvB#yX8Kp-X|AIs0@VX zf!Go+wI(eYolw+X=)T@JXPpTChx^Oexq3dONbnWv&`67agM@#g)n6o57%@9CZtAra zyV->i;5;nN!}5?UHcnb@lWd^W$IWHN!+0=4Jt4=j`th=g&m)X_nzjxJ=EKp)l%$rh zS{|_b-K~suE;KjaJR&2-SG8Tj>BZ5=;R@0v(8qI-oQo1vOO(GN^xoa7e()f07sAKQ zA&>v?y4toE+HZp?>00C$PW>O1`|bR1(5524Gg9g2bu{38dxZL!ryr0)7Sc|{S`9E4 zn8?2^aSkcddE1|wu}G=uuz+Pq^#gjKA7Pe8X|*h*Rf7$9TqB^on7^Ii$iB>Ca}8Q^ z12!lP{kfTub&0tLOLc{L!@P&2sJe^<5WP>Ma4+$+oYu#8LZorfp29I7)kCu4NDT9ZGoRoJ~bXyj~c-yT}~Zr%h) zTN#4|bbprOi?t`VdyCZymUO(GIn*ly+ccWb4d!kzn)=z&LS{4Mc6m^4l$+%qsEfQt zU;6?rszind_tL#VnLj=w%Qk--}=O&#z@>DjrY)Ew{^TMZc5z+`;`WFvIku zexrDQ3;t##bo){^kBmmMDCm*XZSX1(QaQg1in0Ii(k6NZ!&`Uy`xyI4 z7+3y!rQ^|y>1TYgn=$y4(dfO7)8p|ehnm5RZ=;anbtVM88EYQKhxWD8-p*h3C|-ly z1I7fm>owQJ+7aRQ--~38y}Evv{WOmrRe>IU zNS!t#-FQlR!?ZDN(8fmkSe>2fKK!&KJ0vpHTudE;dFqG_jX~df(jrUjUZzPF(o4qi z8H+4#kn5PSjKSBRL2FFp?F}GNll|q2rQCR8)M6yqGI!Do-)%{AnH?+W_8l!Lyoeb@ z8Ta6CXd9)rqztEbFOs|HN1vlZYtVfUq_It&mnZQ9+~Y_zy3~R6(;0Du)^xYAA9_xZ zR`tX32)2WeAsw-Pc>Q3F|1OBW*N1^=|&dwpM<`hSSf*wwErR)cf_a z?_Q)`jWpu0!(-V)y30IomSQ&|%wnv!p{Gv7`VT>R7m{l+a!3d2JFE4L*8XCLiYTds zuzJ>hw%&#Fb|B$I`pgBi#Wd2nn4?X?Z^)-T?}Vc@^ow5^_4nbC`#1kCeeB%dLF+If zgAN41+jZocZClD`7?u5~%T`9{e%!TYt!VW&tnv!DuE2+Qp3-(>?Rybk zkA?G+FjC%V_tjF#ToWNohX3FQRrugbPeK zbcfULvY;DGZSUl-piy_Q_jaXt$Xn(@-bCWNHyS6Y&$rV(iG2vB?HbYRD72>&v7L-3 z9M7j!gZU)Dbtm+=6`x*&E+#HU9zYIl8NE02H=R6#X^j(qz2GN?vV~asJan{mm6rM} z>SySitFY1W(AgljsW!law$v#6?m&7sIo?Y!67CQGow12) zkiuMMR^#z?BcwI_t&*3Sk+q@r8Tf3An1{B4lfl%%#aNX`pBaU0K7rF3w4$Cm?dPrP zq5D&h@2L7eLPlW0##63JAQ-#R2@mah{2#C82IdfJkmy+2Mx}ij{Ho5n<@G2vYJ={# zLc97(pt;xdF&CMOk^FUx(Q5IM#Gkt8toBOck{Mg?WDLC>FQb**VtVuUE8~LhbfEn# zRzJklF+$d%5m!oUb2gfw7RAM1K}xDMf<0}AwA<5Xo=2zV$Q1mVEBS;|j|Beqz;7+J z(+1O8BgirY84u&{0-I6|{Om=iYLG?|-pDPqK`x)C_!RTe+WNssmQ7`a&0Q9;C$6ip zh&8m1AjQLc>am@}O(OHs5Tw)x%{i>IP;~1Mt=!oBJNZTSkk{lIJe)exCE1#SJ;OKfLN|ix3&Hf%=@O5| z(O2lD1GpSv~nU_^5wafe&ZoS92e! zyHUn0`9mINMPi&e2fmL>1OBbUuHCs%2&U!3O?%4wggRHqm+&(SIuXQ#yZutQQLSz? z>tr5nSc7e!gPvW>s>Up48jE=6hb#xu?`L4w6DYl&6qlI?(Y-9**3jR*Z7qx7X$`YH zUnEm!F5yWzV0Fo;x3YqfvK;NY1e@@bTq9T0|8xK1H$BMcS%xJ_$9v46C4a)wFUD#t z#Alt(h&uyq%|+I)Q{qA}opkH)HQ$8#>91k%*q_!FXcX`fMxFtD9_N#X1y#RBy^pVW zw}|+EaG{eoLvej`6MdW27)IDwESfKNZVgm^rUv_v`X+kXPmE<%cp3+g_J!DllUEz@ zZ2kr5oJW5eX3u&O?2sqx4yV6L>Ej2?T;@0{DdiScag&hvtMV_(eGe`A%ATEm0UIDAn-9^8y|C(|8TlGnd(JRLobjlq4Z@K|z5HQxHta`zJ&;3%ZA-lHa>JXCX%B2Z zE*~3zT2FmV9e<9>Qaeqt{$)KYl-3+06yy7ji&8|_fN4Nbiibr z+bJhoRx{skFaD;x%t1pk8KVjqRn*p3VAa&03#517MXz$fr+ajXhs*x(5CPwTw3V*% zj3!R4W+?ucdWUMu@ciI+I#$b%9;sIJDdssLgq>Ke2b4Y>olj46&yRD7QCp=R^#nN5 zHE}VVRvs&CzpEbrEsiv){9=wSs>!vvz~PFY8uV0R}IhVd8j4PJW55^ z-Sl3sGhgb*7;4`e;Y=;Edwfu%+s`PB$wAGCIsWCPM z_iC@wisrqJ2v^_fbE`LC`7(lw(0?o>nR(I+)fJ@RPmLmf34#;js5Gt8^Z zjYymoRQmKbJl(-2l2V4ygN6B0EVI{f%xLG>)*zNTsL!Ugo5k$K#o9?d_Iw4Jn$1&d z-b7>DC&*>!NQIr!J%19s&xQ2Sxo{9*RHjO023B8dekod^^&L#8-hT5OW0(sb?xr{N zwcBMe8lWwrIRp5+l6SYlqt01X*0%u|ypu*K{J@p#AL_H3z_<`Z8Ha z?pDeQlbYrx>RrUj&=r*42F>k6&GPU>V(?aOr3`l+65zsx+_UVFFq&~~8a-UKO+9DQ zFs`cCR|Du}w0|C6-Q_$lre^3jrRmN=A@ym6N7D`OHCpasm32RT_IhmgT&QW?3$RWz z@DeP%<2KCuW-`xNjxTT(<+LYdN35ccJ!YtWpG~PBnlSu^{+?Ozu)-tk$w4t(pVHQvBN67@JRC!8~7W z>(I$K=0!YUamD{+Bz&LH_){YPuV8yh`1O?7P-vjD^s|?5Jm%%ayaj z_cF1ic=CQ>mLmudB9 zNgHn0yp%FET=8eU=kdh)4!r-!Xf?o`#Tb?VR|)KwCouZy%tB|l(a1QR=X0?vhpZ&88fy zv2_fgjG?2XkU{VY}Qyvw{&yD1-fl7O%bOp748QztF(2jTy-2hQ!U%V>a~j*u|+Am9+!w5@~FWc)+Q}lOXIwled@|r zIJWq9o{uonG%{mLq}~?Kd8BlEGy0sz+hAh6NOx+!dY;m0dldnzKS(*4HH;LzF86L{ zHY3VCSddDdm74OTt9v!rjRO3J8rnnbnKSRrG_z21y32xpUGvj<)64&fmTI3qbN&Bb z0%(@{JvsuVn^vY3D^neb`5pbw;$0zco<&b?z%x@1;%WL?9zFI5y|ej{@^g|8 z6U1{fJLk+~@HSde%6oR4uFLqJ$}zE6cGl^_(eLNjON@rM#aO39@~qCf;H6aUH#Jo{ z1$Z5gLitlHb%kB>R@T!C@MfBre`R64D@+Z20P9Fwwo_Amo=)*4T!6DO?GS^|LcVef1#8dnZ3zEQSSI=E%5+P97 zM5&{x$q?hOGa2aiz?--XuSoZOj$(QLfS<`o)n#*)fyGS1CaH|xx7zR$X2Ii9O~eQZ9qRL`8%AtgV?b8TZig{J!u7b64eU|&ipx+Q$(c18mKb_uYy zpgXbkSjbwmJX=QMYu#Xv+rwor+Ip%sMxMfs+ebJVF_M+(JJITNJfk@1JqWd({GH4? zz+OD!@1T`I&$^s<57TGVXWYuuV*buxjdB~knqE_0$9yi>_Ob?(CK;P`2|e^?yPRvVJTds-!$@^D z>8@uVK0q!f-A(k)OPJ?RAic1*9Zp}4W=5bhhdciC|4Q-Dw?gZF>R(2E)M}UgZ4FMo z=#Q<*NBa59v!{TfzexOKy1$05gQo=cL<*>zt^u653gBlUADtg*sFYD;A+4e-1QUp> z!OCXQ3Z;0_*Yi;>Pk#+&B+Vt?M*g0>UWJFn_6ShKnuqQwo_guN?~{B^or6tA!Ykn8 z zqxZ$EcFcjJ7g+=ILxUGm!#Ml=kggEu3X#qj)oax|KIxyAu50Txk$efrN4?i@hX{jacN z<-Wq14La;#%bsIP{NLSlPhUT8(IzvPH!R{4%-lhDyYw`b#cG7G;xM1Ou)<;cl)C$- z^mNAN_7;9ZDVCCf6THc*)tUQ91B^ zbS6&KWIM;ymHl#ajPMv=Hl6@XgGJ(?YtgBD8otYhaTIDUaE# zb$o&4I#n|V+B~VY`LLSRfweI8(2A&eG_xzc!tLEx!Her=YxPixz}63GZYJ#^@ijy6 zcyF|K(G3<<&nK&&a;a)Jv$`z2t4yAgSRH>D&(#H&X*S(xdmr8oLe~#D&9r-w+ow4j zOM2qc^@H!>$VG&n1oNf8=-RcmPb6)gMI1YtXoK!!cu^zPQb|)oJ{NE6!Dcf6es7|r zU2x`s+|-iqA$7DF$o`XRu46-y&AsOoOVuri(A`?i*TG1>ESG zoND)bq>E;*ue|CGq>HzD`Oz1(#=0V>m&#mcO?*4Rl-gk(+f_5&^mI*tR7hX*>W+u5 zwYgZ0O+@Qnm*22!skHtBoGO@M#!ydhwAYiJA{Tc4Q{{&ia(|TnaC&|^mP&WSbp^2o z$wos{XKa&A1YEgyFS;Pl?q&onG#p!O(1%yZqrGV{_eN@_D@S(_)_n^-{rv>8clS7w z*)1E-J(&FQ@EVL3va$;=I!?Rjb;9V~hFQp5$}F-qQtQ1DxeGnvF#gFs=#gQar@x%X zdBeL|BYTnc^g`*&$&n3=ITh>xci~e&$uVeC3hlfW%dT41NIfQ#JArjg7uGaRCBY8i zNXlHyTGv?BdsgO@)qWacRgHcP&0yZ@&iNeXYid9J=*fQUH!SAu)5HbY)En@f8iD?8 zWUhEO^0=E&vHkoV{5RTo)_&G=1Z$aRXuE1lX7Q~1>&JN3mG;-s-?gkCRpIY#VLnq$ z%YDb5zy{`SMaI{)(ce$xzs9 zZs2|+{7*-6sl*oXtUI!)ShQ?x&y75#o}M5xsL8ZI5E{o$h-nKQ9i6@4TIW|fI;0|_ z*=9C-#QUgoF*C_i>3Yj|tSz_4LT#7N=%XGclssNgWH#g&- zozy#l_Y0Bn7pJ69tyc|K?<@;WRKuC^qc>T0SkE)+o=^(Bszu?XhpfUU?T)ri;92`? z0ku#+LibhFf@zHIq`080r#$rJ?%C*3uAM#snMI+=KbR=AeO~SU z29k2VJo0i%6rk3a z@1fWhf}a;)%~kifzho5K#$L?_?2+vwor}8G&_ZgJ!Z~^4-UHKE_qzq`(q!3v#RV@T z=-K|1IUcL0vKm1tH%T1!b2=qt(Oo)`;(S8dx9+f|rm6It)(G~hC(*0@c(1FV$Ap;+ zs}&>c@J-NL*g`XbxCv;4_5ke@NS%puxj%fxs+ZvVplP8{$vIr@t*d|zT3a5!3!M8cy&J1RSqtwEQZ4Q z{JloGfW8M*)h2K zsO$Hd=fwSVdDWKGP`b`24E0W+e z#ZGgv6F!#x0ZlcMInmX4btkW*w5s;@IY#%#^|ZuuoR)Z$n)l%xOBeGBNg1!`4fs}Y zKB~Eq`fBefK*D;`;Kb$C{2Tsf1t?;a^JZT~FSVn4>>MgL^=8xc+iBeA^JXzmdU`=a zx_2Iq_xX)!PiQpI?;k|-9$x|uO8Ka#c{QmfA*IE<)6q=#9@Gk@GiPd~HFU?ffHd02 zy%;-GJN~>(Bf(B^rPS4D)l_axQyX1GKDE$l+ce*sq%Y7!dJ%>?axAd@9k*r$+nlN- zwC5-#wMQx!9W&ijG*;_fZ_`pcsPtXfAC3E&^nDlwG``+0HO|hdwW#2odRR&!jDA?a z`l;^tYDrqkiF-KpFJNa>y{>BN5zbshtw25BUOL}gXQxiUXHlA}iMns9^SNMX>a(tL z))Qwd2|2Y~9c7g#oe4a~$fNqMV}{xz{oc(rB(4YQRjEg;ZMm2}r2eR$#`>07$anZD zpP{FP;2TcaYv{BW9$;%MrJfTlqRsU@f!3PcDLB?Xr`)MT{IIX;hb9uQW6(m%cYpMK z5p#iSR2IC8CWZPO+FRUbs!N$wsK>bydpe!ks86|pIf%}%7`b`Mq;_gezQ+d|Vb5ku zh`o<;l*;L^drzN4)|xK(F<;0#?3`BMw|vBS_BNy4PB^M$^g8|JW&7h6Z8QQt@8F|z zq7>>Aj!&#Q(jA#U&K_)EY`%_OE8xsHJwYVW~wDsopWo0 zu5jpy!IPKz1&y>&4ODcD&}S{T7i(@2_EQ#5dRj&ERG