diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 55443cf3..3b41d7a6 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -4,7 +4,7 @@ on: [workflow_dispatch, push, pull_request] jobs: run: - uses: flarum/framework/.github/workflows/REUSABLE_backend.yml@1.x + uses: flarum/framework/.github/workflows/REUSABLE_backend.yml@2.x with: enable_backend_testing: true enable_phpstan: true diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml index d0734e31..6dbff045 100644 --- a/.github/workflows/frontend.yml +++ b/.github/workflows/frontend.yml @@ -4,7 +4,7 @@ on: [workflow_dispatch, push, pull_request] jobs: run: - uses: flarum/framework/.github/workflows/REUSABLE_frontend.yml@1.x + uses: flarum/framework/.github/workflows/REUSABLE_frontend.yml@2.x with: enable_bundlewatch: false enable_prettier: true @@ -13,7 +13,7 @@ jobs: frontend_directory: ./js backend_directory: . js_package_manager: yarn - main_git_branch: 1.x + main_git_branch: 2.x secrets: bundlewatch_github_token: ${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }} diff --git a/composer.json b/composer.json index 51edf8f8..27d80944 100644 --- a/composer.json +++ b/composer.json @@ -31,13 +31,9 @@ } ], "require": { - "flarum/core": "^1.7", - "fof/extend": "^1.0.0", + "flarum/core": "^2.0.0", "ext-json": "*" }, - "replace": { - "reflar/gamification": "*" - }, "autoload": { "psr-4": { "FoF\\Gamification\\": "src/" @@ -53,14 +49,14 @@ "color": "#fff" } }, - "flagrow": { - "discuss": "https://discuss.flarum.org/d/20671" - }, "flarum-cli": { "modules": { "githubActions": true, "backendTesting": true } + }, + "branch-alias": { + "2.x": "2.x-dev" } }, "scripts": { @@ -82,13 +78,16 @@ "test:setup": "Sets up a database for use with integration tests. Execute this only once." }, "require-dev": { - "flarum/phpstan": "*", + "flarum/phpstan": "^2.0.0", "flarum/pusher": "*", - "flarum/testing": "^1.0.0" + "flarum/testing": "^2.0.0", + "flarum/likes": "*" }, "autoload-dev": { "psr-4": { "FoF\\Gamification\\Tests\\": "tests/" } - } + }, + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/extend.php b/extend.php index 10bf8c4e..6df8b53d 100644 --- a/extend.php +++ b/extend.php @@ -11,24 +11,22 @@ namespace FoF\Gamification; -use Flarum\Api\Controller; -use Flarum\Api\Serializer; +use Flarum\Api\Context; +use Flarum\Api\Endpoint; +use Flarum\Api\Resource; +use Flarum\Api\Sort\SortColumn; use Flarum\Discussion\Discussion; use Flarum\Discussion\Event\Started; -use Flarum\Discussion\Filter\DiscussionFilterer; use Flarum\Discussion\Search\DiscussionSearcher; use Flarum\Extend; use Flarum\Post\Event\Deleted; use Flarum\Post\Event\Posted; -use Flarum\Post\Event\Saving; -use Flarum\Post\Filter\PostFilterer; +use Flarum\Post\Filter\PostSearcher; use Flarum\Post\Post; +use Flarum\User\Search\UserSearcher; use Flarum\User\User; -use FoF\Extend\Extend\ExtensionSettings; use FoF\Gamification\Api\Controllers; -use FoF\Gamification\Api\Serializers; use FoF\Gamification\Notification\VoteBlueprint; -use FoF\Gamification\Provider\GamificationSortOptionsProvider; return [ (new Extend\Frontend('admin')) @@ -63,131 +61,87 @@ ->cast('votes', 'int') ->cast('hotness', 'float'), - (new ExtensionSettings()) - ->setPrefix('fof-gamification.') - ->addKeys([ - 'iconName', - 'pointsPlaceholder', - 'showVotesOnDiscussionPage', - 'rankAmt', - 'customRankingImages', - 'useAlternateLayout', - 'upVotesOnly', - 'iconNameAlt', - 'altPostVotingUi', - ]), - (new Extend\Routes('api')) ->post('/fof/gamification/convert', 'fof.gamification.convert', Controllers\ConvertLikesController::class) - ->post('/fof/gamification/topimage{id}', 'fof.topImage.add', Controllers\UploadTopImageController::class) - ->delete('/fof/gamification/topimage{id}', 'fof.topImage.delete', Controllers\DeleteTopImageController::class) - ->get('/ranks', 'ranks.index', Controllers\ListRanksController::class) - ->post('/ranks', 'ranks.create', Controllers\CreateRankController::class) - ->patch('/ranks/{id}', 'ranks.update', Controllers\UpdateRankController::class) - ->delete('/ranks/{id}', 'ranks.delete', Controllers\DeleteRankController::class) - ->get('/rankings', 'rankings', Controllers\OrderByPointsController::class), + ->post('/fof/gamification/topimage{id}', 'fof.topImage.add', Controllers\UploadTopImageController::class), (new Extend\Policy()) ->modelPolicy(Post::class, Access\PostPolicy::class), (new Extend\Event()) - ->listen(Saving::class, Listeners\SaveVotesToDatabase::class) ->listen(Posted::class, Listeners\AddVoteHandler::class) ->listen(Deleted::class, Listeners\RemoveVoteHandler::class) ->listen(Started::class, Listeners\AddDiscussionVotes::class) ->listen(Events\UserPointsUpdated::class, Listeners\UpdateAutoAssignedGroups::class) ->subscribe(Listeners\QueueJobs::class), - (new Extend\ApiSerializer(Serializer\PostSerializer::class)) - ->hasMany('upvotes', Serializer\BasicUserSerializer::class) - ->hasMany('downvotes', Serializer\BasicUserSerializer::class), - - (new Extend\ApiSerializer(Serializer\UserSerializer::class)) - ->hasMany('ranks', Serializers\RankSerializer::class), - - (new Extend\ApiSerializer(Serializer\ForumSerializer::class)) - ->hasMany('ranks', Serializers\RankSerializer::class) - ->attributes(Api\AddForumAttributes::class), - - (new Extend\ApiController(Controller\ShowForumController::class)) - ->prepareDataForSerialization(function (Controller\ShowForumController $controller, &$data) { - $data['ranks'] = Rank::get(); - }), + new Extend\ApiResource(Api\Resource\RankResource::class), (new Extend\Settings()) + ->default('fof-gamification.iconName', 'thumbs') + ->default('fof-gamification.iconNameAlt', 'arrow') + ->default('fof-gamification.showVotesOnDiscussionPage', true) + ->default('fof-gamification.useAlternateLayout', false) + ->default('fof-gamification.upVotesOnly', false) + ->default('fof-gamification.altPostVotingUi', false) ->default('fof-gamification.blockedUsers', '') ->default('fof-gamification.rankAmt', 2) - ->default('fof-gamification.firstPostOnly', false) - ->default('fof-gamification.allowSelfVotes', true), - - (new Extend\ApiSerializer(Serializer\UserSerializer::class)) - ->attributes(AddUserAttributes::class), - - (new Extend\ApiSerializer(Serializer\BasicDiscussionSerializer::class)) - ->attributes(AddDiscussionData::class), - - (new Extend\ApiSerializer(Serializer\PostSerializer::class)) - ->attributes(AddPostData::class), - - (new Extend\ApiController(Controller\ListUsersController::class)) - ->addInclude('ranks'), - - (new Extend\ApiController(Controller\ShowUserController::class)) - ->addInclude('ranks'), - - (new Extend\ApiController(Controller\CreateUserController::class)) - ->addInclude('ranks'), - - (new Extend\ApiController(Controllers\OrderByPointsController::class)) - ->addInclude('ranks'), - - (new Extend\ApiController(Controller\UpdateUserController::class)) - ->addInclude('ranks'), - - (new Extend\ApiController(Controller\ShowDiscussionController::class)) - ->addInclude('posts.user.ranks') - ->loadWhere('posts.actualvotes', [LoadActorVoteRelationship::class, 'mutateRelation']) - ->prepareDataForSerialization([LoadActorVoteRelationship::class, 'sumRelation']), - - (new Extend\ApiController(Controller\ListDiscussionsController::class)) - ->addSortField('hotness') - ->addSortField('votes') - ->loadWhere('firstPost.actualvotes', [LoadActorVoteRelationship::class, 'mutateRelation']) - ->prepareDataForSerialization([LoadActorVoteRelationship::class, 'sumRelation']), - - (new Extend\ApiController(Controller\ListPostsController::class)) - ->addInclude('user.ranks') - ->addOptionalInclude(['upvotes', 'downvotes']) - ->loadWhere('actualvotes', [LoadActorVoteRelationship::class, 'mutateRelation']) - ->prepareDataForSerialization([LoadActorVoteRelationship::class, 'sumRelation']), - - (new Extend\ApiController(Controller\ShowPostController::class)) - ->addInclude('user.ranks') - ->addOptionalInclude(['upvotes', 'downvotes']) - ->loadWhere('actualvotes', [LoadActorVoteRelationship::class, 'mutateRelation']) - ->prepareDataForSerialization([LoadActorVoteRelationship::class, 'sumRelation']), + ->default('fof-gamification.firstPostOnly', true) + ->default('fof-gamification.allowSelfVotes', true) + ->serializeToForum('fof-gamification.showVotesOnDiscussionPage', 'fof-gamification.showVotesOnDiscussionPage', 'boolval') + ->serializeToForum('fof-gamification.useAlternateLayout', 'fof-gamification.useAlternateLayout', 'boolval') + ->serializeToForum('fof-gamification.upVotesOnly', 'fof-gamification.upVotesOnly', 'boolval') + ->serializeToForum('fof-gamification.altPostVotingUi', 'fof-gamification.altPostVotingUi', 'boolval') + ->serializeToForum('fof-gamification.iconName', 'fof-gamification.iconName') + ->serializeToForum('fof-gamification.iconNameAlt', 'fof-gamification.iconNameAlt') + ->serializeToForum('fof-gamification.rankAmt', 'fof-gamification.rankAmt', 'intval') + ->serializeToForum('fof-gamification.firstPostOnly', 'fof-gamification.firstPostOnly', 'boolval'), + + (new Extend\ApiResource(Resource\UserResource::class)) + ->endpoint(['show', 'update', 'create', 'index'], function (Endpoint\Show|Endpoint\Update|Endpoint\Create|Endpoint\Index $endpoint) { + return $endpoint->addDefaultInclude(['ranks']); + }) + ->fields(Api\UserResourceFields::class) + ->sorts(fn () => [ + SortColumn::make('votes') + ->visible(function (Context $context) { + return $context->getActor()->can('fof.gamification.viewRankingPage'); + }), + ]), - (new Extend\ApiController(Controller\CreatePostController::class)) - ->addInclude('user.ranks') - ->addOptionalInclude(['upvotes', 'downvotes']), + (new Extend\ApiResource(Resource\DiscussionResource::class)) + ->fields(Api\DiscussionResourceFields::class) + ->sorts(fn () => [ + SortColumn::make('hotness') + ->descendingAlias('hot'), + SortColumn::make('votes') + ->descendingAlias('votes'), + ]) + ->endpoint('index', function (Endpoint\Index $endpoint) { + return $endpoint->eagerLoadWhere('firstPost.actualvotes', function ($query, Context $context) { + $query->where('user_id', $context->getActor()->id); + }); + }), - (new Extend\ApiController(Controller\UpdatePostController::class)) - ->addInclude('user.ranks') - ->addOptionalInclude(['upvotes', 'downvotes']) - ->loadWhere('actualvotes', [LoadActorVoteRelationship::class, 'mutateRelation']) - ->prepareDataForSerialization([LoadActorVoteRelationship::class, 'sumRelation']), + (new Extend\ApiResource(Resource\PostResource::class)) + ->fields(Api\PostResourceFields::class) + ->endpoint(['index', 'show', 'create', 'update'], function (Endpoint\Index|Endpoint\Show|Endpoint\Create|Endpoint\Update $endpoint) { + return $endpoint->addDefaultInclude(['user.ranks']); + }) + ->endpoint(['index', 'show', 'update'], function (Endpoint\Index|Endpoint\Show|Endpoint\Update $endpoint) { + return $endpoint->eagerLoadWhere('actualvotes', function ($query, Context $context) { + $query->where('user_id', $context->getActor()->id); + }); + }), - (new Extend\ApiController(Controller\ShowForumController::class)) - ->addInclude('ranks'), + (new Extend\ApiResource(Resource\ForumResource::class)) + ->fields(Api\ForumResourceFields::class) + ->endpoint('show', function (Endpoint\Show $endpoint) { + return $endpoint->addDefaultInclude(['ranks']); + }), (new Extend\Notification()) - ->type(VoteBlueprint::class, Serializer\BasicPostSerializer::class, ['alert']), - - (new Extend\SimpleFlarumSearch(DiscussionSearcher::class)) - ->addGambit(Search\HotFilterGambit::class), - - (new Extend\Filter(DiscussionFilterer::class)) - ->addFilter(Search\HotFilterGambit::class), + ->type(VoteBlueprint::class, ['alert']), (new Extend\Console()) ->command(Console\ResyncUserVotes::class) @@ -197,9 +151,8 @@ (new Extend\View()) ->namespace('fof-gamification', __DIR__.'/resources/views'), - (new Extend\ServiceProvider()) - ->register(GamificationSortOptionsProvider::class), - - (new Extend\Filter(PostFilterer::class)) - ->addFilter(Filter\VotedFilter::class), + (new Extend\SearchDriver(\Flarum\Search\Database\DatabaseSearchDriver::class)) + ->addFilter(DiscussionSearcher::class, Search\HotFilter::class) + ->addFilter(PostSearcher::class, Filter\VotedFilter::class) + ->addFilter(UserSearcher::class, Filter\RankableFilter::class), ]; diff --git a/js/admin.ts b/js/admin.ts index 1f9e14ab..3e69ff3b 100755 --- a/js/admin.ts +++ b/js/admin.ts @@ -1,2 +1 @@ -export * from './src/common'; export * from './src/admin'; diff --git a/js/forum.ts b/js/forum.ts index f49b8710..facb26fa 100755 --- a/js/forum.ts +++ b/js/forum.ts @@ -1,2 +1 @@ -export * from './src/common'; export * from './src/forum'; diff --git a/js/package.json b/js/package.json index f26e008c..e580be3d 100644 --- a/js/package.json +++ b/js/package.json @@ -1,29 +1,29 @@ { - "name": "@fof/gamification", - "private": true, - "prettier": "@flarum/prettier-config", - "dependencies": { - "lodash.debounce": "^4.0.8" - }, - "devDependencies": { - "@flarum/prettier-config": "^1.0.0", - "flarum-tsconfig": "^1.0.3", - "flarum-webpack-config": "^2.0.0", - "prettier": "^3.0.3", - "typescript-coverage-report": "^0.6.1", - "webpack": "^5.89.0", - "webpack-cli": "^5.1.4" - }, - "scripts": { - "dev": "webpack --mode development --watch", - "build": "webpack --mode production", - "analyze": "cross-env ANALYZER=true yarn run build", - "format": "prettier --write src", - "format-check": "prettier --check src", - "clean-typings": "npx rimraf dist-typings && mkdir dist-typings", - "build-typings": "yarn run clean-typings && ([ -e src/@types ] && cp -r src/@types dist-typings/@types || true) && tsc && yarn run post-build-typings", - "post-build-typings": "find dist-typings -type f -name '*.d.ts' -print0 | xargs -0 sed -i 's,../src/@types,@types,g'", - "check-typings": "tsc --noEmit --emitDeclarationOnly false", - "check-typings-coverage": "typescript-coverage-report" - } + "name": "@fof/gamification", + "private": true, + "prettier": "@flarum/prettier-config", + "dependencies": { + "lodash.debounce": "^4.0.8" + }, + "devDependencies": { + "@flarum/prettier-config": "^1.0.0", + "flarum-tsconfig": "^2.0.0", + "flarum-webpack-config": "^3.0.2", + "prettier": "^3.0.3", + "typescript-coverage-report": "^0.6.1", + "webpack": "^5.89.0", + "webpack-cli": "^5.1.4" + }, + "scripts": { + "dev": "webpack --mode development --watch", + "build": "webpack --mode production", + "analyze": "cross-env ANALYZER=true yarn run build", + "format": "prettier --write src", + "format-check": "prettier --check src", + "clean-typings": "npx rimraf dist-typings && mkdir dist-typings", + "build-typings": "yarn run clean-typings && ([ -e src/@types ] && cp -r src/@types dist-typings/@types || true) && tsc && yarn run post-build-typings", + "post-build-typings": "find dist-typings -type f -name '*.d.ts' -print0 | xargs -0 sed -i 's,../src/@types,@types,g'", + "check-typings": "tsc --noEmit --emitDeclarationOnly false", + "check-typings-coverage": "typescript-coverage-report" + } } diff --git a/js/src/admin/components/SettingsPage.js b/js/src/admin/components/SettingsPage.js index 574715b5..699122ce 100755 --- a/js/src/admin/components/SettingsPage.js +++ b/js/src/admin/components/SettingsPage.js @@ -6,8 +6,12 @@ import Switch from 'flarum/common/components/Switch'; import withAttr from 'flarum/common/utils/withAttr'; import Stream from 'flarum/common/utils/Stream'; import ItemList from 'flarum/common/utils/ItemList'; +import Form from 'flarum/common/components/Form'; +import FormSection from 'flarum/admin/components/FormSection'; +import FormSectionGroup from 'flarum/admin/components/FormSectionGroup'; import UploadImageButton from './UploadImageButton'; import GroupSettings from './GroupSettings'; +import Icon from 'flarum/common/components/Icon'; export default class SettingsPage extends ExtensionPage { oninit(vnode) { @@ -99,11 +103,13 @@ export default class SettingsPage extends ExtensionPage { name: this.newRank.name(), color: this.newRank.color(), }) - .then(() => { + .then((rank) => { this.newRank.color(''); this.newRank.name(''); this.newRank.points(''); + this.ranks.push(rank); + m.redraw(); }); } @@ -160,7 +166,7 @@ export default class SettingsPage extends ExtensionPage { items.add( 'convertLikesToUpvotes', -
+
{app.translator.trans('fof-gamification.admin.page.convert.help')}
{this.values.convertedLikes() === undefined ? ( , + 0 + ); + + return items; + } + + firstSectionGroupItems() { + const items = new ItemList(); + + items.add( + 'ranks', + +
{this.rankItems().toArray()}
+
, + 90 + ); + + items.add( + 'voteSettings', + +
{this.voteItems().toArray()}
+
, + 80 + ); + + return items; + } + + secondSectionGroupItems() { + const items = new ItemList(); + + items.add( + 'rankingsPage', + {this.rankingsItems().toArray()}, + 70 + ); + + items.add( + 'groups', + +
{app.translator.trans('fof-gamification.admin.page.groups.help')}
+ +
, + 60 + ); + + return items; + } + + rankItems() { + const items = new ItemList(); + items.add( 'ranks', -
- {app.translator.trans('fof-gamification.admin.page.ranks.title')} +
{app.translator.trans('fof-gamification.admin.page.ranks.help.help')}
-
- {this.ranks.map((rank) => ( -
- - - -
- ))} -
-
+ {this.ranks.length > 0 ? ( +
+ {this.ranks.map((rank) => ( +
+ + + +
+ ))} +
+ ) : null} +
+
, + 100 + ); + + items.add( + 'rankNumbers', +
-
, - 90 - ); - - items.add( - 'voteSettings', - <> - {app.translator.trans('fof-gamification.admin.page.votes.title')} - {this.voteItems().toArray()} - , +
, 80 ); - items.add( - 'rankingsPage', - <> - {app.translator.trans('fof-gamification.admin.page.rankings.title')} - {this.rankingsItems().toArray()} - , - 70 - ); - - items.add( - 'groups', -
- {app.translator.trans('fof-gamification.admin.page.groups.title')} -
{app.translator.trans('fof-gamification.admin.page.groups.help')}
- -
, - 60 - ); - - items.add( - 'submit', - , - 0 - ); - return items; } @@ -304,95 +348,125 @@ export default class SettingsPage extends ExtensionPage { items.add( 'icon', - <> +
{app.translator.trans('fof-gamification.admin.page.votes.icon_help')}
- - , + + {this.values.iconName() && ( +
+ + + {app.translator.trans('fof-gamification.admin.page.votes.icon_preview_upvote')} + + + + {app.translator.trans('fof-gamification.admin.page.votes.icon_preview_downvote')} + +
+ )} +
, 100 ); items.add( 'altIcon', - <> +
{app.translator.trans('fof-gamification.admin.page.votes.icon_help')}
- - , + + {this.values.iconNameAlt() && ( +
+ + + {app.translator.trans('fof-gamification.admin.page.votes.icon_preview_upvote')} + + + + {app.translator.trans('fof-gamification.admin.page.votes.icon_preview_downvote')} + +
+ )} +
, 90 ); items.add( 'autoUpvote', - - {app.translator.trans('fof-gamification.admin.page.votes.auto_upvote')} - , +
+ + {app.translator.trans('fof-gamification.admin.page.votes.auto_upvote')} + +
, 80 ); items.add( 'rateLimit', - - {app.translator.trans('fof-gamification.admin.page.votes.rate_limit')} - , +
+ + {app.translator.trans('fof-gamification.admin.page.votes.rate_limit')} + +
, 70 ); items.add( 'opVotesOnDiscussionList', - - {app.translator.trans('fof-gamification.admin.page.votes.discussion_page')} - , +
+ + {app.translator.trans('fof-gamification.admin.page.votes.discussion_page')} + +
, 60 ); items.add( 'altDiscussionListLayout', - - {app.translator.trans('fof-gamification.admin.page.votes.alternate_layout')} - , +
+ + {app.translator.trans('fof-gamification.admin.page.votes.alternate_layout')} + +
, 50 ); items.add( 'altPostLayout', - - {app.translator.trans('fof-gamification.admin.page.votes.alternate_post_layout')} - , +
+ + {app.translator.trans('fof-gamification.admin.page.votes.alternate_post_layout')} + +
, 40 ); items.add( 'upvotesOnly', - - {app.translator.trans('fof-gamification.admin.page.votes.upvotes_only')} - , +
+ + {app.translator.trans('fof-gamification.admin.page.votes.upvotes_only')} + +
, 30 ); items.add( 'firstPostOnly', - - {app.translator.trans('fof-gamification.admin.page.votes.first_post_only')} - , +
+ + {app.translator.trans('fof-gamification.admin.page.votes.first_post_only')} + +
, 20 ); items.add( 'allowSelfVotes', - - {app.translator.trans('fof-gamification.admin.page.votes.allow_self_votes')} - , +
+ + {app.translator.trans('fof-gamification.admin.page.votes.allow_self_votes')} + +
, 10 ); @@ -404,15 +478,17 @@ export default class SettingsPage extends ExtensionPage { items.add( 'customImages', - - {app.translator.trans('fof-gamification.admin.page.rankings.enable')} - , +
+ + {app.translator.trans('fof-gamification.admin.page.rankings.enable')} + +
, 100 ); items.add( 'ignoredUsers', - <> +
- , +
, 90 ); items.add( 'customImages', <> -
{app.translator.trans('fof-gamification.admin.page.rankings.blocked.help')}
{[1, 2, 3].map((num) => ( - <> +

- +
))} , 80 diff --git a/js/src/admin/components/UploadImageButton.js b/js/src/admin/components/UploadImageButton.js index aa7230a5..76b037bc 100644 --- a/js/src/admin/components/UploadImageButton.js +++ b/js/src/admin/components/UploadImageButton.js @@ -1,5 +1,5 @@ import app from 'flarum/admin/app'; -import FlarumUploadImageButton from 'flarum/admin/components/UploadImageButton'; +import FlarumUploadImageButton from 'flarum/common/components/UploadImageButton'; export default class UploadImageButton extends FlarumUploadImageButton { resourceUrl() { diff --git a/js/src/admin/components/index.js b/js/src/admin/components/index.js deleted file mode 100644 index 348dd837..00000000 --- a/js/src/admin/components/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import SettingsPage from './SettingsPage'; -import UploadImageButton from './UploadImageButton'; - -export const components = { - SettingsPage, - UploadImageButton, -}; diff --git a/js/src/admin/extend.ts b/js/src/admin/extend.ts index 753b8ea5..d91219dc 100644 --- a/js/src/admin/extend.ts +++ b/js/src/admin/extend.ts @@ -1,3 +1,62 @@ +import app from 'flarum/admin/app'; +import Extend from 'flarum/common/extenders'; import { default as commonExtend } from '../common/extend'; +import SettingsPage from './components/SettingsPage'; -export default [...commonExtend]; +export default [ + ...commonExtend, + + new Extend.Admin() // + .page(SettingsPage) + .permission( + () => ({ + icon: 'fas fa-thumbs-up', + label: app.translator.trans('fof-gamification.admin.permissions.vote_label'), + permission: 'discussion.votePosts', + }), + 'reply' + ) + .permission( + () => ({ + icon: 'fas fa-thumbs-up', + label: app.translator.trans('fof-gamification.admin.permissions.see_votes_label'), + permission: 'discussion.canSeeVotes', + allowGuest: true, + }), + 'view' + ) + .permission( + () => ({ + icon: 'fas fa-info-circle', + label: app.translator.trans('fof-gamification.admin.permissions.see_voters_label'), + permission: 'discussion.canSeeVoters', + allowGuest: true, + }), + 'view' + ) + .permission( + () => ({ + icon: 'fas fa-trophy', + label: app.translator.trans('fof-gamification.admin.permissions.see_ranking_page'), + permission: 'fof.gamification.viewRankingPage', + allowGuest: true, + }), + 'view' + ) + .permission( + () => ({ + icon: 'fas fa-bell', + label: app.translator.trans('fof-gamification.admin.permissions.upvote_notifications'), + permission: 'discussion.upvote_notifications', + }), + 'view' + ) + .permission( + () => ({ + icon: 'fas fa-bell', + label: app.translator.trans('fof-gamification.admin.permissions.downvote_notifications'), + permission: 'discussion.downvote_notifications', + }), + 'view' + ), +]; diff --git a/js/src/admin/index.ts b/js/src/admin/index.ts index 650fa28c..2741fe53 100755 --- a/js/src/admin/index.ts +++ b/js/src/admin/index.ts @@ -1,64 +1,7 @@ import app from 'flarum/admin/app'; -import SettingsPage from './components/SettingsPage'; export { default as extend } from './extend'; -app.initializers.add('fof-gamification', (app) => { - app.extensionData - .for('fof-gamification') - .registerPermission( - { - icon: 'fas fa-thumbs-up', - label: app.translator.trans('fof-gamification.admin.permissions.vote_label'), - permission: 'discussion.votePosts', - }, - 'reply' - ) - .registerPermission( - { - icon: 'fas fa-thumbs-up', - label: app.translator.trans('fof-gamification.admin.permissions.see_votes_label'), - permission: 'discussion.canSeeVotes', - allowGuest: true, - }, - 'view' - ) - .registerPermission( - { - icon: 'fas fa-info-circle', - label: app.translator.trans('fof-gamification.admin.permissions.see_voters_label'), - permission: 'discussion.canSeeVoters', - allowGuest: true, - }, - 'view' - ) - .registerPermission( - { - icon: 'fas fa-trophy', - label: app.translator.trans('fof-gamification.admin.permissions.see_ranking_page'), - permission: 'fof.gamification.viewRankingPage', - allowGuest: true, - }, - 'view' - ) - .registerPermission( - { - icon: 'fas fa-bell', - label: app.translator.trans('fof-gamification.admin.permissions.upvote_notifications'), - permission: 'discussion.upvote_notifications', - }, - 'view' - ) - .registerPermission( - { - icon: 'fas fa-bell', - label: app.translator.trans('fof-gamification.admin.permissions.downvote_notifications'), - permission: 'discussion.downvote_notifications', - }, - 'view' - ) - .registerPage(SettingsPage); +app.initializers.add('fof-gamification', () => { + // }); - -export * from '../common/helpers'; -export * from './components'; diff --git a/js/src/common/extend.ts b/js/src/common/extend.ts index 1072c86f..2abb8309 100644 --- a/js/src/common/extend.ts +++ b/js/src/common/extend.ts @@ -1,7 +1,11 @@ import Extend from 'flarum/common/extenders'; import Rank from './models/Rank'; +import HotGambit from './gambits/HotGambit'; export default [ new Extend.Store() // .add('ranks', Rank), + + new Extend.Search() // + .gambit('discussions', HotGambit), ]; diff --git a/js/src/common/gambits/HotGambit.tsx b/js/src/common/gambits/HotGambit.tsx new file mode 100644 index 00000000..3537f2b7 --- /dev/null +++ b/js/src/common/gambits/HotGambit.tsx @@ -0,0 +1,12 @@ +import app from 'flarum/common/app'; +import { BooleanGambit } from 'flarum/common/query/IGambit'; + +export default class HotGambit extends BooleanGambit { + key() { + return app.translator.trans('fof-gamification.lib.gambits.hot.key', {}, true); + } + + filterKey() { + return 'hot'; + } +} diff --git a/js/src/common/helpers/index.js b/js/src/common/helpers/index.js deleted file mode 100644 index 0c0444a4..00000000 --- a/js/src/common/helpers/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import rankLabel from './rankLabel'; - -export const helpers = { - rankLabel, -}; diff --git a/js/src/common/index.ts b/js/src/common/index.ts deleted file mode 100755 index e9644dae..00000000 --- a/js/src/common/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './models'; diff --git a/js/src/common/models/index.ts b/js/src/common/models/index.ts deleted file mode 100644 index 76a61756..00000000 --- a/js/src/common/models/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import Rank from './Rank'; - -export const models = { - Rank, -}; diff --git a/js/src/forum/addAlternateLayout.js b/js/src/forum/addAlternateLayout.js index 3cc89cb0..81053de3 100644 --- a/js/src/forum/addAlternateLayout.js +++ b/js/src/forum/addAlternateLayout.js @@ -7,7 +7,6 @@ import Button from 'flarum/common/components/Button'; import LoadingIndicator from 'flarum/common/components/LoadingIndicator'; import saveVote from './helpers/saveVote'; -import setting from './helpers/setting'; const get = (discussion, key) => { const post = discussion.firstPost(); @@ -21,6 +20,10 @@ const get = (discussion, key) => { export default function addAlternateLayout() { extend(DiscussionListItem.prototype, 'oninit', function () { + if (app.forum.attribute('fof-gamification.useAlternateLayout')) { + return; + } + const discussion = this.attrs.discussion; if (!discussion.seeVotes()) { @@ -30,16 +33,17 @@ export default function addAlternateLayout() { this.subtree.check(() => this.voteLoading); }); - extend(DiscussionListItem.prototype, 'view', function (vdom) { + extend(DiscussionListItem.prototype, 'contentItems', function (items) { + if (!app.forum.attribute('fof-gamification.useAlternateLayout')) { + return; + } + const discussion = this.attrs.discussion; if (!discussion.seeVotes()) { return; } - if (!vdom || !vdom.children) return; - - const content = vdom.children.find((v) => v && v.attrs && v.attrs.className && v.attrs.className.includes('DiscussionListItem-content')); const post = discussion.firstPost(); const hasUpvoted = get(discussion, 'hasUpvoted'); @@ -47,12 +51,13 @@ export default function addAlternateLayout() { // We set canVote to true for guest users so that they can access the login by clicking the button const canVote = !app.session.user || get(discussion, 'canVote'); - const upvotesOnly = setting('upVotesOnly', true); - const altIcon = setting('iconNameAlt') || 'arrow'; + const upvotesOnly = app.forum.attribute('fof-gamification.upVotesOnly'); + const altIcon = app.forum.attribute('fof-gamification.iconNameAlt'); const onclick = (upvoted, downvoted) => saveVote(post, upvoted, downvoted, (val) => (this.voteLoading = val)); - content.children.unshift( + items.add( + 'votes-alt',
+
, + 110 ); }); } diff --git a/js/src/forum/addHotnessSort.js b/js/src/forum/addHotnessSort.js index 87189571..dd0e34ee 100644 --- a/js/src/forum/addHotnessSort.js +++ b/js/src/forum/addHotnessSort.js @@ -1,3 +1,4 @@ +import IndexSidebar from 'flarum/forum/components/IndexSidebar'; import app from 'flarum/forum/app'; import { extend } from 'flarum/common/extend'; import IndexPage from 'flarum/forum/components/IndexPage'; @@ -5,7 +6,7 @@ import DiscussionListState from 'flarum/forum/states/DiscussionListState'; import LinkButton from 'flarum/common/components/LinkButton'; export default function () { - extend(IndexPage.prototype, 'navItems', function (items) { + extend(IndexSidebar.prototype, 'navItems', function (items) { if (!app.forum.attribute('canViewRankingPage')) { return; } diff --git a/js/src/forum/addNotifications.ts b/js/src/forum/addNotifications.ts index 10f79386..904a1f83 100644 --- a/js/src/forum/addNotifications.ts +++ b/js/src/forum/addNotifications.ts @@ -1,13 +1,12 @@ import { extend } from 'flarum/common/extend'; import app from 'flarum/forum/app'; import VoteNotification from './components/VoteNotification'; -import NotificationGrid from 'flarum/forum/components/NotificationGrid'; import ItemList from 'flarum/common/utils/ItemList'; export default function addNotifications() { app.notificationComponents.vote = VoteNotification; - extend(NotificationGrid.prototype, 'notificationTypes', function (items: ItemList<{ name: string; icon: string; label: any }>) { + extend('flarum/forum/components/NotificationGrid', 'notificationTypes', function (items: ItemList<{ name: string; icon: string; label: any }>) { const user = app.session?.user; if (!user?.canHaveVotingNotifications?.()) return; diff --git a/js/src/forum/addUpvoteTabToUserProfile.js b/js/src/forum/addUpvoteTabToUserProfile.js index a883ac0d..4e9e2077 100644 --- a/js/src/forum/addUpvoteTabToUserProfile.js +++ b/js/src/forum/addUpvoteTabToUserProfile.js @@ -3,13 +3,12 @@ import app from 'flarum/forum/app'; import UserPage from 'flarum/forum/components/UserPage'; import LinkButton from 'flarum/common/components/LinkButton'; import VotesUserPage from './components/VotesUserPage'; -import setting from './helpers/setting'; export default function addUpvoteTabToUserProfile() { app.routes['user.votes'] = { path: '/u/:username/votes', component: VotesUserPage }; extend(UserPage.prototype, 'navItems', function (items) { const user = this.user; - const icon = setting('iconName') || 'thumbs'; + const icon = app.forum.attribute('fof-gamification.iconName'); items.add( 'votes', diff --git a/js/src/forum/addUpvotesToDiscussion.js b/js/src/forum/addUpvotesToDiscussion.js index 75954389..050ecebe 100644 --- a/js/src/forum/addUpvotesToDiscussion.js +++ b/js/src/forum/addUpvotesToDiscussion.js @@ -2,16 +2,15 @@ import app from 'flarum/forum/app'; import { extend } from 'flarum/common/extend'; import DiscussionListItem from 'flarum/forum/components/DiscussionListItem'; import abbreviateNumber from 'flarum/common/utils/abbreviateNumber'; -import icon from 'flarum/common/helpers/icon'; -import setting from './helpers/setting'; +import Icon from 'flarum/common/components/Icon'; export default function () { - if (!setting('showVotesOnDiscussionPage', true) || setting('useAlternateLayout', true)) { - return; - } - extend(DiscussionListItem.prototype, 'elementAttrs', function (attrs) { - if (!this.attrs.discussion.seeVotes()) { + if ( + !this.attrs.discussion.seeVotes() || + !app.forum.attribute('fof-gamification.showVotesOnDiscussionPage') || + app.forum.attribute('fof-gamification.useAlternateLayout') + ) { return; } @@ -19,6 +18,10 @@ export default function () { }); extend(DiscussionListItem.prototype, 'infoItems', function (items) { + if (!app.forum.attribute('fof-gamification.showVotesOnDiscussionPage') || app.forum.attribute('fof-gamification.useAlternateLayout')) { + return; + } + const discussion = this.attrs.discussion; if (!discussion.seeVotes()) { @@ -28,7 +31,7 @@ export default function () { items.add( 'discussion-votes', - {icon('far fa-thumbs-up')} + {abbreviateNumber(this.attrs.discussion.votes())} , 20 diff --git a/js/src/forum/addUserInfo.js b/js/src/forum/addUserInfo.js index 5c17267c..38bd2157 100644 --- a/js/src/forum/addUserInfo.js +++ b/js/src/forum/addUserInfo.js @@ -3,8 +3,7 @@ import { extend } from 'flarum/common/extend'; import PostUser from 'flarum/forum/components/PostUser'; import UserCard from 'flarum/forum/components/UserCard'; import rankLabel from '../common/helpers/rankLabel'; -import setting from './helpers/setting'; -import icon from 'flarum/common/helpers/icon'; +import Icon from 'flarum/common/components/Icon'; export default function () { const matchClass = (className) => { @@ -35,7 +34,7 @@ export default function () { items.add( 'points',
- {icon('fas fa-medal')} + {app.translator.trans('fof-gamification.forum.user.card.points', { count: user.points(), })} @@ -47,7 +46,7 @@ export default function () { extend(UserCard.prototype, 'view', function (vnode) { const user = this.attrs.user; const profile_node = findMatchClass(vnode, 'UserCard-profile')[0]; - const amt = Number(setting('rankAmt')); + const amt = app.forum.attribute('fof-gamification.rankAmt') ?? user.ranks().length; if (!profile_node) return; @@ -98,7 +97,7 @@ export default function () { } const header_node = vnode.children.find(matchClass('PostUser-name')); - const amt = Number(setting('rankAmt')) ?? user.ranks().length; + const amt = app.forum.attribute('fof-gamification.rankAmt') ?? user.ranks().length; if (!user.ranks()) return; diff --git a/js/src/forum/addVoteButtons.js b/js/src/forum/addVoteButtons.js index 56550c0e..a0492837 100644 --- a/js/src/forum/addVoteButtons.js +++ b/js/src/forum/addVoteButtons.js @@ -6,7 +6,6 @@ import classList from 'flarum/common/utils/classList'; import PostControls from 'flarum/forum/utils/PostControls'; import VotesModal from './components/VotesModal'; -import setting from './helpers/setting'; import saveVote from './helpers/saveVote'; export default function () { @@ -35,8 +34,8 @@ export default function () { const hasDownvoted = post.hasDownvoted(); const hasUpvoted = post.hasUpvoted(); - const icon = setting('iconName') || 'thumbs'; - const upVotesOnly = setting('upVotesOnly', true); + const icon = app.forum.attribute('fof-gamification.iconName'); + const upVotesOnly = app.forum.attribute('fof-gamification.upVotesOnly'); const canSeeVotes = post.canSeeVotes(); @@ -47,7 +46,7 @@ export default function () { items.add( 'votes', -
+
{Button.component({ icon: this.voteLoading ? undefined : `fas fa-fw fa-${icon}-up`, className: classList('Post-vote Post-upvote', hasUpvoted && 'Post-vote--active'), diff --git a/js/src/forum/addVotersToDiscussionPageSideBar.tsx b/js/src/forum/addVotersToDiscussionPageSideBar.tsx index 0afbfcab..b54b4038 100644 --- a/js/src/forum/addVotersToDiscussionPageSideBar.tsx +++ b/js/src/forum/addVotersToDiscussionPageSideBar.tsx @@ -14,8 +14,7 @@ export default function addVotersToDiscussionPageSideBar() { const discussion = this.discussion; const posts = discussion!.posts() || []; const firstPost = posts?.[0]; - - if (firstPost?.canSeeVotes?.() && firstPost?.seeVoters?.() && !!app.forum.attribute('fof-gamification-op-votes-only')) { + if (firstPost?.canSeeVotes?.() && firstPost?.seeVoters?.() && !!app.forum.attribute('fof-gamification.firstPostOnly')) { items.add('op-voters', , 90); } }); diff --git a/js/src/forum/addVotesSort.js b/js/src/forum/addVotesSort.js index 962b6ffe..6eb74405 100644 --- a/js/src/forum/addVotesSort.js +++ b/js/src/forum/addVotesSort.js @@ -1,5 +1,5 @@ import { extend } from 'flarum/common/extend'; -import DiscussionListState from 'flarum/common/states/DiscussionListState'; +import DiscussionListState from 'flarum/forum/states/DiscussionListState'; export default function () { extend(DiscussionListState.prototype, 'sortMap', function (map) { diff --git a/js/src/forum/components/RankingImage.tsx b/js/src/forum/components/RankingImage.tsx index f071dff4..bcd1a304 100644 --- a/js/src/forum/components/RankingImage.tsx +++ b/js/src/forum/components/RankingImage.tsx @@ -1,6 +1,6 @@ import app from 'flarum/forum/app'; import Component, { ComponentAttrs } from 'flarum/common/Component'; -import icon from 'flarum/common/helpers/icon'; +import Icon from 'flarum/common/components/Icon'; export interface RankingImageAttrs extends ComponentAttrs { place: number; @@ -14,7 +14,9 @@ export default class RankingImage extends Component { return imgUrl ? ( ) : ( - {icon('fas fa-trophy')} + + + ); } } diff --git a/js/src/forum/components/RankingsPage.js b/js/src/forum/components/RankingsPage.js index f277fe73..8dac804e 100755 --- a/js/src/forum/components/RankingsPage.js +++ b/js/src/forum/components/RankingsPage.js @@ -1,5 +1,7 @@ +import IndexSidebar from 'flarum/forum/components/IndexSidebar'; +import PageStructure from 'flarum/forum/components/PageStructure'; import app from 'flarum/forum/app'; -import avatar from 'flarum/common/helpers/avatar'; +import Avatar from 'flarum/common/components/Avatar'; import Page from 'flarum/common/components/Page'; import IndexPage from 'flarum/forum/components/IndexPage'; import Button from 'flarum/common/components/Button'; @@ -41,44 +43,34 @@ export default class RankingsPage extends Page { } return ( -
- {IndexPage.prototype.hero()} -
-
- -
- - - - - - - {this.users.map((user, i) => { - ++i; - return [ - - {i < 4 ? : } - - {i < 4 ? : } - , - ]; - })} -
{app.translator.trans('fof-gamification.forum.ranking.rank')}{app.translator.trans('fof-gamification.forum.ranking.name')}{app.translator.trans('fof-gamification.forum.ranking.amount')}
{this.addOrdinalSuffix(i)} -
-

- - {i < 4 ? avatar(user, { className: 'info-avatar rankings-' + i + '-avatar' }) : ''} {username(user)} - -

-
-
{user.points()}{user.points()}
-
{loading}
-
-
-
-
+ IndexPage.prototype.hero()} sidebar={() => }> + + + + + + + {this.users.map((user, i) => { + ++i; + return [ + + {i < 4 ? : } + + {i < 4 ? : } + , + ]; + })} +
{app.translator.trans('fof-gamification.forum.ranking.rank')}{app.translator.trans('fof-gamification.forum.ranking.name')}{app.translator.trans('fof-gamification.forum.ranking.amount')}
{this.addOrdinalSuffix(i)} +
+

+ + {i < 4 ? : ''} {username(user)} + +

+
+
{user.points()}{user.points()}
+
{loading}
+
); } @@ -121,11 +113,16 @@ export default class RankingsPage extends Page { loadResults(offset) { const params = {}; params.page = { + filter: { + rankable: true, + }, + include: 'ranks', + sort: '-votes', offset: offset, limit: '10', }; - return app.store.find('rankings', params); + return app.store.find('users', params); } loadMore() { diff --git a/js/src/forum/components/VoteNotification.js b/js/src/forum/components/VoteNotification.js index 24a9189d..b16ff4e3 100755 --- a/js/src/forum/components/VoteNotification.js +++ b/js/src/forum/components/VoteNotification.js @@ -1,10 +1,9 @@ import app from 'flarum/forum/app'; import Notification from 'flarum/forum/components/Notification'; -import setting from '../helpers/setting'; export default class UpvotedNotification extends Notification { icon() { - const icon = setting('iconName') || 'thumbs'; + const icon = app.forum.attribute('fof-gamification.iconName'); if (this.attrs.notification.content() > 0) { return `fas fa-${icon}-up`; diff --git a/js/src/forum/components/Voters.tsx b/js/src/forum/components/Voters.tsx index 84247a23..161f35b0 100644 --- a/js/src/forum/components/Voters.tsx +++ b/js/src/forum/components/Voters.tsx @@ -3,8 +3,8 @@ import Component, { ComponentAttrs } from 'flarum/common/Component'; import LoadingIndicator from 'flarum/common/components/LoadingIndicator'; import Link from 'flarum/common/components/Link'; import Tooltip from 'flarum/common/components/Tooltip'; -import avatar from 'flarum/common/helpers/avatar'; -import icon from 'flarum/common/helpers/icon'; +import Avatar from 'flarum/common/components/Avatar'; +import Icon from 'flarum/common/components/Icon'; import SubtreeRetainer from 'flarum/common/utils/SubtreeRetainer'; import type Mithril from 'mithril'; @@ -57,7 +57,7 @@ export default class Voters extends Component {
- {icon('fas fa-users')} + {app.translator.trans('fof-gamification.forum.voters.label')} {app.translator.trans('fof-gamification.forum.voters.label')} @@ -79,7 +79,7 @@ export default class Voters extends Component {
- {icon('fas fa-users')} + {app.translator.trans('fof-gamification.forum.voters.label')} {voters.length === 0 @@ -94,7 +94,9 @@ export default class Voters extends Component {
{voters.slice(0, max).map((user: any) => ( - {avatar(user)} + + + ))} {voters.length > max ? ( diff --git a/js/src/forum/components/VotesModal.js b/js/src/forum/components/VotesModal.js index cc8e3a18..c6563e90 100755 --- a/js/src/forum/components/VotesModal.js +++ b/js/src/forum/components/VotesModal.js @@ -1,7 +1,7 @@ import app from 'flarum/forum/app'; import Modal from 'flarum/common/components/Modal'; import LoadingIndicator from 'flarum/common/components/LoadingIndicator'; -import avatar from 'flarum/common/helpers/avatar'; +import Avatar from 'flarum/common/components/Avatar'; import username from 'flarum/common/helpers/username'; import Link from 'flarum/common/components/Link'; @@ -47,7 +47,7 @@ export default class VotesModal extends Modal { {voters.map((user) => (
  • - {avatar(user)} {username(user)} + {username(user)}
  • ))} diff --git a/js/src/forum/components/index.ts b/js/src/forum/components/index.ts deleted file mode 100644 index 44359c04..00000000 --- a/js/src/forum/components/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -import RankingsPage from './RankingsPage'; -import VoteNotification from './VoteNotification'; -import VotesModal from './VotesModal'; -import Voters from './Voters'; -import RankingImage from './RankingImage'; - -export const components = { - RankingImage, - RankingsPage, - VoteNotification, - VotesModal, - Voters, -}; diff --git a/js/src/forum/extend.ts b/js/src/forum/extend.ts index 5c75e764..6f271276 100644 --- a/js/src/forum/extend.ts +++ b/js/src/forum/extend.ts @@ -1,5 +1,5 @@ +import commonExtend from '../common/extend'; import Extend from 'flarum/common/extenders'; -import { default as commonExtend } from '../common/extend'; import RankingsPage from './components/RankingsPage'; import Discussion from 'flarum/common/models/Discussion'; diff --git a/js/src/forum/helpers/index.js b/js/src/forum/helpers/index.js deleted file mode 100644 index e07af5b0..00000000 --- a/js/src/forum/helpers/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import saveVote from './saveVote'; -import setting from './setting'; - -import { helpers as commonHelpers } from '../../common/helpers'; - -export const helpers = { - saveVote, - setting, - ...commonHelpers, -}; diff --git a/js/src/forum/helpers/saveVote.js b/js/src/forum/helpers/saveVote.js index b596e861..63529513 100644 --- a/js/src/forum/helpers/saveVote.js +++ b/js/src/forum/helpers/saveVote.js @@ -15,12 +15,26 @@ export default (post, upvoted, downvoted, load, discussion = post.discussion()) downvoted = false; } + let action; + + switch (true) { + case (upvoted && downvoted) || (!upvoted && !downvoted): + action = null; + break; + case upvoted: + action = 'up'; + break; + case downvoted: + action = 'down'; + break; + } + if (load) load(true); m.redraw(); return post - .save([upvoted, downvoted, 'vote']) + .save({ vote: action }) .then( () => null, () => null diff --git a/js/src/forum/helpers/setting.js b/js/src/forum/helpers/setting.js deleted file mode 100644 index 20d64b8a..00000000 --- a/js/src/forum/helpers/setting.js +++ /dev/null @@ -1,11 +0,0 @@ -import app from 'flarum/forum/app'; - -export default (key, isBool = false) => { - const val = app.data[`fof-gamification.${key}`]; - - if (isBool) { - return !!parseInt(val); - } - - return val; -}; diff --git a/js/src/forum/index.ts b/js/src/forum/index.ts index fa944150..9bcc0f2c 100755 --- a/js/src/forum/index.ts +++ b/js/src/forum/index.ts @@ -6,8 +6,6 @@ import addUpvotesToDiscussion from './addUpvotesToDiscussion'; import addUserInfo from './addUserInfo'; import addPusher from './addPusher'; import addAlternateLayout from './addAlternateLayout'; - -import setting from './helpers/setting'; import addVotesSort from './addVotesSort'; import useAlternatePostVoteLayout from './useAlternatePostVoteLayout'; import addNotifications from './addNotifications'; @@ -27,14 +25,7 @@ app.initializers.add('fof-gamification', () => { addVotersToDiscussionPageSideBar(); addUpvoteTabToUserProfile(); - if (setting('useAlternateLayout', true)) { - addAlternateLayout(); - } + addAlternateLayout(); - if (setting('altPostVotingUi', true)) { - useAlternatePostVoteLayout(); - } + useAlternatePostVoteLayout(); }); - -export * from './components'; -export * from './helpers'; diff --git a/js/src/forum/useAlternatePostVoteLayout.tsx b/js/src/forum/useAlternatePostVoteLayout.tsx index 183d20bc..a643dad0 100644 --- a/js/src/forum/useAlternatePostVoteLayout.tsx +++ b/js/src/forum/useAlternatePostVoteLayout.tsx @@ -6,7 +6,6 @@ import CommentPost from 'flarum/forum/components/CommentPost'; import Button from 'flarum/common/components/Button'; import abbreviateNumber from 'flarum/common/utils/abbreviateNumber'; import LoadingIndicator from 'flarum/common/components/LoadingIndicator'; -import setting from './helpers/setting'; import saveVote from './helpers/saveVote'; import type ItemList from 'flarum/common/utils/ItemList'; @@ -14,15 +13,23 @@ import type Mithril from 'mithril'; export default function useAlternatePostVoteLayout() { extend(CommentPost.prototype, 'actionItems', function (this: CommentPost, items: ItemList) { + if (!app.forum.attribute('fof-gamification.altPostVotingUi')) { + return; + } + if (this.attrs.post.isHidden()) return; items.remove('votes'); }); extend(CommentPost.prototype, 'classes', function (this: CommentPost, classes: string[]) { + if (!app.forum.attribute('fof-gamification.altPostVotingUi')) { + return; + } + if (this.attrs.post.isHidden()) return; - const upvotesOnly = setting('upVotesOnly', true); + const upvotesOnly = app.forum.attribute('fof-gamification.upVotesOnly'); classes.push('votesAlternativeLayout'); @@ -32,10 +39,18 @@ export default function useAlternatePostVoteLayout() { }); extend(CommentPost.prototype, 'oninit', function () { + if (!app.forum.attribute('fof-gamification.altPostVotingUi')) { + return; + } + (this as any).voteLoading = false; }); - extend(CommentPost.prototype, 'headerItems', function (this: CommentPost, items: ItemList) { + extend(CommentPost.prototype, 'sideItems', function (this: CommentPost, items: ItemList) { + if (!app.forum.attribute('fof-gamification.altPostVotingUi')) { + return; + } + const post = this.attrs.post; if (post.isHidden()) return; @@ -44,8 +59,8 @@ export default function useAlternatePostVoteLayout() { const hasDownvoted = post.hasDownvoted(); const hasUpvoted = post.hasUpvoted(); - const icon = setting('iconName') || 'thumbs'; - const upvotesOnly = setting('upVotesOnly', true); + const icon = app.forum.attribute('fof-gamification.iconName'); + const upvotesOnly = app.forum.attribute('fof-gamification.upVotesOnly'); const canSeeVotes = post.canSeeVotes(); @@ -83,8 +98,7 @@ export default function useAlternatePostVoteLayout() { )} {(this as any).voteLoading && } -
    , - 10000 +
    ); }); } diff --git a/js/tsconfig.json b/js/tsconfig.json index 5559bc50..4ea9e001 100644 --- a/js/tsconfig.json +++ b/js/tsconfig.json @@ -8,7 +8,7 @@ "baseUrl": ".", "paths": { "flarum/*": ["../vendor/flarum/core/js/dist-typings/*"], - "@flarum/core/*": ["../vendor/flarum/core/js/dist-typings/*"] + "@flarum/core/*": ["../vendor/flarum/core/js/dist-typings/*"], } } } diff --git a/js/yarn.lock b/js/yarn.lock index f78bc92c..67ff8861 100644 --- a/js/yarn.lock +++ b/js/yarn.lock @@ -2,15 +2,7 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.2.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" - integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.24" - -"@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0": +"@babel/code-frame@^7.25.9": version "7.26.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.0.tgz#9374b5cd068d128dac0b94ff482594273b1c2815" integrity sha512-INCKxTtbXtcNbUZ3YXutwMpEleqttcswhAdee7dhuoVrD2cnuc3PqtERBtxkX5nziX9vnBL8WXmSGwv8CuPV6g== @@ -19,33 +11,42 @@ js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.9", "@babel/compat-data@^7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.0.tgz#f02ba6d34e88fadd5e8861e8b38902f43cc1c819" - integrity sha512-qETICbZSLe7uXv9VE8T/RWOdIE5qqyTucOt4zLYMafj2MRO271VGgLd4RACJMeBO37UPWhXiKMBk7YlJ0fOzQA== - -"@babel/core@^7.16.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.0.tgz#d78b6023cc8f3114ccf049eb219613f74a747b40" - integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.26.0" - "@babel/generator" "^7.26.0" - "@babel/helper-compilation-targets" "^7.25.9" - "@babel/helper-module-transforms" "^7.26.0" - "@babel/helpers" "^7.26.0" - "@babel/parser" "^7.26.0" - "@babel/template" "^7.25.9" - "@babel/traverse" "^7.25.9" - "@babel/types" "^7.26.0" +"@babel/code-frame@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" + integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== + dependencies: + "@babel/helper-validator-identifier" "^7.27.1" + js-tokens "^4.0.0" + picocolors "^1.1.1" + +"@babel/compat-data@^7.27.2", "@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.5.tgz#a8a4962e1567121ac0b3b487f52107443b455c7f" + integrity sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA== + +"@babel/core@^7.20.2": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.5.tgz#4c81b35e51e1b734f510c99b07dfbc7bbbb48f7e" + integrity sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.5" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-module-transforms" "^7.28.3" + "@babel/helpers" "^7.28.4" + "@babel/parser" "^7.28.5" + "@babel/template" "^7.27.2" + "@babel/traverse" "^7.28.5" + "@babel/types" "^7.28.5" + "@jridgewell/remapping" "^2.3.5" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.25.9", "@babel/generator@^7.26.0": +"@babel/generator@^7.25.9": version "7.26.0" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.0.tgz#505cc7c90d92513f458a477e5ef0703e7c91b8d7" integrity sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w== @@ -56,6 +57,17 @@ "@jridgewell/trace-mapping" "^0.3.25" jsesc "^3.0.2" +"@babel/generator@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.5.tgz#712722d5e50f44d07bc7ac9fe84438742dd61298" + integrity sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ== + dependencies: + "@babel/parser" "^7.28.5" + "@babel/types" "^7.28.5" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + "@babel/helper-annotate-as-pure@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz#d8eac4d2dc0d7b6e11fa6e535332e0d3184f06b4" @@ -63,26 +75,25 @@ dependencies: "@babel/types" "^7.25.9" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz#f41752fe772a578e67286e6779a68a5a92de1ee9" - integrity sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g== +"@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz#f31fd86b915fc4daf1f3ac6976c59be7084ed9c5" + integrity sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg== dependencies: - "@babel/traverse" "^7.25.9" - "@babel/types" "^7.25.9" + "@babel/types" "^7.27.3" -"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz#55af025ce365be3cdc0c1c1e56c6af617ce88875" - integrity sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ== +"@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.27.2": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d" + integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== dependencies: - "@babel/compat-data" "^7.25.9" - "@babel/helper-validator-option" "^7.25.9" + "@babel/compat-data" "^7.27.2" + "@babel/helper-validator-option" "^7.27.1" browserslist "^4.24.0" lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.25.9": +"@babel/helper-create-class-features-plugin@^7.18.6": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz#7644147706bb90ff613297d49ed5266bde729f83" integrity sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ== @@ -95,7 +106,20 @@ "@babel/traverse" "^7.25.9" semver "^6.3.1" -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.25.9": +"@babel/helper-create-class-features-plugin@^7.27.1", "@babel/helper-create-class-features-plugin@^7.28.3", "@babel/helper-create-class-features-plugin@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz#472d0c28028850968979ad89f173594a6995da46" + integrity sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-member-expression-to-functions" "^7.28.5" + "@babel/helper-optimise-call-expression" "^7.27.1" + "@babel/helper-replace-supers" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/traverse" "^7.28.5" + semver "^6.3.1" + +"@babel/helper-create-regexp-features-plugin@^7.18.6": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz#3e8999db94728ad2b2458d7a470e7770b7764e26" integrity sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw== @@ -104,16 +128,30 @@ regexpu-core "^6.1.1" semver "^6.3.1" -"@babel/helper-define-polyfill-provider@^0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz#18594f789c3594acb24cfdb4a7f7b7d2e8bd912d" - integrity sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ== +"@babel/helper-create-regexp-features-plugin@^7.27.1": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz#7c1ddd64b2065c7f78034b25b43346a7e19ed997" + integrity sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.3" + regexpu-core "^6.3.1" + semver "^6.3.1" + +"@babel/helper-define-polyfill-provider@^0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz#742ccf1cb003c07b48859fc9fa2c1bbe40e5f753" + integrity sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg== dependencies: - "@babel/helper-compilation-targets" "^7.22.6" - "@babel/helper-plugin-utils" "^7.22.5" - debug "^4.1.1" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-plugin-utils" "^7.27.1" + debug "^4.4.1" lodash.debounce "^4.0.8" - resolve "^1.14.2" + resolve "^1.22.10" + +"@babel/helper-globals@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674" + integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== "@babel/helper-member-expression-to-functions@^7.25.9": version "7.25.9" @@ -123,22 +161,30 @@ "@babel/traverse" "^7.25.9" "@babel/types" "^7.25.9" -"@babel/helper-module-imports@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715" - integrity sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw== +"@babel/helper-member-expression-to-functions@^7.27.1", "@babel/helper-member-expression-to-functions@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz#f3e07a10be37ed7a63461c63e6929575945a6150" + integrity sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg== dependencies: - "@babel/traverse" "^7.25.9" - "@babel/types" "^7.25.9" + "@babel/traverse" "^7.28.5" + "@babel/types" "^7.28.5" -"@babel/helper-module-transforms@^7.25.9", "@babel/helper-module-transforms@^7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz#8ce54ec9d592695e58d84cd884b7b5c6a2fdeeae" - integrity sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw== +"@babel/helper-module-imports@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz#7ef769a323e2655e126673bb6d2d6913bbead204" + integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== dependencies: - "@babel/helper-module-imports" "^7.25.9" - "@babel/helper-validator-identifier" "^7.25.9" - "@babel/traverse" "^7.25.9" + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" + +"@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.3": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz#a2b37d3da3b2344fe085dab234426f2b9a2fa5f6" + integrity sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw== + dependencies: + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + "@babel/traverse" "^7.28.3" "@babel/helper-optimise-call-expression@^7.25.9": version "7.25.9" @@ -147,19 +193,31 @@ dependencies: "@babel/types" "^7.25.9" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.25.9": +"@babel/helper-optimise-call-expression@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz#c65221b61a643f3e62705e5dd2b5f115e35f9200" + integrity sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw== + dependencies: + "@babel/types" "^7.27.1" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.18.6": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz#9cbdd63a9443a2c92a725cca7ebca12cc8dd9f46" integrity sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw== -"@babel/helper-remap-async-to-generator@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz#e53956ab3d5b9fb88be04b3e2f31b523afd34b92" - integrity sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw== +"@babel/helper-plugin-utils@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz#ddb2f876534ff8013e6c2b299bf4d39b3c51d44c" + integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== + +"@babel/helper-remap-async-to-generator@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz#4601d5c7ce2eb2aea58328d43725523fcd362ce6" + integrity sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.9" - "@babel/helper-wrap-function" "^7.25.9" - "@babel/traverse" "^7.25.9" + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-wrap-function" "^7.27.1" + "@babel/traverse" "^7.27.1" "@babel/helper-replace-supers@^7.25.9": version "7.25.9" @@ -170,13 +228,14 @@ "@babel/helper-optimise-call-expression" "^7.25.9" "@babel/traverse" "^7.25.9" -"@babel/helper-simple-access@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz#6d51783299884a2c74618d6ef0f86820ec2e7739" - integrity sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q== +"@babel/helper-replace-supers@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz#b1ed2d634ce3bdb730e4b52de30f8cccfd692bc0" + integrity sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA== dependencies: - "@babel/traverse" "^7.25.9" - "@babel/types" "^7.25.9" + "@babel/helper-member-expression-to-functions" "^7.27.1" + "@babel/helper-optimise-call-expression" "^7.27.1" + "@babel/traverse" "^7.27.1" "@babel/helper-skip-transparent-expression-wrappers@^7.25.9": version "7.25.9" @@ -186,37 +245,55 @@ "@babel/traverse" "^7.25.9" "@babel/types" "^7.25.9" +"@babel/helper-skip-transparent-expression-wrappers@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz#62bb91b3abba8c7f1fec0252d9dbea11b3ee7a56" + integrity sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg== + dependencies: + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" + "@babel/helper-string-parser@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== + "@babel/helper-validator-identifier@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== -"@babel/helper-validator-option@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72" - integrity sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw== +"@babel/helper-validator-identifier@^7.27.1", "@babel/helper-validator-identifier@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" + integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== -"@babel/helper-wrap-function@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz#d99dfd595312e6c894bd7d237470025c85eea9d0" - integrity sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g== +"@babel/helper-validator-option@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" + integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== + +"@babel/helper-wrap-function@^7.27.1": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz#fe4872092bc1438ffd0ce579e6f699609f9d0a7a" + integrity sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g== dependencies: - "@babel/template" "^7.25.9" - "@babel/traverse" "^7.25.9" - "@babel/types" "^7.25.9" + "@babel/template" "^7.27.2" + "@babel/traverse" "^7.28.3" + "@babel/types" "^7.28.2" -"@babel/helpers@^7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.0.tgz#30e621f1eba5aa45fe6f4868d2e9154d884119a4" - integrity sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw== +"@babel/helpers@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.4.tgz#fe07274742e95bdf7cf1443593eeb8926ab63827" + integrity sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w== dependencies: - "@babel/template" "^7.25.9" - "@babel/types" "^7.26.0" + "@babel/template" "^7.27.2" + "@babel/types" "^7.28.4" "@babel/parser@^7.25.9", "@babel/parser@^7.26.0": version "7.26.1" @@ -225,46 +302,53 @@ dependencies: "@babel/types" "^7.26.0" -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz#cc2e53ebf0a0340777fff5ed521943e253b4d8fe" - integrity sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g== +"@babel/parser@^7.27.2", "@babel/parser@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.5.tgz#0b0225ee90362f030efd644e8034c99468893b08" + integrity sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/traverse" "^7.25.9" + "@babel/types" "^7.28.5" -"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz#af9e4fb63ccb8abcb92375b2fcfe36b60c774d30" - integrity sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw== +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz#fbde57974707bbfa0376d34d425ff4fa6c732421" + integrity sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.28.5" -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz#e8dc26fcd616e6c5bf2bd0d5a2c151d4f92a9137" - integrity sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug== +"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz#43f70a6d7efd52370eefbdf55ae03d91b293856d" + integrity sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz#807a667f9158acac6f6164b4beb85ad9ebc9e1d1" - integrity sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz#beb623bd573b8b6f3047bd04c32506adc3e58a72" + integrity sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" - "@babel/plugin-transform-optional-chaining" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz#de7093f1e7deaf68eadd7cc6b07f2ab82543269e" - integrity sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz#e134a5479eb2ba9c02714e8c1ebf1ec9076124fd" + integrity sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/traverse" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/plugin-transform-optional-chaining" "^7.27.1" -"@babel/plugin-proposal-class-properties@^7.16.0": +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.28.3": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz#373f6e2de0016f73caf8f27004f61d167743742a" + integrity sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.28.3" + +"@babel/plugin-proposal-class-properties@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== @@ -272,7 +356,7 @@ "@babel/helper-create-class-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-proposal-private-methods@^7.16.0": +"@babel/plugin-proposal-private-methods@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== @@ -285,33 +369,33 @@ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== -"@babel/plugin-syntax-import-assertions@^7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz#620412405058efa56e4a564903b79355020f445f" - integrity sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg== +"@babel/plugin-syntax-import-assertions@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz#88894aefd2b03b5ee6ad1562a7c8e1587496aecd" + integrity sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-import-attributes@^7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz#3b1412847699eea739b4f2602c74ce36f6b0b0f7" - integrity sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A== +"@babel/plugin-syntax-import-attributes@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz#34c017d54496f9b11b61474e7ea3dfd5563ffe07" + integrity sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-jsx@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz#a34313a178ea56f1951599b929c1ceacee719290" - integrity sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA== +"@babel/plugin-syntax-jsx@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz#2f9beb5eff30fa507c5532d107daac7b888fa34c" + integrity sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-typescript@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz#67dda2b74da43727cf21d46cf9afef23f4365399" - integrity sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ== +"@babel/plugin-syntax-typescript@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz#5147d29066a793450f220c63fa3a9431b7e6dd18" + integrity sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" @@ -321,531 +405,540 @@ "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-arrow-functions@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz#7821d4410bee5daaadbb4cdd9a6649704e176845" - integrity sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg== - dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - -"@babel/plugin-transform-async-generator-functions@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz#1b18530b077d18a407c494eb3d1d72da505283a2" - integrity sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw== - dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-remap-async-to-generator" "^7.25.9" - "@babel/traverse" "^7.25.9" - -"@babel/plugin-transform-async-to-generator@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz#c80008dacae51482793e5a9c08b39a5be7e12d71" - integrity sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ== - dependencies: - "@babel/helper-module-imports" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-remap-async-to-generator" "^7.25.9" - -"@babel/plugin-transform-block-scoped-functions@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz#5700691dbd7abb93de300ca7be94203764fce458" - integrity sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA== - dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - -"@babel/plugin-transform-block-scoping@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz#c33665e46b06759c93687ca0f84395b80c0473a1" - integrity sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg== - dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - -"@babel/plugin-transform-class-properties@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz#a8ce84fedb9ad512549984101fa84080a9f5f51f" - integrity sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - -"@babel/plugin-transform-class-static-block@^7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz#6c8da219f4eb15cae9834ec4348ff8e9e09664a0" - integrity sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - -"@babel/plugin-transform-classes@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz#7152457f7880b593a63ade8a861e6e26a4469f52" - integrity sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.25.9" - "@babel/helper-compilation-targets" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-replace-supers" "^7.25.9" - "@babel/traverse" "^7.25.9" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz#db36492c78460e534b8852b1d5befe3c923ef10b" - integrity sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA== +"@babel/plugin-transform-arrow-functions@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz#6e2061067ba3ab0266d834a9f94811196f2aba9a" + integrity sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/template" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-destructuring@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz#966ea2595c498224340883602d3cfd7a0c79cea1" - integrity sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ== +"@babel/plugin-transform-async-generator-functions@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz#1276e6c7285ab2cd1eccb0bc7356b7a69ff842c2" + integrity sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-remap-async-to-generator" "^7.27.1" + "@babel/traverse" "^7.28.0" -"@babel/plugin-transform-dotall-regex@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz#bad7945dd07734ca52fe3ad4e872b40ed09bb09a" - integrity sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA== +"@babel/plugin-transform-async-to-generator@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz#9a93893b9379b39466c74474f55af03de78c66e7" + integrity sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-remap-async-to-generator" "^7.27.1" -"@babel/plugin-transform-duplicate-keys@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz#8850ddf57dce2aebb4394bb434a7598031059e6d" - integrity sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw== +"@babel/plugin-transform-block-scoped-functions@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz#558a9d6e24cf72802dd3b62a4b51e0d62c0f57f9" + integrity sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz#6f7259b4de127721a08f1e5165b852fcaa696d31" - integrity sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog== +"@babel/plugin-transform-block-scoping@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz#e0d3af63bd8c80de2e567e690a54e84d85eb16f6" + integrity sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-dynamic-import@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz#23e917de63ed23c6600c5dd06d94669dce79f7b8" - integrity sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg== +"@babel/plugin-transform-class-properties@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz#dd40a6a370dfd49d32362ae206ddaf2bb082a925" + integrity sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-class-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-exponentiation-operator@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz#ece47b70d236c1d99c263a1e22b62dc20a4c8b0f" - integrity sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA== +"@babel/plugin-transform-class-static-block@^7.28.3": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz#d1b8e69b54c9993bc558203e1f49bfc979bfd852" + integrity sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-class-features-plugin" "^7.28.3" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-export-namespace-from@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz#90745fe55053394f554e40584cda81f2c8a402a2" - integrity sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww== +"@babel/plugin-transform-classes@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz#75d66175486788c56728a73424d67cbc7473495c" + integrity sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-globals" "^7.28.0" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-replace-supers" "^7.27.1" + "@babel/traverse" "^7.28.4" -"@babel/plugin-transform-for-of@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz#4bdc7d42a213397905d89f02350c5267866d5755" - integrity sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A== +"@babel/plugin-transform-computed-properties@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz#81662e78bf5e734a97982c2b7f0a793288ef3caa" + integrity sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/template" "^7.27.1" -"@babel/plugin-transform-function-name@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz#939d956e68a606661005bfd550c4fc2ef95f7b97" - integrity sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA== +"@babel/plugin-transform-destructuring@^7.28.0", "@babel/plugin-transform-destructuring@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz#b8402764df96179a2070bb7b501a1586cf8ad7a7" + integrity sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw== dependencies: - "@babel/helper-compilation-targets" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/traverse" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.28.5" -"@babel/plugin-transform-json-strings@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz#c86db407cb827cded902a90c707d2781aaa89660" - integrity sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw== +"@babel/plugin-transform-dotall-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz#aa6821de864c528b1fecf286f0a174e38e826f4d" + integrity sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-literals@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz#1a1c6b4d4aa59bc4cad5b6b3a223a0abd685c9de" - integrity sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ== +"@babel/plugin-transform-duplicate-keys@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz#f1fbf628ece18e12e7b32b175940e68358f546d1" + integrity sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-logical-assignment-operators@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz#b19441a8c39a2fda0902900b306ea05ae1055db7" - integrity sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q== +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz#5043854ca620a94149372e69030ff8cb6a9eb0ec" + integrity sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-member-expression-literals@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz#63dff19763ea64a31f5e6c20957e6a25e41ed5de" - integrity sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA== +"@babel/plugin-transform-dynamic-import@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz#4c78f35552ac0e06aa1f6e3c573d67695e8af5a4" + integrity sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-modules-amd@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz#49ba478f2295101544abd794486cd3088dddb6c5" - integrity sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw== +"@babel/plugin-transform-explicit-resource-management@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz#45be6211b778dbf4b9d54c4e8a2b42fa72e09a1a" + integrity sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ== dependencies: - "@babel/helper-module-transforms" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/plugin-transform-destructuring" "^7.28.0" -"@babel/plugin-transform-modules-commonjs@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz#d165c8c569a080baf5467bda88df6425fc060686" - integrity sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg== +"@babel/plugin-transform-exponentiation-operator@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz#7cc90a8170e83532676cfa505278e147056e94fe" + integrity sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw== dependencies: - "@babel/helper-module-transforms" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-simple-access" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-modules-systemjs@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz#8bd1b43836269e3d33307151a114bcf3ba6793f8" - integrity sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA== +"@babel/plugin-transform-export-namespace-from@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz#71ca69d3471edd6daa711cf4dfc3400415df9c23" + integrity sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ== dependencies: - "@babel/helper-module-transforms" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-validator-identifier" "^7.25.9" - "@babel/traverse" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-modules-umd@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz#6710079cdd7c694db36529a1e8411e49fcbf14c9" - integrity sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw== +"@babel/plugin-transform-for-of@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz#bc24f7080e9ff721b63a70ac7b2564ca15b6c40a" + integrity sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw== dependencies: - "@babel/helper-module-transforms" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" -"@babel/plugin-transform-named-capturing-groups-regex@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz#454990ae6cc22fd2a0fa60b3a2c6f63a38064e6a" - integrity sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA== +"@babel/plugin-transform-function-name@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz#4d0bf307720e4dce6d7c30fcb1fd6ca77bdeb3a7" + integrity sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-compilation-targets" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.27.1" -"@babel/plugin-transform-new-target@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz#42e61711294b105c248336dcb04b77054ea8becd" - integrity sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ== +"@babel/plugin-transform-json-strings@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz#a2e0ce6ef256376bd527f290da023983527a4f4c" + integrity sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-nullish-coalescing-operator@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz#bcb1b0d9e948168102d5f7104375ca21c3266949" - integrity sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog== +"@babel/plugin-transform-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz#baaefa4d10a1d4206f9dcdda50d7d5827bb70b24" + integrity sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-numeric-separator@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz#bfed75866261a8b643468b0ccfd275f2033214a1" - integrity sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q== +"@babel/plugin-transform-logical-assignment-operators@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz#d028fd6db8c081dee4abebc812c2325e24a85b0e" + integrity sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-object-assign@^7.16.0": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.25.9.tgz#686203d53ee688d1642bf3a8c751dfb3981021c8" - integrity sha512-I/Vl1aQnPsrrn837oLbo+VQtkNcjuuiATqwmuweg4fTauwHHQoxyjmjjOVKyO8OaTxgqYTKW3LuQsykXjDf5Ag== +"@babel/plugin-transform-member-expression-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz#37b88ba594d852418e99536f5612f795f23aeaf9" + integrity sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-object-rest-spread@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz#0203725025074164808bcf1a2cfa90c652c99f18" - integrity sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg== +"@babel/plugin-transform-modules-amd@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz#a4145f9d87c2291fe2d05f994b65dba4e3e7196f" + integrity sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA== dependencies: - "@babel/helper-compilation-targets" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/plugin-transform-parameters" "^7.25.9" + "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-object-super@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz#385d5de135162933beb4a3d227a2b7e52bb4cf03" - integrity sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A== +"@babel/plugin-transform-modules-commonjs@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz#8e44ed37c2787ecc23bdc367f49977476614e832" + integrity sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-replace-supers" "^7.25.9" + "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-optional-catch-binding@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz#10e70d96d52bb1f10c5caaac59ac545ea2ba7ff3" - integrity sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g== +"@babel/plugin-transform-modules-systemjs@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz#7439e592a92d7670dfcb95d0cbc04bd3e64801d2" + integrity sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-module-transforms" "^7.28.3" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + "@babel/traverse" "^7.28.5" -"@babel/plugin-transform-optional-chaining@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz#e142eb899d26ef715435f201ab6e139541eee7dd" - integrity sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A== +"@babel/plugin-transform-modules-umd@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz#63f2cf4f6dc15debc12f694e44714863d34cd334" + integrity sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-parameters@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz#b856842205b3e77e18b7a7a1b94958069c7ba257" - integrity sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g== +"@babel/plugin-transform-named-capturing-groups-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz#f32b8f7818d8fc0cc46ee20a8ef75f071af976e1" + integrity sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-private-methods@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz#847f4139263577526455d7d3223cd8bda51e3b57" - integrity sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw== +"@babel/plugin-transform-new-target@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz#259c43939728cad1706ac17351b7e6a7bea1abeb" + integrity sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-private-property-in-object@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz#9c8b73e64e6cc3cbb2743633885a7dd2c385fe33" - integrity sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw== +"@babel/plugin-transform-nullish-coalescing-operator@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz#4f9d3153bf6782d73dd42785a9d22d03197bc91d" + integrity sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.9" - "@babel/helper-create-class-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-property-literals@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz#d72d588bd88b0dec8b62e36f6fda91cedfe28e3f" - integrity sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA== +"@babel/plugin-transform-numeric-separator@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz#614e0b15cc800e5997dadd9bd6ea524ed6c819c6" + integrity sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-react-display-name@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.9.tgz#4b79746b59efa1f38c8695065a92a9f5afb24f7d" - integrity sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ== +"@babel/plugin-transform-object-assign@^7.18.6": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.27.1.tgz#2a76d9bbf7610296ce906a6fe7c7317025c9a67c" + integrity sha512-LP6tsnirA6iy13uBKiYgjJsfQrodmlSrpZModtlo1Vk8sOO68gfo7dfA9TGJyEgxTiO7czK4EGZm8FJEZtk4kQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-react-jsx-development@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.9.tgz#8fd220a77dd139c07e25225a903b8be8c829e0d7" - integrity sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw== +"@babel/plugin-transform-object-rest-spread@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz#9ee1ceca80b3e6c4bac9247b2149e36958f7f98d" + integrity sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew== dependencies: - "@babel/plugin-transform-react-jsx" "^7.25.9" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/plugin-transform-destructuring" "^7.28.0" + "@babel/plugin-transform-parameters" "^7.27.7" + "@babel/traverse" "^7.28.4" -"@babel/plugin-transform-react-jsx@^7.16.0", "@babel/plugin-transform-react-jsx@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.9.tgz#06367940d8325b36edff5e2b9cbe782947ca4166" - integrity sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw== +"@babel/plugin-transform-object-super@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz#1c932cd27bf3874c43a5cac4f43ebf970c9871b5" + integrity sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.9" - "@babel/helper-module-imports" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/plugin-syntax-jsx" "^7.25.9" - "@babel/types" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-replace-supers" "^7.27.1" -"@babel/plugin-transform-react-pure-annotations@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.9.tgz#ea1c11b2f9dbb8e2d97025f43a3b5bc47e18ae62" - integrity sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg== +"@babel/plugin-transform-optional-catch-binding@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz#84c7341ebde35ccd36b137e9e45866825072a30c" + integrity sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-regenerator@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz#03a8a4670d6cebae95305ac6defac81ece77740b" - integrity sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg== - dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - regenerator-transform "^0.15.2" +"@babel/plugin-transform-optional-chaining@^7.27.1", "@babel/plugin-transform-optional-chaining@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz#8238c785f9d5c1c515a90bf196efb50d075a4b26" + integrity sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" -"@babel/plugin-transform-regexp-modifiers@^7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz#2f5837a5b5cd3842a919d8147e9903cc7455b850" - integrity sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" +"@babel/plugin-transform-parameters@^7.27.7": + version "7.27.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz#1fd2febb7c74e7d21cf3b05f7aebc907940af53a" + integrity sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-reserved-words@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz#0398aed2f1f10ba3f78a93db219b27ef417fb9ce" - integrity sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg== +"@babel/plugin-transform-private-methods@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz#fdacbab1c5ed81ec70dfdbb8b213d65da148b6af" + integrity sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - -"@babel/plugin-transform-runtime@^7.16.0": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz#62723ea3f5b31ffbe676da9d6dae17138ae580ea" - integrity sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ== - dependencies: - "@babel/helper-module-imports" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - babel-plugin-polyfill-corejs2 "^0.4.10" - babel-plugin-polyfill-corejs3 "^0.10.6" - babel-plugin-polyfill-regenerator "^0.6.1" - semver "^6.3.1" + "@babel/helper-create-class-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-shorthand-properties@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz#bb785e6091f99f826a95f9894fc16fde61c163f2" - integrity sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng== +"@babel/plugin-transform-private-property-in-object@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz#4dbbef283b5b2f01a21e81e299f76e35f900fb11" + integrity sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-create-class-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-spread@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz#24a35153931b4ba3d13cec4a7748c21ab5514ef9" - integrity sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A== +"@babel/plugin-transform-property-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz#07eafd618800591e88073a0af1b940d9a42c6424" + integrity sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-sticky-regex@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz#c7f02b944e986a417817b20ba2c504dfc1453d32" - integrity sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA== +"@babel/plugin-transform-react-display-name@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz#6f20a7295fea7df42eb42fed8f896813f5b934de" + integrity sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-template-literals@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz#6dbd4a24e8fad024df76d1fac6a03cf413f60fe1" - integrity sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw== +"@babel/plugin-transform-react-jsx-development@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz#47ff95940e20a3a70e68ad3d4fcb657b647f6c98" + integrity sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/plugin-transform-react-jsx" "^7.27.1" -"@babel/plugin-transform-typeof-symbol@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz#224ba48a92869ddbf81f9b4a5f1204bbf5a2bc4b" - integrity sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA== +"@babel/plugin-transform-react-jsx@^7.19.0", "@babel/plugin-transform-react-jsx@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz#1023bc94b78b0a2d68c82b5e96aed573bcfb9db0" + integrity sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/plugin-syntax-jsx" "^7.27.1" + "@babel/types" "^7.27.1" -"@babel/plugin-transform-typescript@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.9.tgz#69267905c2b33c2ac6d8fe765e9dc2ddc9df3849" - integrity sha512-7PbZQZP50tzv2KGGnhh82GSyMB01yKY9scIjf1a+GfZCtInOWqUH5+1EBU4t9fyR5Oykkkc9vFTs4OHrhHXljQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.25.9" - "@babel/helper-create-class-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" - "@babel/plugin-syntax-typescript" "^7.25.9" +"@babel/plugin-transform-react-pure-annotations@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz#339f1ce355eae242e0649f232b1c68907c02e879" + integrity sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-unicode-escapes@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz#a75ef3947ce15363fccaa38e2dd9bc70b2788b82" - integrity sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q== - dependencies: - "@babel/helper-plugin-utils" "^7.25.9" +"@babel/plugin-transform-regenerator@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz#9d3fa3bebb48ddd0091ce5729139cd99c67cea51" + integrity sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-unicode-property-regex@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz#a901e96f2c1d071b0d1bb5dc0d3c880ce8f53dd3" - integrity sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg== +"@babel/plugin-transform-regexp-modifiers@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz#df9ba5577c974e3f1449888b70b76169998a6d09" + integrity sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-unicode-regex@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz#5eae747fe39eacf13a8bd006a4fb0b5d1fa5e9b1" - integrity sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA== +"@babel/plugin-transform-reserved-words@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz#40fba4878ccbd1c56605a4479a3a891ac0274bb4" + integrity sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-unicode-sets-regex@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz#65114c17b4ffc20fa5b163c63c70c0d25621fabe" - integrity sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ== +"@babel/plugin-transform-runtime@^7.19.6": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz#ae3e21fbefe2831ebac04dfa6b463691696afe17" + integrity sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + babel-plugin-polyfill-corejs2 "^0.4.14" + babel-plugin-polyfill-corejs3 "^0.13.0" + babel-plugin-polyfill-regenerator "^0.6.5" + semver "^6.3.1" -"@babel/preset-env@^7.16.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.26.0.tgz#30e5c6bc1bcc54865bff0c5a30f6d4ccdc7fa8b1" - integrity sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw== - dependencies: - "@babel/compat-data" "^7.26.0" - "@babel/helper-compilation-targets" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-validator-option" "^7.25.9" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.25.9" - "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.25.9" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.25.9" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.25.9" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.9" +"@babel/plugin-transform-shorthand-properties@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz#532abdacdec87bfee1e0ef8e2fcdee543fe32b90" + integrity sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-spread@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz#1a264d5fc12750918f50e3fe3e24e437178abb08" + integrity sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + +"@babel/plugin-transform-sticky-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz#18984935d9d2296843a491d78a014939f7dcd280" + integrity sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-template-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz#1a0eb35d8bb3e6efc06c9fd40eb0bcef548328b8" + integrity sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-typeof-symbol@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz#70e966bb492e03509cf37eafa6dcc3051f844369" + integrity sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-typescript@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz#441c5f9a4a1315039516c6c612fc66d5f4594e72" + integrity sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-create-class-features-plugin" "^7.28.5" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/plugin-syntax-typescript" "^7.27.1" + +"@babel/plugin-transform-unicode-escapes@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz#3e3143f8438aef842de28816ece58780190cf806" + integrity sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-unicode-property-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz#bdfe2d3170c78c5691a3c3be934c8c0087525956" + integrity sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-unicode-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz#25948f5c395db15f609028e370667ed8bae9af97" + integrity sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-unicode-sets-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz#6ab706d10f801b5c72da8bb2548561fa04193cd1" + integrity sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/preset-env@^7.20.2": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.28.5.tgz#82dd159d1563f219a1ce94324b3071eb89e280b0" + integrity sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg== + dependencies: + "@babel/compat-data" "^7.28.5" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-validator-option" "^7.27.1" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.28.5" + "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.27.1" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.27.1" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.27.1" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.28.3" "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-import-assertions" "^7.26.0" - "@babel/plugin-syntax-import-attributes" "^7.26.0" + "@babel/plugin-syntax-import-assertions" "^7.27.1" + "@babel/plugin-syntax-import-attributes" "^7.27.1" "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" - "@babel/plugin-transform-arrow-functions" "^7.25.9" - "@babel/plugin-transform-async-generator-functions" "^7.25.9" - "@babel/plugin-transform-async-to-generator" "^7.25.9" - "@babel/plugin-transform-block-scoped-functions" "^7.25.9" - "@babel/plugin-transform-block-scoping" "^7.25.9" - "@babel/plugin-transform-class-properties" "^7.25.9" - "@babel/plugin-transform-class-static-block" "^7.26.0" - "@babel/plugin-transform-classes" "^7.25.9" - "@babel/plugin-transform-computed-properties" "^7.25.9" - "@babel/plugin-transform-destructuring" "^7.25.9" - "@babel/plugin-transform-dotall-regex" "^7.25.9" - "@babel/plugin-transform-duplicate-keys" "^7.25.9" - "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.9" - "@babel/plugin-transform-dynamic-import" "^7.25.9" - "@babel/plugin-transform-exponentiation-operator" "^7.25.9" - "@babel/plugin-transform-export-namespace-from" "^7.25.9" - "@babel/plugin-transform-for-of" "^7.25.9" - "@babel/plugin-transform-function-name" "^7.25.9" - "@babel/plugin-transform-json-strings" "^7.25.9" - "@babel/plugin-transform-literals" "^7.25.9" - "@babel/plugin-transform-logical-assignment-operators" "^7.25.9" - "@babel/plugin-transform-member-expression-literals" "^7.25.9" - "@babel/plugin-transform-modules-amd" "^7.25.9" - "@babel/plugin-transform-modules-commonjs" "^7.25.9" - "@babel/plugin-transform-modules-systemjs" "^7.25.9" - "@babel/plugin-transform-modules-umd" "^7.25.9" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.25.9" - "@babel/plugin-transform-new-target" "^7.25.9" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.25.9" - "@babel/plugin-transform-numeric-separator" "^7.25.9" - "@babel/plugin-transform-object-rest-spread" "^7.25.9" - "@babel/plugin-transform-object-super" "^7.25.9" - "@babel/plugin-transform-optional-catch-binding" "^7.25.9" - "@babel/plugin-transform-optional-chaining" "^7.25.9" - "@babel/plugin-transform-parameters" "^7.25.9" - "@babel/plugin-transform-private-methods" "^7.25.9" - "@babel/plugin-transform-private-property-in-object" "^7.25.9" - "@babel/plugin-transform-property-literals" "^7.25.9" - "@babel/plugin-transform-regenerator" "^7.25.9" - "@babel/plugin-transform-regexp-modifiers" "^7.26.0" - "@babel/plugin-transform-reserved-words" "^7.25.9" - "@babel/plugin-transform-shorthand-properties" "^7.25.9" - "@babel/plugin-transform-spread" "^7.25.9" - "@babel/plugin-transform-sticky-regex" "^7.25.9" - "@babel/plugin-transform-template-literals" "^7.25.9" - "@babel/plugin-transform-typeof-symbol" "^7.25.9" - "@babel/plugin-transform-unicode-escapes" "^7.25.9" - "@babel/plugin-transform-unicode-property-regex" "^7.25.9" - "@babel/plugin-transform-unicode-regex" "^7.25.9" - "@babel/plugin-transform-unicode-sets-regex" "^7.25.9" + "@babel/plugin-transform-arrow-functions" "^7.27.1" + "@babel/plugin-transform-async-generator-functions" "^7.28.0" + "@babel/plugin-transform-async-to-generator" "^7.27.1" + "@babel/plugin-transform-block-scoped-functions" "^7.27.1" + "@babel/plugin-transform-block-scoping" "^7.28.5" + "@babel/plugin-transform-class-properties" "^7.27.1" + "@babel/plugin-transform-class-static-block" "^7.28.3" + "@babel/plugin-transform-classes" "^7.28.4" + "@babel/plugin-transform-computed-properties" "^7.27.1" + "@babel/plugin-transform-destructuring" "^7.28.5" + "@babel/plugin-transform-dotall-regex" "^7.27.1" + "@babel/plugin-transform-duplicate-keys" "^7.27.1" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.27.1" + "@babel/plugin-transform-dynamic-import" "^7.27.1" + "@babel/plugin-transform-explicit-resource-management" "^7.28.0" + "@babel/plugin-transform-exponentiation-operator" "^7.28.5" + "@babel/plugin-transform-export-namespace-from" "^7.27.1" + "@babel/plugin-transform-for-of" "^7.27.1" + "@babel/plugin-transform-function-name" "^7.27.1" + "@babel/plugin-transform-json-strings" "^7.27.1" + "@babel/plugin-transform-literals" "^7.27.1" + "@babel/plugin-transform-logical-assignment-operators" "^7.28.5" + "@babel/plugin-transform-member-expression-literals" "^7.27.1" + "@babel/plugin-transform-modules-amd" "^7.27.1" + "@babel/plugin-transform-modules-commonjs" "^7.27.1" + "@babel/plugin-transform-modules-systemjs" "^7.28.5" + "@babel/plugin-transform-modules-umd" "^7.27.1" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.27.1" + "@babel/plugin-transform-new-target" "^7.27.1" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.27.1" + "@babel/plugin-transform-numeric-separator" "^7.27.1" + "@babel/plugin-transform-object-rest-spread" "^7.28.4" + "@babel/plugin-transform-object-super" "^7.27.1" + "@babel/plugin-transform-optional-catch-binding" "^7.27.1" + "@babel/plugin-transform-optional-chaining" "^7.28.5" + "@babel/plugin-transform-parameters" "^7.27.7" + "@babel/plugin-transform-private-methods" "^7.27.1" + "@babel/plugin-transform-private-property-in-object" "^7.27.1" + "@babel/plugin-transform-property-literals" "^7.27.1" + "@babel/plugin-transform-regenerator" "^7.28.4" + "@babel/plugin-transform-regexp-modifiers" "^7.27.1" + "@babel/plugin-transform-reserved-words" "^7.27.1" + "@babel/plugin-transform-shorthand-properties" "^7.27.1" + "@babel/plugin-transform-spread" "^7.27.1" + "@babel/plugin-transform-sticky-regex" "^7.27.1" + "@babel/plugin-transform-template-literals" "^7.27.1" + "@babel/plugin-transform-typeof-symbol" "^7.27.1" + "@babel/plugin-transform-unicode-escapes" "^7.27.1" + "@babel/plugin-transform-unicode-property-regex" "^7.27.1" + "@babel/plugin-transform-unicode-regex" "^7.27.1" + "@babel/plugin-transform-unicode-sets-regex" "^7.27.1" "@babel/preset-modules" "0.1.6-no-external-plugins" - babel-plugin-polyfill-corejs2 "^0.4.10" - babel-plugin-polyfill-corejs3 "^0.10.6" - babel-plugin-polyfill-regenerator "^0.6.1" - core-js-compat "^3.38.1" + babel-plugin-polyfill-corejs2 "^0.4.14" + babel-plugin-polyfill-corejs3 "^0.13.0" + babel-plugin-polyfill-regenerator "^0.6.5" + core-js-compat "^3.43.0" semver "^6.3.1" "@babel/preset-modules@0.1.6-no-external-plugins": @@ -857,36 +950,41 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-react@^7.16.0": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.25.9.tgz#5f473035dc2094bcfdbc7392d0766bd42dce173e" - integrity sha512-D3to0uSPiWE7rBrdIICCd0tJSIGpLaaGptna2+w7Pft5xMqLpA1sz99DK5TZ1TjGbdQ/VI1eCSZ06dv3lT4JOw== - dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-validator-option" "^7.25.9" - "@babel/plugin-transform-react-display-name" "^7.25.9" - "@babel/plugin-transform-react-jsx" "^7.25.9" - "@babel/plugin-transform-react-jsx-development" "^7.25.9" - "@babel/plugin-transform-react-pure-annotations" "^7.25.9" - -"@babel/preset-typescript@^7.16.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz#4a570f1b8d104a242d923957ffa1eaff142a106d" - integrity sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg== - dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-validator-option" "^7.25.9" - "@babel/plugin-syntax-jsx" "^7.25.9" - "@babel/plugin-transform-modules-commonjs" "^7.25.9" - "@babel/plugin-transform-typescript" "^7.25.9" - -"@babel/runtime@^7.1.2", "@babel/runtime@^7.16.0", "@babel/runtime@^7.8.4": +"@babel/preset-react@^7.18.6": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.28.5.tgz#6fcc0400fa79698433d653092c3919bb4b0878d9" + integrity sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-validator-option" "^7.27.1" + "@babel/plugin-transform-react-display-name" "^7.28.0" + "@babel/plugin-transform-react-jsx" "^7.27.1" + "@babel/plugin-transform-react-jsx-development" "^7.27.1" + "@babel/plugin-transform-react-pure-annotations" "^7.27.1" + +"@babel/preset-typescript@^7.18.6": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz#540359efa3028236958466342967522fd8f2a60c" + integrity sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-validator-option" "^7.27.1" + "@babel/plugin-syntax-jsx" "^7.27.1" + "@babel/plugin-transform-modules-commonjs" "^7.27.1" + "@babel/plugin-transform-typescript" "^7.28.5" + +"@babel/runtime@^7.1.2": version "7.26.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1" integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw== dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.20.1": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326" + integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ== + "@babel/template@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.9.tgz#ecb62d81a8a6f5dc5fe8abfc3901fc52ddf15016" @@ -896,6 +994,15 @@ "@babel/parser" "^7.25.9" "@babel/types" "^7.25.9" +"@babel/template@^7.27.1", "@babel/template@^7.27.2": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d" + integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/parser" "^7.27.2" + "@babel/types" "^7.27.1" + "@babel/traverse@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84" @@ -909,6 +1016,19 @@ debug "^4.3.1" globals "^11.1.0" +"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4", "@babel/traverse@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.5.tgz#450cab9135d21a7a2ca9d2d35aa05c20e68c360b" + integrity sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.5" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.28.5" + "@babel/template" "^7.27.2" + "@babel/types" "^7.28.5" + debug "^4.3.1" + "@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.4.4": version "7.26.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.0.tgz#deabd08d6b753bc8e0f198f8709fb575e31774ff" @@ -917,6 +1037,14 @@ "@babel/helper-string-parser" "^7.25.9" "@babel/helper-validator-identifier" "^7.25.9" +"@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.5.tgz#10fc405f60897c35f07e85493c932c7b5ca0592b" + integrity sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" @@ -940,6 +1068,14 @@ gud "^1.0.0" warning "^4.0.3" +"@jridgewell/gen-mapping@^0.3.12": + version "0.3.13" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" + integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" @@ -949,6 +1085,14 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.24" +"@jridgewell/remapping@^2.3.5": + version "2.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1" + integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/resolve-uri@^3.1.0": version "3.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" @@ -972,6 +1116,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== +"@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" + integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== + "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" @@ -980,6 +1129,14 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@jridgewell/trace-mapping@^0.3.28": + version "0.3.31" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" + integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1043,7 +1200,7 @@ dependencies: "@types/sizzle" "*" -"@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8": +"@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -1233,12 +1390,26 @@ acorn@^8.0.4, acorn@^8.11.0, acorn@^8.7.1, acorn@^8.8.2: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.13.0.tgz#2a30d670818ad16ddd6a35d3842dacec9e5d7ca3" integrity sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w== +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.12.4, ajv@^6.12.5: +ajv-keywords@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1248,6 +1419,16 @@ ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.0.0, ajv@^8.9.0: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -1260,45 +1441,48 @@ ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -babel-loader@^8.2.3: - version "8.4.1" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.4.1.tgz#6ccb75c66e62c3b144e1c5f2eaec5b8f6c08c675" - integrity sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA== +babel-loader@^9.1.0: + version "9.2.1" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-9.2.1.tgz#04c7835db16c246dd19ba0914418f3937797587b" + integrity sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA== dependencies: - find-cache-dir "^3.3.1" - loader-utils "^2.0.4" - make-dir "^3.1.0" - schema-utils "^2.6.5" + find-cache-dir "^4.0.0" + schema-utils "^4.0.0" -babel-plugin-polyfill-corejs2@^0.4.10: - version "0.4.11" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz#30320dfe3ffe1a336c15afdcdafd6fd615b25e33" - integrity sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q== +babel-plugin-polyfill-corejs2@^0.4.14: + version "0.4.14" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz#8101b82b769c568835611542488d463395c2ef8f" + integrity sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg== dependencies: - "@babel/compat-data" "^7.22.6" - "@babel/helper-define-polyfill-provider" "^0.6.2" + "@babel/compat-data" "^7.27.7" + "@babel/helper-define-polyfill-provider" "^0.6.5" semver "^6.3.1" -babel-plugin-polyfill-corejs3@^0.10.6: - version "0.10.6" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz#2deda57caef50f59c525aeb4964d3b2f867710c7" - integrity sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA== +babel-plugin-polyfill-corejs3@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz#bb7f6aeef7addff17f7602a08a6d19a128c30164" + integrity sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A== dependencies: - "@babel/helper-define-polyfill-provider" "^0.6.2" - core-js-compat "^3.38.0" + "@babel/helper-define-polyfill-provider" "^0.6.5" + core-js-compat "^3.43.0" -babel-plugin-polyfill-regenerator@^0.6.1: - version "0.6.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz#addc47e240edd1da1058ebda03021f382bba785e" - integrity sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg== +babel-plugin-polyfill-regenerator@^0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz#32752e38ab6f6767b92650347bf26a31b16ae8c5" + integrity sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg== dependencies: - "@babel/helper-define-polyfill-provider" "^0.6.2" + "@babel/helper-define-polyfill-provider" "^0.6.5" balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +baseline-browser-mapping@^2.9.0: + version "2.9.7" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz#d36ce64f2a2c468f6f743c8db495d319120007db" + integrity sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg== + big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -1326,7 +1510,7 @@ braces@^3.0.3: dependencies: fill-range "^7.1.1" -browserslist@^4.21.10, browserslist@^4.23.3, browserslist@^4.24.0: +browserslist@^4.21.10, browserslist@^4.24.0: version "4.24.2" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580" integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg== @@ -1336,6 +1520,17 @@ browserslist@^4.21.10, browserslist@^4.23.3, browserslist@^4.24.0: node-releases "^2.0.18" update-browserslist-db "^1.1.1" +browserslist@^4.28.0: + version "4.28.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" + integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== + dependencies: + baseline-browser-mapping "^2.9.0" + caniuse-lite "^1.0.30001759" + electron-to-chromium "^1.5.263" + node-releases "^2.0.27" + update-browserslist-db "^1.2.0" + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -1357,6 +1552,11 @@ caniuse-lite@^1.0.30001669: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001672.tgz#02ac296ad4765c6c4f93031525f60cf8bdf4a44f" integrity sha512-XhW1vRo1ob6aeK2w3rTohwTPBLse/rvjq+s3RTSBwnlZqoFFjx9cHsShJjAIbLsLjyoacaTxpLZy9v3gg6zypw== +caniuse-lite@^1.0.30001759: + version "1.0.30001760" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz#bdd1960fafedf8d5f04ff16e81460506ff9b798f" + integrity sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw== + chalk@^4.0.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -1430,10 +1630,10 @@ commander@^7.2.0: resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== +common-path-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" + integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== concat-map@0.0.1: version "0.0.1" @@ -1445,12 +1645,12 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -core-js-compat@^3.38.0, core-js-compat@^3.38.1: - version "3.38.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.38.1.tgz#2bc7a298746ca5a7bcb9c164bcb120f2ebc09a09" - integrity sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw== +core-js-compat@^3.43.0: + version "3.47.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.47.0.tgz#698224bbdbb6f2e3f39decdda4147b161e3772a3" + integrity sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ== dependencies: - browserslist "^4.23.3" + browserslist "^4.28.0" cross-spawn@^7.0.3: version "7.0.6" @@ -1471,13 +1671,20 @@ debounce@^1.2.1: resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== -debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: +debug@^4.1.0, debug@^4.3.1: version "4.3.7" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== dependencies: ms "^2.1.3" +debug@^4.4.1: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + deep-equal@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.2.tgz#78a561b7830eef3134c7f6f3a3d6af272a678761" @@ -1513,6 +1720,11 @@ duplexer@^0.1.2: resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== +electron-to-chromium@^1.5.263: + version "1.5.267" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz#5d84f2df8cdb6bfe7e873706bb21bd4bfb574dc7" + integrity sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw== + electron-to-chromium@^1.5.41: version "1.5.47" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.47.tgz#ef0751bc19b28be8ee44cd8405309de3bf3b20c7" @@ -1608,7 +1820,7 @@ exenv@^1.2.2: resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d" integrity sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw== -fast-deep-equal@^3.1.1: +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== @@ -1629,6 +1841,11 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== +fast-uri@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa" + integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA== + fastest-levenshtein@^1.0.12: version "1.0.16" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" @@ -1648,14 +1865,13 @@ fill-range@^7.1.1: dependencies: to-regex-range "^5.0.1" -find-cache-dir@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== +find-cache-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-4.0.0.tgz#a30ee0448f81a3990708f6453633c733e2f6eec2" + integrity sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg== dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" + common-path-prefix "^3.0.0" + pkg-dir "^7.0.0" find-up@^4.0.0: version "4.1.0" @@ -1665,35 +1881,45 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" -flarum-tsconfig@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/flarum-tsconfig/-/flarum-tsconfig-1.0.3.tgz#70420511f833f65f2d83a4541677f9cefbac664e" - integrity sha512-//zFt0zFlPBukJvH0gRI4SQH1hLsUHYxZD+xVbuFdBaiJxmYxVMFWhmDrpA6kRT5miokZ8veuN28mwq1SzeGKw== +find-up@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790" + integrity sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw== + dependencies: + locate-path "^7.1.0" + path-exists "^5.0.0" + +flarum-tsconfig@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/flarum-tsconfig/-/flarum-tsconfig-2.0.0.tgz#72cd1f8cb5e5c8f58acad599a2c05f3e00df928b" + integrity sha512-YEyYu9uZCc7WIXw4Q+W60aC2RVSw7/K0tlaVfQrJbovw6Uu0dIV5AdRRtpJFGjVhzv+OmMfbQeG5aI+xxf/gvQ== dependencies: "@types/jquery" "^3.5.5" "@types/mithril" "^2.0.7" "@types/throttle-debounce" "^2.1.0" dayjs "^1.10.4" -flarum-webpack-config@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flarum-webpack-config/-/flarum-webpack-config-2.0.2.tgz#efa67268904390a1e7aee55e1ac5a794a57e0855" - integrity sha512-kUCaCsXL8s/OhSWleWtIppRXDNBzAf8/ewCx9OIF0zNO0hlvY5T1N0EO0AnyUJbsp5nOCdzsTo9rTRRsbKT+IA== - dependencies: - "@babel/core" "^7.16.0" - "@babel/plugin-proposal-class-properties" "^7.16.0" - "@babel/plugin-proposal-private-methods" "^7.16.0" - "@babel/plugin-transform-object-assign" "^7.16.0" - "@babel/plugin-transform-react-jsx" "^7.16.0" - "@babel/plugin-transform-runtime" "^7.16.0" - "@babel/preset-env" "^7.16.0" - "@babel/preset-react" "^7.16.0" - "@babel/preset-typescript" "^7.16.0" - "@babel/runtime" "^7.16.0" - babel-loader "^8.2.3" - typescript "^4.4.4" +flarum-webpack-config@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/flarum-webpack-config/-/flarum-webpack-config-3.0.2.tgz#5ed106b2ac619707c109631831858743a542f37f" + integrity sha512-33BZNdqtaFWiGQOOJCMh507Xw3V13Ok5Ozg9iRDns6fmkfnqJW1M4A1WIhxA9HdC7/xp7PM+055giacqJkK0qA== + dependencies: + "@babel/core" "^7.20.2" + "@babel/plugin-proposal-class-properties" "^7.18.6" + "@babel/plugin-proposal-private-methods" "^7.18.6" + "@babel/plugin-transform-object-assign" "^7.18.6" + "@babel/plugin-transform-react-jsx" "^7.19.0" + "@babel/plugin-transform-runtime" "^7.19.6" + "@babel/preset-env" "^7.20.2" + "@babel/preset-react" "^7.18.6" + "@babel/preset-typescript" "^7.18.6" + "@babel/runtime" "^7.20.1" + babel-loader "^9.1.0" + loader-utils "^1.4.0" + schema-utils "^3.0.0" + typescript "^4.9.3" webpack "^5.76.0" - webpack-bundle-analyzer "^4.5.0" + webpack-bundle-analyzer "^4.7.0" flat@^5.0.2: version "5.0.2" @@ -1866,6 +2092,13 @@ is-core-module@^2.13.0: dependencies: hasown "^2.0.2" +is-core-module@^2.16.1: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" + integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== + dependencies: + hasown "^2.0.2" + is-date-object@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" @@ -1939,6 +2172,11 @@ jsesc@^3.0.2, jsesc@~3.0.2: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== +jsesc@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== + json-parse-even-better-errors@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -1949,7 +2187,19 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json5@^2.1.2, json5@^2.2.3: +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json5@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + +json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -1969,14 +2219,14 @@ loader-runner@^4.2.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== -loader-utils@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" - integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== +loader-utils@^1.4.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3" + integrity sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg== dependencies: big.js "^5.2.2" emojis-list "^3.0.0" - json5 "^2.1.2" + json5 "^1.0.1" locate-path@^5.0.0: version "5.0.0" @@ -1985,6 +2235,13 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a" + integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA== + dependencies: + p-locate "^6.0.0" + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -2009,13 +2266,6 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -make-dir@^3.0.2, make-dir@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -2060,6 +2310,11 @@ minimatch@^3.1.1: dependencies: brace-expansion "^1.1.7" +minimist@^1.2.0: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + mrmime@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-2.0.0.tgz#151082a6e06e59a9a39b46b3e14d5cfe92b3abb4" @@ -2085,6 +2340,11 @@ node-releases@^2.0.18: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== +node-releases@^2.0.27: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== + normalize-path@3: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -2127,6 +2387,13 @@ p-limit@^2.2.0: dependencies: p-try "^2.0.0" +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + p-locate@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" @@ -2134,6 +2401,13 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f" + integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw== + dependencies: + p-limit "^4.0.0" + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -2144,6 +2418,11 @@ path-exists@^4.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== +path-exists@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7" + integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -2159,7 +2438,7 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -picocolors@^1.0.0, picocolors@^1.1.0: +picocolors@^1.0.0, picocolors@^1.1.0, picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== @@ -2169,13 +2448,20 @@ picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pkg-dir@^4.1.0, pkg-dir@^4.2.0: +pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" +pkg-dir@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-7.0.0.tgz#8f0c08d6df4476756c5ff29b3282d0bab7517d11" + integrity sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA== + dependencies: + find-up "^6.3.0" + popper.js@^1.14.4: version "1.16.1" resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" @@ -2263,6 +2549,13 @@ regenerate-unicode-properties@^10.2.0: dependencies: regenerate "^1.4.2" +regenerate-unicode-properties@^10.2.2: + version "10.2.2" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz#aa113812ba899b630658c7623466be71e1f86f66" + integrity sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g== + dependencies: + regenerate "^1.4.2" + regenerate@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" @@ -2273,13 +2566,6 @@ regenerator-runtime@^0.14.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== -regenerator-transform@^0.15.2: - version "0.15.2" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" - integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== - dependencies: - "@babel/runtime" "^7.8.4" - regexp.prototype.flags@^1.5.1: version "1.5.3" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz#b3ae40b1d2499b8350ab2c3fe6ef3845d3a96f42" @@ -2302,6 +2588,18 @@ regexpu-core@^6.1.1: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.1.0" +regexpu-core@^6.3.1: + version "6.4.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.4.0.tgz#3580ce0c4faedef599eccb146612436b62a176e5" + integrity sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.2.2" + regjsgen "^0.8.0" + regjsparser "^0.13.0" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.2.1" + regjsgen@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.8.0.tgz#df23ff26e0c5b300a6470cad160a9d090c3a37ab" @@ -2314,6 +2612,18 @@ regjsparser@^0.11.0: dependencies: jsesc "~3.0.2" +regjsparser@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.13.0.tgz#01f8351335cf7898d43686bc74d2dd71c847ecc0" + integrity sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q== + dependencies: + jsesc "~3.1.0" + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" @@ -2326,7 +2636,7 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve@^1.14.2, resolve@^1.20.0: +resolve@^1.20.0: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -2335,6 +2645,15 @@ resolve@^1.14.2, resolve@^1.20.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^1.22.10: + version "1.22.11" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262" + integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== + dependencies: + is-core-module "^2.16.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -2367,16 +2686,7 @@ scheduler@^0.19.1: loose-envify "^1.1.0" object-assign "^4.1.1" -schema-utils@^2.6.5: - version "2.7.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" - integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== - dependencies: - "@types/json-schema" "^7.0.5" - ajv "^6.12.4" - ajv-keywords "^3.5.2" - -schema-utils@^3.1.1, schema-utils@^3.2.0: +schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== @@ -2385,6 +2695,16 @@ schema-utils@^3.1.1, schema-utils@^3.2.0: ajv "^6.12.5" ajv-keywords "^3.5.2" +schema-utils@^4.0.0: + version "4.3.3" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" + integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.9.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.1.0" + semantic-ui-react@^0.88.2: version "0.88.2" resolved "https://registry.yarnpkg.com/semantic-ui-react/-/semantic-ui-react-0.88.2.tgz#3d4b54f8b799769b412435c8531475fd34aa4149" @@ -2402,7 +2722,7 @@ semantic-ui-react@^0.88.2: react-popper "^1.3.4" shallowequal "^1.1.0" -semver@^6.0.0, semver@^6.3.1: +semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== @@ -2603,7 +2923,7 @@ typescript-coverage-report@^0.6.1: semantic-ui-react "^0.88.2" type-coverage-core "^2.17.2" -typescript@^4.4.4: +typescript@^4.9.3: version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== @@ -2631,6 +2951,11 @@ unicode-match-property-value-ecmascript@^2.1.0: resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz#a0401aee72714598f739b68b104e4fe3a0cb3c71" integrity sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg== +unicode-match-property-value-ecmascript@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz#65a7adfad8574c219890e219285ce4c64ed67eaa" + integrity sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg== + unicode-property-aliases-ecmascript@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" @@ -2644,6 +2969,14 @@ update-browserslist-db@^1.1.1: escalade "^3.2.0" picocolors "^1.1.0" +update-browserslist-db@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz#cfb4358afa08b3d5731a2ecd95eebf4ddef8033e" + integrity sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.1" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -2666,7 +2999,7 @@ watchpack@^2.4.1: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" -webpack-bundle-analyzer@^4.5.0: +webpack-bundle-analyzer@^4.7.0: version "4.10.2" resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz#633af2862c213730be3dbdf40456db171b60d5bd" integrity sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw== @@ -2772,3 +3105,8 @@ yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yocto-queue@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.2.2.tgz#3e09c95d3f1aa89a58c114c99223edf639152c00" + integrity sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ== diff --git a/migrations/2019_07_09_000001_add_attributes_to_users.php b/migrations/2019_07_09_000001_add_attributes_to_users.php index 59f2c58c..4e26d0f0 100755 --- a/migrations/2019_07_09_000001_add_attributes_to_users.php +++ b/migrations/2019_07_09_000001_add_attributes_to_users.php @@ -19,7 +19,7 @@ } $schema->table('users', function (Blueprint $table) { - $table->integer('votes'); + $table->integer('votes')->default(0); $table->string('rank')->nullable(); $table->dateTime('last_vote_time')->nullable(); }); diff --git a/migrations/2022_10_11_000001_remove_duplicate_votes_and_apply_unique_index.php b/migrations/2022_10_11_000001_remove_duplicate_votes_and_apply_unique_index.php index 869a779a..5ddcd171 100644 --- a/migrations/2022_10_11_000001_remove_duplicate_votes_and_apply_unique_index.php +++ b/migrations/2022_10_11_000001_remove_duplicate_votes_and_apply_unique_index.php @@ -15,27 +15,28 @@ return [ 'up' => function (Builder $schema) { // Find duplicate votes based on `user_id` and `post_id` columns and delete them. - $schema->getConnection() + $duplicates = $schema->getConnection() ->table('post_votes') + ->select('user_id', 'post_id') ->groupBy('user_id', 'post_id') ->havingRaw('COUNT(*) > 1') - ->orderBy('id', 'desc') - ->each(function ($row) use ($schema) { - $keep = $schema->getConnection() - ->table('post_votes') - ->where('user_id', $row->user_id) - ->where('post_id', $row->post_id) - ->orderBy('id', 'asc') - ->first(); + ->get(); - $schema->getConnection() - ->table('post_votes') - ->where('user_id', $row->user_id) - ->where('post_id', $row->post_id) - ->where('id', '!=', $keep->id) - ->orderBy('id', 'desc') - ->delete(); - }); + foreach ($duplicates as $row) { + $keep = $schema->getConnection() + ->table('post_votes') + ->where('user_id', $row->user_id) + ->where('post_id', $row->post_id) + ->orderBy('id', 'asc') + ->first(); + + $schema->getConnection() + ->table('post_votes') + ->where('user_id', $row->user_id) + ->where('post_id', $row->post_id) + ->where('id', '!=', $keep->id) + ->delete(); + } $schema->table('post_votes', function (Blueprint $table) { $table->unique(['post_id', 'user_id']); diff --git a/phpstan.neon b/phpstan.neon index 03cf2619..36a5508d 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,12 +2,11 @@ includes: - vendor/flarum/phpstan/extension.neon parameters: - # The level will be increased in Flarum 2.0 - level: 5 + level: 6 paths: - extend.php + - vendor/flarum/likes/extend.php - src excludePaths: - *.blade.php - checkMissingIterableValueType: false databaseMigrationsPath: ['migrations'] diff --git a/resources/less/admin/extension.less b/resources/less/admin/extension.less index cb55190e..3d744e4e 100755 --- a/resources/less/admin/extension.less +++ b/resources/less/admin/extension.less @@ -3,17 +3,7 @@ .SettingsPage { padding: 20px 0; - - legend { - margin-top: 25px; - } - @media @desktop-up { - .container { - max-width: 600px; - margin: 0; - } - fieldset { margin-bottom: 30px; @@ -30,42 +20,16 @@ margin-top: 5px; margin-bottom: 5px } - + .Upload-label { margin-right: 15px; } - + .Upload-button { margin-top: 7.5px; margin-bottom: 7.5px; } - .helpText { - margin-bottom: 20px; - } - - .SettingsPage-ranks { - margin-top: 20px; - } - - .Ranks-number { - width: 15%; - float: left; - margin: 5px 5px 5px; - } - .Ranks-name { - width: 30%; - float: left; - margin: 5px 5px 5px; - } - .Ranks-color { - width: 18%; - float: left; - margin: 5px 5px 5px; - } - .Ranks-button { - margin: 5px 0 5px; - } .Ranks-default { width: 30%; margin-top: 5px; @@ -74,8 +38,56 @@ .Ranks-save { margin-top: 15px; } - .votes-switch { - margin-top: 20px; - margin-bottom: 20px; + + .Ranks--Container-row { + display: flex; + gap: 4px; + width: auto; + } + + .Ranks--Container-row > * { + flex-shrink: 1; + flex-grow: 0; + } + + .Ranks--Container-row > button { + flex-grow: 1; + flex-shrink: 0; + } + + .Ranks--Container { + display: flex; + flex-direction: column; + gap: 6px; + } + + .IconPreview { + display: flex; + gap: 16px; + margin-top: 10px; + padding: 12px; + background: rgba(0, 0, 0, 0.05); + border-radius: 6px; + align-items: center; + + > span { + display: flex; + align-items: center; + gap: 8px; + + > span { + opacity: 0.7; + } + } + + i { + font-size: 24px; + color: var(--primary-color); + transition: all 0.2s ease; + } + + i:hover { + transform: scale(1.2); + } } } diff --git a/resources/less/forum/VotesBox.less b/resources/less/forum/VotesBox.less index 8973a73b..0abcbdd7 100644 --- a/resources/less/forum/VotesBox.less +++ b/resources/less/forum/VotesBox.less @@ -1,7 +1,7 @@ .VotingContainer { padding: 12px; - background: @control-bg; - border-radius: @border-radius; + background: var(--control-bg); + border-radius: var(--border-radius); @media @phone { padding: 8px; @@ -27,7 +27,7 @@ &-title { margin-bottom: 8px; - color: @control-color; + color: var(--control-color); white-space: nowrap; @media @phone { @@ -60,7 +60,7 @@ } &-message { - color: @control-color; + color: var(--control-color); @media @phone { display: none; @@ -98,8 +98,8 @@ } &--plus .Avatar { - background-color: @body-bg; - color: @control-color; + background-color: var(--body-bg); + color: var(--control-color); font-size: 13px; } } diff --git a/resources/less/forum/alternateLayout.less b/resources/less/forum/alternateLayout.less index 1682352a..efadee99 100644 --- a/resources/less/forum/alternateLayout.less +++ b/resources/less/forum/alternateLayout.less @@ -1,41 +1,23 @@ -:root { - & when (@config-dark-mode = false) { - --vote-box-hover-color: #f4f6f8; - } +[data-theme^=light] { + --vote-box-hover-color: #f4f6f8; +} - & when (@config-dark-mode = true) { - --vote-box-hover-color: lighten(@body-bg, 3%); - } +[data-theme^=dark] { + --vote-box-hover-color: lighten(@body-bg-dark, 3%); } .CommentPost.votesAlternativeLayout { min-height: 165px; - - .Post-header { - margin-right: 36px; - } } .CommentPost.votesAlternativeLayout.votesUpvotesOnly { min-height: 150px; } -.DiscussionListItem-votes.alternateLayout { - + .DiscussionListItem-author { - margin-left: -2px; - margin-right: 12px; - } - - + .DiscussionListItem-main { - @media @phone { - padding-right: 28px; - } - } -} .DiscussionListItem-votes.alternateLayout, .Post-votes { - position: absolute; + position: relative; cursor: pointer; height: 42px; @@ -43,15 +25,16 @@ left: 0; - background: @body-bg; + background: var(--body-bg); border-radius: 4px; - border: 1px solid fade(@primary-color, 80%); + border: 1px solid color-mix(in srgb, var(--primary-color) 80%, transparent); + color: var(--muted-color); line-height: 24px; .LoadingIndicator-container { - color: @control-color; + color: var(--control-color); position: absolute; top: 50%; @@ -66,7 +49,7 @@ width: 100%; &[data-active] { - color: @primary-color !important; + color: var(--primary-color) !important; } &:hover, @@ -120,42 +103,31 @@ } } -@screen-tablet-under: @screen-tablet - 0.01px; +@screen-tablet-under: calc(@screen-tablet - 0.01px); .DiscussionListItem-votes.alternateLayout { - top: 4px; - - @media (max-width: @screen-tablet-under) { - left: 8px; - } + margin: -8px 0; } .Post-votes { - top: 12px; + margin-top: 12px; @media (max-width: @screen-tablet-under) { - position: relative; - display: inline-block; - vertical-align: middle; - top: 0; - left: 0; + margin-top: -8px; + float: right; } } -.Post-header .item-votes { +.Post-votes { @media @tablet-up { - position: absolute; - left: 34px !important; - top: 84px !important; - margin-right: 0; + margin-left: 12px; } @screen-tablet-under: @screen-tablet - 0.01px; @media (max-width: @screen-tablet-under) { - position: absolute; - right: 4px; - top: 8px; + margin-right: 4px; + margin-top: 8px; } } diff --git a/resources/less/forum/extension.less b/resources/less/forum/extension.less index 3f70bef9..9682bdf4 100755 --- a/resources/less/forum/extension.less +++ b/resources/less/forum/extension.less @@ -24,7 +24,7 @@ ); font-size: 14px; line-height: 1; - color: @muted-color; + color: var(--muted-color); .icon { margin-right: 8px; @@ -47,7 +47,7 @@ margin: 0; a { - color: @text-color; + color: var(--text-color); font-size: 15px; font-weight: bold; display: block; @@ -83,11 +83,11 @@ background-color: transparent; border: none; margin: 8px 0 0; - color: @text-color; + color: var(--text-color); cursor: pointer; &--active { - color: @primary-color; + color: var(--primary-color); } &.loading { diff --git a/resources/less/lib/rankLabel.less b/resources/less/lib/rankLabel.less index c1411107..2cd340b9 100755 --- a/resources/less/lib/rankLabel.less +++ b/resources/less/lib/rankLabel.less @@ -3,14 +3,14 @@ font-weight: 600; display: inline-block; padding: 0.2em 1.0em; - border-radius: @border-radius; - background: @control-bg; - color: @control-color; + border-radius: var(--border-radius); + background: var(--control-bg); + color: var(--control-color); text-transform: none; &.colored { .rankLabel-text { - color: @body-bg !important; + color: var(--body-bg) !important; } } } @@ -21,15 +21,15 @@ border-radius: 0; &:first-child { - border-radius: @border-radius 0 0 @border-radius; + border-radius: var(--border-radius) 0 0 var(--border-radius); } &:last-child { - border-radius: 0 @border-radius @border-radius 0; + border-radius: var(--border-radius) var(--border-radius) 0; } &:first-child:last-child { - border-radius: @border-radius; + border-radius: var(--border-radius); } } } diff --git a/resources/locale/en.yml b/resources/locale/en.yml index 48f86f5e..e1912c2b 100755 --- a/resources/locale/en.yml +++ b/resources/locale/en.yml @@ -71,13 +71,15 @@ fof-gamification: vote_color: Voted color icon_name: Upvote/downvote icon icon_help: "Input any Font-Awesome icon that is suffixed with -up and -down. Examples: arrow, thumbs, chevron" + icon_preview_upvote: Upvote + icon_preview_downvote: Downvote upvotes_only: Only allow upvoting first_post_only: Only allow up/down votes in the first post in a discussion allow_self_votes: Users may vote on their own posts save_settings: Save settings convert: button: Convert likes to upvotes - help: Convert your previous likes from flarum-ext-likes into upvotes, as well as calculate the hotness for all current discussions. + help: Convert your previous likes from flarum/likes into upvotes, as well as calculate the hotness for all current discussions. converting: Your likes are now being converted. Refresh your site after a few minutes to see the process finished. (Conversion time might take a while depending on your total forum likes) converted: "Successfully converted all {number} likes" ranks: @@ -113,3 +115,8 @@ fof-gamification: View it here: {discussion_url} subject: postVoted: Your post was voted on by {display_name} + +lib: + gambits: + hot: + key: hot diff --git a/resources/views/emails/html/postVoted.blade.php b/resources/views/emails/html/postVoted.blade.php new file mode 100644 index 00000000..a042e4e9 --- /dev/null +++ b/resources/views/emails/html/postVoted.blade.php @@ -0,0 +1,12 @@ + + + {!! $translator->trans('fof-gamification.email.body.postVoted', [ + '{recipient_display_name}' => $user->display_name, + '{actor_display_name}' => $blueprint->vote->user->display_name, + '{discussion_title}' => $blueprint->vote->post->discussion->title, + '{discussion_url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->vote->post->discussion->id, 'near' => $blueprint->vote->post->number]), +]) !!} + + + + diff --git a/resources/views/emails/postVoted.blade.php b/resources/views/emails/plain/postVoted.blade.php similarity index 82% rename from resources/views/emails/postVoted.blade.php rename to resources/views/emails/plain/postVoted.blade.php index 0ccdf502..61de9863 100644 --- a/resources/views/emails/postVoted.blade.php +++ b/resources/views/emails/plain/postVoted.blade.php @@ -1,6 +1,10 @@ + + {!! $translator->trans('fof-gamification.email.body.postVoted', [ '{recipient_display_name}' => $user->display_name, '{actor_display_name}' => $blueprint->vote->user->display_name, '{discussion_title}' => $blueprint->vote->post->discussion->title, '{discussion_url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->vote->post->discussion->id, 'near' => $blueprint->vote->post->number]), ]) !!} + + diff --git a/src/Access/PostPolicy.php b/src/Access/PostPolicy.php index e58f0462..ef4f941c 100644 --- a/src/Access/PostPolicy.php +++ b/src/Access/PostPolicy.php @@ -18,14 +18,9 @@ class PostPolicy extends AbstractPolicy { - /** - * @var SettingsRepositoryInterface - */ - protected $settings; - - public function __construct(SettingsRepositoryInterface $settings) - { - $this->settings = $settings; + public function __construct( + protected SettingsRepositoryInterface $settings + ) { } private function isFirstPostOnlyMode(): bool @@ -38,7 +33,7 @@ private function voteForSelfEnabled(): bool return $this->settings->get('fof-gamification.allowSelfVotes'); } - public function vote(User $actor, Post $post) + public function vote(User $actor, Post $post): string|bool|null { if ($post->number !== 1 && $this->isFirstPostOnlyMode()) { return $this->deny(); @@ -51,7 +46,7 @@ public function vote(User $actor, Post $post) return $actor->can('votePosts', $post->discussion); } - public function canSeeVotes(User $actor, Post $post) + public function canSeeVotes(User $actor, Post $post): string|bool|null { if ($post->number !== 1 && $this->isFirstPostOnlyMode()) { return $this->deny(); @@ -60,7 +55,7 @@ public function canSeeVotes(User $actor, Post $post) return $actor->can('canSeeVotes', $post->discussion); } - public function canSeeVoters(User $actor, Post $post) + public function canSeeVoters(User $actor, Post $post): string|bool|null { if ($post->number !== 1 && $this->isFirstPostOnlyMode()) { return $this->deny(); diff --git a/src/AddDiscussionData.php b/src/AddDiscussionData.php deleted file mode 100644 index 313cf1f7..00000000 --- a/src/AddDiscussionData.php +++ /dev/null @@ -1,41 +0,0 @@ -firstPost ?: $discussion->posts()->where('number', 1)->first(); - $actor = $serializer->getActor(); - - if (!$actor->isGuest() && $actor->exists && $post) { - /** @phpstan-ignore-next-line */ - $vote = $post->actualvotes->first(); - - $attributes['hasUpvoted'] = $vote && $vote->isUpvote(); - $attributes['hasDownvoted'] = $vote && $vote->isDownvote(); - } - - if ($seeVotes = $actor->can('canSeeVotes', $discussion)) { - $attributes['votes'] = (int) $discussion->votes; - } - - $attributes['seeVotes'] = $seeVotes; - $attributes['canVote'] = $post && $actor->can('votePosts', $discussion) && $actor->can('vote', $post); - - return $attributes; - } -} diff --git a/src/AddPostData.php b/src/AddPostData.php deleted file mode 100644 index c2b4160b..00000000 --- a/src/AddPostData.php +++ /dev/null @@ -1,59 +0,0 @@ -settings = $settings; - } - - public function __invoke(PostSerializer $serializer, Post $post, array $attributes): array - { - $actor = $serializer->getActor(); - - $canSeeVotes = (bool) $actor->can('canSeeVotes', $post->discussion) && (bool) $actor->can('canSeeVotes', $post); - - if ($canSeeVotes) { - if ($actor->exists) { - /** @phpstan-ignore-next-line */ - $vote = $post->actualvotes->first(); - - $attributes['hasUpvoted'] = $vote && $vote->isUpvote(); - $attributes['hasDownvoted'] = $vote && $vote->isDownvote(); - } else { - $attributes['hasUpvoted'] = null; - $attributes['hasDownvoted'] = null; - } - $attributes['canSeeVotes'] = $canSeeVotes; - /** @phpstan-ignore-next-line */ - $attributes['votes'] = $post->actualvotes_sum_value; - } else { - $attributes['votes'] = null; - } - - $attributes['canVote'] = (bool) $actor->can('vote', $post); - $attributes['seeVoters'] = (bool) $actor->can('canSeeVoters', $post->discussion) && (bool) $actor->can('canSeeVoters', $post); - - return $attributes; - } -} diff --git a/src/AddUserAttributes.php b/src/AddUserAttributes.php deleted file mode 100644 index 661f514e..00000000 --- a/src/AddUserAttributes.php +++ /dev/null @@ -1,26 +0,0 @@ -votes; - $attributes['canHaveVotingNotifications'] = $user->hasPermission('discussion.upvote_notifications') || $user->hasPermission('discussion.downvote_notifications'); - - return $attributes; - } -} diff --git a/src/Api/AddForumAttributes.php b/src/Api/AddForumAttributes.php deleted file mode 100644 index 99a9fd96..00000000 --- a/src/Api/AddForumAttributes.php +++ /dev/null @@ -1,59 +0,0 @@ -settings = $settings; - $this->uploadDir = $factory->disk('flarum-assets'); - } - - public function __invoke(ForumSerializer $serializer, $model, array $attributes): array - { - $attributes['canViewRankingPage'] = $serializer->getActor()->can('fof.gamification.viewRankingPage'); - $attributes['fof-gamification-op-votes-only'] = (bool) $this->settings->get('fof-gamification.firstPostOnly'); - - $attributes['fof-gamification.topimage1Url'] = $this->urlForKey('fof-gamification.topimage1_path'); - $attributes['fof-gamification.topimage2Url'] = $this->urlForKey('fof-gamification.topimage2_path'); - $attributes['fof-gamification.topimage3Url'] = $this->urlForKey('fof-gamification.topimage3_path'); - - return $attributes; - } - - protected function urlForKey(string $key): ?string - { - $value = $this->settings->get($key); - - if ($value === null) { - return null; - } - - return $this->uploadDir->url($value); - } -} diff --git a/src/Api/Controllers/ConvertLikesController.php b/src/Api/Controllers/ConvertLikesController.php index 4d88cea7..5cd6e411 100755 --- a/src/Api/Controllers/ConvertLikesController.php +++ b/src/Api/Controllers/ConvertLikesController.php @@ -15,6 +15,7 @@ use Flarum\Settings\SettingsRepositoryInterface; use FoF\Gamification\Gamification; use FoF\Gamification\Jobs; +use Illuminate\Contracts\Queue\Queue; use Laminas\Diactoros\Response\EmptyResponse; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -22,20 +23,11 @@ class ConvertLikesController implements RequestHandlerInterface { - /** - * @var SettingsRepositoryInterface - */ - protected $settings; - - /** - * @var Gamification - */ - protected $gamification; - - public function __construct(SettingsRepositoryInterface $settings, Gamification $gamification) - { - $this->settings = $settings; - $this->gamification = $gamification; + public function __construct( + protected SettingsRepositoryInterface $settings, + protected Gamification $gamification, + protected Queue $queue + ) { } public function handle(ServerRequestInterface $request): ResponseInterface @@ -43,7 +35,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface RequestUtil::getActor($request)->assertAdmin(); if ('POST' === $request->getMethod() && false == $this->settings->get('fof-gamification.convertedLikes')) { - resolve('flarum.queue.connection')->push( + $this->queue->push( new Jobs\ConvertLikesToUpvotes() ); } diff --git a/src/Api/Controllers/CreateRankController.php b/src/Api/Controllers/CreateRankController.php deleted file mode 100755 index f588d67b..00000000 --- a/src/Api/Controllers/CreateRankController.php +++ /dev/null @@ -1,43 +0,0 @@ -bus = $bus; - } - - protected function data(ServerRequestInterface $request, Document $document) - { - return $this->bus->dispatch( - new CreateRank(RequestUtil::getActor($request), Arr::get($request->getParsedBody(), 'data', [])) - ); - } -} diff --git a/src/Api/Controllers/DeleteRankController.php b/src/Api/Controllers/DeleteRankController.php deleted file mode 100755 index 266a5d8c..00000000 --- a/src/Api/Controllers/DeleteRankController.php +++ /dev/null @@ -1,39 +0,0 @@ -bus = $bus; - } - - protected function delete(ServerRequestInterface $request) - { - $this->bus->dispatch( - new DeleteRank(Arr::get($request->getQueryParams(), 'id'), RequestUtil::getActor($request)) - ); - } -} diff --git a/src/Api/Controllers/DeleteTopImageController.php b/src/Api/Controllers/DeleteTopImageController.php index 41e35cb0..65b0441f 100755 --- a/src/Api/Controllers/DeleteTopImageController.php +++ b/src/Api/Controllers/DeleteTopImageController.php @@ -17,28 +17,23 @@ use Illuminate\Contracts\Filesystem\Cloud; use Illuminate\Contracts\Filesystem\Factory; use Illuminate\Support\Arr; -use Laminas\Diactoros\Response\EmptyResponse; use Psr\Http\Message\ServerRequestInterface; class DeleteTopImageController extends AbstractDeleteController { - /** - * @var SettingsRepositoryInterface - */ - protected $settings; - /** * @var Cloud */ protected $uploadDir; - public function __construct(SettingsRepositoryInterface $settings, Factory $factory) - { - $this->settings = $settings; + public function __construct( + protected SettingsRepositoryInterface $settings, + Factory $factory + ) { $this->uploadDir = $factory->disk('flarum-assets'); } - protected function delete(ServerRequestInterface $request) + protected function delete(ServerRequestInterface $request): void { $id = Arr::get($request->getQueryParams(), 'id'); @@ -51,7 +46,5 @@ protected function delete(ServerRequestInterface $request) if ($this->uploadDir->exists($path)) { $this->uploadDir->delete($path); } - - return new EmptyResponse(204); } } diff --git a/src/Api/Controllers/ListRanksController.php b/src/Api/Controllers/ListRanksController.php deleted file mode 100755 index ce8cf939..00000000 --- a/src/Api/Controllers/ListRanksController.php +++ /dev/null @@ -1,28 +0,0 @@ -gamification = $gamification; - } - - protected function data(ServerRequestInterface $request, Document $document) - { - if (RequestUtil::getActor($request)->cannot('fof.gamification.viewRankingPage')) { - throw new PermissionDeniedException(); - } - - $limit = $this->extractLimit($request); - $offset = $this->extractOffset($request); - - return $this->gamification->orderByPoints($limit, $offset); - } -} diff --git a/src/Api/Controllers/UpdateRankController.php b/src/Api/Controllers/UpdateRankController.php deleted file mode 100755 index 2f37c2c9..00000000 --- a/src/Api/Controllers/UpdateRankController.php +++ /dev/null @@ -1,43 +0,0 @@ -bus = $bus; - } - - protected function data(ServerRequestInterface $request, Document $document) - { - return $this->bus->dispatch( - new EditRank(Arr::get($request->getQueryParams(), 'id'), RequestUtil::getActor($request), Arr::get($request->getParsedBody(), 'data', [])) - ); - } -} diff --git a/src/Api/Controllers/UploadTopImageController.php b/src/Api/Controllers/UploadTopImageController.php index 7aa796dd..d4d30599 100755 --- a/src/Api/Controllers/UploadTopImageController.php +++ b/src/Api/Controllers/UploadTopImageController.php @@ -12,6 +12,7 @@ namespace FoF\Gamification\Api\Controllers; use Flarum\Api\Controller\ShowForumController; +use Flarum\Api\JsonApi; use Flarum\Foundation\Paths; use Flarum\Foundation\ValidationException; use Flarum\Http\RequestUtil; @@ -22,40 +23,29 @@ use Illuminate\Support\Str; use Intervention\Image\ImageManager; use Laminas\Diactoros\UploadedFile; +use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; -use Tobscure\JsonApi\Document; class UploadTopImageController extends ShowForumController { - /** - * @var SettingsRepositoryInterface - */ - protected $settings; - - /** - * @var Paths - */ - protected $paths; - - /** - * @var ImageManager - */ - protected $imageManager; - /** * @var Cloud */ protected $uploadDir; - public function __construct(SettingsRepositoryInterface $settings, Paths $paths, ImageManager $imageManager, FilesystemFactory $factory) - { - $this->settings = $settings; - $this->paths = $paths; - $this->imageManager = $imageManager; + public function __construct( + JsonApi $api, + protected SettingsRepositoryInterface $settings, + protected Paths $paths, + protected ImageManager $imageManager, + FilesystemFactory $factory + ) { + parent::__construct($api); + $this->uploadDir = $factory->disk('flarum-assets'); } - public function data(ServerRequestInterface $request, Document $document) + public function handle(ServerRequestInterface $request): ResponseInterface { RequestUtil::getActor($request)->assertAdmin(); @@ -89,13 +79,13 @@ public function data(ServerRequestInterface $request, Document $document) break; } - $image = $this->imageManager->make($tmpFile); + $image = $this->imageManager->read($tmpFile); if (extension_loaded('exif')) { - $image->orientate(); + $image->orient(); } - $encodedImage = $image->fit($size, $size)->encode('png'); + $encodedImage = $image->resize($size, $size)->toPng(); $key = "fof-gamification.topimage{$id}_path"; $uploadName = 'topimage-'.Str::lower(Str::random(8)).'.png'; @@ -106,6 +96,10 @@ public function data(ServerRequestInterface $request, Document $document) unlink($tmpFile); - return parent::data($request, $document); + return parent::handle( + // The parent controller expects a show forum request. + // `GET /api/forum` + $request->withMethod('GET')->withUri($request->getUri()->withPath('/api/forum')) + ); } } diff --git a/src/Api/DiscussionResourceFields.php b/src/Api/DiscussionResourceFields.php new file mode 100644 index 00000000..a0263c8c --- /dev/null +++ b/src/Api/DiscussionResourceFields.php @@ -0,0 +1,56 @@ +visible($hasUpvotedVisible = function (Discussion $discussion, Context $context) { + $postExists = $discussion->firstPost || $discussion->posts()->where('number', 1)->first(); + + return !$context->getActor()->isGuest() && $context->getActor()->exists && $postExists; + }) + ->get(function (Discussion $discussion) { + $post = $discussion->firstPost ?: $discussion->posts()->where('number', 1)->first(); + + /** @phpstan-ignore-next-line */ + return $post->actualvotes->first()?->isUpvote() ?? false; + }), + Schema\Boolean::make('hasDownvoted') + ->visible($hasUpvotedVisible) + ->get(function (Discussion $discussion) { + $post = $discussion->firstPost ?: $discussion->posts()->where('number', 1)->first(); + + /** @phpstan-ignore-next-line */ + return $post->actualvotes->first()?->isDownvote() ?? false; + }), + Schema\Number::make('votes') + ->visible(fn (Discussion $discussion, Context $context) => $context->getActor()->can('canSeeVotes', $discussion)) + ->get(fn (Discussion $discussion) => $discussion->votes), + Schema\Boolean::make('seeVotes') + ->get(fn (Discussion $discussion, Context $context) => $context->getActor()->can('canSeeVotes', $discussion)), + Schema\Boolean::make('canVote') + ->get(function (Discussion $discussion, Context $context) { + $post = $discussion->firstPost ?: $discussion->posts()->where('number', 1)->first(); + + return $post && $context->getActor()->can('votePosts', $discussion) && $context->getActor()->can('vote', $post); + }), + ]; + } +} diff --git a/src/Api/ForumResourceFields.php b/src/Api/ForumResourceFields.php new file mode 100644 index 00000000..aec2bba8 --- /dev/null +++ b/src/Api/ForumResourceFields.php @@ -0,0 +1,65 @@ +uploadDir = $factory->disk('flarum-assets'); + } + + public function __invoke(): array + { + return [ + Schema\Boolean::make('canViewRankingPage') + ->get(function ($forum, Context $context) { + return $context->getActor()->can('fof.gamification.viewRankingPage'); + }), + Schema\Boolean::make('fof-gamification-op-votes-only') + ->get(function () { + return (bool) $this->settings->get('fof-gamification.firstPostOnly'); + }), + Schema\Str::make('fof-gamification.topimage1Url') + ->get(fn () => $this->urlForKey('fof-gamification.topimage1_path')), + Schema\Str::make('fof-gamification.topimage2Url') + ->get(fn () => $this->urlForKey('fof-gamification.topimage2_path')), + Schema\Str::make('fof-gamification.topimage3Url') + ->get(fn () => $this->urlForKey('fof-gamification.topimage3_path')), + + Schema\Relationship\ToMany::make('ranks') + ->type('ranks') + ->includable() + ->get(fn () => Rank::query()->get()->all()), + ]; + } + + protected function urlForKey(string $key): ?string + { + $value = $this->settings->get($key); + + if ($value === null) { + return null; + } + + return $this->uploadDir->url($value); + } +} diff --git a/src/Api/PostResourceFields.php b/src/Api/PostResourceFields.php new file mode 100644 index 00000000..579bb40d --- /dev/null +++ b/src/Api/PostResourceFields.php @@ -0,0 +1,184 @@ +visible(function (Post $post, Context $context) { + return $context->getActor()->can('canSeeVotes', $post->discussion) + && $context->getActor()->can('canSeeVotes', $post); + }) + ->get(function (Post $post, Context $context) { + if ($context->getActor()->exists) { + /** @phpstan-ignore-next-line */ + $vote = $post->actualvotes->first(); + + return $vote && $vote->isUpvote(); + } + + return null; + }), + Schema\Boolean::make('hasDownvoted') + ->visible(function (Post $post, Context $context) { + return $context->getActor()->can('canSeeVotes', $post->discussion) + && $context->getActor()->can('canSeeVotes', $post); + }) + ->get(function (Post $post, Context $context) { + if ($context->getActor()->exists) { + /** @phpstan-ignore-next-line */ + $vote = $post->actualvotes->first(); + + return $vote && $vote->isDownvote(); + } + + return null; + }), + Schema\Boolean::make('canSeeVotes') + ->get(function (Post $post, Context $context) { + return $context->getActor()->can('canSeeVotes', $post->discussion) + && $context->getActor()->can('canSeeVotes', $post); + }), + Schema\Number::make('votes') + ->sumRelation('actualvotes', 'value') + ->visible(function (Post $post, Context $context) { + return $context->getActor()->can('canSeeVotes', $post->discussion) + && $context->getActor()->can('canSeeVotes', $post); + }), + Schema\Boolean::make('canVote') + ->get(function (Post $post, Context $context) { + return $context->getActor()->can('vote', $post); + }), + Schema\Boolean::make('seeVoters') + ->get(function (Post $post, Context $context) { + return $context->getActor()->can('canSeeVoters', $post->discussion) + && $context->getActor()->can('canSeeVoters', $post); + }), + + Schema\Str::make('vote') + ->hidden() + ->writable(function (Post $post, Context $context) { + return $context->updating() + && $context->getActor()->can('vote', $post); + }) + ->in(['up', 'down']) + ->nullable() + ->set(function (Post $post, ?string $value, Context $context) { + if ($this->settings->get('fof-gamification.rateLimit')) { + $this->assertNotFlooding($context->getActor()); + } + + $this->vote($post, $value, $context->getActor()); + }), + + Schema\Relationship\ToMany::make('upvotes') + ->includable() + ->type('users'), + Schema\Relationship\ToMany::make('downvotes') + ->includable() + ->type('users'), + ]; + } + + public function vote(Post $post, ?string $voteValue, User $actor): void + { + $vote = Vote::build($post, $actor); + + $vote->value = match (true) { + $voteValue === 'up' => 1, + $voteValue === 'down' => -1, + default => 0, + }; + + $vote->save(); + + $this->pushNewVote($vote); + + $this->updatePoints($post->user, $post); + + if ($voteUser = $vote->post->user) { + $ranks = Rank::where('points', '<=', $voteUser->votes)->pluck('id'); + + $voteUser->ranks()->sync($ranks); + } + + $actor->last_vote_time = Carbon::now(); + $actor->save(); + + $this->events->dispatch( + new PostWasVoted($vote) + ); + } + + public function updatePoints(?User $user, Post $post): void + { + if ($user) { + $user = Vote::updateUserVotes($user); + $user->save(); + + $this->events->dispatch(new UserPointsUpdated($user)); + } + + $discussion = $post->discussion; + + if ($post->id === $discussion->first_post_id) { + $this->gamification->calculateHotness( + Vote::updateDiscussionVotes($discussion) + ); + } + } + + public function pushNewVote(Vote $vote): void + { + if ($this->container->bound(Pusher::class)) { + $this->container->make(Pusher::class)->trigger('public', 'newVote', [ + 'post_id' => $vote->post->id, + 'user_id' => $vote->user->id, + 'votes' => $vote->post->votes()->sum('value'), + ]); + } + } + + public function assertNotFlooding(User $actor): void + { + if ($actor->last_vote_time !== null && Carbon::parse($actor->last_vote_time)->greaterThanOrEqualTo(Carbon::now()->subSeconds(10))) { + throw new FloodingException(); + } + } +} diff --git a/src/Api/Resource/RankResource.php b/src/Api/Resource/RankResource.php new file mode 100644 index 00000000..62bf4682 --- /dev/null +++ b/src/Api/Resource/RankResource.php @@ -0,0 +1,78 @@ + + */ +class RankResource extends Resource\AbstractDatabaseResource +{ + public function type(): string + { + return 'ranks'; + } + + public function model(): string + { + return Rank::class; + } + + public function scope(Builder $query, OriginalContext $context): void + { + // $query->whereVisibleTo($context->getActor()); + } + + public function endpoints(): array + { + return [ + Endpoint\Create::make() + ->admin(), + Endpoint\Update::make() + ->admin(), + Endpoint\Delete::make() + ->admin(), + Endpoint\Index::make(), + ]; + } + + public function fields(): array + { + return [ + + Schema\Number::make('points') + ->requiredOnCreate() + ->writable(), + Schema\Str::make('name') + ->requiredOnCreate() + ->writable(), + Schema\Str::make('color') + ->requiredOnCreate() + ->writable(), + + ]; + } + + public function sorts(): array + { + return [ + // SortColumn::make('createdAt'), + ]; + } +} diff --git a/src/Api/Serializers/RankSerializer.php b/src/Api/Serializers/RankSerializer.php deleted file mode 100755 index c9cd7352..00000000 --- a/src/Api/Serializers/RankSerializer.php +++ /dev/null @@ -1,44 +0,0 @@ - $rank->points, - 'name' => $rank->name, - 'color' => $rank->color, - ]; - } -} diff --git a/src/Api/UserResourceFields.php b/src/Api/UserResourceFields.php new file mode 100644 index 00000000..aa99e139 --- /dev/null +++ b/src/Api/UserResourceFields.php @@ -0,0 +1,35 @@ +property('votes'), + Schema\Boolean::make('canHaveVotingNotifications') + ->get(function (User $user) { + return $user->hasPermission('discussion.upvote_notifications') + || $user->hasPermission('discussion.downvote_notifications'); + }), + + Schema\Relationship\ToMany::make('ranks') + ->type('ranks') + ->includable(), + ]; + } +} diff --git a/src/Commands/CreateRank.php b/src/Commands/CreateRank.php deleted file mode 100755 index 6574da69..00000000 --- a/src/Commands/CreateRank.php +++ /dev/null @@ -1,37 +0,0 @@ -actor = $actor; - $this->data = $data; - } -} diff --git a/src/Commands/CreateRankHandler.php b/src/Commands/CreateRankHandler.php deleted file mode 100755 index a9dd8965..00000000 --- a/src/Commands/CreateRankHandler.php +++ /dev/null @@ -1,58 +0,0 @@ -validator = $validator; - } - - /** - * @param CreateRank $command - * - * @throws PermissionDeniedException - * - * @return Rank - */ - public function handle(CreateRank $command) - { - $command->actor->assertAdmin(); - $data = $command->data; - - $rank = Rank::build( - Arr::get($data, 'attributes.name'), - Arr::get($data, 'attributes.color'), - Arr::get($data, 'attributes.points') - ); - - $this->validator->assertValid($rank->getAttributes()); - - $rank->save(); - - return $rank; - } -} diff --git a/src/Commands/DeleteRank.php b/src/Commands/DeleteRank.php deleted file mode 100755 index 52c322c4..00000000 --- a/src/Commands/DeleteRank.php +++ /dev/null @@ -1,36 +0,0 @@ -rankId = $rankId; - $this->actor = $actor; - } -} diff --git a/src/Commands/DeleteRankHandler.php b/src/Commands/DeleteRankHandler.php deleted file mode 100755 index c0af27d7..00000000 --- a/src/Commands/DeleteRankHandler.php +++ /dev/null @@ -1,36 +0,0 @@ -actor->assertAdmin(); - - $rank = Rank::where('id', $command->rankId)->firstOrFail(); - - $rank->delete(); - - return $rank; - } -} diff --git a/src/Commands/EditRank.php b/src/Commands/EditRank.php deleted file mode 100755 index cd4dbdff..00000000 --- a/src/Commands/EditRank.php +++ /dev/null @@ -1,44 +0,0 @@ -rankId = $rankId; - $this->actor = $actor; - $this->data = $data; - } -} diff --git a/src/Commands/EditRankHandler.php b/src/Commands/EditRankHandler.php deleted file mode 100755 index f7080427..00000000 --- a/src/Commands/EditRankHandler.php +++ /dev/null @@ -1,72 +0,0 @@ -validator = $validator; - } - - /** - * @param EditRank $command - * - * @throws PermissionDeniedException - * - * @return Rank - */ - public function handle(EditRank $command) - { - $command->actor->assertAdmin(); - $data = $command->data; - $attributes = Arr::get($data, 'attributes', []); - - $validate = []; - - $rank = Rank::where('id', $command->rankId)->firstOrFail(); - - if (isset($attributes['points']) && '' !== $attributes['points']) { - $validate['points'] = $attributes['points']; - $rank->updatePoints($attributes['points']); - } - - if (isset($attributes['name']) && '' !== $attributes['name']) { - $validate['name'] = $attributes['name']; - $rank->updateName($attributes['name']); - } - - if (isset($attributes['color']) && '' !== $attributes['color']) { - $validate['color'] = $attributes['color']; - $rank->updateColor($attributes['color']); - } - - $this->validator->assertValid(array_merge($rank->getDirty(), $validate)); - - $rank->save(); - - return $rank; - } -} diff --git a/src/Console/AutoAssignGroups.php b/src/Console/AutoAssignGroups.php index ff835647..ae4baa2a 100644 --- a/src/Console/AutoAssignGroups.php +++ b/src/Console/AutoAssignGroups.php @@ -22,11 +22,11 @@ class AutoAssignGroups extends Command protected $signature = 'fof:gamification:assign-groups'; protected $description = 'Updates the auto-assigned groups of all users'; - protected $totalAdded = 0; - protected $totalRemoved = 0; - protected $totalUsersUpdated = 0; + protected int $totalAdded = 0; + protected int $totalRemoved = 0; + protected int $totalUsersUpdated = 0; - public function handle(SettingsRepositoryInterface $settings) + public function handle(SettingsRepositoryInterface $settings): void { $this->output->progressStart(User::query()->count()); /** @var Dispatcher $dispatcher */ diff --git a/src/Console/ResyncDiscussionVotes.php b/src/Console/ResyncDiscussionVotes.php index 4bc4e99c..b0fec005 100644 --- a/src/Console/ResyncDiscussionVotes.php +++ b/src/Console/ResyncDiscussionVotes.php @@ -20,9 +20,9 @@ class ResyncDiscussionVotes extends Command protected $signature = 'fof:gamification:resync'; protected $description = 'Resync discussion vote counts'; - protected $updateCount = 0; + protected int $updateCount = 0; - public function handle() + public function handle(): void { $this->info('Syncing discussion votes. This may take some time if you have many discussions!'); diff --git a/src/Console/ResyncUserVotes.php b/src/Console/ResyncUserVotes.php index d30a66fe..ad670c1f 100644 --- a/src/Console/ResyncUserVotes.php +++ b/src/Console/ResyncUserVotes.php @@ -22,18 +22,14 @@ class ResyncUserVotes extends Command protected $signature = 'fof:gamification:resyncUsers'; protected $description = 'Resync user vote counts'; - protected $events; + protected int $updateCount = 0; - protected $updateCount = 0; - - public function __construct(Dispatcher $events) + public function __construct(protected Dispatcher $events) { - $this->events = $events; - parent::__construct(); } - public function handle() + public function handle(): void { $this->info('Syncing user votes. This may take some time if you have many users!'); diff --git a/src/Events/PostWasVoted.php b/src/Events/PostWasVoted.php index 53372b39..0f501e0d 100755 --- a/src/Events/PostWasVoted.php +++ b/src/Events/PostWasVoted.php @@ -15,18 +15,8 @@ class PostWasVoted { - /** - * @var Vote - */ - public $vote; - - /** - * PostWasVoted constructor. - * - * @param Vote $vote - */ - public function __construct(Vote $vote) - { - $this->vote = $vote; + public function __construct( + public Vote $vote + ) { } } diff --git a/src/Events/UserPointsUpdated.php b/src/Events/UserPointsUpdated.php index 450ed9b0..0da3b452 100644 --- a/src/Events/UserPointsUpdated.php +++ b/src/Events/UserPointsUpdated.php @@ -15,10 +15,8 @@ class UserPointsUpdated { - public $user; - - public function __construct(User $user) - { - $this->user = $user; + public function __construct( + public User $user + ) { } } diff --git a/src/Filter/RankableFilter.php b/src/Filter/RankableFilter.php new file mode 100644 index 00000000..6aca958c --- /dev/null +++ b/src/Filter/RankableFilter.php @@ -0,0 +1,44 @@ +getActor()->cannot('fof.gamification.viewRankingPage')) { + throw new PermissionDeniedException(); + } + + $blockedUsers = explode(', ', $this->settings->get('fof-gamification.blockedUsers')); + + /** @phpstan-ignore-next-line */ + $state + ->getQuery() + ->whereIn('username', $blockedUsers, 'and', !$negate); + } +} diff --git a/src/Filter/VotedFilter.php b/src/Filter/VotedFilter.php index fc08babc..83407b9a 100644 --- a/src/Filter/VotedFilter.php +++ b/src/Filter/VotedFilter.php @@ -11,20 +11,15 @@ namespace FoF\Gamification\Filter; -use Flarum\Filter\FilterInterface; -use Flarum\Filter\FilterState; +use Flarum\Search\Filter\FilterInterface; +use Flarum\Search\SearchState; use Flarum\Settings\SettingsRepositoryInterface; class VotedFilter implements FilterInterface { - /** - * @var SettingsRepositoryInterface - */ - public $settings; - - public function __construct(SettingsRepositoryInterface $settings) - { - $this->settings = $settings; + public function __construct( + public SettingsRepositoryInterface $settings + ) { } public function getFilterKey(): string @@ -32,18 +27,19 @@ public function getFilterKey(): string return 'voted'; } - public function filter(FilterState $filterState, string $filterValue, bool $negate) + public function filter(SearchState $state, array|string $value, bool $negate): void { - $votedId = trim($filterValue, '"'); + $votedId = trim($value, '"'); - $filterState + /** @phpstan-ignore-next-line */ + $state ->getQuery() - ->whereIn('id', function ($query) use ($votedId, $negate, $filterState) { + ->whereIn('id', function ($query) use ($votedId, $negate, $state) { $query->select('post_id') ->from('post_votes') ->where('user_id', $negate ? '!=' : '=', $votedId); - if (!$filterState->getActor()->hasPermission('canSeeVoters')) { - $query->where('user_id', '=', $filterState->getActor()->id); + if (!$state->getActor()->hasPermission('canSeeVoters')) { + $query->where('user_id', '=', $state->getActor()->id); } }) ->when((bool) $this->settings->get('fof-gamification.firstPostOnly'), function ($query) { diff --git a/src/Gambit/HotGambit.php b/src/Gambit/HotGambit.php deleted file mode 100755 index 41afe8cc..00000000 --- a/src/Gambit/HotGambit.php +++ /dev/null @@ -1,33 +0,0 @@ -getQuery()->orderBy('hotness', 'desc'); - } -} diff --git a/src/Gamification.php b/src/Gamification.php index 33228559..311923ae 100755 --- a/src/Gamification.php +++ b/src/Gamification.php @@ -22,25 +22,17 @@ class Gamification */ const MAXIMUM_USER_EXPOSED = 25; - /** - * @var SettingsRepositoryInterface - */ - protected $settings; - - /** - * @param SettingsRepositoryInterface $settings - */ - public function __construct(SettingsRepositoryInterface $settings) - { - $this->settings = $settings; + public function __construct( + protected SettingsRepositoryInterface $settings + ) { } /** * The Reddit hotness algorithm from https://github.com/reddit/reddit. * - * @param $discussion + * @param \Flarum\Discussion\Discussion $discussion */ - public function calculateHotness($discussion) + public function calculateHotness(\Flarum\Discussion\Discussion $discussion): void { $date = strtotime($discussion->created_at); @@ -93,10 +85,10 @@ public function orderByPoints(int $limit, int $offset) } /** - * @param $postId - * @param $userId + * @param int $postId + * @param int $userId */ - public function convertLike($postId, $userId) + public function convertLike(int $postId, int $userId): void { $user = User::find($userId); $post = Post::find($postId); diff --git a/src/Jobs/AutoAssignUserGroups.php b/src/Jobs/AutoAssignUserGroups.php index 719b516c..36e6767b 100644 --- a/src/Jobs/AutoAssignUserGroups.php +++ b/src/Jobs/AutoAssignUserGroups.php @@ -27,17 +27,15 @@ class AutoAssignUserGroups implements ShouldQueue { use Queueable; use SerializesModels; + public int $statsAdded = 0; + public int $statsRemoved = 0; - protected $user; - public $statsAdded = 0; - public $statsRemoved = 0; - - public function __construct(User $user) - { - $this->user = $user; + public function __construct( + protected User $user + ) { } - public function handle(SettingsRepositoryInterface $settings, Dispatcher $dispatcher) + public function handle(SettingsRepositoryInterface $settings, Dispatcher $dispatcher): void { if ($this->user->isAdmin()) { return; diff --git a/src/Jobs/ConvertLikesToUpvotes.php b/src/Jobs/ConvertLikesToUpvotes.php index 69adff94..5a5bf504 100644 --- a/src/Jobs/ConvertLikesToUpvotes.php +++ b/src/Jobs/ConvertLikesToUpvotes.php @@ -41,6 +41,7 @@ public function handle(): void Likes::orderBy('post_id')->chunk(self::CHUNK_SIZE, function (Collection $likes) use ($gamification, &$counter) { foreach ($likes as $like) { + /** @phpstan-ignore-next-line */ $gamification->convertLike($like->post_id, $like->user_id); $counter++; } diff --git a/src/Jobs/VoteNotificationsJob.php b/src/Jobs/VoteNotificationsJob.php index f2a60d89..9cca3883 100644 --- a/src/Jobs/VoteNotificationsJob.php +++ b/src/Jobs/VoteNotificationsJob.php @@ -24,17 +24,12 @@ class VoteNotificationsJob implements ShouldQueue use Queueable; use SerializesModels; - /** - * @var Vote - */ - protected $vote; - - public function __construct(Vote $vote) - { - $this->vote = $vote; + public function __construct( + protected Vote $vote + ) { } - public function handle(NotificationSyncer $notifications) + public function handle(NotificationSyncer $notifications): void { $post = $this->vote->post; $user = $post->user; @@ -49,6 +44,7 @@ public function handle(NotificationSyncer $notifications) if ($this->vote->value === 0) { $notif->delete(); } else { + /** @phpstan-ignore-next-line */ $notif->data = $this->vote->value; $notif->save(); } diff --git a/src/Listeners/AddDiscussionVotes.php b/src/Listeners/AddDiscussionVotes.php index dbc4f1df..f9a300c7 100644 --- a/src/Listeners/AddDiscussionVotes.php +++ b/src/Listeners/AddDiscussionVotes.php @@ -17,7 +17,7 @@ class AddDiscussionVotes { - public function handle(Started $event) + public function handle(Started $event): void { /** @var Discussion $discussion */ $discussion = Vote::updateDiscussionVotes($event->discussion); diff --git a/src/Listeners/AddVoteHandler.php b/src/Listeners/AddVoteHandler.php index 6bfc9e8a..532dbbbf 100644 --- a/src/Listeners/AddVoteHandler.php +++ b/src/Listeners/AddVoteHandler.php @@ -19,29 +19,13 @@ class AddVoteHandler { - /** - * @var SettingsRepositoryInterface - */ - protected $settings; - - /** - * @var Gamification - */ - protected $gamification; - - /** - * EventHandlers constructor. - * - * @param SettingsRepositoryInterface $settings - * @param Gamification $gamification - */ - public function __construct(SettingsRepositoryInterface $settings, Gamification $gamification) - { - $this->settings = $settings; - $this->gamification = $gamification; + public function __construct( + protected SettingsRepositoryInterface $settings, + protected Gamification $gamification + ) { } - public function handle(Posted $event) + public function handle(Posted $event): void { if ((bool) $this->settings->get('fof-gamification.autoUpvotePosts') && $event->post->exists()) { $actor = $event->actor; diff --git a/src/Listeners/QueueJobs.php b/src/Listeners/QueueJobs.php index 29c69cfb..0f9a988f 100644 --- a/src/Listeners/QueueJobs.php +++ b/src/Listeners/QueueJobs.php @@ -14,18 +14,22 @@ use FoF\Gamification\Events\PostWasVoted; use FoF\Gamification\Jobs; use Illuminate\Contracts\Events\Dispatcher; +use Illuminate\Contracts\Queue\Queue; class QueueJobs { - public function subscribe(Dispatcher $events) + public function __construct( + protected Queue $queue + ) { + } + + public function subscribe(Dispatcher $events): void { $events->listen(PostWasVoted::class, [$this, 'notifications']); } - public function notifications(PostWasVoted $event) + public function notifications(PostWasVoted $event): void { - resolve('flarum.queue.connection')->push( - new Jobs\VoteNotificationsJob($event->vote) - ); + $this->queue->push(new Jobs\VoteNotificationsJob($event->vote)); } } diff --git a/src/Listeners/RemoveVoteHandler.php b/src/Listeners/RemoveVoteHandler.php index abc876b3..42c8797b 100644 --- a/src/Listeners/RemoveVoteHandler.php +++ b/src/Listeners/RemoveVoteHandler.php @@ -17,7 +17,7 @@ class RemoveVoteHandler { - public function handle(Deleted $event) + public function handle(Deleted $event): void { $post = $event->post; diff --git a/src/Listeners/SaveVotesToDatabase.php b/src/Listeners/SaveVotesToDatabase.php deleted file mode 100755 index cf791fc1..00000000 --- a/src/Listeners/SaveVotesToDatabase.php +++ /dev/null @@ -1,177 +0,0 @@ -events = $events; - $this->gamification = $gamification; - $this->settings = $settings; - $this->container = $container; - } - - /** - * @param Saving $event - * - * @throws FloodingException - * @throws \Flarum\User\Exception\PermissionDeniedException - */ - public function handle(Saving $event) - { - $post = $event->post; - if ($post->exists()) { - $data = Arr::get($event->data, 'attributes', []); - - if (Arr::exists($data, 2) && Arr::get($data, 2) === 'vote') { - $actor = $event->actor; - $user = $post->user; - - $actor->assertCan('vote', $post); - - if ($this->settings->get('fof-gamification.rateLimit')) { - $this->assertNotFlooding($actor); - } - - $isUpvoted = Arr::get($data, 0, false); - - $isDownvoted = Arr::get($data, 1, false); - - $this->vote($post, $isDownvoted, $isUpvoted, $actor, $user); - } - } - } - - public function vote(Post $post, bool $isDownvoted, bool $isUpvoted, User $actor, User $user) - { - $vote = Vote::build($post, $actor); - - if (!$isDownvoted && !$isUpvoted) { - $vote->value = 0; - } else { - if ($isUpvoted) { - $vote->value = 1; - } else { - $vote->value = -1; - } - } - - $vote->save(); - - $this->pushNewVote($vote); - - $this->updatePoints($user, $post); - - if ($voteUser = $vote->post->user) { - $ranks = Rank::where('points', '<=', $voteUser->votes)->pluck('id'); - - $voteUser->ranks()->sync($ranks); - } - - $actor->last_vote_time = Carbon::now(); - $actor->save(); - - $this->events->dispatch( - new PostWasVoted($vote) - ); - } - - /** - * @param $user - * @param $post - */ - public function updatePoints(?User $user, Post $post) - { - if ($user) { - $user = Vote::updateUserVotes($user); - $user->save(); - - $this->events->dispatch(new UserPointsUpdated($user)); - } - - $discussion = $post->discussion; - - if ($post->id === $discussion->first_post_id) { - $this->gamification->calculateHotness( - Vote::updateDiscussionVotes($discussion) - ); - } - } - - public function pushNewVote(Vote $vote) - { - if ($this->container->bound(Pusher::class)) { - $this->container->make(Pusher::class)->trigger('public', 'newVote', [ - 'post_id' => $vote->post->id, - 'user_id' => $vote->user->id, - 'votes' => $vote->post->votes()->sum('value'), - ]); - } - } - - /** - * @param $user - * - * @throws FloodingException - */ - public function assertNotFlooding($actor) - { - if ($actor->last_vote_time !== null && Carbon::parse($actor->last_vote_time)->greaterThanOrEqualTo(Carbon::now()->subSeconds(10))) { - throw new FloodingException(); - } - } -} diff --git a/src/Listeners/UpdateAutoAssignedGroups.php b/src/Listeners/UpdateAutoAssignedGroups.php index 2c637585..27d97a38 100644 --- a/src/Listeners/UpdateAutoAssignedGroups.php +++ b/src/Listeners/UpdateAutoAssignedGroups.php @@ -17,14 +17,12 @@ class UpdateAutoAssignedGroups { - protected $queue; - - public function __construct(Queue $queue) - { - $this->queue = $queue; + public function __construct( + protected Queue $queue + ) { } - public function handle(UserPointsUpdated $event) + public function handle(UserPointsUpdated $event): void { $this->queue->push(new AutoAssignUserGroups($event->user)); } diff --git a/src/LoadActorVoteRelationship.php b/src/LoadActorVoteRelationship.php deleted file mode 100644 index 3ca41b4c..00000000 --- a/src/LoadActorVoteRelationship.php +++ /dev/null @@ -1,52 +0,0 @@ -where('user_id', $actor->id); - } - - public static function sumRelation($controller, $data): void - { - $loadable = null; - - if ($data instanceof Discussion) { - $loadable = $data->newCollection($data->posts)->filter(function ($post) { - return $post instanceof Post; - }); - } elseif ($data instanceof Collection) { - $loadable = (new Post())->newCollection($data->map(function ($model) { - return $model instanceof Discussion ? ($model->mostRelevantPost ?? $model->firstPost) : $model; - })->filter()); - } elseif ($data instanceof Post) { - $loadable = $data->newCollection([$data]); - } - - if ($loadable && $loadable instanceof Collection) { - $loadable->loadSum('actualvotes', 'value'); - } - } -} diff --git a/src/Notification/VoteBlueprint.php b/src/Notification/VoteBlueprint.php index 2d8e2868..647a0480 100755 --- a/src/Notification/VoteBlueprint.php +++ b/src/Notification/VoteBlueprint.php @@ -11,33 +11,23 @@ namespace FoF\Gamification\Notification; +use Flarum\Notification\AlertableInterface; use Flarum\Notification\Blueprint\BlueprintInterface; use Flarum\Notification\MailableInterface; use Flarum\Post\Post; use FoF\Gamification\Vote; -use Symfony\Contracts\Translation\TranslatorInterface; -class VoteBlueprint implements BlueprintInterface, MailableInterface +class VoteBlueprint implements BlueprintInterface, MailableInterface, AlertableInterface { - /** - * @var Vote - */ - public $vote; - - /** - * VoteBlueprint constructor. - * - * @param Vote $vote - */ - public function __construct(Vote $vote) - { - $this->vote = $vote; + public function __construct( + public Vote $vote + ) { } /** * {@inheritdoc} */ - public function getSubject() + public function getSubject(): ?\Flarum\Database\AbstractModel { return $this->vote->post; } @@ -45,7 +35,7 @@ public function getSubject() /** * {@inheritdoc} */ - public function getFromUser() + public function getFromUser(): ?\Flarum\User\User { return $this->vote->user; } @@ -53,7 +43,7 @@ public function getFromUser() /** * {@inheritdoc} */ - public function getData() + public function getData(): mixed { return $this->vote->value; } @@ -61,7 +51,7 @@ public function getData() /** * {@inheritdoc} */ - public static function getType() + public static function getType(): string { return 'vote'; } @@ -69,7 +59,7 @@ public static function getType() /** * {@inheritdoc} */ - public static function getSubjectModel() + public static function getSubjectModel(): string { return Post::class; } @@ -79,9 +69,9 @@ public static function getSubjectModel() * * @return array */ - public function getEmailView() + public function getEmailViews(): array { - return ['text' => 'fof-gamification::emails.postVoted']; + return ['text' => 'fof-gamification::email.plain.postVoted', 'html' => 'fof-gamification::email.html.postVoted']; } /** @@ -89,7 +79,7 @@ public function getEmailView() * * @return string */ - public function getEmailSubject(TranslatorInterface $translator) + public function getEmailSubject(\Flarum\Locale\TranslatorInterface $translator): string { return $translator->trans('fof-gamification.email.subject.postVoted', [ '{display_name}' => $this->vote->user->display_name, diff --git a/src/Rank.php b/src/Rank.php index 89ca3045..934cd5d6 100755 --- a/src/Rank.php +++ b/src/Rank.php @@ -45,11 +45,11 @@ public static function build($name, $color, $points) } /** - * @param $name + * @param string $name * * @return $this */ - public function updateName($name) + public function updateName(string $name): self { $this->name = $name; @@ -57,11 +57,11 @@ public function updateName($name) } /** - * @param $points + * @param int $points * * @return $this */ - public function updatePoints($points) + public function updatePoints(int $points): self { $this->points = $points; @@ -69,18 +69,18 @@ public function updatePoints($points) } /** - * @param $color + * @param string $color * * @return $this */ - public function updateColor($color) + public function updateColor(string $color): self { $this->color = $color; return $this; } - public function users() + public function users(): \Illuminate\Database\Eloquent\Relations\BelongsToMany { return $this->belongsToMany(User::class); } diff --git a/src/Search/HotFilter.php b/src/Search/HotFilter.php new file mode 100644 index 00000000..5bc1bf27 --- /dev/null +++ b/src/Search/HotFilter.php @@ -0,0 +1,36 @@ +sort($state->getQuery(), $state->getActor(), $negate); + } + + protected function sort(Builder $query, User $actor, bool $negate): void + { + $query->orderBy('hotness', 'desc'); + } +} diff --git a/src/Search/HotFilterGambit.php b/src/Search/HotFilterGambit.php deleted file mode 100755 index 5c547b67..00000000 --- a/src/Search/HotFilterGambit.php +++ /dev/null @@ -1,61 +0,0 @@ -sort($filterState->getQuery(), $filterState->getActor(), $negate); - } - - protected function sort(Builder $query, User $actor, bool $negate) - { - $query->orderBy('hotness', 'desc'); - } - - /** - * @param SearchState $search - * @param array $matches - * @param $negate - */ - protected function conditions(SearchState $search, array $matches, $negate) - { - $this->sort($search->getQuery(), $search->getActor(), $negate); - } -} diff --git a/src/Validator/RankValidator.php b/src/Validator/RankValidator.php index 4c4c6e4e..e7dda19a 100755 --- a/src/Validator/RankValidator.php +++ b/src/Validator/RankValidator.php @@ -15,7 +15,7 @@ class RankValidator extends AbstractValidator { - protected $rules = [ + protected array $rules = [ 'name' => ['required', 'string'], 'color' => ['required', 'string'], 'points' => ['required', 'integer'], diff --git a/src/Vote.php b/src/Vote.php index 4e0d8502..86838045 100755 --- a/src/Vote.php +++ b/src/Vote.php @@ -54,7 +54,7 @@ public static function build(Post $post, User $user): Vote ]); } - public static function calculate($paramsOrQuery): int + public static function calculate(array|\Illuminate\Database\Eloquent\Builder $paramsOrQuery): int { $query = $paramsOrQuery; @@ -84,22 +84,22 @@ public static function updateDiscussionVotes(Discussion $discussion): Discussion return $discussion; } - public function isUpvote() + public function isUpvote(): bool { return $this->value > 0; } - public function isDownvote() + public function isDownvote(): bool { return $this->value < 0; } - public function post() + public function post(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Post::class); } - public function user() + public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(User::class); } diff --git a/tests/integration/api/TopImageTest.php b/tests/integration/api/TopImageTest.php index 108dac6c..f2cbb0e1 100644 --- a/tests/integration/api/TopImageTest.php +++ b/tests/integration/api/TopImageTest.php @@ -12,7 +12,10 @@ namespace FoF\Gamification\Tests\integration\api; use Flarum\Testing\integration\RetrievesAuthorizedUsers; +use Flarum\User\User; use FoF\Gamification\Tests\EnhancedTestCase; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; class TopImageTest extends EnhancedTestCase { @@ -25,13 +28,13 @@ public function setUp(): void $this->extension('fof-gamification'); $this->prepareDatabase([ - 'users' => [ + User::class => [ $this->normalUser(), ], ]); } - public function topImagesProvider() + public static function topImagesProvider() { return [ [1], @@ -40,11 +43,8 @@ public function topImagesProvider() ]; } - /** - * @dataProvider topImagesProvider - * - * @test - */ + #[Test] + #[DataProvider('topImagesProvider')] public function normal_user_cannot_upload_top_image(int $imageNo) { $response = $this->send( @@ -60,11 +60,8 @@ public function normal_user_cannot_upload_top_image(int $imageNo) $this->assertEquals(403, $response->getStatusCode()); } - /** - * @dataProvider topImagesProvider - * - * @test - */ + #[Test] + #[DataProvider('topImagesProvider')] public function admin_can_upload_top_image(int $imageNo) { $response = $this->send(