From 42f1f7ab47f2a459307659fc1cb81456e91c58ed Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Thu, 26 Feb 2026 09:47:18 +0100 Subject: [PATCH 001/190] fix: share and assign team issue Signed-off-by: Luka Trovic --- lib/Service/AssignmentService.php | 10 +++++++--- src/components/board/SharingTabSidebar.vue | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/Service/AssignmentService.php b/lib/Service/AssignmentService.php index 734f7a5f9b..dd8d8f17a0 100644 --- a/lib/Service/AssignmentService.php +++ b/lib/Service/AssignmentService.php @@ -48,7 +48,7 @@ public function __construct( public function assignUser(int $cardId, string $userId, int $type = Assignment::TYPE_USER): Assignment { $this->assignmentServiceValidator->check(compact('cardId', 'userId')); - if ($type !== Assignment::TYPE_USER && $type !== Assignment::TYPE_GROUP && $type !== Assignment::TYPE_REMOTE) { + if ($type !== Assignment::TYPE_USER && $type !== Assignment::TYPE_GROUP && $type !== Assignment::TYPE_REMOTE && $type !== Assignment::TYPE_CIRCLE) { throw new BadRequestException('Invalid type provided for assignemnt'); } @@ -63,10 +63,14 @@ public function assignUser(int $cardId, string $userId, int $type = Assignment:: $card = $this->cardMapper->find($cardId); $boardId = $this->cardMapper->findBoardId($cardId); $boardUsers = array_keys($this->permissionService->findUsers($boardId, true)); - $groups = array_filter($this->aclMapper->findAll($boardId), function (Acl $acl) use ($userId) { + $acls = $this->aclMapper->findAll($boardId); + $groups = array_filter($acls, function (Acl $acl) use ($userId) { return $acl->getType() === Acl::PERMISSION_TYPE_GROUP && $acl->getParticipant() === $userId; }); - if (!in_array($userId, $boardUsers, true) && count($groups) !== 1) { + $teams = array_filter($acls, function (Acl $acl) use ($userId) { + return $acl->getType() === Acl::PERMISSION_TYPE_CIRCLE && $acl->getParticipant() === $userId; + }); + if (!in_array($userId, $boardUsers, true) && count($groups) !== 1 && count($teams) !== 1) { throw new BadRequestException('The user is not part of the board'); } diff --git a/src/components/board/SharingTabSidebar.vue b/src/components/board/SharingTabSidebar.vue index 3d0a3de03e..035b1f363b 100644 --- a/src/components/board/SharingTabSidebar.vue +++ b/src/components/board/SharingTabSidebar.vue @@ -91,6 +91,7 @@ const SOURCE_TO_SHARE_TYPE = { emails: 4, remotes: 6, circles: 7, + teams: 7, } export default { From f9685eed19fe776eea1f15f6ff6975d40c0e34bc Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Wed, 15 Apr 2026 15:21:47 +0200 Subject: [PATCH 002/190] refactor: Remove deprecated call to OC_User::useBackend Signed-off-by: Carl Schwan --- tests/integration/database/AssignmentMapperTest.php | 1 - tests/integration/database/BoardDatabaseTest.php | 3 ++- tests/integration/database/TransferOwnershipTest.php | 1 - tests/integration/import/ImportExportTest.php | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/integration/database/AssignmentMapperTest.php b/tests/integration/database/AssignmentMapperTest.php index d28c6c836c..585f9daafe 100644 --- a/tests/integration/database/AssignmentMapperTest.php +++ b/tests/integration/database/AssignmentMapperTest.php @@ -67,7 +67,6 @@ public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); $backend = new \Test\Util\User\Dummy(); - \OC_User::useBackend($backend); Server::get(IUserManager::class)->registerBackend($backend); $backend->createUser(self::TEST_USER1, self::TEST_USER1); $backend->createUser(self::TEST_USER2, self::TEST_USER2); diff --git a/tests/integration/database/BoardDatabaseTest.php b/tests/integration/database/BoardDatabaseTest.php index b657216752..d8eb8009a7 100644 --- a/tests/integration/database/BoardDatabaseTest.php +++ b/tests/integration/database/BoardDatabaseTest.php @@ -25,6 +25,7 @@ use OCA\Deck\Db\Board; use OCA\Deck\Service\BoardService; use OCP\IGroupManager; +use OCP\IUserManager; use OCP\IUserSession; use OCP\Server; @@ -45,7 +46,7 @@ public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); $backend = new \Test\Util\User\Dummy(); - \OC_User::useBackend($backend); + Server::get(IUserManager::class)->registerBackend($backend); $backend->createUser(self::TEST_USER1, self::TEST_USER1); $backend->createUser(self::TEST_USER2, self::TEST_USER2); $backend->createUser(self::TEST_USER3, self::TEST_USER3); diff --git a/tests/integration/database/TransferOwnershipTest.php b/tests/integration/database/TransferOwnershipTest.php index c17d8b7fc0..d5bcd4fa02 100644 --- a/tests/integration/database/TransferOwnershipTest.php +++ b/tests/integration/database/TransferOwnershipTest.php @@ -41,7 +41,6 @@ public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); $backend = new \Test\Util\User\Dummy(); - \OC_User::useBackend($backend); Server::get(IUserManager::class)->registerBackend($backend); $backend->createUser(self::TEST_USER_1, self::TEST_USER_1); $backend->createUser(self::TEST_USER_2, self::TEST_USER_2); diff --git a/tests/integration/import/ImportExportTest.php b/tests/integration/import/ImportExportTest.php index 436ec72125..4131e7eefa 100644 --- a/tests/integration/import/ImportExportTest.php +++ b/tests/integration/import/ImportExportTest.php @@ -61,7 +61,6 @@ public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); $backend = new \Test\Util\User\Dummy(); - \OC_User::useBackend($backend); Server::get(IUserManager::class)->registerBackend($backend); $backend->createUser('alice', 'alice'); $backend->createUser('jane', 'jane'); From a1654e05ed1dc9eee3e7b7a8d3f73d5ddccea7cf Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 16 Apr 2026 12:55:58 -0100 Subject: [PATCH 003/190] fix(teams): use lighter probeCircles() Signed-off-by: Maxence Lange --- lib/Service/CirclesService.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/Service/CirclesService.php b/lib/Service/CirclesService.php index e604a78698..96af9c155c 100644 --- a/lib/Service/CirclesService.php +++ b/lib/Service/CirclesService.php @@ -14,6 +14,7 @@ use OCA\Circles\Model\Circle; use OCA\Circles\Model\Member; use OCA\Circles\Model\Probes\CircleProbe; +use OCA\Circles\Model\Probes\DataProbe; use OCP\App\IAppManager; use OCP\Server; use Throwable; @@ -45,7 +46,9 @@ public function getCircle(string $circleId): ?Circle { // Enforce current user condition since we always want the full list of members $circlesManager = Server::get(CirclesManager::class); $circlesManager->startSuperSession(); - return $circlesManager->getCircle($circleId); + $dataProbe = new DataProbe(); + $dataProbe->add(DataProbe::OWNER); + return $circlesManager->probeCircle($circleId, null, $dataProbe); } catch (Throwable $e) { } return null; @@ -64,7 +67,9 @@ public function isUserInCircle(string $circleId, string $userId): bool { $circlesManager = Server::get(CirclesManager::class); $federatedUser = $circlesManager->getFederatedUser($userId, Member::TYPE_USER); $circlesManager->startSession($federatedUser); - $circle = $circlesManager->getCircle($circleId); + $dataProbe = new DataProbe(); + $dataProbe->add(DataProbe::INITIATOR); + $circle = $circlesManager->probeCircle($circleId, null, $dataProbe); $member = $circle->getInitiator(); $isUserInCircle = $member->getLevel() >= Member::LEVEL_MEMBER; @@ -96,7 +101,7 @@ public function getUserCircles(string $userId): array { $probe->mustBeMember(); return array_map(function (Circle $circle) { return $circle->getSingleId(); - }, $circlesManager->getCircles($probe)); + }, $circlesManager->probeCircles($probe)); } catch (Throwable $e) { } return []; From 298f567bd2d9668536ba53329507e7bc668895ea Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 16 Apr 2026 15:29:11 -0100 Subject: [PATCH 004/190] adding probeCircle/probeCircles Signed-off-by: Maxence Lange --- tests/stub.phpstub | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/stub.phpstub b/tests/stub.phpstub index d55ced5670..8ca73d9dd8 100644 --- a/tests/stub.phpstub +++ b/tests/stub.phpstub @@ -99,17 +99,27 @@ namespace OCA\Circles\Model\Probes { public function __construct() {} public function mustBeMember(bool $must = true): self {} } + class DataProbe { + public const OWNER = 'd'; + public const INITIATOR = 'h'; + public function __construct() {} + public function add(string $key, array $path = []): self {} + public function mustBeMember(bool $must = true): self {} + } } namespace OCA\Circles { use OCA\Circles\Model\Circle; use OCA\Circles\Model\FederatedUser; use OCA\Circles\Model\Probes\CircleProbe; + use OCA\Circles\Model\Probes\DataProbe; class CirclesManager { public function startSuperSession(): void {} public function startSession(?FederatedUser $federatedUser = null): void {} public function getCircles(?CircleProbe $probe = null): array {} public function getCircle(string $singleId, ?CircleProbe $probe = null): Circle {} + public function probeCircles(?CircleProbe $circleProbe = null, ?DataProbe $dataProbe = null): array {} + public function probeCircle(string $singleId, ?CircleProbe $probe = null, ?DataProbe $dataProbe = null): Circle {} public function getFederatedUser(string $federatedId, int $type = Member::TYPE_SINGLE): FederatedUser {} } } From fd93f99c3051ba7f98fb684a0b26907e43b47ec8 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Thu, 23 Apr 2026 00:37:57 +0000 Subject: [PATCH 005/190] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/en_GB.js | 3 +++ l10n/en_GB.json | 3 +++ l10n/uz.js | 1 + l10n/uz.json | 1 + 4 files changed, 8 insertions(+) diff --git a/l10n/en_GB.js b/l10n/en_GB.js index f89ee68dac..9ad6683317 100644 --- a/l10n/en_GB.js +++ b/l10n/en_GB.js @@ -263,6 +263,9 @@ OC.L10N.register( "Remove attachment" : "Remove attachment", "Delete Attachment" : "Delete Attachment", "Restore Attachment" : "Restore Attachment", + "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Modified: {modifiedDate} ⸱ Created: {createdDate}", + "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}", + "Modified: {modifiedDate}\nCreated: {createdDate}" : "Modified: {modifiedDate}\nCreated: {createdDate}", "The title cannot be empty." : "The title cannot be empty.", "Cannot close unsaved card!" : "Cannot close unsaved card!", "Open in sidebar view" : "Open in sidebar view", diff --git a/l10n/en_GB.json b/l10n/en_GB.json index 2786687e72..145a10f1b8 100644 --- a/l10n/en_GB.json +++ b/l10n/en_GB.json @@ -261,6 +261,9 @@ "Remove attachment" : "Remove attachment", "Delete Attachment" : "Delete Attachment", "Restore Attachment" : "Restore Attachment", + "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Modified: {modifiedDate} ⸱ Created: {createdDate}", + "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}", + "Modified: {modifiedDate}\nCreated: {createdDate}" : "Modified: {modifiedDate}\nCreated: {createdDate}", "The title cannot be empty." : "The title cannot be empty.", "Cannot close unsaved card!" : "Cannot close unsaved card!", "Open in sidebar view" : "Open in sidebar view", diff --git a/l10n/uz.js b/l10n/uz.js index 207429c90d..5a52d91479 100644 --- a/l10n/uz.js +++ b/l10n/uz.js @@ -38,6 +38,7 @@ OC.L10N.register( "Tags" : "Tags", "Activity" : "Faollik", "Undo" : "Bekor qilish", + "(remote)" : "(remote)", "Can edit" : "Can edit", "Owner" : "Owner", "Delete" : "O'chirish", diff --git a/l10n/uz.json b/l10n/uz.json index 24cbabd68c..2ee5ac9712 100644 --- a/l10n/uz.json +++ b/l10n/uz.json @@ -36,6 +36,7 @@ "Tags" : "Tags", "Activity" : "Faollik", "Undo" : "Bekor qilish", + "(remote)" : "(remote)", "Can edit" : "Can edit", "Owner" : "Owner", "Delete" : "O'chirish", From cdb1a4ced959c8ad0b9aa3e5a99188c29fd7583c Mon Sep 17 00:00:00 2001 From: Jonas Date: Thu, 23 Apr 2026 15:55:47 +0200 Subject: [PATCH 006/190] fix(comments): use message source when updating a message Signed-off-by: Jonas --- src/components/card/CommentItem.vue | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/card/CommentItem.vue b/src/components/card/CommentItem.vue index a419661a83..bd76153218 100644 --- a/src/components/card/CommentItem.vue +++ b/src/components/card/CommentItem.vue @@ -183,9 +183,7 @@ export default { }, showUpdateForm() { this.edit = true - this.$nextTick(() => { - this.commentMsg = this.$refs.richTextElement.children[0].innerHTML - }) + this.commentMsg = this.comment.message }, hideUpdateForm() { this.commentMsg = '' From 451a1428f43b645e6d03ca2ebaf4c487d1ef8d2f Mon Sep 17 00:00:00 2001 From: Jonas Date: Thu, 23 Apr 2026 16:19:42 +0200 Subject: [PATCH 007/190] fix(comment): bring back submit button to text field Signed-off-by: Jonas --- src/components/card/CommentForm.vue | 34 ++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/components/card/CommentForm.vue b/src/components/card/CommentForm.vue index 1ba7620582..9dec552e04 100644 --- a/src/components/card/CommentForm.vue +++ b/src/components/card/CommentForm.vue @@ -10,6 +10,16 @@ :maxlength="1000" :user-data="members" @submit="submit" /> + + +

{{ error }}

@@ -18,11 +28,14 @@ diff --git a/src/store/card.js b/src/store/card.js index 31ce1e8e81..85986d8d00 100644 --- a/src/store/card.js +++ b/src/store/card.js @@ -388,6 +388,11 @@ export default function cardModuleFactory() { const updatedCard = await apiClient.updateCard(card, stack.boardId) commit('updateCardProperty', { property: 'startdate', card: updatedCard }) }, + async updateCardColor({ commit, getters }, card) { + const stack = getters.stackById(card.stackId) + const updatedCard = await apiClient.updateCard(card, stack.boardId) + commit('updateCardProperty', { property: 'color', card: updatedCard }) + }, addCardData({ commit }, cardData) { const card = { ...cardData } diff --git a/tests/data/deck.json b/tests/data/deck.json index 72a5bef071..207de16084 100644 --- a/tests/data/deck.json +++ b/tests/data/deck.json @@ -74,6 +74,7 @@ "id": 114, "title": "1", "description": "", + "color": null, "stackId": 64, "type": "plain", "lastModified": 1689667779, @@ -119,6 +120,7 @@ "id": 115, "title": "2", "description": "", + "color": null, "stackId": 64, "type": "plain", "lastModified": 1689667752, @@ -153,6 +155,7 @@ "id": 116, "title": "3", "description": "", + "color": null, "stackId": 64, "type": "plain", "lastModified": 1689667760, @@ -211,6 +214,7 @@ "id": 117, "title": "4", "description": "", + "color": null, "stackId": 65, "type": "plain", "lastModified": 1689667767, @@ -273,6 +277,7 @@ "id": 118, "title": "5", "description": "", + "color": null, "stackId": 65, "type": "plain", "lastModified": 1689667773, @@ -317,6 +322,7 @@ "id": 119, "title": "6", "description": "# Test description\n\nHello world", + "color": null, "stackId": 65, "type": "plain", "lastModified": 1689667796, @@ -502,6 +508,7 @@ "id": 107, "title": "Write tests", "description": "", + "color": null, "stackId": 61, "type": "plain", "lastModified": 1689667521, @@ -536,6 +543,7 @@ "id": 111, "title": "Write blog post", "description": "", + "color": null, "stackId": 61, "type": "plain", "lastModified": 1689667521, @@ -570,6 +578,7 @@ "id": 112, "title": "Announce feature", "description": "", + "color": null, "stackId": 61, "type": "plain", "lastModified": 1689667527, @@ -604,6 +613,7 @@ "id": 113, "title": "\ud83c\udf89 Party", "description": "", + "color": null, "stackId": 61, "type": "plain", "lastModified": 1689667537, @@ -650,6 +660,7 @@ "id": 108, "title": "Write feature", "description": "", + "color": null, "stackId": 62, "type": "plain", "lastModified": 1689667488, @@ -696,6 +707,7 @@ "id": 109, "title": "Plan feature", "description": "", + "color": null, "stackId": 63, "type": "plain", "lastModified": 1689667506, @@ -730,6 +742,7 @@ "id": 110, "title": "Design feature", "description": "", + "color": null, "stackId": 63, "type": "plain", "lastModified": 1689667506, diff --git a/tests/unit/Db/CardTest.php b/tests/unit/Db/CardTest.php index 4b566bf8cc..6e06b81017 100644 --- a/tests/unit/Db/CardTest.php +++ b/tests/unit/Db/CardTest.php @@ -43,6 +43,7 @@ private function createCard() { $card->setOrder(12); $card->setArchived(false); $card->setDone(null); + $card->setColor('ffffff'); // TODO: relation shared labels acl return $card; } @@ -100,6 +101,7 @@ public function testJsonSerialize() { 'ETag' => $card->getETag(), 'done' => null, 'referenceData' => null, + 'color' => 'ffffff', ], (new CardDetails($card))->jsonSerialize()); } public function testJsonSerializeLabels() { @@ -130,6 +132,7 @@ public function testJsonSerializeLabels() { 'ETag' => $card->getETag(), 'done' => false, 'referenceData' => null, + 'color' => 'ffffff', ], (new CardDetails($card))->jsonSerialize()); } @@ -162,6 +165,7 @@ public function testJsonSerializeAsignedUsers() { 'ETag' => $card->getETag(), 'done' => false, 'referenceData' => null, + 'color' => 'ffffff', ], (new CardDetails($card))->jsonSerialize()); } } diff --git a/tests/unit/Service/CardServiceTest.php b/tests/unit/Service/CardServiceTest.php index cd000d7dfa..b6299b17ac 100644 --- a/tests/unit/Service/CardServiceTest.php +++ b/tests/unit/Service/CardServiceTest.php @@ -221,6 +221,7 @@ public function testCreate() { 'order' => 999, 'type' => 'text', 'id' => 0, + 'color' => '00ff00', ]); $stack = Stack::fromParams([ 'id' => 123, @@ -233,13 +234,14 @@ public function testCreate() { ->method('find') ->with(123) ->willReturn($stack); - $b = $this->cardService->create('Card title', 123, 'text', 999, 'admin'); + $b = $this->cardService->create('Card title', 123, 'text', 999, 'admin', '', null, null, '00ff00'); $this->assertEquals($b->getTitle(), 'Card title'); $this->assertEquals($b->getOwner(), 'admin'); $this->assertEquals($b->getType(), 'text'); $this->assertEquals($b->getOrder(), 999); $this->assertEquals($b->getStackId(), 123); + $this->assertEquals($b->getColor(), '00ff00'); } public function testClone() { @@ -350,6 +352,7 @@ public function testUpdate() { 'title' => 'Card title', 'archived' => 'false', 'stackId' => 234, + 'color' => '00ff00', ]); $stack = Stack::fromParams([ 'id' => 234, @@ -364,13 +367,14 @@ public function testUpdate() { ->method('find') ->with(234) ->willReturn($stack); - $actual = $this->cardService->update(123, 'newtitle', 234, 'text', 'admin', 'foo', 999, '2017-01-01 00:00:00', null); + $actual = $this->cardService->update(123, 'newtitle', 234, 'text', 'admin', 'foo', 999, '2017-01-01 00:00:00', null, null, null, null, 'ffffff'); $this->assertEquals('newtitle', $actual->getTitle()); $this->assertEquals(234, $actual->getStackId()); $this->assertEquals('text', $actual->getType()); $this->assertEquals(999, $actual->getOrder()); $this->assertEquals('foo', $actual->getDescription()); $this->assertEquals(new \DateTime('2017-01-01T00:00:00+00:00'), $actual->getDuedate()); + $this->assertEquals('ffffff', $actual->getColor()); } public function testUpdateWithStartdate() { From 15d5adb51ef61b75cc01e92067e7f284de4c8cf0 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sat, 25 Apr 2026 00:37:39 +0000 Subject: [PATCH 010/190] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/af.js | 1 + l10n/af.json | 1 + l10n/ar.js | 1 + l10n/ar.json | 1 + l10n/ast.js | 1 + l10n/ast.json | 1 + l10n/be.js | 1 + l10n/be.json | 1 + l10n/bg.js | 1 + l10n/bg.json | 1 + l10n/br.js | 1 + l10n/br.json | 1 + l10n/ca.js | 1 + l10n/ca.json | 1 + 14 files changed, 14 insertions(+) diff --git a/l10n/af.js b/l10n/af.js index 7e10edba1c..b041ddfa96 100644 --- a/l10n/af.js +++ b/l10n/af.js @@ -28,6 +28,7 @@ OC.L10N.register( "Edit" : "Wysig", "Download" : "Laai af", "Comments" : "Kommentare", + "Submit" : "Dien in", "Created:" : "Geskep:", "Reply" : "Antwoord", "Update" : "Werk by", diff --git a/l10n/af.json b/l10n/af.json index 16f7ebb5a8..f642150bfa 100644 --- a/l10n/af.json +++ b/l10n/af.json @@ -26,6 +26,7 @@ "Edit" : "Wysig", "Download" : "Laai af", "Comments" : "Kommentare", + "Submit" : "Dien in", "Created:" : "Geskep:", "Reply" : "Antwoord", "Update" : "Werk by", diff --git a/l10n/ar.js b/l10n/ar.js index 41db6d358a..9b74c725ec 100644 --- a/l10n/ar.js +++ b/l10n/ar.js @@ -262,6 +262,7 @@ OC.L10N.register( "No comments yet. Begin the discussion!" : "لا يوجد تعليقات بعد, ابدأ النقاش الآن!", "The comment cannot be empty." : "التعليق لايمكن ان يكون فارغا.", "The comment cannot be longer than 1000 characters." : "التعليق لا يمكن ان يكون اطول من 1000 حرف.", + "Submit" : "إرسال ", "Created:" : "تاريخ الإنشاء :", "In reply to" : "يقوم بالرد على", "Cancel reply" : "إلغاء الرد", diff --git a/l10n/ar.json b/l10n/ar.json index 52119a1a68..acc5d036f8 100644 --- a/l10n/ar.json +++ b/l10n/ar.json @@ -260,6 +260,7 @@ "No comments yet. Begin the discussion!" : "لا يوجد تعليقات بعد, ابدأ النقاش الآن!", "The comment cannot be empty." : "التعليق لايمكن ان يكون فارغا.", "The comment cannot be longer than 1000 characters." : "التعليق لا يمكن ان يكون اطول من 1000 حرف.", + "Submit" : "إرسال ", "Created:" : "تاريخ الإنشاء :", "In reply to" : "يقوم بالرد على", "Cancel reply" : "إلغاء الرد", diff --git a/l10n/ast.js b/l10n/ast.js index bca924cadf..35a5c2bb71 100644 --- a/l10n/ast.js +++ b/l10n/ast.js @@ -71,6 +71,7 @@ OC.L10N.register( "Failed to load comments" : "Nun se puen cargar los comentarios", "No comments yet. Begin the discussion!" : "Nun hai nengún comentariu. ¡Comienza'l discutiniu!", "The comment cannot be empty." : "El comentariu nun pue tar baleru.", + "Submit" : "Unviar", "Created:" : "Creóse'l", "In reply to" : "En rempuesta a", "Reply" : "Responder", diff --git a/l10n/ast.json b/l10n/ast.json index 5be619d2dd..e37ea9680e 100644 --- a/l10n/ast.json +++ b/l10n/ast.json @@ -69,6 +69,7 @@ "Failed to load comments" : "Nun se puen cargar los comentarios", "No comments yet. Begin the discussion!" : "Nun hai nengún comentariu. ¡Comienza'l discutiniu!", "The comment cannot be empty." : "El comentariu nun pue tar baleru.", + "Submit" : "Unviar", "Created:" : "Creóse'l", "In reply to" : "En rempuesta a", "Reply" : "Responder", diff --git a/l10n/be.js b/l10n/be.js index 07d1c87317..897147c065 100644 --- a/l10n/be.js +++ b/l10n/be.js @@ -53,6 +53,7 @@ OC.L10N.register( "Show in Files" : "Паказаць у Файлах", "Download" : "Спампаваць", "Comments" : "Каментарыі", + "Submit" : "Адправіць", "Created:" : "Створана:", "Cancel reply" : "Скасаваць адказ", "Reply" : "Адказаць", diff --git a/l10n/be.json b/l10n/be.json index 6016d81657..50f19570bc 100644 --- a/l10n/be.json +++ b/l10n/be.json @@ -51,6 +51,7 @@ "Show in Files" : "Паказаць у Файлах", "Download" : "Спампаваць", "Comments" : "Каментарыі", + "Submit" : "Адправіць", "Created:" : "Створана:", "Cancel reply" : "Скасаваць адказ", "Reply" : "Адказаць", diff --git a/l10n/bg.js b/l10n/bg.js index 2c1b079b86..bcc035ea86 100644 --- a/l10n/bg.js +++ b/l10n/bg.js @@ -220,6 +220,7 @@ OC.L10N.register( "No comments yet. Begin the discussion!" : "Все още няма коментари. Започнете дискусията!", "The comment cannot be empty." : "Коментарът не може да бъде празен.", "The comment cannot be longer than 1000 characters." : "Коментарът не може да бъде по-дълъг от 1000 знака.", + "Submit" : "Изпращане", "Created:" : "Създадено:", "In reply to" : "В отговор на", "Cancel reply" : "Отказ на отговор", diff --git a/l10n/bg.json b/l10n/bg.json index abc0f79d24..0e7d74d27d 100644 --- a/l10n/bg.json +++ b/l10n/bg.json @@ -218,6 +218,7 @@ "No comments yet. Begin the discussion!" : "Все още няма коментари. Започнете дискусията!", "The comment cannot be empty." : "Коментарът не може да бъде празен.", "The comment cannot be longer than 1000 characters." : "Коментарът не може да бъде по-дълъг от 1000 знака.", + "Submit" : "Изпращане", "Created:" : "Създадено:", "In reply to" : "В отговор на", "Cancel reply" : "Отказ на отговор", diff --git a/l10n/br.js b/l10n/br.js index 8a70c99928..c685ff5486 100644 --- a/l10n/br.js +++ b/l10n/br.js @@ -31,6 +31,7 @@ OC.L10N.register( "Share from Files" : "Rannañ diouzh Restroù", "Download" : "Pellgargañ", "Comments" : "Displegadennoù", + "Submit" : "Kinnig", "Created:" : "Krouet :", "Reply" : "Respont", "Update" : "Adnevesaat", diff --git a/l10n/br.json b/l10n/br.json index 5d21e2014f..2664981526 100644 --- a/l10n/br.json +++ b/l10n/br.json @@ -29,6 +29,7 @@ "Share from Files" : "Rannañ diouzh Restroù", "Download" : "Pellgargañ", "Comments" : "Displegadennoù", + "Submit" : "Kinnig", "Created:" : "Krouet :", "Reply" : "Respont", "Update" : "Adnevesaat", diff --git a/l10n/ca.js b/l10n/ca.js index bc3d9836ae..33e5308876 100644 --- a/l10n/ca.js +++ b/l10n/ca.js @@ -261,6 +261,7 @@ OC.L10N.register( "No comments yet. Begin the discussion!" : "No hi ha comentaris encara. Començar la discussió!", "The comment cannot be empty." : "El comentari no pot estar buit.", "The comment cannot be longer than 1000 characters." : "El comentari no pot ser més llarg que 1000 caràcters.", + "Submit" : "Envia", "Created:" : "Data de creació:", "In reply to" : "En resposta a", "Cancel reply" : "Cancel·la la resposta", diff --git a/l10n/ca.json b/l10n/ca.json index d2f65a5479..3fc0e68e4f 100644 --- a/l10n/ca.json +++ b/l10n/ca.json @@ -259,6 +259,7 @@ "No comments yet. Begin the discussion!" : "No hi ha comentaris encara. Començar la discussió!", "The comment cannot be empty." : "El comentari no pot estar buit.", "The comment cannot be longer than 1000 characters." : "El comentari no pot ser més llarg que 1000 caràcters.", + "Submit" : "Envia", "Created:" : "Data de creació:", "In reply to" : "En resposta a", "Cancel reply" : "Cancel·la la resposta", From c1e749a3639b9e43242929c2f16ce3fec338f210 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Apr 2026 02:11:28 +0000 Subject: [PATCH 011/190] Chore(deps-dev): Update behat/behat requirement in /tests/integration Updates the requirements on [behat/behat](https://github.com/Behat/Behat) to permit the latest version. - [Release notes](https://github.com/Behat/Behat/releases) - [Changelog](https://github.com/Behat/Behat/blob/3.x/CHANGELOG.md) - [Commits](https://github.com/Behat/Behat/compare/v3.30.0...v3.31.0) --- updated-dependencies: - dependency-name: behat/behat dependency-version: 3.31.0 dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- tests/integration/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/composer.json b/tests/integration/composer.json index 31ee7dc37a..384302a85d 100644 --- a/tests/integration/composer.json +++ b/tests/integration/composer.json @@ -1,7 +1,7 @@ { "require-dev": { "phpunit/phpunit": "~9", - "behat/behat": "~3.30.0", + "behat/behat": "~3.31.0", "guzzlehttp/guzzle": "7.9.2", "jarnaiz/behat-junit-formatter": "^1.3", "sabre/dav": "4.7.0", From e80f0499f8ee184ad8a493950148772a68c53452 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Apr 2026 02:18:08 +0000 Subject: [PATCH 012/190] Chore(deps): Bump actions/setup-node from 6.1.0 to 6.4.0 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.1.0 to 6.4.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v6.1.0...48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: 6.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/appstore-build-publish.yml | 2 +- .github/workflows/cypress-e2e.yml | 2 +- .github/workflows/lint-eslint.yml | 2 +- .github/workflows/lint-stylelint.yml | 2 +- .github/workflows/node.yml | 2 +- .github/workflows/npm-audit-fix.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/appstore-build-publish.yml b/.github/workflows/appstore-build-publish.yml index ff7181ae21..6f97963f60 100644 --- a/.github/workflows/appstore-build-publish.yml +++ b/.github/workflows/appstore-build-publish.yml @@ -71,7 +71,7 @@ jobs: - name: Set up node ${{ steps.versions.outputs.nodeVersion }} # Skip if no package.json if: ${{ steps.versions.outputs.nodeVersion }} - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: ${{ steps.versions.outputs.nodeVersion }} diff --git a/.github/workflows/cypress-e2e.yml b/.github/workflows/cypress-e2e.yml index 5f5b667c95..12db70aac6 100644 --- a/.github/workflows/cypress-e2e.yml +++ b/.github/workflows/cypress-e2e.yml @@ -42,7 +42,7 @@ jobs: steps: - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/lint-eslint.yml b/.github/workflows/lint-eslint.yml index f87467dce9..7343685465 100644 --- a/.github/workflows/lint-eslint.yml +++ b/.github/workflows/lint-eslint.yml @@ -68,7 +68,7 @@ jobs: fallbackNpm: '^11.3' - name: Set up node ${{ steps.versions.outputs.nodeVersion }} - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: ${{ steps.versions.outputs.nodeVersion }} diff --git a/.github/workflows/lint-stylelint.yml b/.github/workflows/lint-stylelint.yml index e39f07ac21..52544acbb9 100644 --- a/.github/workflows/lint-stylelint.yml +++ b/.github/workflows/lint-stylelint.yml @@ -37,7 +37,7 @@ jobs: fallbackNpm: '^11.3' - name: Set up node ${{ steps.versions.outputs.nodeVersion }} - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: ${{ steps.versions.outputs.nodeVersion }} diff --git a/.github/workflows/node.yml b/.github/workflows/node.yml index 69f43cbb5c..616d28eaa0 100644 --- a/.github/workflows/node.yml +++ b/.github/workflows/node.yml @@ -65,7 +65,7 @@ jobs: fallbackNpm: '^11.3' - name: Set up node ${{ steps.versions.outputs.nodeVersion }} - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: ${{ steps.versions.outputs.nodeVersion }} diff --git a/.github/workflows/npm-audit-fix.yml b/.github/workflows/npm-audit-fix.yml index d45c3a2641..3cf372a436 100644 --- a/.github/workflows/npm-audit-fix.yml +++ b/.github/workflows/npm-audit-fix.yml @@ -49,7 +49,7 @@ jobs: fallbackNpm: '^11.3' - name: Set up node ${{ steps.versions.outputs.nodeVersion }} - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: ${{ steps.versions.outputs.nodeVersion }} From 4b48d2453ff22fe8de356b3f0014b78e695a1ff8 Mon Sep 17 00:00:00 2001 From: Anna Larch Date: Sat, 25 Apr 2026 10:24:47 +0200 Subject: [PATCH 013/190] fix(comments): register event listener for typed comment events Since the typed comment events (CommentAddedEvent, CommentUpdatedEvent, etc.) were introduced in NC34, dispatchTyped() dispatches using the exact subclass name. Registering only for CommentsEvent::class means the listener never fires, so comment mentions in Deck cards never create notifications or activity entries. Update tests to use typed events directly, matching how Manager now dispatches them. AI-Assisted-By: Claude Sonnet 4.6 Signed-off-by: Anna Larch --- lib/AppInfo/Application.php | 10 ++++++++-- tests/integration/features/decks.feature | 2 +- tests/unit/Listeners/CommentEventListenerTest.php | 9 +++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 9a072988df..c4f58c9de2 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -60,7 +60,10 @@ use OCP\Collaboration\Resources\IProviderManager; use OCP\Collaboration\Resources\LoadAdditionalScriptsEvent; use OCP\Comments\CommentsEntityEvent; -use OCP\Comments\CommentsEvent; +use OCP\Comments\Events\BeforeCommentUpdatedEvent; +use OCP\Comments\Events\CommentAddedEvent; +use OCP\Comments\Events\CommentDeletedEvent; +use OCP\Comments\Events\CommentUpdatedEvent; use OCP\EventDispatcher\IEventDispatcher; use OCP\Federation\ICloudFederationProvider; use OCP\Federation\ICloudFederationProviderManager; @@ -155,7 +158,10 @@ public function register(IRegistrationContext $context): void { $context->registerEventListener(AclCreatedEvent::class, FullTextSearchEventListener::class); $context->registerEventListener(AclUpdatedEvent::class, FullTextSearchEventListener::class); $context->registerEventListener(AclDeletedEvent::class, FullTextSearchEventListener::class); - $context->registerEventListener(CommentsEvent::class, CommentEventListener::class); + $context->registerEventListener(CommentAddedEvent::class, CommentEventListener::class); + $context->registerEventListener(BeforeCommentUpdatedEvent::class, CommentEventListener::class); + $context->registerEventListener(CommentUpdatedEvent::class, CommentEventListener::class); + $context->registerEventListener(CommentDeletedEvent::class, CommentEventListener::class); // Handling cache invalidation for collections $context->registerEventListener(AclCreatedEvent::class, ResourceListener::class); diff --git a/tests/integration/features/decks.feature b/tests/integration/features/decks.feature index 8d29cf7532..60d5f6c118 100644 --- a/tests/integration/features/decks.feature +++ b/tests/integration/features/decks.feature @@ -127,7 +127,7 @@ Feature: decks And remember the last attachment as "my-attachment" And post a comment with content "My first comment" on the card When get the activities for the last card - Then the fetched activities should have 2 entries + Then the fetched activities should have 3 entries And delete the card When get the activities for the last card diff --git a/tests/unit/Listeners/CommentEventListenerTest.php b/tests/unit/Listeners/CommentEventListenerTest.php index 8183738dbd..62dd3f55e0 100644 --- a/tests/unit/Listeners/CommentEventListenerTest.php +++ b/tests/unit/Listeners/CommentEventListenerTest.php @@ -29,7 +29,8 @@ use OCA\Deck\Db\CardMapper; use OCA\Deck\Db\ChangeHelper; use OCA\Deck\Notification\NotificationHelper; -use OCP\Comments\CommentsEvent; +use OCP\Comments\Events\CommentAddedEvent; +use OCP\Comments\Events\CommentUpdatedEvent; use OCP\Comments\IComment; use PHPUnit\Framework\TestCase; @@ -68,7 +69,7 @@ public function testHandle() { $this->cardMapper->expects($this->once()) ->method('find') ->willReturn($card); - $commentsEvent = new CommentsEvent(CommentsEvent::EVENT_ADD, $comment); + $commentsEvent = new CommentAddedEvent($comment); $this->activityManager->expects($this->once()) ->method('triggerEvent') ->with(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_CARD_COMMENT_CREATE, ['comment' => $comment]); @@ -82,7 +83,7 @@ public function testHandleUpdate() { $comment = $this->createMock(IComment::class); $comment->expects($this->any())->method('getId')->willReturn(1); $comment->expects($this->any())->method('getObjectType')->willReturn('deckCard'); - $commentsEvent = new CommentsEvent(CommentsEvent::EVENT_UPDATE, $comment); + $commentsEvent = new CommentUpdatedEvent($comment); $this->activityManager->expects($this->never()) ->method('triggerEvent'); $this->notificationHelper->expects($this->once()) @@ -95,7 +96,7 @@ public function testHandleInvalid() { $comment = $this->createMock(IComment::class); $comment->expects($this->any())->method('getId')->willReturn(1); $comment->expects($this->any())->method('getObjectType')->willReturn('other'); - $commentsEvent = new CommentsEvent(CommentsEvent::EVENT_ADD, $comment); + $commentsEvent = new CommentAddedEvent($comment); $this->activityManager->expects($this->never()) ->method('triggerEvent'); $this->commentEventHandler->handle($commentsEvent); From c75f5415e2bdcd6115dbeb5c80f417112299bc20 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sun, 26 Apr 2026 00:37:26 +0000 Subject: [PATCH 014/190] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/de.js | 1 + l10n/de.json | 1 + l10n/de_DE.js | 1 + l10n/de_DE.json | 1 + l10n/en_GB.js | 1 + l10n/en_GB.json | 1 + l10n/pt_BR.js | 5 +++-- l10n/pt_BR.json | 5 +++-- l10n/ru.js | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ l10n/ru.json | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ l10n/zh_CN.js | 1 + l10n/zh_CN.json | 1 + l10n/zh_HK.js | 1 + l10n/zh_HK.json | 1 + 14 files changed, 116 insertions(+), 4 deletions(-) diff --git a/l10n/de.js b/l10n/de.js index 13235aad8c..5f3414f5ef 100644 --- a/l10n/de.js +++ b/l10n/de.js @@ -324,6 +324,7 @@ OC.L10N.register( "Edit card title" : "Kartentitel bearbeiten", "Open link" : "Link öffnen", "Card deleted" : "Karte gelöscht", + "Change card color" : "Kartenfarbe ändern", "Edit title" : "Titel bearbeiten", "Assign to me" : "Mir zuweisen", "Unassign myself" : "Nicht mehr mir zuweisen", diff --git a/l10n/de.json b/l10n/de.json index e81fd1421a..402764a264 100644 --- a/l10n/de.json +++ b/l10n/de.json @@ -322,6 +322,7 @@ "Edit card title" : "Kartentitel bearbeiten", "Open link" : "Link öffnen", "Card deleted" : "Karte gelöscht", + "Change card color" : "Kartenfarbe ändern", "Edit title" : "Titel bearbeiten", "Assign to me" : "Mir zuweisen", "Unassign myself" : "Nicht mehr mir zuweisen", diff --git a/l10n/de_DE.js b/l10n/de_DE.js index 3e4804d619..698906a5a9 100644 --- a/l10n/de_DE.js +++ b/l10n/de_DE.js @@ -324,6 +324,7 @@ OC.L10N.register( "Edit card title" : "Kartentitel bearbeiten", "Open link" : "Link öffnen", "Card deleted" : "Karte gelöscht", + "Change card color" : "Kartenfarbe ändern", "Edit title" : "Titel bearbeiten", "Assign to me" : "Mir zuweisen", "Unassign myself" : "Nicht mehr mir zuweisen", diff --git a/l10n/de_DE.json b/l10n/de_DE.json index d5f73441d6..9967d8d02f 100644 --- a/l10n/de_DE.json +++ b/l10n/de_DE.json @@ -322,6 +322,7 @@ "Edit card title" : "Kartentitel bearbeiten", "Open link" : "Link öffnen", "Card deleted" : "Karte gelöscht", + "Change card color" : "Kartenfarbe ändern", "Edit title" : "Titel bearbeiten", "Assign to me" : "Mir zuweisen", "Unassign myself" : "Nicht mehr mir zuweisen", diff --git a/l10n/en_GB.js b/l10n/en_GB.js index fffe63d5bf..f7757b0bfd 100644 --- a/l10n/en_GB.js +++ b/l10n/en_GB.js @@ -324,6 +324,7 @@ OC.L10N.register( "Edit card title" : "Edit card title", "Open link" : "Open link", "Card deleted" : "Card deleted", + "Change card color" : "Change card colour", "Edit title" : "Edit title", "Assign to me" : "Assign to me", "Unassign myself" : "Unassign myself", diff --git a/l10n/en_GB.json b/l10n/en_GB.json index 6b964eec80..445a10ecd7 100644 --- a/l10n/en_GB.json +++ b/l10n/en_GB.json @@ -322,6 +322,7 @@ "Edit card title" : "Edit card title", "Open link" : "Open link", "Card deleted" : "Card deleted", + "Change card color" : "Change card colour", "Edit title" : "Edit title", "Assign to me" : "Assign to me", "Unassign myself" : "Unassign myself", diff --git a/l10n/pt_BR.js b/l10n/pt_BR.js index 1601f6f20b..d6396a80f3 100644 --- a/l10n/pt_BR.js +++ b/l10n/pt_BR.js @@ -263,8 +263,8 @@ OC.L10N.register( "Remove attachment" : "Remover anexo", "Delete Attachment" : "Excluir Anexo", "Restore Attachment" : "Restaurar Anexo", - "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Modificado: ⸱{modifiedDate} Criado: {createdDate}", - "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Modificado: {modifiedDate}\nCriado: {createdDate}\nCriado por: {owner} ", + "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Modificado: ⸱{modifiedDate} ⸱ Criado: {createdDate}", + "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Modificado: {modifiedDate}\nCriado: {createdDate}\nCriado por: {owner}", "Modified: {modifiedDate}\nCreated: {createdDate}" : "Modificado: {modifiedDate}\nCriado: {createdDate}", "The title cannot be empty." : "O título não pode ficar em branco.", "Cannot close unsaved card!" : "Não é possível fechar um cartão não salvo!", @@ -324,6 +324,7 @@ OC.L10N.register( "Edit card title" : "Editar título do cartão", "Open link" : "Abrir link", "Card deleted" : "Cartão excluído", + "Change card color" : "Alterar cor do cartão", "Edit title" : "Editar título", "Assign to me" : "Atribuir a mim", "Unassign myself" : "Desatribuir-me", diff --git a/l10n/pt_BR.json b/l10n/pt_BR.json index 79f4903b51..d22e1b5ef9 100644 --- a/l10n/pt_BR.json +++ b/l10n/pt_BR.json @@ -261,8 +261,8 @@ "Remove attachment" : "Remover anexo", "Delete Attachment" : "Excluir Anexo", "Restore Attachment" : "Restaurar Anexo", - "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Modificado: ⸱{modifiedDate} Criado: {createdDate}", - "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Modificado: {modifiedDate}\nCriado: {createdDate}\nCriado por: {owner} ", + "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Modificado: ⸱{modifiedDate} ⸱ Criado: {createdDate}", + "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Modificado: {modifiedDate}\nCriado: {createdDate}\nCriado por: {owner}", "Modified: {modifiedDate}\nCreated: {createdDate}" : "Modificado: {modifiedDate}\nCriado: {createdDate}", "The title cannot be empty." : "O título não pode ficar em branco.", "Cannot close unsaved card!" : "Não é possível fechar um cartão não salvo!", @@ -322,6 +322,7 @@ "Edit card title" : "Editar título do cartão", "Open link" : "Abrir link", "Card deleted" : "Cartão excluído", + "Change card color" : "Alterar cor do cartão", "Edit title" : "Editar título", "Assign to me" : "Atribuir a mim", "Unassign myself" : "Desatribuir-me", diff --git a/l10n/ru.js b/l10n/ru.js index 3dff10dcd2..f73cb06920 100644 --- a/l10n/ru.js +++ b/l10n/ru.js @@ -81,17 +81,23 @@ OC.L10N.register( "Could not write file to disk" : "Невозможно записать файл на диск", "A PHP extension stopped the file upload" : "Загрузка файла была прервана модулем расширений PHP", "No file uploaded or file size exceeds maximum of %s" : "Файл не получен или его размер превышает %s", + "Invalid file type. Only JSON files are allowed." : "Неверный тип файла. Разрешены только файлы JSON.", + "Invalid JSON data" : "Неверные данные JSON", + "Failed to import board" : "Не удалось импортировать доску", "Cards due today" : "Завершающиеся сегодня", "Cards due tomorrow" : "Завершающиеся завтра", "Upcoming cards" : "Ожидающие выполнения", "Load more" : "Загрузить больше", + "Welcome to Nextcloud Deck!" : "Добро пожаловать в Nextcloud Deck!", "The card \"%s\" on \"%s\" has been assigned to you by %s." : "Вам назначена карточка «%s» с рабочей доски «%s» пользователем %s.", "{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} назначил Вам карточку {deck-card} из {deck-board}.", + "The card \"%1$s\" on \"%2$s\" has reached its due date." : "Срок оплаты карты \"%1$s\" на \"%2$s\" истёк.", "The card {deck-card} on {deck-board} has reached its due date." : "Сегодня дата исполнения по карточке {deck-card} в {deck-board}.", "%s has mentioned you in a comment on \"%s\"." : "Вы были упомянуты пользователем %s в комментарии «%s».", "{user} has mentioned you in a comment on {deck-card}." : "Вы были упомянуты пользователем {user} в комментарии {deck-card}.", "The board \"%s\" has been shared with you by %s." : "Вам предоставлен доступ к рабочей доске «%s» пользователем %s.", "{user} has shared {deck-board} with you." : "{user} предоставил(а) вам доступ к {deck-board}.", + "The remote board %1$s has been shared with you by %2$s" : "Удаленная доска %1$s была предоставлена ​​вам пользователем %2$s", "Deck board" : "Доска", "Owned by %1$s" : "Владелец: %1$s", "Deck boards, cards and comments" : "Доски, карточки и комментарии", @@ -106,13 +112,20 @@ OC.L10N.register( "Action needed" : "Требуется действие", "Later" : "Позже", "copy" : "Копировать", + "Read more inside" : "Подробнее читайте внутри", "Custom lists - click to rename!" : "Пользовательские списки — нажмите, чтобы переименовать!", "To Do" : "Задачи", "In Progress" : "Выполянется", "Done" : "Выполненные", + "1. Open to learn more about boards and cards" : "1. Откройте, чтобы узнать больше о досках и карточках.", + "2. Drag cards left and right, up and down" : "2. Перетаскивайте карточки влево и вправо, вверх и вниз.", + "3. Apply rich formatting and link content" : "3. Примените расширенное форматирование и свяжите контент", + "4. Share, comment and collaborate!" : "4. Делитесь, комментируйте и сотрудничайте!", + "Create your first card!" : "Создайте свою первую карту!", "This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Этот комментарий содержит более %s символов.\nКомментарий добавлен к карточке «%s» в виде вложения.\nПостоянный адрес этого комментария: %s.", "Attachments" : "Вложения", "File" : "Файл", + "date" : "дата", "Card not found" : "Карточка не найдена", "Path is already shared with this card" : "Этот путь уже опубликован в карточке", "Invalid date, date format must be YYYY-MM-DD" : "Некорректный формат даты, дата должна быть в формате YYYY-MM-DD", @@ -123,10 +136,12 @@ OC.L10N.register( "Select the board to link to a project" : "Выберите рабочую доску, чтобы связать с проектом", "Search by board title" : "Поиск по заголовкам досок", "Select board" : "Выбор рабочей доски", + "Move/copy card" : "Переместить/копировать карту", "Select a board" : "Выберите доску", "No lists available" : "Нет ни одного списка", "Select a list" : "Выберите список", "Move card" : "Переместить карточку", + "Copy card" : "Копировать карту", "Select the card to link to a project" : "Выберите карточку для связывания с проектом", "Link to card" : "Ссылка на карточку", "Select a card" : "Выберите карточку", @@ -176,6 +191,7 @@ OC.L10N.register( "Admin settings" : "Настройки администратора", "Limit board creation to some groups" : "Разрешить создавать доски только участниками определённых групп", "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Создание собственных рабочих досок пользователям, не входящим в заданные группы, будет заблокировано. Тем не менее такие пользователи смогут продолжить работать с общими досками, к которым у них есть доступ. ", + "Enable federation" : "Включить федерацию", "Board actions" : "Управление доской", "Scroll sideways" : "Боковая прокрутка", "Navigate between cards" : "Перемещение между карточками", @@ -221,6 +237,8 @@ OC.L10N.register( "Edit list title" : "Изменить название списка", "Archive all cards" : "Переместить все карточки в архив", "Unarchive all cards" : "Восстановить все карточки из архива", + "Do not set cards as \"done\"" : "Не устанавливать статус карточек как «выполнено»", + "Set cards as \"done\"" : "Установить статус карточек как «выполнено»", "Delete list" : "Удалить список", "Archive all cards in this list" : "Переместить в архив все карточки текущего списка", "Unarchive all cards in this list" : "Восстановить из архива все карточки списка", @@ -245,7 +263,11 @@ OC.L10N.register( "Remove attachment" : "Убрать вложение", "Delete Attachment" : "Удалить вложение", "Restore Attachment" : "Восстановить вложение", + "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Изменено: {modifiedDate} ⸱ Создано: {createdDate}", + "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Изменено: {modifiedDate}\nСоздано: {createdDate}\nСоздано: {owner}", + "Modified: {modifiedDate}\nCreated: {createdDate}" : "Изменено: {modifiedDate}\nСоздано: {createdDate}", "The title cannot be empty." : "Название не может быть пустым", + "Cannot close unsaved card!" : "Невозможно закрыть несохранённую карточку!", "Open in sidebar view" : "Открыть в боковой панели", "Open in bigger view" : "Открыть режиме подробного просмотра", "Comments" : "Комментарии", @@ -260,6 +282,8 @@ OC.L10N.register( "Reply" : "Ответить", "Update" : "Обновить", "Write a description …" : "Добавьте описание...", + "The description has been changed by another user." : "Описание изменено другим пользователем.", + "Could not save description" : "Не удалось сохранить описание", "Description" : "Описание", "(Unsaved)" : "(Не сохранен)", "(Saving…)" : "(Сохранение...)", @@ -287,6 +311,10 @@ OC.L10N.register( "Not done" : "Незавершённые", "Unarchive card" : "Восстановить из архива", "Archive card" : "Переместить в архив", + "Assign a start date to this card…" : "Назначьте этой карточке дату начала…", + "Set a start date" : "Установите дату начала", + "Add start date" : "Добавить дату начала", + "Remove start date" : "Удалить дату начала", "Assign a tag to this card…" : "Назначить метку этой карточке…", "Select or create a tag…" : "Выбрать или создать метку…", "Create a new tag:" : "Создать метку:", @@ -296,6 +324,7 @@ OC.L10N.register( "Edit card title" : "Изменить заголовок карточки", "Open link" : "Открыть ссылку", "Card deleted" : "Карточка удалена", + "Change card color" : "Изменить цвет карточки", "Edit title" : "Редактировать заголовок", "Assign to me" : "Назначить себе", "Unassign myself" : "Отказаться от назначения", @@ -314,7 +343,11 @@ OC.L10N.register( "An error occurred" : "Произошла ошибка", "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Подтвердите удаление доски «{title}»; это действие приведёт к удалению также все данных, принадлежащих этой доске, включая карточки в архиве.", "Delete the board?" : "Удалить доску?", + "Are you sure you want to leave the board {title}?" : "Вы уверены, что хотите покинуть доску {title}?", + "Leave the board?" : "Покинуть доску?", "Leave" : "Выйти", + "Failed to leave the board" : "Не удалось покинуть доску", + "Exporting board..." : "Экспорт доски...", "Board details" : "Свойства доски", "Edit board" : "Редактировать", "Clone board" : "Скопировать доску", @@ -323,16 +356,32 @@ OC.L10N.register( "Export board" : "Экспортировать доску", "Turn on due date reminders" : "Включить напоминания о сроке выполнения", "Turn off due date reminders" : "Отключить напоминания о сроке выполнения", + "Remove as default board" : "Удалить как доску по умолчанию", + "Set as default board" : "Установить как доску по умолчанию", "Due date reminders" : "Напоминания о сроке выполнения", "Assigned cards" : "Назначенные карточки", "No notifications" : "Без уведомлений", "Delete board" : "Удалить доску", + "Leave board" : "Покинуть доску", + "Importing board..." : "Импорт доски...", + "Board imported successfully" : "Доска успешно импортирована", + "Import board" : "Импортировать доску", + "Clone {boardTitle}" : "Клонировать {boardTitle}", "Clone cards" : "Скопировать карточку", + "Clone assignments" : "Клонировать задания", + "Clone labels" : "Клонировать метки", + "Clone due dates" : "Сроки выполнения клонирования", "Advanced options" : "Дополнительные настройки", + "Move all cards to the first list" : "Переместить все карточки в первый список", + "Restore archived cards" : "Восстановить заархивированные карты", "Clone" : "Скопировать", + "Export {boardTitle}" : "Экспортировать {boardTitle}", + "Export as JSON" : "Экспорт как JSON", "Export as CSV" : "Экспортировать в файл CSV", + "Note: Only the JSON format is supported for importing back into the Deck app." : "Примечание. Для обратного импорта в приложение Deck поддерживается только формат JSON.", "Export" : "Экспорт", "Loading filtered view" : "Выполняется отбор", + "Search for {searchQuery} in other boards" : "Искать {searchQuery} на других досках", "Search for {searchQuery} in all boards" : "Искать {searchQuery} на всех досках", "No results found" : "Результаты отсутствуют", "Deck board {name}\n* Last modified on {lastMod}" : "Доска «{name}»\n* Последнее изменение: {lastMod}", @@ -361,6 +410,7 @@ OC.L10N.register( "Something went wrong" : "Неизвестная ошибка", "Failed to upload {name}" : "Не удалось передать на сервер {name}", "Maximum file size of {size} exceeded" : "Превышен максимально разрешённый размер файла в {size}", + "Assigned users" : "Назначенные пользователи", "Due date" : "Дата исполнения", "Created" : "Создано", "Modified" : "Изменено", diff --git a/l10n/ru.json b/l10n/ru.json index f3e00efeeb..ea5e67c9bc 100644 --- a/l10n/ru.json +++ b/l10n/ru.json @@ -79,17 +79,23 @@ "Could not write file to disk" : "Невозможно записать файл на диск", "A PHP extension stopped the file upload" : "Загрузка файла была прервана модулем расширений PHP", "No file uploaded or file size exceeds maximum of %s" : "Файл не получен или его размер превышает %s", + "Invalid file type. Only JSON files are allowed." : "Неверный тип файла. Разрешены только файлы JSON.", + "Invalid JSON data" : "Неверные данные JSON", + "Failed to import board" : "Не удалось импортировать доску", "Cards due today" : "Завершающиеся сегодня", "Cards due tomorrow" : "Завершающиеся завтра", "Upcoming cards" : "Ожидающие выполнения", "Load more" : "Загрузить больше", + "Welcome to Nextcloud Deck!" : "Добро пожаловать в Nextcloud Deck!", "The card \"%s\" on \"%s\" has been assigned to you by %s." : "Вам назначена карточка «%s» с рабочей доски «%s» пользователем %s.", "{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} назначил Вам карточку {deck-card} из {deck-board}.", + "The card \"%1$s\" on \"%2$s\" has reached its due date." : "Срок оплаты карты \"%1$s\" на \"%2$s\" истёк.", "The card {deck-card} on {deck-board} has reached its due date." : "Сегодня дата исполнения по карточке {deck-card} в {deck-board}.", "%s has mentioned you in a comment on \"%s\"." : "Вы были упомянуты пользователем %s в комментарии «%s».", "{user} has mentioned you in a comment on {deck-card}." : "Вы были упомянуты пользователем {user} в комментарии {deck-card}.", "The board \"%s\" has been shared with you by %s." : "Вам предоставлен доступ к рабочей доске «%s» пользователем %s.", "{user} has shared {deck-board} with you." : "{user} предоставил(а) вам доступ к {deck-board}.", + "The remote board %1$s has been shared with you by %2$s" : "Удаленная доска %1$s была предоставлена ​​вам пользователем %2$s", "Deck board" : "Доска", "Owned by %1$s" : "Владелец: %1$s", "Deck boards, cards and comments" : "Доски, карточки и комментарии", @@ -104,13 +110,20 @@ "Action needed" : "Требуется действие", "Later" : "Позже", "copy" : "Копировать", + "Read more inside" : "Подробнее читайте внутри", "Custom lists - click to rename!" : "Пользовательские списки — нажмите, чтобы переименовать!", "To Do" : "Задачи", "In Progress" : "Выполянется", "Done" : "Выполненные", + "1. Open to learn more about boards and cards" : "1. Откройте, чтобы узнать больше о досках и карточках.", + "2. Drag cards left and right, up and down" : "2. Перетаскивайте карточки влево и вправо, вверх и вниз.", + "3. Apply rich formatting and link content" : "3. Примените расширенное форматирование и свяжите контент", + "4. Share, comment and collaborate!" : "4. Делитесь, комментируйте и сотрудничайте!", + "Create your first card!" : "Создайте свою первую карту!", "This comment has more than %s characters.\nAdded as an attachment to the card with name %s.\nAccessible on URL: %s." : "Этот комментарий содержит более %s символов.\nКомментарий добавлен к карточке «%s» в виде вложения.\nПостоянный адрес этого комментария: %s.", "Attachments" : "Вложения", "File" : "Файл", + "date" : "дата", "Card not found" : "Карточка не найдена", "Path is already shared with this card" : "Этот путь уже опубликован в карточке", "Invalid date, date format must be YYYY-MM-DD" : "Некорректный формат даты, дата должна быть в формате YYYY-MM-DD", @@ -121,10 +134,12 @@ "Select the board to link to a project" : "Выберите рабочую доску, чтобы связать с проектом", "Search by board title" : "Поиск по заголовкам досок", "Select board" : "Выбор рабочей доски", + "Move/copy card" : "Переместить/копировать карту", "Select a board" : "Выберите доску", "No lists available" : "Нет ни одного списка", "Select a list" : "Выберите список", "Move card" : "Переместить карточку", + "Copy card" : "Копировать карту", "Select the card to link to a project" : "Выберите карточку для связывания с проектом", "Link to card" : "Ссылка на карточку", "Select a card" : "Выберите карточку", @@ -174,6 +189,7 @@ "Admin settings" : "Настройки администратора", "Limit board creation to some groups" : "Разрешить создавать доски только участниками определённых групп", "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Создание собственных рабочих досок пользователям, не входящим в заданные группы, будет заблокировано. Тем не менее такие пользователи смогут продолжить работать с общими досками, к которым у них есть доступ. ", + "Enable federation" : "Включить федерацию", "Board actions" : "Управление доской", "Scroll sideways" : "Боковая прокрутка", "Navigate between cards" : "Перемещение между карточками", @@ -219,6 +235,8 @@ "Edit list title" : "Изменить название списка", "Archive all cards" : "Переместить все карточки в архив", "Unarchive all cards" : "Восстановить все карточки из архива", + "Do not set cards as \"done\"" : "Не устанавливать статус карточек как «выполнено»", + "Set cards as \"done\"" : "Установить статус карточек как «выполнено»", "Delete list" : "Удалить список", "Archive all cards in this list" : "Переместить в архив все карточки текущего списка", "Unarchive all cards in this list" : "Восстановить из архива все карточки списка", @@ -243,7 +261,11 @@ "Remove attachment" : "Убрать вложение", "Delete Attachment" : "Удалить вложение", "Restore Attachment" : "Восстановить вложение", + "Modified: {modifiedDate} ⸱ Created: {createdDate}" : "Изменено: {modifiedDate} ⸱ Создано: {createdDate}", + "Modified: {modifiedDate}\nCreated: {createdDate}\nCreated by: {owner}" : "Изменено: {modifiedDate}\nСоздано: {createdDate}\nСоздано: {owner}", + "Modified: {modifiedDate}\nCreated: {createdDate}" : "Изменено: {modifiedDate}\nСоздано: {createdDate}", "The title cannot be empty." : "Название не может быть пустым", + "Cannot close unsaved card!" : "Невозможно закрыть несохранённую карточку!", "Open in sidebar view" : "Открыть в боковой панели", "Open in bigger view" : "Открыть режиме подробного просмотра", "Comments" : "Комментарии", @@ -258,6 +280,8 @@ "Reply" : "Ответить", "Update" : "Обновить", "Write a description …" : "Добавьте описание...", + "The description has been changed by another user." : "Описание изменено другим пользователем.", + "Could not save description" : "Не удалось сохранить описание", "Description" : "Описание", "(Unsaved)" : "(Не сохранен)", "(Saving…)" : "(Сохранение...)", @@ -285,6 +309,10 @@ "Not done" : "Незавершённые", "Unarchive card" : "Восстановить из архива", "Archive card" : "Переместить в архив", + "Assign a start date to this card…" : "Назначьте этой карточке дату начала…", + "Set a start date" : "Установите дату начала", + "Add start date" : "Добавить дату начала", + "Remove start date" : "Удалить дату начала", "Assign a tag to this card…" : "Назначить метку этой карточке…", "Select or create a tag…" : "Выбрать или создать метку…", "Create a new tag:" : "Создать метку:", @@ -294,6 +322,7 @@ "Edit card title" : "Изменить заголовок карточки", "Open link" : "Открыть ссылку", "Card deleted" : "Карточка удалена", + "Change card color" : "Изменить цвет карточки", "Edit title" : "Редактировать заголовок", "Assign to me" : "Назначить себе", "Unassign myself" : "Отказаться от назначения", @@ -312,7 +341,11 @@ "An error occurred" : "Произошла ошибка", "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Подтвердите удаление доски «{title}»; это действие приведёт к удалению также все данных, принадлежащих этой доске, включая карточки в архиве.", "Delete the board?" : "Удалить доску?", + "Are you sure you want to leave the board {title}?" : "Вы уверены, что хотите покинуть доску {title}?", + "Leave the board?" : "Покинуть доску?", "Leave" : "Выйти", + "Failed to leave the board" : "Не удалось покинуть доску", + "Exporting board..." : "Экспорт доски...", "Board details" : "Свойства доски", "Edit board" : "Редактировать", "Clone board" : "Скопировать доску", @@ -321,16 +354,32 @@ "Export board" : "Экспортировать доску", "Turn on due date reminders" : "Включить напоминания о сроке выполнения", "Turn off due date reminders" : "Отключить напоминания о сроке выполнения", + "Remove as default board" : "Удалить как доску по умолчанию", + "Set as default board" : "Установить как доску по умолчанию", "Due date reminders" : "Напоминания о сроке выполнения", "Assigned cards" : "Назначенные карточки", "No notifications" : "Без уведомлений", "Delete board" : "Удалить доску", + "Leave board" : "Покинуть доску", + "Importing board..." : "Импорт доски...", + "Board imported successfully" : "Доска успешно импортирована", + "Import board" : "Импортировать доску", + "Clone {boardTitle}" : "Клонировать {boardTitle}", "Clone cards" : "Скопировать карточку", + "Clone assignments" : "Клонировать задания", + "Clone labels" : "Клонировать метки", + "Clone due dates" : "Сроки выполнения клонирования", "Advanced options" : "Дополнительные настройки", + "Move all cards to the first list" : "Переместить все карточки в первый список", + "Restore archived cards" : "Восстановить заархивированные карты", "Clone" : "Скопировать", + "Export {boardTitle}" : "Экспортировать {boardTitle}", + "Export as JSON" : "Экспорт как JSON", "Export as CSV" : "Экспортировать в файл CSV", + "Note: Only the JSON format is supported for importing back into the Deck app." : "Примечание. Для обратного импорта в приложение Deck поддерживается только формат JSON.", "Export" : "Экспорт", "Loading filtered view" : "Выполняется отбор", + "Search for {searchQuery} in other boards" : "Искать {searchQuery} на других досках", "Search for {searchQuery} in all boards" : "Искать {searchQuery} на всех досках", "No results found" : "Результаты отсутствуют", "Deck board {name}\n* Last modified on {lastMod}" : "Доска «{name}»\n* Последнее изменение: {lastMod}", @@ -359,6 +408,7 @@ "Something went wrong" : "Неизвестная ошибка", "Failed to upload {name}" : "Не удалось передать на сервер {name}", "Maximum file size of {size} exceeded" : "Превышен максимально разрешённый размер файла в {size}", + "Assigned users" : "Назначенные пользователи", "Due date" : "Дата исполнения", "Created" : "Создано", "Modified" : "Изменено", diff --git a/l10n/zh_CN.js b/l10n/zh_CN.js index 796cc5a6f1..6ee48faf09 100644 --- a/l10n/zh_CN.js +++ b/l10n/zh_CN.js @@ -324,6 +324,7 @@ OC.L10N.register( "Edit card title" : "编辑卡片标题", "Open link" : "打开链接", "Card deleted" : "卡片被删除", + "Change card color" : "更改卡片颜色", "Edit title" : "编辑标题", "Assign to me" : "指派给我", "Unassign myself" : "不再指派给我", diff --git a/l10n/zh_CN.json b/l10n/zh_CN.json index 6737578681..918af593fc 100644 --- a/l10n/zh_CN.json +++ b/l10n/zh_CN.json @@ -322,6 +322,7 @@ "Edit card title" : "编辑卡片标题", "Open link" : "打开链接", "Card deleted" : "卡片被删除", + "Change card color" : "更改卡片颜色", "Edit title" : "编辑标题", "Assign to me" : "指派给我", "Unassign myself" : "不再指派给我", diff --git a/l10n/zh_HK.js b/l10n/zh_HK.js index d73338e052..c41f3048cb 100644 --- a/l10n/zh_HK.js +++ b/l10n/zh_HK.js @@ -324,6 +324,7 @@ OC.L10N.register( "Edit card title" : "編輯卡片標題", "Open link" : "打開連結", "Card deleted" : "卡片被刪除", + "Change card color" : "更新卡片顏色", "Edit title" : "編輯標題", "Assign to me" : "指派給我", "Unassign myself" : "自己解除指派", diff --git a/l10n/zh_HK.json b/l10n/zh_HK.json index 810d8e8301..01b338837b 100644 --- a/l10n/zh_HK.json +++ b/l10n/zh_HK.json @@ -322,6 +322,7 @@ "Edit card title" : "編輯卡片標題", "Open link" : "打開連結", "Card deleted" : "卡片被刪除", + "Change card color" : "更新卡片顏色", "Edit title" : "編輯標題", "Assign to me" : "指派給我", "Unassign myself" : "自己解除指派", From 9eed51937d38cab88482557cbd83686ca097b9a6 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Mon, 27 Apr 2026 00:37:00 +0000 Subject: [PATCH 015/190] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/et_EE.js | 9 +++++---- l10n/et_EE.json | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/l10n/et_EE.js b/l10n/et_EE.js index 3d4245f47a..e8c410b5f9 100644 --- a/l10n/et_EE.js +++ b/l10n/et_EE.js @@ -146,7 +146,7 @@ OC.L10N.register( "Link to card" : "Lisa link kaardile", "Select a card" : "Vali kaart", "Cancel" : "Katkesta", - "This board is read only" : "See tahvle on vaid loetav", + "This board is read only" : "See tahvel on vaid loetav", "Drop your files to upload" : "Üleslaadimiseks lohista failid siia", "File already exists" : "Fail on juba olemas", "A file with the name {filename} already exists." : "„{filename}“ nimega fail on juba olemas.", @@ -215,7 +215,7 @@ OC.L10N.register( "Tags" : "Sildid", "Deleted items" : "Kustutatud kirjed", "Activity" : "Tegevus", - "Deleted lists" : "Kustutatud loendis", + "Deleted lists" : "Kustutatud loendid", "Undo" : "Tühista", "Deleted cards" : "Kustutatud kaart", "Failed to create share with {displayName}" : "Jagamine ei õnnestunud: {displayName}", @@ -324,6 +324,7 @@ OC.L10N.register( "Edit card title" : "Muuda kaardi pealkirja", "Open link" : "Ava link", "Card deleted" : "Kaart on kustutatud", + "Change card color" : "Muuda kaardi värvi", "Edit title" : "Muuda pealkirja", "Assign to me" : "Anna täitmiseks mulle", "Unassign myself" : "Võta endalt see ülesanne ära", @@ -341,7 +342,7 @@ OC.L10N.register( "No reminder" : "Meeldetuletust pole", "An error occurred" : "Tekkis viga", "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Kas oled kindel, et soovid „{title}“ tahvli kustutada. Sellega saavad kustutatud kõik selle tahvli andmed, sealhulgas arhiveeritud kaardid.", - "Delete the board?" : "Kas kustutame selle tahvli?", + "Delete the board?" : "Kas kustutad selle tahvli?", "Are you sure you want to leave the board {title}?" : "Kas sa oled kindel, et soovid „{title}“ tahvlilt lahkuda?", "Leave the board?" : "Kas lahkud tahvlilt?", "Leave" : "Lahku", @@ -406,7 +407,7 @@ OC.L10N.register( "Link to a card" : "Lisa link kaardile", "Create a card" : "Koosta kaart", "Message from {author} in {conversationName}" : "Sõnum kasutajalt „{author}“ „{conversationName}“ vestluses", - "Something went wrong" : "Midagi läks valesti", + "Something went wrong" : "Vaat kus lops, midagi läks valesti", "Failed to upload {name}" : "„{name}“ üleslaadimine ei õnnestunud", "Maximum file size of {size} exceeded" : "Failide maksimaalne lubatud suurus {size} on ületatud", "Assigned users" : "Ülesannetega kasutajad", diff --git a/l10n/et_EE.json b/l10n/et_EE.json index 7a697fcc9a..2d4eb999ca 100644 --- a/l10n/et_EE.json +++ b/l10n/et_EE.json @@ -144,7 +144,7 @@ "Link to card" : "Lisa link kaardile", "Select a card" : "Vali kaart", "Cancel" : "Katkesta", - "This board is read only" : "See tahvle on vaid loetav", + "This board is read only" : "See tahvel on vaid loetav", "Drop your files to upload" : "Üleslaadimiseks lohista failid siia", "File already exists" : "Fail on juba olemas", "A file with the name {filename} already exists." : "„{filename}“ nimega fail on juba olemas.", @@ -213,7 +213,7 @@ "Tags" : "Sildid", "Deleted items" : "Kustutatud kirjed", "Activity" : "Tegevus", - "Deleted lists" : "Kustutatud loendis", + "Deleted lists" : "Kustutatud loendid", "Undo" : "Tühista", "Deleted cards" : "Kustutatud kaart", "Failed to create share with {displayName}" : "Jagamine ei õnnestunud: {displayName}", @@ -322,6 +322,7 @@ "Edit card title" : "Muuda kaardi pealkirja", "Open link" : "Ava link", "Card deleted" : "Kaart on kustutatud", + "Change card color" : "Muuda kaardi värvi", "Edit title" : "Muuda pealkirja", "Assign to me" : "Anna täitmiseks mulle", "Unassign myself" : "Võta endalt see ülesanne ära", @@ -339,7 +340,7 @@ "No reminder" : "Meeldetuletust pole", "An error occurred" : "Tekkis viga", "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Kas oled kindel, et soovid „{title}“ tahvli kustutada. Sellega saavad kustutatud kõik selle tahvli andmed, sealhulgas arhiveeritud kaardid.", - "Delete the board?" : "Kas kustutame selle tahvli?", + "Delete the board?" : "Kas kustutad selle tahvli?", "Are you sure you want to leave the board {title}?" : "Kas sa oled kindel, et soovid „{title}“ tahvlilt lahkuda?", "Leave the board?" : "Kas lahkud tahvlilt?", "Leave" : "Lahku", @@ -404,7 +405,7 @@ "Link to a card" : "Lisa link kaardile", "Create a card" : "Koosta kaart", "Message from {author} in {conversationName}" : "Sõnum kasutajalt „{author}“ „{conversationName}“ vestluses", - "Something went wrong" : "Midagi läks valesti", + "Something went wrong" : "Vaat kus lops, midagi läks valesti", "Failed to upload {name}" : "„{name}“ üleslaadimine ei õnnestunud", "Maximum file size of {size} exceeded" : "Failide maksimaalne lubatud suurus {size} on ületatud", "Assigned users" : "Ülesannetega kasutajad", From e344f6ece2792618da2737a3ee7b8dae7f9b2c5f Mon Sep 17 00:00:00 2001 From: samin-z Date: Mon, 20 Apr 2026 17:29:34 +0200 Subject: [PATCH 016/190] add deck to user migration Signed-off-by: samin-z --- lib/AppInfo/Application.php | 3 + lib/Service/Importer/BoardImportService.php | 11 + .../Importer/Systems/DeckJsonService.php | 112 ++++++- .../ShareFileAttachmentExportService.php | 75 +++++ lib/UserMigration/DeckMigrator.php | 287 ++++++++++++++++++ lib/UserMigration/DeckMigratorException.php | 15 + tests/unit/UserMigration/DeckMigratorTest.php | 155 ++++++++++ 7 files changed, 653 insertions(+), 5 deletions(-) create mode 100644 lib/Service/ShareFileAttachmentExportService.php create mode 100644 lib/UserMigration/DeckMigrator.php create mode 100644 lib/UserMigration/DeckMigratorException.php create mode 100644 tests/unit/UserMigration/DeckMigratorTest.php diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 9a072988df..05811543b3 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -50,6 +50,7 @@ use OCA\Deck\Sharing\DeckShareProvider; use OCA\Deck\Sharing\Listener; use OCA\Deck\Teams\DeckTeamResourceProvider; +use OCA\Deck\UserMigration\DeckMigrator; use OCA\Text\Event\LoadEditor; use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; @@ -180,6 +181,8 @@ public function register(IRegistrationContext $context): void { $context->registerEventListener(LoadAdditionalScriptsEvent::class, ResourceAdditionalScriptsListener::class); $context->registerTeamResourceProvider(DeckTeamResourceProvider::class); + + $context->registerUserMigrator(DeckMigrator::class); } public function registerCommentsEntity(IEventDispatcher $eventDispatcher): void { diff --git a/lib/Service/Importer/BoardImportService.php b/lib/Service/Importer/BoardImportService.php index b47f011db8..453e4f0030 100644 --- a/lib/Service/Importer/BoardImportService.php +++ b/lib/Service/Importer/BoardImportService.php @@ -321,9 +321,20 @@ public function assignCardsToLabels(): void { public function importComments(): void { $allComments = $this->getImportSystem()->getComments(); + $sourceToImportedCommentId = []; foreach ($allComments as $cardId => $comments) { foreach ($comments as $commentId => $comment) { + $metaData = $comment->getMetaData() ?? []; + $sourceParentId = (string)($metaData['deckImportParentId'] ?? '0'); + if ($sourceParentId !== '0' && isset($sourceToImportedCommentId[$sourceParentId])) { + $comment->setParentId($sourceToImportedCommentId[$sourceParentId]); + } else { + $comment->setParentId('0'); + } + $this->insertComment((int)$cardId, $comment); + $sourceId = (string)($metaData['deckImportSourceId'] ?? $commentId); + $sourceToImportedCommentId[$sourceId] = $comment->getId(); $this->getImportSystem()->updateComment((int)$cardId, $commentId, $comment); } } diff --git a/lib/Service/Importer/Systems/DeckJsonService.php b/lib/Service/Importer/Systems/DeckJsonService.php index b378cae8da..01c9efa38d 100644 --- a/lib/Service/Importer/Systems/DeckJsonService.php +++ b/lib/Service/Importer/Systems/DeckJsonService.php @@ -11,12 +11,14 @@ use OCA\Deck\BadRequestException; use OCA\Deck\Db\Acl; use OCA\Deck\Db\Assignment; +use OCA\Deck\Db\Attachment; use OCA\Deck\Db\Board; use OCA\Deck\Db\Card; use OCA\Deck\Db\Label; use OCA\Deck\Db\Stack; use OCA\Deck\Service\Importer\ABoardImportService; use OCP\Comments\IComment; +use OCP\Comments\ICommentsManager; use OCP\IUser; use OCP\IUserManager; @@ -108,21 +110,121 @@ public function getCardAssignments(): array { public function getComments(): array { $comments = []; foreach ($this->tmpCards as $sourceCard) { + $this->importAttachments($sourceCard); + if (!property_exists($sourceCard, 'comments')) { continue; } $commentsOriginal = $sourceCard->comments; + $pending = []; foreach ($commentsOriginal as $commentOriginal) { - $comment = new Comment(); - $comment->setActor($commentOriginal->actorType, $commentOriginal->actorId) - ->setMessage($commentOriginal->message)->setCreationDateTime(\DateTime::createFromFormat('Y-m-d\TH:i:sP', $commentOriginal->creationDateTime)); - $comments[$this->cards[$sourceCard->id]->getId()][$commentOriginal->id] = $comment; + $pending[(string)$commentOriginal->id] = $commentOriginal; + } + + $ordered = []; + while (!empty($pending)) { + $progress = false; + foreach ($pending as $commentId => $commentOriginal) { + $parentId = (string)($commentOriginal->parentId ?? '0'); + if ($parentId === '0' || isset($ordered[$parentId])) { + [$actorType, $actorId] = $this->resolveCommentActor($commentOriginal); + $comment = new Comment(); + $comment->setActor($actorType, $actorId) + ->setParentId($parentId) + ->setMessage($commentOriginal->message) + ->setCreationDateTime(\DateTime::createFromFormat('Y-m-d\TH:i:sP', $commentOriginal->creationDateTime)); + $comment->setMetaData([ + 'deckImportSourceId' => (string)$commentId, + 'deckImportParentId' => $parentId, + ]); + $ordered[$commentId] = $comment; + unset($pending[$commentId]); + $progress = true; + } + } + + if (!$progress) { + foreach ($pending as $commentId => $commentOriginal) { + [$actorType, $actorId] = $this->resolveCommentActor($commentOriginal); + $comment = new Comment(); + $comment->setActor($actorType, $actorId) + ->setParentId('0') + ->setMessage($commentOriginal->message) + ->setCreationDateTime(\DateTime::createFromFormat('Y-m-d\TH:i:sP', $commentOriginal->creationDateTime)); + $comment->setMetaData([ + 'deckImportSourceId' => (string)$commentId, + 'deckImportParentId' => '0', + ]); + $ordered[$commentId] = $comment; + } + $pending = []; + } + } + + foreach ($ordered as $commentId => $comment) { + $comments[$this->cards[$sourceCard->id]->getId()][$commentId] = $comment; } } /** @var array> */ return $comments; } + /** + * @return array{0: string, 1: string} + */ + private function resolveCommentActor(\stdClass $commentOriginal): array { + $actorType = (string)($commentOriginal->actorType ?? 'users'); + $actorId = $commentOriginal->actorId ?? null; + + if (!is_string($actorId) || $actorId === '') { + return [ICommentsManager::DELETED_USER, ICommentsManager::DELETED_USER]; + } + + if ($actorType === 'users' && !$this->userManager->userExists($actorId)) { + return [ICommentsManager::DELETED_USER, ICommentsManager::DELETED_USER]; + } + + return [$actorType, $actorId]; + } + + private function importAttachments(\stdClass $sourceCard): void { + if (!property_exists($sourceCard, 'attachments') || !isset($this->cards[$sourceCard->id])) { + return; + } + + $targetCardId = $this->cards[$sourceCard->id]->getId(); + foreach ($sourceCard->attachments as $sourceAttachment) { + if (($sourceAttachment->type ?? null) !== 'deck_file') { + continue; + } + if (!isset($sourceAttachment->data) || !isset($sourceAttachment->contentBase64)) { + continue; + } + + $attachment = new Attachment(); + $attachment->setCardId($targetCardId); + $attachment->setType('deck_file'); + $attachment->setData((string)$sourceAttachment->data); + $attachment->setCreatedBy( + $this->mapMember($sourceAttachment->createdBy ?? $this->getImportService()->getData()->owner) + ?? $this->mapOwner($this->getImportService()->getData()->owner) + ); + $attachment->setCreatedAt((int)($sourceAttachment->createdAt ?? time())); + $attachment->setLastModified((int)($sourceAttachment->lastModified ?? time())); + + $content = base64_decode((string)$sourceAttachment->contentBase64, true); + if ($content === false) { + continue; + } + + try { + $this->getImportService()->insertAttachment($attachment, $content); + } catch (\Throwable $e) { + continue; + } + } + } + public function getCardLabelAssignment(): array { $cardsLabels = []; foreach ($this->tmpCards as $sourceCard) { @@ -184,7 +286,7 @@ public function getStacks(): array { if (isset($source->cards)) { foreach ($source->cards as $card) { - $card->stackId = $index; + $card->stackId = $source->id; $this->tmpCards[] = $card; } } diff --git a/lib/Service/ShareFileAttachmentExportService.php b/lib/Service/ShareFileAttachmentExportService.php new file mode 100644 index 0000000000..92a293cb6f --- /dev/null +++ b/lib/Service/ShareFileAttachmentExportService.php @@ -0,0 +1,75 @@ +> + */ + public function exportCardAttachments(int $cardId, string $fallbackUserId): array { + $formattedAttachments = []; + foreach ($this->getShareFileAttachments($cardId) as $share) { + $shareAttachment = $this->serializeShareAttachment($share, $fallbackUserId); + if ($shareAttachment !== null) { + $formattedAttachments[] = $shareAttachment; + } + } + + return $formattedAttachments; + } + + /** + * @return array> + */ + private function getShareFileAttachments(int $cardId): array { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->select('id', 'uid_owner', 'uid_initiator', 'file_source', 'stime') + ->from('share') + ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(12))) + ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter((string)$cardId))) + ->andWhere($qb->expr()->eq('item_type', $qb->createNamedParameter('file'))); + return $qb->executeQuery()->fetchAllAssociative(); + } + + /** + * @param array $share + * + * @return array|null + */ + private function serializeShareAttachment(array $share, string $fallbackUserId): ?array { + try { + $nodes = $this->rootFolder->getById((int)$share['file_source']); + $node = $nodes[0] ?? null; + if ($node === null || !method_exists($node, 'getContent') || !method_exists($node, 'getName')) { + return null; + } + + return [ + 'type' => 'deck_file', + 'data' => (string)$node->getName(), + 'createdBy' => (string)($share['uid_initiator'] ?? $share['uid_owner'] ?? $fallbackUserId), + 'createdAt' => (int)($share['stime'] ?? time()), + 'lastModified' => method_exists($node, 'getMTime') ? (int)$node->getMTime() : (int)($share['stime'] ?? time()), + 'contentBase64' => base64_encode($node->getContent()), + ]; + } catch (\Throwable $e) { + return null; + } + } +} diff --git a/lib/UserMigration/DeckMigrator.php b/lib/UserMigration/DeckMigrator.php new file mode 100644 index 0000000000..61c48067cb --- /dev/null +++ b/lib/UserMigration/DeckMigrator.php @@ -0,0 +1,287 @@ +getUID(); + + try { + $exportData = $this->buildExportData($uid); + $jsonData = json_encode($exportData, self::JSON_OPTIONS); + + $exportDestination->addFileContents( + self::FILE_BOARDS, + $jsonData + ); + } catch (\Throwable $e) { + throw new DeckMigratorException($e->getMessage(), 0, $e); + } + } + + /** + * {@inheritDoc} + */ + public function import( + IUser $user, + IImportSource $importSource, + OutputInterface $output, + ): void { + if (!$this->shouldImport($importSource)) { + return; + } + + try { + $data = $this->readImportData($importSource); + if (empty($data['boards'])) { + return; + } + $this->configureImportService($user->getUID(), $data); + $this->boardImportService->import(); + } catch (\Throwable $e) { + throw new DeckMigratorException($e->getMessage(), 0, $e); + } + } + + private function buildExportData(string $uid): array { + $boards = $this->boardMapper->findAllByUser($uid); + $exportData = ['boards' => []]; + + foreach ($boards as $board) { + $exportData['boards'][] = $this->serializeBoard($board, $uid); + } + + return $exportData; + } + + private function serializeBoard(object $board, string $uid): array { + $boardId = $board->getId(); + $board->setLabels($this->labelMapper->findAll($boardId)); + $board->setAcl($this->aclMapper->findAll($boardId)); + + $stacksById = $this->getBoardStacksById($boardId); + $this->attachSerializedCardsToStacks($stacksById, $uid); + $board->setStacks($stacksById); + + return $board->jsonSerialize(); + } + + private function getBoardStacksById(int $boardId): array { + $stacksById = []; + foreach ($this->stackMapper->findAll($boardId) as $stack) { + $stacksById[$stack->getId()] = $stack; + } + return $stacksById; + } + + private function attachSerializedCardsToStacks(array &$stacksById, string $uid): void { + $stackIds = array_map(static fn($stack) => $stack->getId(), $stacksById); + if (empty($stackIds)) { + return; + } + + $allCardsByStack = $this->cardMapper->findAllForStacks($stackIds); + $archivedCardsByStack = $this->cardMapper->findAllArchivedForStacks($stackIds); + + foreach ($stacksById as $stackId => $stack) { + $stackCards = array_merge( + $allCardsByStack[$stackId] ?? [], + $archivedCardsByStack[$stackId] ?? [] + ); + $serializedCards = []; + foreach ($stackCards as $card) { + $serializedCards[] = $this->serializeCard($card, $uid); + } + $stack->setCards($serializedCards); + } + } + + private function serializeCard(object $card, string $uid): array { + $cardId = $card->getId(); + $card->setLabels($this->labelMapper->findAssignedLabelsForCard($cardId)); + + $cardData = $card->jsonSerialize(); + $cardData['labels'] = $cardData['labels'] ?? []; + $cardData['comments'] = $this->serializeCardComments($cardId); + $cardData['attachments'] = $this->serializeCardAttachments($cardId, $uid); + + return $cardData; + } + + private function serializeCardComments(int $cardId): array { + $comments = iterator_to_array($this->commentsManager->getForObject( + Application::COMMENT_ENTITY_TYPE, + (string)$cardId + )); + usort($comments, static function ($firstComment, $secondComment): int { + return ((int)$firstComment->getId()) <=> ((int)$secondComment->getId()); + }); + + $formattedComments = []; + foreach ($comments as $comment) { + $formattedComments[] = [ + 'id' => $comment->getId(), + 'parentId' => $comment->getParentId(), + 'actorType' => $comment->getActorType(), + 'actorId' => $comment->getActorId(), + 'message' => $comment->getMessage(), + 'creationDateTime' => $comment->getCreationDateTime()->format(\DateTime::ATOM), + 'objectType' => $comment->getObjectType(), + 'objectId' => $comment->getObjectId(), + 'verb' => $comment->getVerb(), + ]; + } + + return $formattedComments; + } + + private function serializeCardAttachments(int $cardId, string $uid): array { + $formattedAttachments = []; + foreach ($this->attachmentMapper->findAll($cardId) as $attachment) { + $formattedAttachments[] = $this->serializeDeckFileAttachment($attachment, $cardId); + } + + foreach ($this->getShareFileAttachments($cardId, $uid) as $share) { + $formattedAttachments[] = $share; + } + + return $formattedAttachments; + } + + private function serializeDeckFileAttachment(object $attachment, int $cardId): array { + $attachmentData = $attachment->jsonSerialize(); + if (($attachmentData['type'] ?? null) === 'deck_file') { + try { + $folder = $this->appData->getFolder('file-card-' . $cardId); + $file = $folder->getFile((string)$attachment->getData()); + $attachmentData['contentBase64'] = base64_encode($file->getContent()); + } catch (\Throwable $e) { + } + } + return $attachmentData; + } + + private function getShareFileAttachments(int $cardId, string $uid): array { + return $this->shareFileAttachmentExportService->exportCardAttachments($cardId, $uid); + } + + private function shouldImport(IImportSource $importSource): bool { + return $importSource->getMigratorVersion($this->getId()) !== null; + } + + private function readImportData(IImportSource $importSource): array { + $fileContents = $importSource->getFileContents(self::FILE_BOARDS); + $data = json_decode( + $fileContents, + true, + self::JSON_DEPTH, + self::JSON_OPTIONS + ); + + if ($data === null) { + throw new \Exception('Failed to parse JSON: ' . json_last_error_msg()); + } + + return $data; + } + + private function configureImportService(string $userId, array $data): void { + $this->boardImportService->setSystem('DeckJson'); + $this->boardImportService->setConfigInstance((object)[ + 'owner' => $userId, + 'uidRelation' => new \stdClass(), + ]); + $this->boardImportService->setData(json_decode( + json_encode(['boards' => $data['boards']]), + false, + self::JSON_DEPTH, + self::JSON_OPTIONS + )); + } + + /** + * {@inheritDoc} + */ + public function getId(): string { + return 'deck'; + } + + /** + * {@inheritDoc} + */ + public function getDisplayName(): string { + return $this->l10n->t('Deck'); + } + + /** + * {@inheritDoc} + */ + public function getDescription(): string { + return $this->l10n->t('All boards owned by you including stacks, cards, labels, assignments, and comments'); + } +} diff --git a/lib/UserMigration/DeckMigratorException.php b/lib/UserMigration/DeckMigratorException.php new file mode 100644 index 0000000000..1cc1c7d6a4 --- /dev/null +++ b/lib/UserMigration/DeckMigratorException.php @@ -0,0 +1,15 @@ +boardMapper = $this->createMock(BoardMapper::class); + $this->stackMapper = $this->createMock(StackMapper::class); + $this->cardMapper = $this->createMock(CardMapper::class); + $this->labelMapper = $this->createMock(LabelMapper::class); + $this->aclMapper = $this->createMock(AclMapper::class); + $this->attachmentMapper = $this->createMock(AttachmentMapper::class); + $this->commentsManager = $this->createMock(ICommentsManager::class); + $this->appData = $this->createMock(IAppData::class); + $this->shareFileAttachmentExportService = $this->createMock(ShareFileAttachmentExportService::class); + $this->boardService = $this->createMock(BoardService::class); + $this->boardImportService = $this->createMock(BoardImportService::class); + + $this->migrator = new DeckMigrator( + $this->createMock(IL10N::class), + $this->boardMapper, + $this->stackMapper, + $this->cardMapper, + $this->labelMapper, + $this->aclMapper, + $this->attachmentMapper, + $this->commentsManager, + $this->appData, + $this->shareFileAttachmentExportService, + $this->boardService, + $this->boardImportService, + ); + } + + public function testExportWritesBoardsJson(): void { + $user = $this->createMock(IUser::class); + $user->method('getUID')->willReturn('admin'); + + $board = $this->createMock(Board::class); + $board->method('getId')->willReturn(42); + $board->method('jsonSerialize')->willReturn(['id' => 42, 'title' => 'Board A', 'stacks' => []]); + + $this->boardMapper->expects($this->once()) + ->method('findAllByUser') + ->with('admin') + ->willReturn([$board]); + $this->labelMapper->expects($this->once())->method('findAll')->with(42)->willReturn([]); + $this->aclMapper->expects($this->once())->method('findAll')->with(42)->willReturn([]); + $this->stackMapper->expects($this->once())->method('findAll')->with(42)->willReturn([]); + $board->expects($this->once())->method('setLabels')->with([]); + $board->expects($this->once())->method('setAcl')->with([]); + $board->expects($this->once())->method('setStacks')->with([]); + + $destination = $this->createMock(IExportDestination::class); + $destination->expects($this->once()) + ->method('addFileContents') + ->with( + 'boards.json', + $this->callback(static function (string $json): bool { + $decoded = json_decode($json, true); + return is_array($decoded) && isset($decoded['boards']) && count($decoded['boards']) === 1; + }) + ); + + $this->migrator->export($user, $destination, $this->createMock(OutputInterface::class)); + } + + public function testImportSkipsWhenNoVersion(): void { + $source = $this->createMock(IImportSource::class); + $source->method('getMigratorVersion')->with('deck')->willReturn(null); + + $this->boardImportService->expects($this->never())->method('import'); + + $this->migrator->import( + $this->createMock(IUser::class), + $source, + $this->createMock(OutputInterface::class), + ); + } + + public function testImportConfiguresServiceAndImports(): void { + $user = $this->createMock(IUser::class); + $user->method('getUID')->willReturn('alice'); + + $source = $this->createMock(IImportSource::class); + $source->method('getMigratorVersion')->with('deck')->willReturn('1'); + $source->method('getFileContents')->with('boards.json')->willReturn('{"boards":[{"id":1,"title":"Board A","stacks":[]}]}'); + + $this->boardImportService->expects($this->once())->method('setSystem')->with('DeckJson'); + $this->boardImportService->expects($this->once()) + ->method('setConfigInstance') + ->with($this->callback(static function (\stdClass $config): bool { + return isset($config->owner, $config->uidRelation) && $config->owner === 'alice'; + })); + $this->boardImportService->expects($this->once()) + ->method('setData') + ->with($this->callback(static function (\stdClass $data): bool { + return isset($data->boards) && is_array($data->boards) && count($data->boards) === 1; + })); + $this->boardImportService->expects($this->once())->method('import'); + + $this->migrator->import($user, $source, $this->createMock(OutputInterface::class)); + } +} From b6a25e1d4e246dcd35c71b2311495673d8a99d77 Mon Sep 17 00:00:00 2001 From: samin-z Date: Tue, 21 Apr 2026 11:23:40 +0200 Subject: [PATCH 017/190] move importattachment / pipeline fixes Signed-off-by: samin-z --- lib/Service/Importer/ABoardImportService.php | 2 ++ lib/Service/Importer/BoardImportService.php | 1 + lib/Service/Importer/Systems/DeckJsonService.php | 14 +++++++++----- lib/Service/Importer/Systems/TrelloJsonService.php | 3 +++ lib/Service/ShareFileAttachmentExportService.php | 2 +- lib/UserMigration/DeckMigrator.php | 8 ++++---- tests/unit/UserMigration/DeckMigratorTest.php | 11 ++++------- 7 files changed, 24 insertions(+), 17 deletions(-) diff --git a/lib/Service/Importer/ABoardImportService.php b/lib/Service/Importer/ABoardImportService.php index 7726f707f4..b0b1576d6e 100644 --- a/lib/Service/Importer/ABoardImportService.php +++ b/lib/Service/Importer/ABoardImportService.php @@ -74,6 +74,8 @@ abstract public function getCardLabelAssignment(): array; */ abstract public function getComments(): array; + abstract public function importAttachments(): void; + /** @return Label[] */ abstract public function getLabels(): array; diff --git a/lib/Service/Importer/BoardImportService.php b/lib/Service/Importer/BoardImportService.php index 453e4f0030..5646308041 100644 --- a/lib/Service/Importer/BoardImportService.php +++ b/lib/Service/Importer/BoardImportService.php @@ -125,6 +125,7 @@ public function import(): void { $this->importLabels(); $this->importStacks(); $this->importCards(); + $this->getImportSystem()->importAttachments(); $this->assignCardsToLabels(); $this->importComments(); $this->importCardAssignments(); diff --git a/lib/Service/Importer/Systems/DeckJsonService.php b/lib/Service/Importer/Systems/DeckJsonService.php index 01c9efa38d..0c6ef85746 100644 --- a/lib/Service/Importer/Systems/DeckJsonService.php +++ b/lib/Service/Importer/Systems/DeckJsonService.php @@ -110,8 +110,6 @@ public function getCardAssignments(): array { public function getComments(): array { $comments = []; foreach ($this->tmpCards as $sourceCard) { - $this->importAttachments($sourceCard); - if (!property_exists($sourceCard, 'comments')) { continue; } @@ -134,7 +132,7 @@ public function getComments(): array { ->setMessage($commentOriginal->message) ->setCreationDateTime(\DateTime::createFromFormat('Y-m-d\TH:i:sP', $commentOriginal->creationDateTime)); $comment->setMetaData([ - 'deckImportSourceId' => (string)$commentId, + 'deckImportSourceId' => $commentId, 'deckImportParentId' => $parentId, ]); $ordered[$commentId] = $comment; @@ -152,7 +150,7 @@ public function getComments(): array { ->setMessage($commentOriginal->message) ->setCreationDateTime(\DateTime::createFromFormat('Y-m-d\TH:i:sP', $commentOriginal->creationDateTime)); $comment->setMetaData([ - 'deckImportSourceId' => (string)$commentId, + 'deckImportSourceId' => $commentId, 'deckImportParentId' => '0', ]); $ordered[$commentId] = $comment; @@ -169,6 +167,12 @@ public function getComments(): array { return $comments; } + public function importAttachments(): void { + foreach ($this->tmpCards as $sourceCard) { + $this->importAttachmentsForCard($sourceCard); + } + } + /** * @return array{0: string, 1: string} */ @@ -187,7 +191,7 @@ private function resolveCommentActor(\stdClass $commentOriginal): array { return [$actorType, $actorId]; } - private function importAttachments(\stdClass $sourceCard): void { + private function importAttachmentsForCard(\stdClass $sourceCard): void { if (!property_exists($sourceCard, 'attachments') || !isset($this->cards[$sourceCard->id])) { return; } diff --git a/lib/Service/Importer/Systems/TrelloJsonService.php b/lib/Service/Importer/Systems/TrelloJsonService.php index 142ad242ff..88cd5e930a 100644 --- a/lib/Service/Importer/Systems/TrelloJsonService.php +++ b/lib/Service/Importer/Systems/TrelloJsonService.php @@ -163,6 +163,9 @@ function (\stdClass $a) use ($trelloCard) { return $comments; } + public function importAttachments(): void { + } + private function sortComments(array $comments): array { $comparison = function (\stdClass $a, \stdClass $b): int { if ($a->date === $b->date) { diff --git a/lib/Service/ShareFileAttachmentExportService.php b/lib/Service/ShareFileAttachmentExportService.php index 92a293cb6f..6fe3c4dda8 100644 --- a/lib/Service/ShareFileAttachmentExportService.php +++ b/lib/Service/ShareFileAttachmentExportService.php @@ -49,7 +49,7 @@ private function getShareFileAttachments(int $cardId): array { /** * @param array $share - * + * * @return array|null */ private function serializeShareAttachment(array $share, string $fallbackUserId): ?array { diff --git a/lib/UserMigration/DeckMigrator.php b/lib/UserMigration/DeckMigrator.php index 61c48067cb..0107389898 100644 --- a/lib/UserMigration/DeckMigrator.php +++ b/lib/UserMigration/DeckMigrator.php @@ -10,12 +10,12 @@ namespace OCA\Deck\UserMigration; use OCA\Deck\AppInfo\Application; +use OCA\Deck\Db\AclMapper; +use OCA\Deck\Db\AttachmentMapper; use OCA\Deck\Db\BoardMapper; +use OCA\Deck\Db\CardMapper; use OCA\Deck\Db\LabelMapper; use OCA\Deck\Db\StackMapper; -use OCA\Deck\Db\CardMapper; -use OCA\Deck\Db\AclMapper; -use OCA\Deck\Db\AttachmentMapper; use OCA\Deck\Service\BoardService; use OCA\Deck\Service\Importer\BoardImportService; use OCA\Deck\Service\ShareFileAttachmentExportService; @@ -140,7 +140,7 @@ private function getBoardStacksById(int $boardId): array { } private function attachSerializedCardsToStacks(array &$stacksById, string $uid): void { - $stackIds = array_map(static fn($stack) => $stack->getId(), $stacksById); + $stackIds = array_map(static fn ($stack) => $stack->getId(), $stacksById); if (empty($stackIds)) { return; } diff --git a/tests/unit/UserMigration/DeckMigratorTest.php b/tests/unit/UserMigration/DeckMigratorTest.php index 4c09bd4a63..00f1b26b35 100644 --- a/tests/unit/UserMigration/DeckMigratorTest.php +++ b/tests/unit/UserMigration/DeckMigratorTest.php @@ -87,9 +87,9 @@ public function testExportWritesBoardsJson(): void { $user = $this->createMock(IUser::class); $user->method('getUID')->willReturn('admin'); - $board = $this->createMock(Board::class); - $board->method('getId')->willReturn(42); - $board->method('jsonSerialize')->willReturn(['id' => 42, 'title' => 'Board A', 'stacks' => []]); + $board = new Board(); + $board->setId(42); + $board->setTitle('Board A'); $this->boardMapper->expects($this->once()) ->method('findAllByUser') @@ -98,9 +98,6 @@ public function testExportWritesBoardsJson(): void { $this->labelMapper->expects($this->once())->method('findAll')->with(42)->willReturn([]); $this->aclMapper->expects($this->once())->method('findAll')->with(42)->willReturn([]); $this->stackMapper->expects($this->once())->method('findAll')->with(42)->willReturn([]); - $board->expects($this->once())->method('setLabels')->with([]); - $board->expects($this->once())->method('setAcl')->with([]); - $board->expects($this->once())->method('setStacks')->with([]); $destination = $this->createMock(IExportDestination::class); $destination->expects($this->once()) @@ -134,7 +131,7 @@ public function testImportConfiguresServiceAndImports(): void { $user->method('getUID')->willReturn('alice'); $source = $this->createMock(IImportSource::class); - $source->method('getMigratorVersion')->with('deck')->willReturn('1'); + $source->method('getMigratorVersion')->with('deck')->willReturn(1); $source->method('getFileContents')->with('boards.json')->willReturn('{"boards":[{"id":1,"title":"Board A","stacks":[]}]}'); $this->boardImportService->expects($this->once())->method('setSystem')->with('DeckJson'); From f5c02dfa7687354fdc001cd6d91f04d219359518 Mon Sep 17 00:00:00 2001 From: samin-z Date: Fri, 24 Apr 2026 10:25:27 +0200 Subject: [PATCH 018/190] update attachment and comments Signed-off-by: samin-z --- lib/Service/AttachmentService.php | 27 ++++++ lib/Service/FilesAppService.php | 93 +++++++++++++++++++ lib/Service/Importer/BoardImportService.php | 30 +++--- .../Importer/Systems/DeckJsonService.php | 79 ++++++---------- .../ShareFileAttachmentExportService.php | 2 +- lib/UserMigration/DeckMigrator.php | 36 +------ 6 files changed, 167 insertions(+), 100 deletions(-) diff --git a/lib/Service/AttachmentService.php b/lib/Service/AttachmentService.php index 671c0b156b..85c691d8dd 100644 --- a/lib/Service/AttachmentService.php +++ b/lib/Service/AttachmentService.php @@ -203,6 +203,33 @@ public function create(int $cardId, string $type, string $data = '') { return $attachment; } + /** + * Import helper: create or reuse a file-type attachment and sync related metadata/activity. + * + * @param Attachment $attachment + * @param string $content + * @return Attachment + */ + public function createFileAttachmentFromImport(Attachment $attachment, string $content): Attachment { + $cardId = $attachment->getCardId(); + $this->attachmentCacheHelper->clearAttachmentCount($cardId); + + $attachment->setType('file'); + $attachment->setLastModified(time()); + $attachment->setCreatedAt(time()); + + /** @var FilesAppService $fileService */ + $fileService = $this->getService('file'); + $fileService->createFromImport($attachment, $content); + $fileService->extendData($attachment); + $this->addCreator($attachment); + + $this->changeHelper->cardChanged($cardId); + $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $attachment, ActivityManager::SUBJECT_ATTACHMENT_CREATE); + + return $attachment; + } + /** * Display the attachment diff --git a/lib/Service/FilesAppService.php b/lib/Service/FilesAppService.php index 1ccf47d14c..27d4820c85 100644 --- a/lib/Service/FilesAppService.php +++ b/lib/Service/FilesAppService.php @@ -31,6 +31,7 @@ use OCP\IPreview; use OCP\IRequest; use OCP\Share\Exceptions\ShareNotFound; +use OCP\Share\Exceptions\GenericShareException; use OCP\Share\IManager; use OCP\Share\IShare; use Psr\Log\LoggerInterface; @@ -238,6 +239,98 @@ public function create(Attachment $attachment) { return $attachment; } + /** + * Ensure the file exists in the owner’s Deck attachment folder, link it to the + * Reuse file/share when already present + * + * @param Attachment $attachment + * @param string $content + * @return Attachment + * @throws BadRequestException + * @throws NoPermissionException + * @throws NotFoundException + * @throws StatusException + */ + public function createFromImport(Attachment $attachment, string $content): Attachment { + $fileName = $attachment->getData(); + $this->validateFilename($fileName); + + $ownerId = $attachment->getCreatedBy() ?: $this->userId; + if (!is_string($ownerId) || $ownerId === '') { + throw new StatusException('Could not resolve owner for imported attachment'); + } + + $userFolder = $this->rootFolder->getUserFolder($ownerId); + $attachmentFolderName = $this->configService->getAttachmentFolder($ownerId); + try { + $folder = $userFolder->get($attachmentFolderName); + } catch (NotFoundException) { + $folder = $userFolder->newFolder($attachmentFolderName); + } + if (!$folder instanceof Folder || $folder->isShared()) { + throw new NotFoundException('No target folder found'); + } + + if ($folder->nodeExists($fileName)) { + $node = $folder->get($fileName); + if (!($node instanceof File)) { + throw new StatusException('Attachment target is not a file'); + } + $target = $node; + } else { + $target = $folder->newFile($fileName); + $target->putContent($content); + } + + $cardId = $attachment->getCardId(); + foreach ($this->shareProvider->getSharesByPath($target) as $share) { + if ((int)$share->getSharedWith() === $cardId) { + $attachment->setId((int)$share->getId()); + $attachment->setData($target->getName()); + return $attachment; + } + } + + $this->permissionService->checkPermission( + $this->cardMapper, + $cardId, + Acl::PERMISSION_EDIT, + $ownerId, + true, + true + ); + // Import usually runs in background jobs without request user context. + // Set the actor explicitly so DeckShareProvider permission checks evaluate correctly. + $this->permissionService->setUserId($ownerId); + + $share = $this->shareManager->newShare(); + $share->setNode($target); + $share->setShareType(IShare::TYPE_DECK); + $share->setSharedWith((string)$cardId); + $share->setPermissions(Constants::PERMISSION_READ); + $share->setSharedBy($ownerId); + $share->setShareOwner($ownerId); + + try { + $share = $this->shareManager->createShare($share); + } catch (GenericShareException) { + $share = null; + foreach ($this->shareProvider->getSharesByPath($target) as $existing) { + if ((int)$existing->getSharedWith() === $cardId) { + $share = $existing; + break; + } + } + if ($share === null) { + throw new StatusException('Could not create deck share for imported attachment'); + } + } + + $attachment->setId((int)$share->getId()); + $attachment->setData($target->getName()); + return $attachment; + } + /** * @return array * @throws StatusException diff --git a/lib/Service/Importer/BoardImportService.php b/lib/Service/Importer/BoardImportService.php index 5646308041..1cc1242d37 100644 --- a/lib/Service/Importer/BoardImportService.php +++ b/lib/Service/Importer/BoardImportService.php @@ -23,7 +23,7 @@ use OCA\Deck\Event\BoardImportGetAllowedEvent; use OCA\Deck\Exceptions\ConflictException; use OCA\Deck\NotFoundException; -use OCA\Deck\Service\FileService; +use OCA\Deck\Service\AttachmentService; use OCA\Deck\Service\Importer\Systems\DeckJsonService; use OCA\Deck\Service\Importer\Systems\TrelloApiService; use OCA\Deck\Service\Importer\Systems\TrelloJsonService; @@ -320,13 +320,18 @@ public function assignCardsToLabels(): void { } } + /** + * Insert parsed comments by card and remap parent IDs from source to imported comments. + * + * @return void + */ public function importComments(): void { - $allComments = $this->getImportSystem()->getComments(); + $commentsByCard = $this->getImportSystem()->getComments(); $sourceToImportedCommentId = []; - foreach ($allComments as $cardId => $comments) { + foreach ($commentsByCard as $cardId => $comments) { foreach ($comments as $commentId => $comment) { $metaData = $comment->getMetaData() ?? []; - $sourceParentId = (string)($metaData['deckImportParentId'] ?? '0'); + $sourceParentId = $comment->getParentId(); if ($sourceParentId !== '0' && isset($sourceToImportedCommentId[$sourceParentId])) { $comment->setParentId($sourceToImportedCommentId[$sourceParentId]); } else { @@ -381,21 +386,8 @@ public function importCardAssignments(): void { } public function insertAttachment(Attachment $attachment, string $content): Attachment { - $service = Server::get(FileService::class); - $folder = $service->getFolder($attachment); - - if ($folder->fileExists($attachment->getData())) { - $attachment = $this->attachmentMapper->findByData($attachment->getCardId(), $attachment->getData()); - throw new ConflictException('File already exists.', $attachment); - } - - $target = $folder->newFile($attachment->getData()); - $target->putContent($content); - - $attachment = $this->attachmentMapper->insert($attachment); - - $service->extendData($attachment); - return $attachment; + $attachmentService = Server::get(AttachmentService::class); + return $attachmentService->createFileAttachmentFromImport($attachment, $content); } public function setData(\stdClass $data): void { diff --git a/lib/Service/Importer/Systems/DeckJsonService.php b/lib/Service/Importer/Systems/DeckJsonService.php index 0c6ef85746..894b231de1 100644 --- a/lib/Service/Importer/Systems/DeckJsonService.php +++ b/lib/Service/Importer/Systems/DeckJsonService.php @@ -19,6 +19,7 @@ use OCA\Deck\Service\Importer\ABoardImportService; use OCP\Comments\IComment; use OCP\Comments\ICommentsManager; +use OCP\Server; use OCP\IUser; use OCP\IUserManager; @@ -96,6 +97,9 @@ public function mapOwner(string $uid): string { public function getCardAssignments(): array { $assignments = []; foreach ($this->tmpCards as $sourceCard) { + if (!property_exists($sourceCard, 'assignedUsers') || !is_iterable($sourceCard->assignedUsers)) { + continue; + } foreach ($sourceCard->assignedUsers as $idMember) { $assignment = new Assignment(); $assignment->setCardId($this->cards[$sourceCard->id]->getId()); @@ -107,60 +111,37 @@ public function getCardAssignments(): array { return $assignments; } + /** + * Parse comments from source cards and return them as an array of comments by card ID. + * + */ public function getComments(): array { $comments = []; foreach ($this->tmpCards as $sourceCard) { - if (!property_exists($sourceCard, 'comments')) { + if (!property_exists($sourceCard, 'comments') || !isset($this->cards[$sourceCard->id])) { continue; } - $commentsOriginal = $sourceCard->comments; - $pending = []; - foreach ($commentsOriginal as $commentOriginal) { - $pending[(string)$commentOriginal->id] = $commentOriginal; + $targetCardId = $this->cards[$sourceCard->id]->getId(); + if (!is_iterable($sourceCard->comments)) { + continue; } - - $ordered = []; - while (!empty($pending)) { - $progress = false; - foreach ($pending as $commentId => $commentOriginal) { - $parentId = (string)($commentOriginal->parentId ?? '0'); - if ($parentId === '0' || isset($ordered[$parentId])) { - [$actorType, $actorId] = $this->resolveCommentActor($commentOriginal); - $comment = new Comment(); - $comment->setActor($actorType, $actorId) - ->setParentId($parentId) - ->setMessage($commentOriginal->message) - ->setCreationDateTime(\DateTime::createFromFormat('Y-m-d\TH:i:sP', $commentOriginal->creationDateTime)); - $comment->setMetaData([ - 'deckImportSourceId' => $commentId, - 'deckImportParentId' => $parentId, - ]); - $ordered[$commentId] = $comment; - unset($pending[$commentId]); - $progress = true; - } + foreach ($sourceCard->comments as $commentOriginal) { + $commentId = (string)($commentOriginal->id ?? ''); + if ($commentId === '') { + continue; } - - if (!$progress) { - foreach ($pending as $commentId => $commentOriginal) { - [$actorType, $actorId] = $this->resolveCommentActor($commentOriginal); - $comment = new Comment(); - $comment->setActor($actorType, $actorId) - ->setParentId('0') - ->setMessage($commentOriginal->message) - ->setCreationDateTime(\DateTime::createFromFormat('Y-m-d\TH:i:sP', $commentOriginal->creationDateTime)); - $comment->setMetaData([ - 'deckImportSourceId' => $commentId, - 'deckImportParentId' => '0', - ]); - $ordered[$commentId] = $comment; - } - $pending = []; - } - } - - foreach ($ordered as $commentId => $comment) { - $comments[$this->cards[$sourceCard->id]->getId()][$commentId] = $comment; + $parentId = (string)($commentOriginal->parentId ?? '0'); + [$actorType, $actorId] = $this->resolveCommentActor($commentOriginal); + $comment = new Comment(); + $comment->setActor($actorType, $actorId) + ->setParentId($parentId) + ->setMessage($commentOriginal->message) + ->setCreationDateTime(\DateTime::createFromFormat('Y-m-d\TH:i:sP', $commentOriginal->creationDateTime)); + $comment->setMetaData([ + 'deckImportSourceId' => $commentId, + 'deckImportParentId' => $parentId, + ]); + $comments[$targetCardId][$commentId] = $comment; } } /** @var array> */ @@ -198,7 +179,7 @@ private function importAttachmentsForCard(\stdClass $sourceCard): void { $targetCardId = $this->cards[$sourceCard->id]->getId(); foreach ($sourceCard->attachments as $sourceAttachment) { - if (($sourceAttachment->type ?? null) !== 'deck_file') { + if (($sourceAttachment->type ?? null) !== 'file') { continue; } if (!isset($sourceAttachment->data) || !isset($sourceAttachment->contentBase64)) { @@ -207,7 +188,7 @@ private function importAttachmentsForCard(\stdClass $sourceCard): void { $attachment = new Attachment(); $attachment->setCardId($targetCardId); - $attachment->setType('deck_file'); + $attachment->setType('file'); $attachment->setData((string)$sourceAttachment->data); $attachment->setCreatedBy( $this->mapMember($sourceAttachment->createdBy ?? $this->getImportService()->getData()->owner) diff --git a/lib/Service/ShareFileAttachmentExportService.php b/lib/Service/ShareFileAttachmentExportService.php index 6fe3c4dda8..2c68a39da1 100644 --- a/lib/Service/ShareFileAttachmentExportService.php +++ b/lib/Service/ShareFileAttachmentExportService.php @@ -61,7 +61,7 @@ private function serializeShareAttachment(array $share, string $fallbackUserId): } return [ - 'type' => 'deck_file', + 'type' => 'file', 'data' => (string)$node->getName(), 'createdBy' => (string)($share['uid_initiator'] ?? $share['uid_owner'] ?? $fallbackUserId), 'createdAt' => (int)($share['stime'] ?? time()), diff --git a/lib/UserMigration/DeckMigrator.php b/lib/UserMigration/DeckMigrator.php index 0107389898..741aca1c5c 100644 --- a/lib/UserMigration/DeckMigrator.php +++ b/lib/UserMigration/DeckMigrator.php @@ -11,6 +11,7 @@ use OCA\Deck\AppInfo\Application; use OCA\Deck\Db\AclMapper; +use OCA\Deck\Db\AssignmentMapper; use OCA\Deck\Db\AttachmentMapper; use OCA\Deck\Db\BoardMapper; use OCA\Deck\Db\CardMapper; @@ -45,6 +46,7 @@ public function __construct( protected CardMapper $cardMapper, protected LabelMapper $labelMapper, protected AclMapper $aclMapper, + protected AssignmentMapper $assignmentMapper, protected AttachmentMapper $attachmentMapper, protected ICommentsManager $commentsManager, protected IAppData $appData, @@ -164,11 +166,13 @@ private function attachSerializedCardsToStacks(array &$stacksById, string $uid): private function serializeCard(object $card, string $uid): array { $cardId = $card->getId(); $card->setLabels($this->labelMapper->findAssignedLabelsForCard($cardId)); + $card->setAssignedUsers($this->assignmentMapper->findAll($cardId)); $cardData = $card->jsonSerialize(); $cardData['labels'] = $cardData['labels'] ?? []; + $cardData['assignedUsers'] = $cardData['assignedUsers'] ?? []; $cardData['comments'] = $this->serializeCardComments($cardId); - $cardData['attachments'] = $this->serializeCardAttachments($cardId, $uid); + $cardData['attachments'] = $this->shareFileAttachmentExportService->exportCardAttachments($cardId, $uid); return $cardData; } @@ -200,36 +204,6 @@ private function serializeCardComments(int $cardId): array { return $formattedComments; } - private function serializeCardAttachments(int $cardId, string $uid): array { - $formattedAttachments = []; - foreach ($this->attachmentMapper->findAll($cardId) as $attachment) { - $formattedAttachments[] = $this->serializeDeckFileAttachment($attachment, $cardId); - } - - foreach ($this->getShareFileAttachments($cardId, $uid) as $share) { - $formattedAttachments[] = $share; - } - - return $formattedAttachments; - } - - private function serializeDeckFileAttachment(object $attachment, int $cardId): array { - $attachmentData = $attachment->jsonSerialize(); - if (($attachmentData['type'] ?? null) === 'deck_file') { - try { - $folder = $this->appData->getFolder('file-card-' . $cardId); - $file = $folder->getFile((string)$attachment->getData()); - $attachmentData['contentBase64'] = base64_encode($file->getContent()); - } catch (\Throwable $e) { - } - } - return $attachmentData; - } - - private function getShareFileAttachments(int $cardId, string $uid): array { - return $this->shareFileAttachmentExportService->exportCardAttachments($cardId, $uid); - } - private function shouldImport(IImportSource $importSource): bool { return $importSource->getMigratorVersion($this->getId()) !== null; } From ca2bec792a8351dd34141a4839b4c6f88e929a62 Mon Sep 17 00:00:00 2001 From: samin-z Date: Fri, 24 Apr 2026 10:50:12 +0200 Subject: [PATCH 019/190] list and DeckMigrator test fixes Signed-off-by: samin-z --- lib/Service/FilesAppService.php | 4 ++-- lib/Service/Importer/Systems/DeckJsonService.php | 3 +-- tests/unit/UserMigration/DeckMigratorTest.php | 5 +++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/Service/FilesAppService.php b/lib/Service/FilesAppService.php index 27d4820c85..f11054dc30 100644 --- a/lib/Service/FilesAppService.php +++ b/lib/Service/FilesAppService.php @@ -30,8 +30,8 @@ use OCP\IL10N; use OCP\IPreview; use OCP\IRequest; -use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\Exceptions\GenericShareException; +use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager; use OCP\Share\IShare; use Psr\Log\LoggerInterface; @@ -242,7 +242,7 @@ public function create(Attachment $attachment) { /** * Ensure the file exists in the owner’s Deck attachment folder, link it to the * Reuse file/share when already present - * + * * @param Attachment $attachment * @param string $content * @return Attachment diff --git a/lib/Service/Importer/Systems/DeckJsonService.php b/lib/Service/Importer/Systems/DeckJsonService.php index 894b231de1..606b96197f 100644 --- a/lib/Service/Importer/Systems/DeckJsonService.php +++ b/lib/Service/Importer/Systems/DeckJsonService.php @@ -19,7 +19,6 @@ use OCA\Deck\Service\Importer\ABoardImportService; use OCP\Comments\IComment; use OCP\Comments\ICommentsManager; -use OCP\Server; use OCP\IUser; use OCP\IUserManager; @@ -114,7 +113,7 @@ public function getCardAssignments(): array { /** * Parse comments from source cards and return them as an array of comments by card ID. * - */ + */ public function getComments(): array { $comments = []; foreach ($this->tmpCards as $sourceCard) { diff --git a/tests/unit/UserMigration/DeckMigratorTest.php b/tests/unit/UserMigration/DeckMigratorTest.php index 00f1b26b35..fa8874e499 100644 --- a/tests/unit/UserMigration/DeckMigratorTest.php +++ b/tests/unit/UserMigration/DeckMigratorTest.php @@ -10,6 +10,7 @@ namespace OCA\Deck\UserMigration; use OCA\Deck\Db\AclMapper; +use OCA\Deck\Db\AssignmentMapper; use OCA\Deck\Db\AttachmentMapper; use OCA\Deck\Db\Board; use OCA\Deck\Db\BoardMapper; @@ -40,6 +41,8 @@ class DeckMigratorTest extends TestCase { private $labelMapper; /** @var AclMapper|MockObject */ private $aclMapper; + /** @var AssignmentMapper|MockObject */ + private $assignmentMapper; /** @var AttachmentMapper|MockObject */ private $attachmentMapper; /** @var ICommentsManager|MockObject */ @@ -60,6 +63,7 @@ public function setUp(): void { $this->cardMapper = $this->createMock(CardMapper::class); $this->labelMapper = $this->createMock(LabelMapper::class); $this->aclMapper = $this->createMock(AclMapper::class); + $this->assignmentMapper = $this->createMock(AssignmentMapper::class); $this->attachmentMapper = $this->createMock(AttachmentMapper::class); $this->commentsManager = $this->createMock(ICommentsManager::class); $this->appData = $this->createMock(IAppData::class); @@ -74,6 +78,7 @@ public function setUp(): void { $this->cardMapper, $this->labelMapper, $this->aclMapper, + $this->assignmentMapper, $this->attachmentMapper, $this->commentsManager, $this->appData, From 5e524ab562fd755e2c6e1752d944fc535c7603c3 Mon Sep 17 00:00:00 2001 From: samin-z Date: Fri, 24 Apr 2026 16:34:32 +0200 Subject: [PATCH 020/190] small improvement and moving AttachmentService logic Signed-off-by: samin-z --- lib/Service/AttachmentService.php | 19 ++--------------- lib/Service/Importer/BoardImportService.php | 21 ++++++++++++------- .../Importer/Systems/DeckJsonService.php | 4 ++-- .../Importer/BoardImportServiceTest.php | 5 +++++ 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/lib/Service/AttachmentService.php b/lib/Service/AttachmentService.php index 85c691d8dd..bcf0bc8eae 100644 --- a/lib/Service/AttachmentService.php +++ b/lib/Service/AttachmentService.php @@ -204,33 +204,18 @@ public function create(int $cardId, string $type, string $data = '') { } /** - * Import helper: create or reuse a file-type attachment and sync related metadata/activity. - * - * @param Attachment $attachment - * @param string $content - * @return Attachment + * Apply import side effects to keep attachment behavior consistent with regular create flow. */ - public function createFileAttachmentFromImport(Attachment $attachment, string $content): Attachment { + public function syncAttachmentCreateSideEffects(Attachment $attachment): Attachment { $cardId = $attachment->getCardId(); $this->attachmentCacheHelper->clearAttachmentCount($cardId); - - $attachment->setType('file'); - $attachment->setLastModified(time()); - $attachment->setCreatedAt(time()); - - /** @var FilesAppService $fileService */ - $fileService = $this->getService('file'); - $fileService->createFromImport($attachment, $content); - $fileService->extendData($attachment); $this->addCreator($attachment); - $this->changeHelper->cardChanged($cardId); $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $attachment, ActivityManager::SUBJECT_ATTACHMENT_CREATE); return $attachment; } - /** * Display the attachment * diff --git a/lib/Service/Importer/BoardImportService.php b/lib/Service/Importer/BoardImportService.php index 1cc1242d37..2bb17dee55 100644 --- a/lib/Service/Importer/BoardImportService.php +++ b/lib/Service/Importer/BoardImportService.php @@ -24,6 +24,7 @@ use OCA\Deck\Exceptions\ConflictException; use OCA\Deck\NotFoundException; use OCA\Deck\Service\AttachmentService; +use OCA\Deck\Service\FilesAppService; use OCA\Deck\Service\Importer\Systems\DeckJsonService; use OCA\Deck\Service\Importer\Systems\TrelloApiService; use OCA\Deck\Service\Importer\Systems\TrelloJsonService; @@ -73,6 +74,7 @@ public function __construct( private ICommentsManager $commentsManager, private IEventDispatcher $eventDispatcher, private LoggerInterface $logger, + private AttachmentService $attachmentService, ) { $this->board = new Board(); $this->disableCommentsEvents(); @@ -332,11 +334,7 @@ public function importComments(): void { foreach ($comments as $commentId => $comment) { $metaData = $comment->getMetaData() ?? []; $sourceParentId = $comment->getParentId(); - if ($sourceParentId !== '0' && isset($sourceToImportedCommentId[$sourceParentId])) { - $comment->setParentId($sourceToImportedCommentId[$sourceParentId]); - } else { - $comment->setParentId('0'); - } + $comment->setParentId($sourceToImportedCommentId[$sourceParentId] ?? '0'); $this->insertComment((int)$cardId, $comment); $sourceId = (string)($metaData['deckImportSourceId'] ?? $commentId); @@ -386,8 +384,17 @@ public function importCardAssignments(): void { } public function insertAttachment(Attachment $attachment, string $content): Attachment { - $attachmentService = Server::get(AttachmentService::class); - return $attachmentService->createFileAttachmentFromImport($attachment, $content); + $attachment->setType('file'); + $attachment->setLastModified(time()); + $attachment->setCreatedAt(time()); + + /** @var FilesAppService $fileService */ + $fileService = $this->attachmentService->getService('file'); + $fileService->createFromImport($attachment, $content); + $fileService->extendData($attachment); + $this->attachmentService->syncAttachmentCreateSideEffects($attachment); + + return $attachment; } public function setData(\stdClass $data): void { diff --git a/lib/Service/Importer/Systems/DeckJsonService.php b/lib/Service/Importer/Systems/DeckJsonService.php index 606b96197f..99dcb36bac 100644 --- a/lib/Service/Importer/Systems/DeckJsonService.php +++ b/lib/Service/Importer/Systems/DeckJsonService.php @@ -156,7 +156,7 @@ public function importAttachments(): void { /** * @return array{0: string, 1: string} */ - private function resolveCommentActor(\stdClass $commentOriginal): array { + private function resolveCommentActor(object $commentOriginal): array { $actorType = (string)($commentOriginal->actorType ?? 'users'); $actorId = $commentOriginal->actorId ?? null; @@ -171,7 +171,7 @@ private function resolveCommentActor(\stdClass $commentOriginal): array { return [$actorType, $actorId]; } - private function importAttachmentsForCard(\stdClass $sourceCard): void { + private function importAttachmentsForCard(object $sourceCard): void { if (!property_exists($sourceCard, 'attachments') || !isset($this->cards[$sourceCard->id])) { return; } diff --git a/tests/unit/Service/Importer/BoardImportServiceTest.php b/tests/unit/Service/Importer/BoardImportServiceTest.php index c1cc7b2f94..4cbaeb9fce 100644 --- a/tests/unit/Service/Importer/BoardImportServiceTest.php +++ b/tests/unit/Service/Importer/BoardImportServiceTest.php @@ -37,6 +37,7 @@ use OCA\Deck\Db\Stack; use OCA\Deck\Db\StackMapper; use OCA\Deck\Event\BoardImportGetAllowedEvent; +use OCA\Deck\Service\AttachmentService; use OCA\Deck\Service\Importer\Systems\TrelloJsonService; use OCP\Comments\ICommentsManager; use OCP\EventDispatcher\IEventDispatcher; @@ -71,6 +72,8 @@ class BoardImportServiceTest extends \Test\TestCase { private $eventDispatcher; /** @var TrelloJsonService|MockObject */ private $trelloJsonService; + /** @var AttachmentService|MockObject */ + private $attachmentService; /** @var BoardImportService|MockObject */ private $boardImportService; public function setUp(): void { @@ -82,6 +85,7 @@ public function setUp(): void { $this->cardMapper = $this->createMock(CardMapper::class); $this->assignmentMapper = $this->createMock(AssignmentMapper::class); $this->attachmentMapper = $this->createMock(AttachmentMapper::class); + $this->attachmentService = $this->createMock(AttachmentService::class); $this->commentsManager = $this->createMock(ICommentsManager::class); $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->boardImportService = new BoardImportService( @@ -96,6 +100,7 @@ public function setUp(): void { $this->commentsManager, $this->eventDispatcher, $this->createMock(LoggerInterface::class), + $this->attachmentService, ); $this->boardImportService->setSystem('trelloJson'); From 723b402bdbfb708b00c7e21cb9fb47d23dacbe46 Mon Sep 17 00:00:00 2001 From: samin-z Date: Mon, 27 Apr 2026 11:39:18 +0200 Subject: [PATCH 021/190] update deckMigrator to use existing functionality of deck export Signed-off-by: samin-z --- lib/UserMigration/DeckMigrator.php | 68 +++++++++---------- tests/unit/UserMigration/DeckMigratorTest.php | 54 ++++++++++++++- 2 files changed, 85 insertions(+), 37 deletions(-) diff --git a/lib/UserMigration/DeckMigrator.php b/lib/UserMigration/DeckMigrator.php index 741aca1c5c..16189022d7 100644 --- a/lib/UserMigration/DeckMigrator.php +++ b/lib/UserMigration/DeckMigrator.php @@ -19,6 +19,7 @@ use OCA\Deck\Db\StackMapper; use OCA\Deck\Service\BoardService; use OCA\Deck\Service\Importer\BoardImportService; +use OCA\Deck\Service\PermissionService; use OCA\Deck\Service\ShareFileAttachmentExportService; use OCP\Comments\ICommentsManager; use OCP\Files\IAppData; @@ -53,6 +54,7 @@ public function __construct( protected ShareFileAttachmentExportService $shareFileAttachmentExportService, protected BoardService $boardService, protected BoardImportService $boardImportService, + protected PermissionService $permissionService, ) { } @@ -72,6 +74,8 @@ public function export( OutputInterface $output, ): void { $uid = $user->getUID(); + $this->boardService->setUserId($uid); + $this->permissionService->setUserId($uid); try { $exportData = $this->buildExportData($uid); @@ -115,62 +119,58 @@ private function buildExportData(string $uid): array { $exportData = ['boards' => []]; foreach ($boards as $board) { - $exportData['boards'][] = $this->serializeBoard($board, $uid); + // skip if the board is deleted (to align with the export service) + if ($board->getDeletedAt() > 0) { + continue; + } + $boardWithStacksAndCards = $this->boardService->export($board->getId()); + $this->appendArchivedCards($boardWithStacksAndCards); + $exportData['boards'][] = $this->serializeBoard($boardWithStacksAndCards, $uid); } return $exportData; } private function serializeBoard(object $board, string $uid): array { - $boardId = $board->getId(); - $board->setLabels($this->labelMapper->findAll($boardId)); - $board->setAcl($this->aclMapper->findAll($boardId)); - - $stacksById = $this->getBoardStacksById($boardId); - $this->attachSerializedCardsToStacks($stacksById, $uid); - $board->setStacks($stacksById); - - return $board->jsonSerialize(); - } - - private function getBoardStacksById(int $boardId): array { - $stacksById = []; - foreach ($this->stackMapper->findAll($boardId) as $stack) { - $stacksById[$stack->getId()] = $stack; + $boardData = $board->jsonSerialize(); + $serializedStacks = []; + foreach ($board->getStacks() ?? [] as $stack) { + $stackData = $stack->jsonSerialize(); + $serializedCards = []; + foreach ($stack->getCards() ?? [] as $card) { + $serializedCards[] = $this->serializeCard($card, $uid); + } + $stackData['cards'] = $serializedCards; + $serializedStacks[] = $stackData; } - return $stacksById; + $boardData['stacks'] = $serializedStacks; + + return $boardData; } - private function attachSerializedCardsToStacks(array &$stacksById, string $uid): void { - $stackIds = array_map(static fn ($stack) => $stack->getId(), $stacksById); - if (empty($stackIds)) { + private function appendArchivedCards(object $board): void { + $stacks = $board->getStacks() ?? []; + if (count($stacks) === 0) { return; } - $allCardsByStack = $this->cardMapper->findAllForStacks($stackIds); + $stackIds = array_map(static fn ($stack) => $stack->getId(), $stacks); $archivedCardsByStack = $this->cardMapper->findAllArchivedForStacks($stackIds); - foreach ($stacksById as $stackId => $stack) { - $stackCards = array_merge( - $allCardsByStack[$stackId] ?? [], - $archivedCardsByStack[$stackId] ?? [] - ); - $serializedCards = []; - foreach ($stackCards as $card) { - $serializedCards[] = $this->serializeCard($card, $uid); + foreach ($stacks as $stack) { + $activeCards = $stack->getCards() ?? []; + $archivedCards = $archivedCardsByStack[$stack->getId()] ?? []; + if (count($archivedCards) === 0) { + continue; } - $stack->setCards($serializedCards); + $stack->setCards(array_merge($activeCards, $archivedCards)); } } private function serializeCard(object $card, string $uid): array { $cardId = $card->getId(); - $card->setLabels($this->labelMapper->findAssignedLabelsForCard($cardId)); - $card->setAssignedUsers($this->assignmentMapper->findAll($cardId)); $cardData = $card->jsonSerialize(); - $cardData['labels'] = $cardData['labels'] ?? []; - $cardData['assignedUsers'] = $cardData['assignedUsers'] ?? []; $cardData['comments'] = $this->serializeCardComments($cardId); $cardData['attachments'] = $this->shareFileAttachmentExportService->exportCardAttachments($cardId, $uid); diff --git a/tests/unit/UserMigration/DeckMigratorTest.php b/tests/unit/UserMigration/DeckMigratorTest.php index fa8874e499..f3f744a3de 100644 --- a/tests/unit/UserMigration/DeckMigratorTest.php +++ b/tests/unit/UserMigration/DeckMigratorTest.php @@ -19,6 +19,7 @@ use OCA\Deck\Db\StackMapper; use OCA\Deck\Service\BoardService; use OCA\Deck\Service\Importer\BoardImportService; +use OCA\Deck\Service\PermissionService; use OCA\Deck\Service\ShareFileAttachmentExportService; use OCP\Comments\ICommentsManager; use OCP\Files\IAppData; @@ -55,6 +56,8 @@ class DeckMigratorTest extends TestCase { private $boardService; /** @var BoardImportService|MockObject */ private $boardImportService; + /** @var PermissionService|MockObject */ + private $permissionService; private DeckMigrator $migrator; public function setUp(): void { @@ -70,6 +73,7 @@ public function setUp(): void { $this->shareFileAttachmentExportService = $this->createMock(ShareFileAttachmentExportService::class); $this->boardService = $this->createMock(BoardService::class); $this->boardImportService = $this->createMock(BoardImportService::class); + $this->permissionService = $this->createMock(PermissionService::class); $this->migrator = new DeckMigrator( $this->createMock(IL10N::class), @@ -85,6 +89,7 @@ public function setUp(): void { $this->shareFileAttachmentExportService, $this->boardService, $this->boardImportService, + $this->permissionService, ); } @@ -100,9 +105,16 @@ public function testExportWritesBoardsJson(): void { ->method('findAllByUser') ->with('admin') ->willReturn([$board]); - $this->labelMapper->expects($this->once())->method('findAll')->with(42)->willReturn([]); - $this->aclMapper->expects($this->once())->method('findAll')->with(42)->willReturn([]); - $this->stackMapper->expects($this->once())->method('findAll')->with(42)->willReturn([]); + $this->boardService->expects($this->once()) + ->method('setUserId') + ->with('admin'); + $this->permissionService->expects($this->once()) + ->method('setUserId') + ->with('admin'); + $this->boardService->expects($this->once()) + ->method('export') + ->with(42) + ->willReturn($board); $destination = $this->createMock(IExportDestination::class); $destination->expects($this->once()) @@ -118,6 +130,42 @@ public function testExportWritesBoardsJson(): void { $this->migrator->export($user, $destination, $this->createMock(OutputInterface::class)); } + public function testExportSkipsDeletedBoards(): void { + $user = $this->createMock(IUser::class); + $user->method('getUID')->willReturn('admin'); + + $deletedBoard = new Board(); + $deletedBoard->setId(5202); + $deletedBoard->setTitle('Deleted board'); + $deletedBoard->setDeletedAt(time()); + + $this->boardMapper->expects($this->once()) + ->method('findAllByUser') + ->with('admin') + ->willReturn([$deletedBoard]); + $this->boardService->expects($this->once()) + ->method('setUserId') + ->with('admin'); + $this->permissionService->expects($this->once()) + ->method('setUserId') + ->with('admin'); + $this->boardService->expects($this->never()) + ->method('export'); + + $destination = $this->createMock(IExportDestination::class); + $destination->expects($this->once()) + ->method('addFileContents') + ->with( + 'boards.json', + $this->callback(static function (string $json): bool { + $decoded = json_decode($json, true); + return is_array($decoded) && isset($decoded['boards']) && count($decoded['boards']) === 0; + }) + ); + + $this->migrator->export($user, $destination, $this->createMock(OutputInterface::class)); + } + public function testImportSkipsWhenNoVersion(): void { $source = $this->createMock(IImportSource::class); $source->method('getMigratorVersion')->with('deck')->willReturn(null); From 853c070bd0a86290fc0a1b13bcd0fc991c2f48ae Mon Sep 17 00:00:00 2001 From: samin-z Date: Mon, 27 Apr 2026 12:18:20 +0200 Subject: [PATCH 022/190] optimize deck migration export queries Signed-off-by: samin-z --- lib/UserMigration/DeckMigrator.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/UserMigration/DeckMigrator.php b/lib/UserMigration/DeckMigrator.php index 16189022d7..85309c3ca0 100644 --- a/lib/UserMigration/DeckMigrator.php +++ b/lib/UserMigration/DeckMigrator.php @@ -171,8 +171,12 @@ private function serializeCard(object $card, string $uid): array { $cardId = $card->getId(); $cardData = $card->jsonSerialize(); - $cardData['comments'] = $this->serializeCardComments($cardId); - $cardData['attachments'] = $this->shareFileAttachmentExportService->exportCardAttachments($cardId, $uid); + $cardData['comments'] = (isset($cardData['comments']) && is_array($cardData['comments']) && $cardData['comments'] !== []) + ? $cardData['comments'] + : $this->serializeCardComments($cardId); + $cardData['attachments'] = (isset($cardData['attachments']) && is_array($cardData['attachments']) && $cardData['attachments'] !== []) + ? $cardData['attachments'] + : $this->shareFileAttachmentExportService->exportCardAttachments($cardId, $uid); return $cardData; } From 9a89470dbbee9dcf2a75800f576bee8dd51f59b8 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Tue, 28 Apr 2026 00:37:47 +0000 Subject: [PATCH 023/190] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/fr.js | 1 + l10n/fr.json | 1 + l10n/lt_LT.js | 3 ++- l10n/lt_LT.json | 3 ++- l10n/sv.js | 1 + l10n/sv.json | 1 + l10n/zh_TW.js | 1 + l10n/zh_TW.json | 1 + 8 files changed, 10 insertions(+), 2 deletions(-) diff --git a/l10n/fr.js b/l10n/fr.js index 2d6a73a822..2f8a5f3a3a 100644 --- a/l10n/fr.js +++ b/l10n/fr.js @@ -191,6 +191,7 @@ OC.L10N.register( "Admin settings" : "Paramètres d'administration", "Limit board creation to some groups" : "Limiter la création de tableaux à certains groupes", "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Les utilisateurs qui ne font pas partie de ces groupes ne pourront pas créer leurs propres tableaux, mais pourront toujours travailler sur les tableaux qui ont été partagés avec eux.", + "Enable federation" : "Activer la fédération", "Board actions" : "Actions sur le tableau", "Scroll sideways" : "Défilement latéral", "Navigate between cards" : "Naviguer entre les cartes", diff --git a/l10n/fr.json b/l10n/fr.json index 6983fab6bc..7aba82de0f 100644 --- a/l10n/fr.json +++ b/l10n/fr.json @@ -189,6 +189,7 @@ "Admin settings" : "Paramètres d'administration", "Limit board creation to some groups" : "Limiter la création de tableaux à certains groupes", "Users outside of those groups will not be able to create their own boards, but will still be able to work on boards that have been shared with them." : "Les utilisateurs qui ne font pas partie de ces groupes ne pourront pas créer leurs propres tableaux, mais pourront toujours travailler sur les tableaux qui ont été partagés avec eux.", + "Enable federation" : "Activer la fédération", "Board actions" : "Actions sur le tableau", "Scroll sideways" : "Défilement latéral", "Navigate between cards" : "Naviguer entre les cartes", diff --git a/l10n/lt_LT.js b/l10n/lt_LT.js index 70ebddfa9c..2cff23cbc0 100644 --- a/l10n/lt_LT.js +++ b/l10n/lt_LT.js @@ -88,7 +88,7 @@ OC.L10N.register( "Cards due tomorrow" : "Rytoj baigiamos kortelės", "Upcoming cards" : "Artėjančios kortelės", "Load more" : "Įkelti daugiau", - "Welcome to Nextcloud Deck!" : "Sveiki atvykę į „Nextcloud Deck“!", + "Welcome to Nextcloud Deck!" : "Sveiki atvykę į „Nextcloud Darbai“!", "The card \"%s\" on \"%s\" has been assigned to you by %s." : "Kortelę \"%s\" ties \"%s\" priskyrė jums %s.", "{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} priskyrė jums {deck-card} kortelę iš {deck-board}.", "The card \"%1$s\" on \"%2$s\" has reached its due date." : "Kortelės „%1$s“ galiojimo laikas baigėsi %2$s.", @@ -324,6 +324,7 @@ OC.L10N.register( "Edit card title" : "Redaguoti kortelės pavadinimą", "Open link" : "Atverti nuorodą", "Card deleted" : "Kortelė ištrinta", + "Change card color" : "Keisti kortelės spalvą", "Edit title" : "Taisyti pavadinimą", "Assign to me" : "Priskirti sau", "Unassign myself" : "Atšaukti savo priskyrimą", diff --git a/l10n/lt_LT.json b/l10n/lt_LT.json index 6206c261d4..24516e9cda 100644 --- a/l10n/lt_LT.json +++ b/l10n/lt_LT.json @@ -86,7 +86,7 @@ "Cards due tomorrow" : "Rytoj baigiamos kortelės", "Upcoming cards" : "Artėjančios kortelės", "Load more" : "Įkelti daugiau", - "Welcome to Nextcloud Deck!" : "Sveiki atvykę į „Nextcloud Deck“!", + "Welcome to Nextcloud Deck!" : "Sveiki atvykę į „Nextcloud Darbai“!", "The card \"%s\" on \"%s\" has been assigned to you by %s." : "Kortelę \"%s\" ties \"%s\" priskyrė jums %s.", "{user} has assigned the card {deck-card} on {deck-board} to you." : "{user} priskyrė jums {deck-card} kortelę iš {deck-board}.", "The card \"%1$s\" on \"%2$s\" has reached its due date." : "Kortelės „%1$s“ galiojimo laikas baigėsi %2$s.", @@ -322,6 +322,7 @@ "Edit card title" : "Redaguoti kortelės pavadinimą", "Open link" : "Atverti nuorodą", "Card deleted" : "Kortelė ištrinta", + "Change card color" : "Keisti kortelės spalvą", "Edit title" : "Taisyti pavadinimą", "Assign to me" : "Priskirti sau", "Unassign myself" : "Atšaukti savo priskyrimą", diff --git a/l10n/sv.js b/l10n/sv.js index c6bf67379b..aaf1c181d8 100644 --- a/l10n/sv.js +++ b/l10n/sv.js @@ -324,6 +324,7 @@ OC.L10N.register( "Edit card title" : "Ändra korttitel", "Open link" : "Öppna länken", "Card deleted" : "Kortet har raderats", + "Change card color" : "Ändra kortfärg", "Edit title" : "Redigera titel", "Assign to me" : "Tilldela till mig", "Unassign myself" : "Ta bort från mig själv", diff --git a/l10n/sv.json b/l10n/sv.json index 8098df75a5..44ebbc3314 100644 --- a/l10n/sv.json +++ b/l10n/sv.json @@ -322,6 +322,7 @@ "Edit card title" : "Ändra korttitel", "Open link" : "Öppna länken", "Card deleted" : "Kortet har raderats", + "Change card color" : "Ändra kortfärg", "Edit title" : "Redigera titel", "Assign to me" : "Tilldela till mig", "Unassign myself" : "Ta bort från mig själv", diff --git a/l10n/zh_TW.js b/l10n/zh_TW.js index c45e0fc787..0d225d4f8e 100644 --- a/l10n/zh_TW.js +++ b/l10n/zh_TW.js @@ -324,6 +324,7 @@ OC.L10N.register( "Edit card title" : "編輯卡片標題", "Open link" : "開啟連結", "Card deleted" : "卡片已刪除", + "Change card color" : "變更卡片顏色", "Edit title" : "編輯標題", "Assign to me" : "分配給我", "Unassign myself" : "取消分配給我", diff --git a/l10n/zh_TW.json b/l10n/zh_TW.json index e56d0f21ee..e86474d1e5 100644 --- a/l10n/zh_TW.json +++ b/l10n/zh_TW.json @@ -322,6 +322,7 @@ "Edit card title" : "編輯卡片標題", "Open link" : "開啟連結", "Card deleted" : "卡片已刪除", + "Change card color" : "變更卡片顏色", "Edit title" : "編輯標題", "Assign to me" : "分配給我", "Unassign myself" : "取消分配給我", From a36515221da994bbea7270eb4de540e516875b37 Mon Sep 17 00:00:00 2001 From: grnd-alt Date: Tue, 28 Apr 2026 12:35:36 +0200 Subject: [PATCH 024/190] fix(comments): allow updating replies Signed-off-by: grnd-alt --- lib/Service/CommentService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Service/CommentService.php b/lib/Service/CommentService.php index f773e41dcc..e5d4bc140e 100644 --- a/lib/Service/CommentService.php +++ b/lib/Service/CommentService.php @@ -72,7 +72,7 @@ private function get(int $cardId, int $commentId): IComment { throw new NotFoundException('No comment found.'); } if ($comment->getParentId() !== '0') { - $this->permissionService->checkPermission($this->cardMapper, (int)$comment->getParentId(), Acl::PERMISSION_READ); + $this->permissionService->checkPermission($this->cardMapper, (int)$comment->getObjectId(), Acl::PERMISSION_READ); } return $comment; From c6f5e6db3947107c95af49863335c7919af8dfd4 Mon Sep 17 00:00:00 2001 From: samin-z Date: Tue, 28 Apr 2026 16:59:04 +0200 Subject: [PATCH 025/190] add condition to check if user is allowed to import Signed-off-by: samin-z --- lib/UserMigration/DeckMigrator.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/UserMigration/DeckMigrator.php b/lib/UserMigration/DeckMigrator.php index 85309c3ca0..7b4caf2545 100644 --- a/lib/UserMigration/DeckMigrator.php +++ b/lib/UserMigration/DeckMigrator.php @@ -102,6 +102,12 @@ public function import( return; } + $this->permissionService->setUserId($user->getUID()); + if (!$this->permissionService->canCreate()) { + $output->writeln('Deck import failed: user is not allowed to create boards.'); + return; + } + try { $data = $this->readImportData($importSource); if (empty($data['boards'])) { From 1ec656b5f4259811c662a16943e0ebbc8bad39fe Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Wed, 29 Apr 2026 00:39:05 +0000 Subject: [PATCH 026/190] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/ga.js | 1 + l10n/ga.json | 1 + l10n/sv.js | 6 +++--- l10n/sv.json | 6 +++--- l10n/uk.js | 1 + l10n/uk.json | 1 + 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/l10n/ga.js b/l10n/ga.js index b342e10960..4e49192615 100644 --- a/l10n/ga.js +++ b/l10n/ga.js @@ -324,6 +324,7 @@ OC.L10N.register( "Edit card title" : "Cuir teideal an chárta in eagar", "Open link" : "Oscail nasc", "Card deleted" : "Cárta scriosta", + "Change card color" : "Athraigh dath an chárta", "Edit title" : "Cuir teideal in eagar", "Assign to me" : "Sann dom", "Unassign myself" : "Díshannadh mé féin", diff --git a/l10n/ga.json b/l10n/ga.json index d6bc4c887a..9a6d3b9c13 100644 --- a/l10n/ga.json +++ b/l10n/ga.json @@ -322,6 +322,7 @@ "Edit card title" : "Cuir teideal an chárta in eagar", "Open link" : "Oscail nasc", "Card deleted" : "Cárta scriosta", + "Change card color" : "Athraigh dath an chárta", "Edit title" : "Cuir teideal in eagar", "Assign to me" : "Sann dom", "Unassign myself" : "Díshannadh mé féin", diff --git a/l10n/sv.js b/l10n/sv.js index aaf1c181d8..d402b9a09c 100644 --- a/l10n/sv.js +++ b/l10n/sv.js @@ -29,7 +29,7 @@ OC.L10N.register( "{user} has deleted card {card} in list {stack} on board {board}" : "{user} har raderat kortet {card} i listan {stack} på tavlan {board}", "You have renamed the card {before} to {card}" : "Du har bytt namn på kortet {before} till {card}", "{user} has renamed the card {before} to {card}" : "{user} har bytt namn på kortet {before} till {card}", - "You have added a description to card {card} in list {stack} on board {board}" : "Du har lagt till en beskrivning till kortet {card} i listan {stack} på tavlan {board}", + "You have added a description to card {card} in list {stack} on board {board}" : "Du har lagt till en beskrivning för kortet {card} i listan {stack} på tavlan {board}", "{user} has added a description to card {card} in list {stack} on board {board}" : "{user} har lagt till en beskrivning till kortet {card} i listan {stack} på tavlan {board}", "You have updated the description of card {card} in list {stack} on board {board}" : "Du har uppdaterat beskrivningen för kortet {card} i listan {stack} på tavlan {board}", "{user} has updated the description of the card {card} in list {stack} on board {board}" : "{user} har uppdaterat beskrivningen för kortet {card} i listan {stack} på tavlan {board}", @@ -227,7 +227,7 @@ OC.L10N.register( "Board owner" : "Tavlans ägare", "(Group)" : "(Grupp)", "(Team)" : "(Team)", - "(remote)" : "(avlägsen)", + "(remote)" : "(fjärr)", "Can edit" : "Kan redigera", "Can share" : "Kan dela", "Can manage" : "Kan hanter", @@ -341,7 +341,7 @@ OC.L10N.register( "Only assigned cards" : "Bara tilldelade kort", "No reminder" : "Ingen påminnelse", "An error occurred" : "Ett fel uppstod", - "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Är du säker på att du vill radera tavla {title}? Detta kommer radera all data som tillhör tavlan inklusive arkiverade kort.", + "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Är du säker på att du vill radera tavlan {title}? Detta kommer radera all data som tillhör tavlan inklusive arkiverade kort.", "Delete the board?" : "Ta bort tavlan?", "Are you sure you want to leave the board {title}?" : "Är du säker att du vill lämna tavlan {title}?", "Leave the board?" : "Lämna tavlan?", diff --git a/l10n/sv.json b/l10n/sv.json index 44ebbc3314..c24257bd89 100644 --- a/l10n/sv.json +++ b/l10n/sv.json @@ -27,7 +27,7 @@ "{user} has deleted card {card} in list {stack} on board {board}" : "{user} har raderat kortet {card} i listan {stack} på tavlan {board}", "You have renamed the card {before} to {card}" : "Du har bytt namn på kortet {before} till {card}", "{user} has renamed the card {before} to {card}" : "{user} har bytt namn på kortet {before} till {card}", - "You have added a description to card {card} in list {stack} on board {board}" : "Du har lagt till en beskrivning till kortet {card} i listan {stack} på tavlan {board}", + "You have added a description to card {card} in list {stack} on board {board}" : "Du har lagt till en beskrivning för kortet {card} i listan {stack} på tavlan {board}", "{user} has added a description to card {card} in list {stack} on board {board}" : "{user} har lagt till en beskrivning till kortet {card} i listan {stack} på tavlan {board}", "You have updated the description of card {card} in list {stack} on board {board}" : "Du har uppdaterat beskrivningen för kortet {card} i listan {stack} på tavlan {board}", "{user} has updated the description of the card {card} in list {stack} on board {board}" : "{user} har uppdaterat beskrivningen för kortet {card} i listan {stack} på tavlan {board}", @@ -225,7 +225,7 @@ "Board owner" : "Tavlans ägare", "(Group)" : "(Grupp)", "(Team)" : "(Team)", - "(remote)" : "(avlägsen)", + "(remote)" : "(fjärr)", "Can edit" : "Kan redigera", "Can share" : "Kan dela", "Can manage" : "Kan hanter", @@ -339,7 +339,7 @@ "Only assigned cards" : "Bara tilldelade kort", "No reminder" : "Ingen påminnelse", "An error occurred" : "Ett fel uppstod", - "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Är du säker på att du vill radera tavla {title}? Detta kommer radera all data som tillhör tavlan inklusive arkiverade kort.", + "Are you sure you want to delete the board {title}? This will delete all the data of this board including archived cards." : "Är du säker på att du vill radera tavlan {title}? Detta kommer radera all data som tillhör tavlan inklusive arkiverade kort.", "Delete the board?" : "Ta bort tavlan?", "Are you sure you want to leave the board {title}?" : "Är du säker att du vill lämna tavlan {title}?", "Leave the board?" : "Lämna tavlan?", diff --git a/l10n/uk.js b/l10n/uk.js index d3998b923c..5de6fcef59 100644 --- a/l10n/uk.js +++ b/l10n/uk.js @@ -324,6 +324,7 @@ OC.L10N.register( "Edit card title" : "Редагувати заголовок картки", "Open link" : "Відкрити посилання", "Card deleted" : "Картку видалено", + "Change card color" : "Змінити колір картки", "Edit title" : "Редагувати", "Assign to me" : "Призначити мені", "Unassign myself" : "Зняти з себе повноваження.", diff --git a/l10n/uk.json b/l10n/uk.json index 54c1bec693..f78559a9d4 100644 --- a/l10n/uk.json +++ b/l10n/uk.json @@ -322,6 +322,7 @@ "Edit card title" : "Редагувати заголовок картки", "Open link" : "Відкрити посилання", "Card deleted" : "Картку видалено", + "Change card color" : "Змінити колір картки", "Edit title" : "Редагувати", "Assign to me" : "Призначити мені", "Unassign myself" : "Зняти з себе повноваження.", From 35bdc592abfca4ef897ffe9d0b27a06896738a60 Mon Sep 17 00:00:00 2001 From: samin-z Date: Wed, 29 Apr 2026 10:52:58 +0200 Subject: [PATCH 027/190] update deckMigratorTest with latest changes Signed-off-by: samin-z --- tests/unit/UserMigration/DeckMigratorTest.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/unit/UserMigration/DeckMigratorTest.php b/tests/unit/UserMigration/DeckMigratorTest.php index f3f744a3de..4fcaa37da5 100644 --- a/tests/unit/UserMigration/DeckMigratorTest.php +++ b/tests/unit/UserMigration/DeckMigratorTest.php @@ -187,6 +187,13 @@ public function testImportConfiguresServiceAndImports(): void { $source->method('getMigratorVersion')->with('deck')->willReturn(1); $source->method('getFileContents')->with('boards.json')->willReturn('{"boards":[{"id":1,"title":"Board A","stacks":[]}]}'); + $this->permissionService->expects($this->once()) + ->method('setUserId') + ->with('alice'); + $this->permissionService->expects($this->once()) + ->method('canCreate') + ->willReturn(true); + $this->boardImportService->expects($this->once())->method('setSystem')->with('DeckJson'); $this->boardImportService->expects($this->once()) ->method('setConfigInstance') From 744e439abbfb47e55ec26dedac4de27977c0fc3f Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Fri, 1 May 2026 00:38:59 +0000 Subject: [PATCH 028/190] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/de.js | 1 + l10n/de.json | 1 + l10n/de_DE.js | 1 + l10n/de_DE.json | 1 + l10n/ga.js | 1 + l10n/ga.json | 1 + l10n/zh_TW.js | 1 + l10n/zh_TW.json | 1 + 8 files changed, 8 insertions(+) diff --git a/l10n/de.js b/l10n/de.js index 5f3414f5ef..4b3dbc80d7 100644 --- a/l10n/de.js +++ b/l10n/de.js @@ -129,6 +129,7 @@ OC.L10N.register( "Card not found" : "Karte nicht gefunden", "Path is already shared with this card" : "Pfad wurde bereits mit dieser Karte geteilt", "Invalid date, date format must be YYYY-MM-DD" : "Ungültiges Datum, zulässiges Datumsformat: JJJJ-MM-TT", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Alle Boards, die dir gehören, einschließlich Stapeln, Karten, Etiketten, Zuordnungen und Kommentaren", "Personal planning and team project organization" : "Persönliche Planung und Teamprojektorganisation", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck ist ein Organisationstool im Kanban-Stil für die persönliche Planung und Projektorganisation von Teams, die in Nextcloud integriert ist.\n\n\n- 📥 Füge deine Aufgaben zu den Karten hinzu und ordne diese\n- 📄 Zusätzliche Hinweise in der Abschrift notieren\n- 🔖 Zuweisen von Schlagworten für noch bessere Organisation\n- 👥 Teile mit deinem Team, Freunden oder der Familie\n- 📎 Füge Dateien hinzu und verwende diese in deinen Markdown-Beschreibungen\n- 💬 Diskutiere mit deinem Team mit Kommentaren\n- ⚡ Behalte den Überblick über Änderungen mit dem Aktivitäten-Stream\n- 🚀 Organisiere dein Projekt", "Add board" : "Board hinzufügen", diff --git a/l10n/de.json b/l10n/de.json index 402764a264..485c8dcd87 100644 --- a/l10n/de.json +++ b/l10n/de.json @@ -127,6 +127,7 @@ "Card not found" : "Karte nicht gefunden", "Path is already shared with this card" : "Pfad wurde bereits mit dieser Karte geteilt", "Invalid date, date format must be YYYY-MM-DD" : "Ungültiges Datum, zulässiges Datumsformat: JJJJ-MM-TT", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Alle Boards, die dir gehören, einschließlich Stapeln, Karten, Etiketten, Zuordnungen und Kommentaren", "Personal planning and team project organization" : "Persönliche Planung und Teamprojektorganisation", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck ist ein Organisationstool im Kanban-Stil für die persönliche Planung und Projektorganisation von Teams, die in Nextcloud integriert ist.\n\n\n- 📥 Füge deine Aufgaben zu den Karten hinzu und ordne diese\n- 📄 Zusätzliche Hinweise in der Abschrift notieren\n- 🔖 Zuweisen von Schlagworten für noch bessere Organisation\n- 👥 Teile mit deinem Team, Freunden oder der Familie\n- 📎 Füge Dateien hinzu und verwende diese in deinen Markdown-Beschreibungen\n- 💬 Diskutiere mit deinem Team mit Kommentaren\n- ⚡ Behalte den Überblick über Änderungen mit dem Aktivitäten-Stream\n- 🚀 Organisiere dein Projekt", "Add board" : "Board hinzufügen", diff --git a/l10n/de_DE.js b/l10n/de_DE.js index 698906a5a9..0bc01c524f 100644 --- a/l10n/de_DE.js +++ b/l10n/de_DE.js @@ -129,6 +129,7 @@ OC.L10N.register( "Card not found" : "Karte nicht gefunden", "Path is already shared with this card" : "Pfad wurde bereits mit dieser Karte geteilt", "Invalid date, date format must be YYYY-MM-DD" : "Ungültiges Datum, zulässiges Datumsformat: JJJJ-MM-TT", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Alle Boards, die Ihnen gehören, einschließlich Stapeln, Karten, Etiketten, Zuordnungen und Kommentaren", "Personal planning and team project organization" : "Persönliche Planung und Teamprojektorganisation", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck ist ein Organisationstool im Kanban-Stil für die persönliche Planung und Projektorganisation von Teams, die in Nextcloud integriert sind.\n\n\n- 📥 Fügen Sie Ihre Aufgaben zu den Karten hinzu und ordnen Sie diese\n- 📄 Zusätzliche Hinweise in der Abschrift notieren\n- 🔖 Zuweisen von Schlagworten für noch bessere Organisation\n- 👥 Teilen Sie mit Ihrem Team, Ihren Freunden oder Ihrer Familie\n- 📎 Fügen Sie Dateien hinzu und verwende diese in Ihren Markdown-Beschreibungen\n- 💬 Diskutieren Sie mit Ihrem Team mit Kommentaren\n- ⚡ Behalten Sie Überblick über Änderungen mit dem Aktivitäten-Stream\n- 🚀 Organisieren Sie Ihr Projekt", "Add board" : "Board hinzufügen", diff --git a/l10n/de_DE.json b/l10n/de_DE.json index 9967d8d02f..19443bfca1 100644 --- a/l10n/de_DE.json +++ b/l10n/de_DE.json @@ -127,6 +127,7 @@ "Card not found" : "Karte nicht gefunden", "Path is already shared with this card" : "Pfad wurde bereits mit dieser Karte geteilt", "Invalid date, date format must be YYYY-MM-DD" : "Ungültiges Datum, zulässiges Datumsformat: JJJJ-MM-TT", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Alle Boards, die Ihnen gehören, einschließlich Stapeln, Karten, Etiketten, Zuordnungen und Kommentaren", "Personal planning and team project organization" : "Persönliche Planung und Teamprojektorganisation", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck ist ein Organisationstool im Kanban-Stil für die persönliche Planung und Projektorganisation von Teams, die in Nextcloud integriert sind.\n\n\n- 📥 Fügen Sie Ihre Aufgaben zu den Karten hinzu und ordnen Sie diese\n- 📄 Zusätzliche Hinweise in der Abschrift notieren\n- 🔖 Zuweisen von Schlagworten für noch bessere Organisation\n- 👥 Teilen Sie mit Ihrem Team, Ihren Freunden oder Ihrer Familie\n- 📎 Fügen Sie Dateien hinzu und verwende diese in Ihren Markdown-Beschreibungen\n- 💬 Diskutieren Sie mit Ihrem Team mit Kommentaren\n- ⚡ Behalten Sie Überblick über Änderungen mit dem Aktivitäten-Stream\n- 🚀 Organisieren Sie Ihr Projekt", "Add board" : "Board hinzufügen", diff --git a/l10n/ga.js b/l10n/ga.js index 4e49192615..6d721dce70 100644 --- a/l10n/ga.js +++ b/l10n/ga.js @@ -129,6 +129,7 @@ OC.L10N.register( "Card not found" : "Cárta gan aimsiú", "Path is already shared with this card" : "Tá an chonair roinnte leis an gcárta seo cheana féin", "Invalid date, date format must be YYYY-MM-DD" : "Dáta neamhbhailí, caithfidh formáid an dáta a bheith BBBB-MM-DD", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Gach bord atá i do sheilbh, lena n-áirítear cruacha, cártaí, lipéid, tascanna agus tuairimí", "Personal planning and team project organization" : "Pleanáil phearsanta agus eagrú tionscadail foirne", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Is uirlis eagraíochta stíl kanban é Deck atá dírithe ar phleanáil phearsanta agus eagrú tionscadail d'fhoirne atá comhtháite le Nextcloud.\n\n\n- 📥 Cuir do thascanna le cártaí agus cuir in ord iad\n- 📄 Scríobh síos nótaí breise i Markdown\n- 🔖 Sann lipéid le haghaidh eagrú níos fearr fós\n- 👥 Roinn le d'fhoireann, do chairde nó do theaghlach\n- 📎 Ceangail comhaid agus leabaigh iad i do chur síos Markdown\n- 💬 Déan plé le d’fhoireann ag úsáid tuairimí\n- ⚡ Coinnigh súil ar athruithe sa sruth gníomhaíochta\n- 🚀 Eagraigh do thionscadal", "Add board" : "Cuir bord leis", diff --git a/l10n/ga.json b/l10n/ga.json index 9a6d3b9c13..b15cd42c58 100644 --- a/l10n/ga.json +++ b/l10n/ga.json @@ -127,6 +127,7 @@ "Card not found" : "Cárta gan aimsiú", "Path is already shared with this card" : "Tá an chonair roinnte leis an gcárta seo cheana féin", "Invalid date, date format must be YYYY-MM-DD" : "Dáta neamhbhailí, caithfidh formáid an dáta a bheith BBBB-MM-DD", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Gach bord atá i do sheilbh, lena n-áirítear cruacha, cártaí, lipéid, tascanna agus tuairimí", "Personal planning and team project organization" : "Pleanáil phearsanta agus eagrú tionscadail foirne", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Is uirlis eagraíochta stíl kanban é Deck atá dírithe ar phleanáil phearsanta agus eagrú tionscadail d'fhoirne atá comhtháite le Nextcloud.\n\n\n- 📥 Cuir do thascanna le cártaí agus cuir in ord iad\n- 📄 Scríobh síos nótaí breise i Markdown\n- 🔖 Sann lipéid le haghaidh eagrú níos fearr fós\n- 👥 Roinn le d'fhoireann, do chairde nó do theaghlach\n- 📎 Ceangail comhaid agus leabaigh iad i do chur síos Markdown\n- 💬 Déan plé le d’fhoireann ag úsáid tuairimí\n- ⚡ Coinnigh súil ar athruithe sa sruth gníomhaíochta\n- 🚀 Eagraigh do thionscadal", "Add board" : "Cuir bord leis", diff --git a/l10n/zh_TW.js b/l10n/zh_TW.js index 0d225d4f8e..5b798deb20 100644 --- a/l10n/zh_TW.js +++ b/l10n/zh_TW.js @@ -129,6 +129,7 @@ OC.L10N.register( "Card not found" : "找不到卡片", "Path is already shared with this card" : "路徑已與此卡片分享", "Invalid date, date format must be YYYY-MM-DD" : "無效的日期,日期格式必須為 YYYY-MM-DD", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "您擁有的所有看板,包括堆疊、卡片、標籤、指派事項與留言", "Personal planning and team project organization" : "個人規劃與團隊專案組織", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck 是一套看板式組織工具,提供與 Nextcloud 整合的個人規劃與團隊專案組織功能。\n\n\n- 📥 將您的工作項目新增到卡片中,並將它們按順序排列\n- 📄 以 Markdown 編寫額外的註釋\n- 🔖 分配標籤讓組織更方便\n- 👥 與您的團隊、朋友與家人分享\n- 📎 附上檔案並將其嵌入到您的 Markdown 描述中\n- 💬 使用留言與您的團隊討論\n- ⚡ 追蹤活動流程中的變動\n- 🚀 整理好您的專案", "Add board" : "新增佈告欄", diff --git a/l10n/zh_TW.json b/l10n/zh_TW.json index e86474d1e5..e84671db26 100644 --- a/l10n/zh_TW.json +++ b/l10n/zh_TW.json @@ -127,6 +127,7 @@ "Card not found" : "找不到卡片", "Path is already shared with this card" : "路徑已與此卡片分享", "Invalid date, date format must be YYYY-MM-DD" : "無效的日期,日期格式必須為 YYYY-MM-DD", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "您擁有的所有看板,包括堆疊、卡片、標籤、指派事項與留言", "Personal planning and team project organization" : "個人規劃與團隊專案組織", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck 是一套看板式組織工具,提供與 Nextcloud 整合的個人規劃與團隊專案組織功能。\n\n\n- 📥 將您的工作項目新增到卡片中,並將它們按順序排列\n- 📄 以 Markdown 編寫額外的註釋\n- 🔖 分配標籤讓組織更方便\n- 👥 與您的團隊、朋友與家人分享\n- 📎 附上檔案並將其嵌入到您的 Markdown 描述中\n- 💬 使用留言與您的團隊討論\n- ⚡ 追蹤活動流程中的變動\n- 🚀 整理好您的專案", "Add board" : "新增佈告欄", From 48e6628a5508f7244cee5dbd03b661d759793e03 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sat, 2 May 2026 00:37:56 +0000 Subject: [PATCH 029/190] fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- l10n/lt_LT.js | 1 + l10n/lt_LT.json | 1 + l10n/pt_BR.js | 1 + l10n/pt_BR.json | 1 + l10n/sv.js | 1 + l10n/sv.json | 1 + 6 files changed, 6 insertions(+) diff --git a/l10n/lt_LT.js b/l10n/lt_LT.js index 2cff23cbc0..9b0ce9fc5a 100644 --- a/l10n/lt_LT.js +++ b/l10n/lt_LT.js @@ -129,6 +129,7 @@ OC.L10N.register( "Card not found" : "Kortelė nerasta", "Path is already shared with this card" : "Kelias jau yra bendrinamas su šia kortele", "Invalid date, date format must be YYYY-MM-DD" : "Netinkama data, datos formatas privalo būti MMMM-mm-dd", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Visos jums priklausančios lentos, įskaitant krūvas, korteles, etiketes, užduotis ir komentarus", "Personal planning and team project organization" : "Asmeninis planavimas ir komandinių projektų organizavimas", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Darbai – tai „kanban“ stiliaus organizavimo įrankis, skirtas asmeniniam planavimui ir komandų projektų organizavimui, integruotas su „Nextcloud“.\n\n\n- 📥 Pridėkite užduotis į korteles ir išdėstykite jas tvarkingai\n- 📄 Įrašykite papildomas pastabas „Markdown“ formatu\n- 🔖 Priskirkite žymes, kad viską būtų dar lengviau tvarkyti\n- 👥 Dalinkitės su komanda, draugais ar šeima\n- 📎 Pridėkite failus ir įterpkite juos į savo „Markdown“ aprašymą\n- 💬 Diskutuokite su savo komanda naudodami komentarus\n- ⚡ Sekite pokyčius veiklos sraute\n- 🚀 Sutvarkykite savo projektą", "Add board" : "Pridėti lentą", diff --git a/l10n/lt_LT.json b/l10n/lt_LT.json index 24516e9cda..fbbee27d3e 100644 --- a/l10n/lt_LT.json +++ b/l10n/lt_LT.json @@ -127,6 +127,7 @@ "Card not found" : "Kortelė nerasta", "Path is already shared with this card" : "Kelias jau yra bendrinamas su šia kortele", "Invalid date, date format must be YYYY-MM-DD" : "Netinkama data, datos formatas privalo būti MMMM-mm-dd", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Visos jums priklausančios lentos, įskaitant krūvas, korteles, etiketes, užduotis ir komentarus", "Personal planning and team project organization" : "Asmeninis planavimas ir komandinių projektų organizavimas", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Darbai – tai „kanban“ stiliaus organizavimo įrankis, skirtas asmeniniam planavimui ir komandų projektų organizavimui, integruotas su „Nextcloud“.\n\n\n- 📥 Pridėkite užduotis į korteles ir išdėstykite jas tvarkingai\n- 📄 Įrašykite papildomas pastabas „Markdown“ formatu\n- 🔖 Priskirkite žymes, kad viską būtų dar lengviau tvarkyti\n- 👥 Dalinkitės su komanda, draugais ar šeima\n- 📎 Pridėkite failus ir įterpkite juos į savo „Markdown“ aprašymą\n- 💬 Diskutuokite su savo komanda naudodami komentarus\n- ⚡ Sekite pokyčius veiklos sraute\n- 🚀 Sutvarkykite savo projektą", "Add board" : "Pridėti lentą", diff --git a/l10n/pt_BR.js b/l10n/pt_BR.js index d6396a80f3..3ad3115d65 100644 --- a/l10n/pt_BR.js +++ b/l10n/pt_BR.js @@ -129,6 +129,7 @@ OC.L10N.register( "Card not found" : "Cartão não encontrado", "Path is already shared with this card" : "O caminho já é compartilhado com este cartão", "Invalid date, date format must be YYYY-MM-DD" : "Data inválida, o formato da data deve ser AAAA-MM-DD", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Todos os painéis de que você é proprietário, incluindo pilhas, cartões, etiquetas, tarefas e comentários", "Personal planning and team project organization" : "Planejamento pessoal e organização de projetos em equipe", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "O Deck é uma ferramenta de organização ao estilo kanban voltada para o planejamento pessoal e para a organização de projetos para equipes, integrada ao Nextcloud.\n\n\n- 📥Adicione suas tarefas aos cartões e coloque-os em ordem\n- 📄 Escreva notas adicionais formatadas em Markdown \n- 🔖 Atribua rótulos para uma organização ainda melhor\n- 👥 Compartilhe com sua equipe, seus amigos ou sua família\n- 📎 Anexe arquivos e incorpore-os à sua descrição em Markdown\n- 💬 Discuta com sua equipe usando comentários\n- ⚡ Acompanhe as alterações no fluxo de atividades \n- 🚀 Organize seu projeto ", "Add board" : "Adicionar painel", diff --git a/l10n/pt_BR.json b/l10n/pt_BR.json index d22e1b5ef9..a75954a6e0 100644 --- a/l10n/pt_BR.json +++ b/l10n/pt_BR.json @@ -127,6 +127,7 @@ "Card not found" : "Cartão não encontrado", "Path is already shared with this card" : "O caminho já é compartilhado com este cartão", "Invalid date, date format must be YYYY-MM-DD" : "Data inválida, o formato da data deve ser AAAA-MM-DD", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Todos os painéis de que você é proprietário, incluindo pilhas, cartões, etiquetas, tarefas e comentários", "Personal planning and team project organization" : "Planejamento pessoal e organização de projetos em equipe", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "O Deck é uma ferramenta de organização ao estilo kanban voltada para o planejamento pessoal e para a organização de projetos para equipes, integrada ao Nextcloud.\n\n\n- 📥Adicione suas tarefas aos cartões e coloque-os em ordem\n- 📄 Escreva notas adicionais formatadas em Markdown \n- 🔖 Atribua rótulos para uma organização ainda melhor\n- 👥 Compartilhe com sua equipe, seus amigos ou sua família\n- 📎 Anexe arquivos e incorpore-os à sua descrição em Markdown\n- 💬 Discuta com sua equipe usando comentários\n- ⚡ Acompanhe as alterações no fluxo de atividades \n- 🚀 Organize seu projeto ", "Add board" : "Adicionar painel", diff --git a/l10n/sv.js b/l10n/sv.js index d402b9a09c..fd9e055af5 100644 --- a/l10n/sv.js +++ b/l10n/sv.js @@ -129,6 +129,7 @@ OC.L10N.register( "Card not found" : "Kortet hittades inte", "Path is already shared with this card" : "Sökvägen är redan delad med detta kort", "Invalid date, date format must be YYYY-MM-DD" : "Ogiltigt datum, måste anges: ÅÅÅÅ-MM-DD", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Alla tavlor som ägs av dig inklusive listor, kort, etiketter, tilldelningar och kommentarer", "Personal planning and team project organization" : "Personlig planering och projekthantering för teams", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck är en kanban-liknande organiseringsverktyg för personlig planering samt projektorganisering för arbetsgrupper integrerade med Nextcloud.\n\n\n- 📥 Lägg till uppgifter på kort och lägg de i ordning\n- 📄 Skriv anteckningar i Markdown\n- 🔖 Tilldela etiketter för bättre organisering\n- 👥 Dela med arbetsgruppen, vänner eller familj\n- 📎 Bifoga filer och bädda in dem i Markdown-anteckningarna\n- 💬 Diskutera med arbetsgruppen med hjälp av kommentarer\n- ⚡ Håll koll på ändringar i aktivitetsflödet\n- 🚀 Få struktur på dina projekt", "Add board" : "Lägg till tavla", diff --git a/l10n/sv.json b/l10n/sv.json index c24257bd89..1d1055f469 100644 --- a/l10n/sv.json +++ b/l10n/sv.json @@ -127,6 +127,7 @@ "Card not found" : "Kortet hittades inte", "Path is already shared with this card" : "Sökvägen är redan delad med detta kort", "Invalid date, date format must be YYYY-MM-DD" : "Ogiltigt datum, måste anges: ÅÅÅÅ-MM-DD", + "All boards owned by you including stacks, cards, labels, assignments, and comments" : "Alla tavlor som ägs av dig inklusive listor, kort, etiketter, tilldelningar och kommentarer", "Personal planning and team project organization" : "Personlig planering och projekthantering för teams", "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck är en kanban-liknande organiseringsverktyg för personlig planering samt projektorganisering för arbetsgrupper integrerade med Nextcloud.\n\n\n- 📥 Lägg till uppgifter på kort och lägg de i ordning\n- 📄 Skriv anteckningar i Markdown\n- 🔖 Tilldela etiketter för bättre organisering\n- 👥 Dela med arbetsgruppen, vänner eller familj\n- 📎 Bifoga filer och bädda in dem i Markdown-anteckningarna\n- 💬 Diskutera med arbetsgruppen med hjälp av kommentarer\n- ⚡ Håll koll på ändringar i aktivitetsflödet\n- 🚀 Få struktur på dina projekt", "Add board" : "Lägg till tavla", From d85e1c8f58292a0e93c395adfab04e06f4c71a26 Mon Sep 17 00:00:00 2001 From: Chris Coutinho Date: Sun, 3 May 2026 18:45:05 +0200 Subject: [PATCH 030/190] feat(events): make card, ACL and board events webhook-compatible Implement OCP\EventDispatcher\IWebhookCompatibleEvent on the event base classes used by Deck so the webhook_listeners app (NC >= 30) can deliver them. Card events serialize the full Card payload, ACL events serialize the Acl entity (with the token already stripped by Acl:: jsonSerialize), and BoardUpdatedEvent exposes the board id it carries. Refs nextcloud/deck#1722, nextcloud/deck#7299, nextcloud/deck#3341 Signed-off-by: Chris Coutinho --- lib/Event/AAclEvent.php | 9 ++- lib/Event/ACardEvent.php | 9 ++- lib/Event/BoardUpdatedEvent.php | 9 ++- .../Event/WebhookCompatibleEventsTest.php | 57 +++++++++++++++++++ 4 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 tests/unit/Event/WebhookCompatibleEventsTest.php diff --git a/lib/Event/AAclEvent.php b/lib/Event/AAclEvent.php index fecd410f50..004d0038da 100644 --- a/lib/Event/AAclEvent.php +++ b/lib/Event/AAclEvent.php @@ -12,8 +12,9 @@ use OCA\Deck\Db\Acl; use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IWebhookCompatibleEvent; -abstract class AAclEvent extends Event { +abstract class AAclEvent extends Event implements IWebhookCompatibleEvent { private $acl; public function __construct(Acl $acl) { @@ -29,4 +30,10 @@ public function getAcl(): Acl { public function getBoardId(): int { return $this->acl->getBoardId(); } + + public function getWebhookSerializable(): array { + return [ + 'acl' => $this->acl->jsonSerialize(), + ]; + } } diff --git a/lib/Event/ACardEvent.php b/lib/Event/ACardEvent.php index b26620c7ad..797665b9c4 100644 --- a/lib/Event/ACardEvent.php +++ b/lib/Event/ACardEvent.php @@ -12,8 +12,9 @@ use OCA\Deck\Db\Card; use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IWebhookCompatibleEvent; -abstract class ACardEvent extends Event { +abstract class ACardEvent extends Event implements IWebhookCompatibleEvent { private $card; public function __construct(Card $card) { @@ -25,4 +26,10 @@ public function __construct(Card $card) { public function getCard(): Card { return $this->card; } + + public function getWebhookSerializable(): array { + return [ + 'card' => $this->card->jsonSerialize(), + ]; + } } diff --git a/lib/Event/BoardUpdatedEvent.php b/lib/Event/BoardUpdatedEvent.php index c2494c4b32..9b37c7e8dd 100644 --- a/lib/Event/BoardUpdatedEvent.php +++ b/lib/Event/BoardUpdatedEvent.php @@ -11,8 +11,9 @@ namespace OCA\Deck\Event; use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IWebhookCompatibleEvent; -class BoardUpdatedEvent extends Event { +class BoardUpdatedEvent extends Event implements IWebhookCompatibleEvent { private $boardId; public function __construct(int $boardId) { @@ -24,4 +25,10 @@ public function __construct(int $boardId) { public function getBoardId(): int { return $this->boardId; } + + public function getWebhookSerializable(): array { + return [ + 'boardId' => $this->boardId, + ]; + } } diff --git a/tests/unit/Event/WebhookCompatibleEventsTest.php b/tests/unit/Event/WebhookCompatibleEventsTest.php new file mode 100644 index 0000000000..ab856e5ec2 --- /dev/null +++ b/tests/unit/Event/WebhookCompatibleEventsTest.php @@ -0,0 +1,57 @@ +setId(42); + $card->setTitle('Test card'); + $card->setStackId(1); + + $event = new CardCreatedEvent($card); + + $this->assertInstanceOf(IWebhookCompatibleEvent::class, $event); + $payload = $event->getWebhookSerializable(); + $this->assertArrayHasKey('card', $payload); + $this->assertSame(42, $payload['card']['id']); + $this->assertSame('Test card', $payload['card']['title']); + } + + public function testAclEventIsWebhookCompatible(): void { + $acl = new Acl(); + $acl->setId(7); + $acl->setBoardId(3); + $acl->setType(Acl::PERMISSION_TYPE_USER); + $acl->setParticipant('alice'); + $acl->setPermissionEdit(true); + + $event = new AclCreatedEvent($acl); + + $this->assertInstanceOf(IWebhookCompatibleEvent::class, $event); + $payload = $event->getWebhookSerializable(); + $this->assertArrayHasKey('acl', $payload); + $this->assertSame(7, $payload['acl']['id']); + $this->assertSame(3, $payload['acl']['boardId']); + $this->assertArrayNotHasKey('token', $payload['acl'], 'token must be stripped from serialized ACL'); + } + + public function testBoardUpdatedEventIsWebhookCompatible(): void { + $event = new BoardUpdatedEvent(99); + + $this->assertInstanceOf(IWebhookCompatibleEvent::class, $event); + $this->assertSame(['boardId' => 99], $event->getWebhookSerializable()); + } +} From 53f29e193c9d5c65e71c98de2b3aa0df4801081b Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Mon, 16 Mar 2026 17:50:36 +0100 Subject: [PATCH 031/190] feat: add Gantt chart view for boards Add a timeline/Gantt view as an alternative to the kanban board view, allowing users to visualize card schedules across time using frappe-gantt. - Add GanttView component with Day/Week/Month view modes - Add Kanban/Gantt view toggle in board controls - Store view mode preference in localStorage via Vuex - Stack-based color coding with legend and undated cards section - Drag-and-drop support for rescheduling cards - Auto-fit column width to fill container on wider views - Add frappe-gantt dependency and webpack resolve alias for its CSS Co-Authored-By: Claude Opus 4.6 Signed-off-by: Paul Spooren --- package-lock.json | 909 +++++------------------------ package.json | 1 + src/components/Controls.vue | 26 +- src/components/board/Board.vue | 7 + src/components/board/GanttView.vue | 514 ++++++++++++++++ src/store/main.js | 8 + webpack.js | 3 + 7 files changed, 710 insertions(+), 758 deletions(-) create mode 100644 src/components/board/GanttView.vue diff --git a/package-lock.json b/package-lock.json index 271b222139..61b94d6c82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "blueimp-md5": "^2.19.0", "chroma-js": "^3.2.0", "dompurify": "^3.4.0", + "frappe-gantt": "^1.2.2", "lodash": "^4.18.1", "markdown-it": "^14.1.1", "markdown-it-link-attributes": "^4.0.1", @@ -76,7 +77,6 @@ "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -151,6 +151,7 @@ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -232,7 +233,6 @@ "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/types": "^7.27.3" }, @@ -290,7 +290,6 @@ "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", @@ -313,7 +312,6 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -324,7 +322,6 @@ "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", @@ -343,7 +340,6 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -354,7 +350,6 @@ "integrity": "sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", @@ -372,7 +367,6 @@ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -401,7 +395,6 @@ "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" @@ -448,7 +441,6 @@ "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/types": "^7.27.1" }, @@ -472,7 +464,6 @@ "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", @@ -491,7 +482,6 @@ "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", @@ -510,7 +500,6 @@ "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" @@ -553,7 +542,6 @@ "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/template": "^7.28.6", "@babel/traverse": "^7.28.6", @@ -598,7 +586,6 @@ "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" @@ -616,7 +603,6 @@ "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -633,7 +619,6 @@ "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -650,7 +635,6 @@ "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", @@ -669,7 +653,6 @@ "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/traverse": "^7.28.6" @@ -687,7 +670,6 @@ "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" }, @@ -750,7 +732,6 @@ "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, @@ -767,7 +748,6 @@ "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, @@ -919,7 +899,6 @@ "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -937,7 +916,6 @@ "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -954,7 +932,6 @@ "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1", @@ -973,7 +950,6 @@ "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", @@ -992,7 +968,6 @@ "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1009,7 +984,6 @@ "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, @@ -1026,7 +1000,6 @@ "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" @@ -1044,7 +1017,6 @@ "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" @@ -1062,7 +1034,6 @@ "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.28.6", @@ -1084,7 +1055,6 @@ "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/template": "^7.28.6" @@ -1102,7 +1072,6 @@ "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" @@ -1120,7 +1089,6 @@ "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" @@ -1138,7 +1106,6 @@ "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1155,7 +1122,6 @@ "integrity": "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" @@ -1173,7 +1139,6 @@ "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1190,7 +1155,6 @@ "integrity": "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/plugin-transform-destructuring": "^7.28.5" @@ -1208,7 +1172,6 @@ "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, @@ -1225,7 +1188,6 @@ "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1242,7 +1204,6 @@ "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" @@ -1260,7 +1221,6 @@ "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", @@ -1279,7 +1239,6 @@ "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, @@ -1296,7 +1255,6 @@ "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1313,7 +1271,6 @@ "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, @@ -1330,7 +1287,6 @@ "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1347,7 +1303,6 @@ "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -1382,7 +1337,6 @@ "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-module-transforms": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", @@ -1402,7 +1356,6 @@ "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -1420,7 +1373,6 @@ "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" @@ -1438,7 +1390,6 @@ "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1455,7 +1406,6 @@ "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, @@ -1472,7 +1422,6 @@ "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, @@ -1489,7 +1438,6 @@ "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", @@ -1510,7 +1458,6 @@ "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1" @@ -1528,7 +1475,6 @@ "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, @@ -1545,7 +1491,6 @@ "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" @@ -1563,7 +1508,6 @@ "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1580,7 +1524,6 @@ "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" @@ -1598,7 +1541,6 @@ "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.6", @@ -1617,7 +1559,6 @@ "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1634,7 +1575,6 @@ "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, @@ -1651,7 +1591,6 @@ "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" @@ -1669,7 +1608,6 @@ "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1686,7 +1624,6 @@ "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1703,7 +1640,6 @@ "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" @@ -1721,7 +1657,6 @@ "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1738,7 +1673,6 @@ "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1755,7 +1689,6 @@ "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1772,7 +1705,6 @@ "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1789,7 +1721,6 @@ "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" @@ -1807,7 +1738,6 @@ "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -1825,7 +1755,6 @@ "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" @@ -1851,7 +1780,6 @@ "integrity": "sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/compat-data": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", @@ -1937,7 +1865,6 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -1948,7 +1875,6 @@ "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", @@ -2080,7 +2006,6 @@ "integrity": "sha512-FvEb29x5wVwu/Kf93IWwsOOEuhHh6dYCJF3vcKLzXc0KXIW181AOzv6ceT4ZpBHDvAfG60eqb+ekmrnLHIy+jw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@cacheable/utils": "^2.4.0", "@keyv/bigmap": "^1.3.1", @@ -2094,7 +2019,6 @@ "integrity": "sha512-PeMMsqjVq+bF0WBsxFBxr/WozBJiZKY0rUojuaCoIaKnEl3Ju1wfEwS+SV1DU/cSe8fqHIPiYJFif8T3MVt4cQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "hashery": "^1.5.0", "keyv": "^5.6.0" @@ -2126,7 +2050,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=20.19.0" }, @@ -2196,7 +2119,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=20.19.0" }, @@ -2299,7 +2221,6 @@ "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=14.17.0" } @@ -2309,7 +2230,6 @@ "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.40.1.tgz", "integrity": "sha512-YORCdZSusAlBrFpZ77pJjc5r1bQs5caPWtAu+WWmiSo+8XaUzseapVrfAtiRFbQWnrBxxLLEwF6f6ZG/UgCQCg==", "dev": true, - "peer": true, "dependencies": { "comment-parser": "1.4.0", "esquery": "^1.5.0", @@ -2766,7 +2686,6 @@ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, - "peer": true, "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -2782,7 +2701,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -2795,7 +2713,6 @@ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, - "peer": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -2805,7 +2722,6 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, - "peer": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -2828,15 +2744,13 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, - "peer": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -2853,7 +2767,6 @@ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -2866,7 +2779,6 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "peer": true, "engines": { "node": ">=8" }, @@ -2879,7 +2791,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -2892,7 +2803,6 @@ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -2979,7 +2889,6 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, - "peer": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", @@ -2994,7 +2903,6 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "peer": true, "engines": { "node": ">=12.22" }, @@ -3007,8 +2915,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -3911,7 +3818,6 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" @@ -3949,7 +3855,6 @@ "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", "dev": true, - "peer": true, "engines": { "node": ">=10.0" }, @@ -3966,7 +3871,6 @@ "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz", "integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==", "dev": true, - "peer": true, "dependencies": { "@jsonjoy.com/base64": "^1.1.1", "@jsonjoy.com/util": "^1.1.2", @@ -3989,7 +3893,6 @@ "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.3.0.tgz", "integrity": "sha512-Cebt4Vk7k1xHy87kHY7KSPLT77A7Ev7IfOblyLZhtYEhrdQ6fX4EoLq3xOQ3O/DRMEh2ok5nyC180E+ABS8Wmw==", "dev": true, - "peer": true, "engines": { "node": ">=10.0" }, @@ -4007,7 +3910,6 @@ "integrity": "sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "hashery": "^1.4.0", "hookified": "^1.15.0" @@ -4024,15 +3926,13 @@ "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@linusborg/vue-simple-portal": { "version": "0.1.5", @@ -4728,6 +4628,7 @@ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.30.tgz", "integrity": "sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==", "license": "MIT", + "peer": true, "dependencies": { "@babel/parser": "^7.29.0", "@vue/compiler-core": "3.5.30", @@ -4756,7 +4657,6 @@ "integrity": "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==", "license": "MIT", "optional": true, - "peer": true, "dependencies": { "@vue/devtools-shared": "^7.7.9", "birpc": "^2.3.0", @@ -4773,7 +4673,6 @@ "integrity": "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==", "license": "MIT", "optional": true, - "peer": true, "dependencies": { "rfdc": "^1.4.1" } @@ -4978,8 +4877,7 @@ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "node_modules/@nextcloud/password-confirmation/node_modules/picomatch": { "version": "4.0.4", @@ -4999,7 +4897,6 @@ "integrity": "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==", "license": "MIT", "optional": true, - "peer": true, "dependencies": { "@vue/devtools-api": "^7.7.7" }, @@ -5022,7 +4919,6 @@ "integrity": "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==", "license": "MIT", "optional": true, - "peer": true, "dependencies": { "@vue/devtools-kit": "^7.7.9" } @@ -5132,6 +5028,7 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.30.tgz", "integrity": "sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==", "license": "MIT", + "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.30", "@vue/compiler-sfc": "3.5.30", @@ -5327,6 +5224,7 @@ "resolved": "https://registry.npmjs.org/@nextcloud/vue/-/vue-8.35.0.tgz", "integrity": "sha512-qPm0aaPbnt7n694WQ97T+EMQTxCa3+RPKDzsBVD6vb01N4uGYwjvrEEOLVmBMlEWqkFy+ks3tpeOjkDPOoJbNA==", "license": "AGPL-3.0-or-later", + "peer": true, "dependencies": { "@floating-ui/dom": "^1.7.4", "@linusborg/vue-simple-portal": "^0.1.5", @@ -5553,7 +5451,6 @@ "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", "dev": true, - "peer": true, "dependencies": { "eslint-scope": "5.1.1" } @@ -5563,7 +5460,6 @@ "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz", "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -5609,7 +5505,6 @@ "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12.4.0" } @@ -5625,7 +5520,6 @@ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz", "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==", "dev": true, - "peer": true, "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", @@ -5666,7 +5560,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5687,7 +5580,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5708,7 +5600,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5729,7 +5620,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5750,7 +5640,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5771,7 +5660,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5792,7 +5680,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5813,7 +5700,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5834,7 +5720,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5855,7 +5740,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5876,7 +5760,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -5897,7 +5780,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -6049,6 +5931,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -6094,7 +5977,6 @@ "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -6172,7 +6054,6 @@ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, - "peer": true, "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -6183,7 +6064,6 @@ "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -6201,7 +6081,6 @@ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -6211,7 +6090,6 @@ "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", "dev": true, - "peer": true, "dependencies": { "@types/express-serve-static-core": "*", "@types/node": "*" @@ -6246,7 +6124,6 @@ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "license": "MIT", - "peer": true, "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -6272,7 +6149,6 @@ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, - "peer": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -6285,7 +6161,6 @@ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.0.tgz", "integrity": "sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -6298,7 +6173,6 @@ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -6327,15 +6201,13 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/http-proxy": { "version": "1.17.15", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -6382,8 +6254,7 @@ "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/marked": { "version": "4.3.0", @@ -6402,8 +6273,7 @@ "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/ms": { "version": "2.1.0", @@ -6424,7 +6294,6 @@ "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -6432,22 +6301,19 @@ "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "peer": true + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/qs": { "version": "6.9.16", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/react": { "version": "18.0.28", @@ -6464,14 +6330,12 @@ "version": "0.12.2", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "peer": true + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "node_modules/@types/semver": { "version": "7.7.1", @@ -6484,7 +6348,6 @@ "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dev": true, - "peer": true, "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -6495,7 +6358,6 @@ "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", "dev": true, - "peer": true, "dependencies": { "@types/express": "*" } @@ -6505,7 +6367,6 @@ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", "dev": true, - "peer": true, "dependencies": { "@types/http-errors": "*", "@types/node": "*", @@ -6528,7 +6389,6 @@ "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -6586,7 +6446,6 @@ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -6621,7 +6480,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz", "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==", "dev": true, - "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "7.9.0", @@ -6738,7 +6596,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", "dev": true, - "peer": true, "dependencies": { "@typescript-eslint/types": "7.9.0", "@typescript-eslint/visitor-keys": "7.9.0" @@ -6773,7 +6630,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz", "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==", "dev": true, - "peer": true, "dependencies": { "@typescript-eslint/typescript-estree": "7.9.0", "@typescript-eslint/utils": "7.9.0", @@ -6801,7 +6657,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", "dev": true, - "peer": true, "engines": { "node": "^18.18.0 || >=20.0.0" }, @@ -6815,7 +6670,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", "dev": true, - "peer": true, "dependencies": { "@typescript-eslint/types": "7.9.0", "@typescript-eslint/visitor-keys": "7.9.0", @@ -6845,7 +6699,6 @@ "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -6856,7 +6709,6 @@ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "brace-expansion": "^2.0.2" }, @@ -6872,7 +6724,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz", "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==", "dev": true, - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "7.9.0", @@ -6895,7 +6746,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", "dev": true, - "peer": true, "dependencies": { "@typescript-eslint/types": "7.9.0", "eslint-visitor-keys": "^3.4.3" @@ -6913,7 +6763,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -7413,7 +7262,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", "@webassemblyjs/helper-wasm-bytecode": "1.13.2" @@ -7423,29 +7271,25 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.13.2", "@webassemblyjs/helper-api-error": "1.13.2", @@ -7456,15 +7300,13 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -7477,7 +7319,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "license": "MIT", - "peer": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -7487,7 +7328,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@xtuc/long": "4.2.2" } @@ -7496,15 +7336,13 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -7521,7 +7359,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-wasm-bytecode": "1.13.2", @@ -7535,7 +7372,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -7548,7 +7384,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-api-error": "1.13.2", @@ -7563,7 +7398,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "license": "MIT", - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" @@ -7575,7 +7409,6 @@ "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18.12.0" }, @@ -7590,7 +7423,6 @@ "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18.12.0" }, @@ -7605,7 +7437,6 @@ "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18.12.0" }, @@ -7623,14 +7454,12 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "peer": true + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, "node_modules/abbrev": { "version": "2.0.0", @@ -7646,7 +7475,6 @@ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "dev": true, - "peer": true, "dependencies": { "event-target-shim": "^5.0.0" }, @@ -7659,7 +7487,6 @@ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, - "peer": true, "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -7673,6 +7500,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -7685,7 +7513,6 @@ "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=10.13.0" }, @@ -7698,7 +7525,6 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "peer": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -7735,7 +7561,6 @@ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -7816,7 +7641,6 @@ "engines": [ "node >= 0.8.0" ], - "peer": true, "bin": { "ansi-html": "bin/ansi-html" } @@ -7886,7 +7710,6 @@ "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", "dev": true, - "peer": true, "engines": { "node": ">=14" } @@ -7924,15 +7747,13 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/array-includes": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7960,7 +7781,6 @@ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7980,7 +7800,6 @@ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7999,7 +7818,6 @@ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -8018,7 +7836,6 @@ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", "dev": true, - "peer": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", "call-bind": "^1.0.2", @@ -8049,7 +7866,6 @@ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, - "peer": true, "dependencies": { "bn.js": "^4.0.0", "inherits": "^2.0.1", @@ -8060,15 +7876,13 @@ "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/assert": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "is-nan": "^1.3.2", @@ -8213,6 +8027,7 @@ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, + "peer": true, "dependencies": { "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", @@ -8354,7 +8169,6 @@ "integrity": "sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-define-polyfill-provider": "^0.6.6", @@ -8370,7 +8184,6 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -8381,7 +8194,6 @@ "integrity": "sha512-AvDcMxJ34W4Wgy4KBIIePQTAOP1Ie2WFwkQp3dB7FQ/f0lI5+nM96zUnYEOE1P9sEg0es5VCP0HxiWu5fUHZAQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.6", "core-js-compat": "^3.48.0" @@ -8396,7 +8208,6 @@ "integrity": "sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.6" }, @@ -8494,8 +8305,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", @@ -8511,7 +8321,6 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, - "peer": true, "engines": { "node": ">=8" }, @@ -8592,8 +8401,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/body-parser": { "version": "1.20.4", @@ -8601,7 +8409,6 @@ "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "bytes": "~3.1.2", "content-type": "~1.0.5", @@ -8626,7 +8433,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -8637,7 +8443,6 @@ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", @@ -8657,8 +8462,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/body-parser/node_modules/statuses": { "version": "2.0.2", @@ -8666,7 +8470,6 @@ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -8676,7 +8479,6 @@ "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", "dev": true, - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" @@ -8686,8 +8488,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true, - "peer": true + "dev": true }, "node_modules/brace-expansion": { "version": "1.1.13", @@ -8716,15 +8517,13 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, - "peer": true, "dependencies": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", @@ -8739,7 +8538,6 @@ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, - "peer": true, "dependencies": { "browserify-aes": "^1.0.4", "browserify-des": "^1.0.0", @@ -8751,7 +8549,6 @@ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", "dev": true, - "peer": true, "dependencies": { "cipher-base": "^1.0.1", "des.js": "^1.0.0", @@ -8764,7 +8561,6 @@ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz", "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==", "dev": true, - "peer": true, "dependencies": { "bn.js": "^5.2.1", "randombytes": "^2.1.0", @@ -8792,15 +8588,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/browserify-sign": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", "dev": true, - "peer": true, "dependencies": { "bn.js": "^5.2.1", "browserify-rsa": "^4.1.0", @@ -8822,7 +8616,6 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -8837,8 +8630,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/browserify-sign/node_modules/safe-buffer": { "version": "5.2.1", @@ -8858,15 +8650,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/browserify-sign/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -8875,15 +8665,13 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/browserify-zlib": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, - "peer": true, "dependencies": { "pako": "~1.0.5" } @@ -8907,6 +8695,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -8949,7 +8738,6 @@ "url": "https://feross.org/support" } ], - "peer": true, "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -8972,8 +8760,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/buildcheck": { "version": "0.0.6", @@ -8990,7 +8777,6 @@ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true, - "peer": true, "engines": { "node": ">=6" }, @@ -9002,15 +8788,13 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/builtins": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", "dev": true, - "peer": true, "dependencies": { "semver": "^7.0.0" } @@ -9020,7 +8804,6 @@ "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", "dev": true, - "peer": true, "dependencies": { "run-applescript": "^7.0.0" }, @@ -9042,7 +8825,6 @@ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -9053,7 +8835,6 @@ "integrity": "sha512-djgxybDbw9fL/ZWMI3+CE8ZilNxcwFkVtDc1gJ+IlOSSWkSMPQabhV/XCHTQ6pwwN6aivXPZ43omTooZiX06Ew==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@cacheable/memory": "^2.0.8", "@cacheable/utils": "^2.4.0", @@ -9261,7 +9042,6 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", "dev": true, - "peer": true, "dependencies": { "readdirp": "^4.0.1" }, @@ -9288,7 +9068,6 @@ "node_modules/chrome-trace-event": { "version": "1.0.3", "license": "MIT", - "peer": true, "engines": { "node": ">=6.0" } @@ -9305,7 +9084,6 @@ "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1", @@ -9334,8 +9112,7 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cjs-module-lexer": { "version": "1.2.3", @@ -9473,7 +9250,6 @@ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", @@ -9489,7 +9265,6 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -9540,8 +9315,7 @@ "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/colorette": { "version": "2.0.16", @@ -9583,7 +9357,6 @@ "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.0.tgz", "integrity": "sha512-QLyTNiZ2KDOibvFPlZ6ZngVsZ/0gYnE6uTXi5aoDg8ed3AkJAz4sEje3Y8a29hQ1s6A99MZXe47fLAXQ1rTqaw==", "dev": true, - "peer": true, "engines": { "node": ">= 12.0.0" } @@ -9602,7 +9375,6 @@ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, - "peer": true, "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -9616,7 +9388,6 @@ "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "bytes": "3.1.2", "compressible": "~2.0.18", @@ -9635,7 +9406,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -9644,8 +9414,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/compression/node_modules/negotiator": { "version": "0.6.4", @@ -9653,7 +9422,6 @@ "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -9677,8 +9445,7 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", @@ -9730,7 +9497,6 @@ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", "dev": true, - "peer": true, "engines": { "node": ">=0.8" } @@ -9739,8 +9505,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/console.table": { "version": "0.10.0", @@ -9771,15 +9536,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, - "peer": true, "dependencies": { "safe-buffer": "5.2.1" }, @@ -9805,15 +9568,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -9833,7 +9594,6 @@ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -9842,8 +9602,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/copy-anything": { "version": "4.0.5", @@ -9851,7 +9610,6 @@ "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==", "license": "MIT", "optional": true, - "peer": true, "dependencies": { "is-what": "^5.2.0" }, @@ -9873,7 +9631,6 @@ "integrity": "sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "browserslist": "^4.28.1" }, @@ -9952,7 +9709,6 @@ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", "dev": true, - "peer": true, "dependencies": { "bn.js": "^4.1.0", "elliptic": "^6.5.3" @@ -9962,15 +9718,13 @@ "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, - "peer": true, "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -9984,7 +9738,6 @@ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, - "peer": true, "dependencies": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -10145,7 +9898,6 @@ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, - "peer": true, "dependencies": { "browserify-cipher": "^1.0.0", "browserify-sign": "^4.0.0", @@ -10169,7 +9921,6 @@ "integrity": "sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" } @@ -10246,6 +9997,7 @@ "integrity": "sha512-5xWkaPurwkIljojFidhw8lFScyxhtiFHl/i/3zov+1Z5CmY4t9tjIdvSXfu82Y3w7wt0uR9KkucbhkVvJZLQSA==", "dev": true, "hasInstallScript": true, + "peer": true, "dependencies": { "@cypress/request": "^3.0.6", "@cypress/xvfb": "^1.2.4", @@ -10649,8 +10401,7 @@ "node_modules/deep-is": { "version": "0.1.3", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", @@ -10666,7 +10417,6 @@ "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", "dev": true, - "peer": true, "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" @@ -10683,7 +10433,6 @@ "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", "dev": true, - "peer": true, "engines": { "node": ">=18" }, @@ -10738,7 +10487,6 @@ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, - "peer": true, "engines": { "node": ">=12" }, @@ -10776,7 +10524,6 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -10823,7 +10570,6 @@ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", "dev": true, - "peer": true, "dependencies": { "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0" @@ -10834,7 +10580,6 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -10845,7 +10590,6 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, - "peer": true, "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -10866,8 +10610,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/detective-amd": { "version": "6.0.1", @@ -11197,7 +10940,6 @@ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, - "peer": true, "dependencies": { "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", @@ -11208,8 +10950,7 @@ "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/dir-glob": { "version": "3.0.1", @@ -11227,7 +10968,6 @@ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", "dev": true, - "peer": true, "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -11288,7 +11028,6 @@ "version": "3.0.0", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "esutils": "^2.0.2" }, @@ -11302,7 +11041,6 @@ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -11317,7 +11055,6 @@ "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-5.7.0.tgz", "integrity": "sha512-edTFu0M/7wO1pXY6GDxVNVW086uqwWYIHP98txhcPyV995X21JIH2DtYp33sQJOupYoXKe9RwTw2Ya2vWaquTQ==", "dev": true, - "peer": true, "engines": { "node": ">=4" }, @@ -11336,8 +11073,7 @@ "url": "https://github.com/sponsors/fb55" } ], - "license": "BSD-2-Clause", - "peer": true + "license": "BSD-2-Clause" }, "node_modules/domhandler": { "version": "5.0.3", @@ -11345,7 +11081,6 @@ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "domelementtype": "^2.3.0" }, @@ -11371,7 +11106,6 @@ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -11516,8 +11250,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true, - "peer": true + "dev": true }, "node_modules/electron-to-chromium": { "version": "1.5.286", @@ -11531,7 +11264,6 @@ "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -11546,8 +11278,7 @@ "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/emittery": { "version": "0.13.1", @@ -11596,7 +11327,6 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -11628,6 +11358,7 @@ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dev": true, + "peer": true, "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -11676,7 +11407,6 @@ "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "envinfo": "dist/cli.js" }, @@ -11697,7 +11427,6 @@ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==", "dev": true, - "peer": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", "arraybuffer.prototype.slice": "^1.0.2", @@ -11795,8 +11524,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/es-object-atoms": { "version": "1.1.1", @@ -11830,7 +11558,6 @@ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", "dev": true, - "peer": true, "dependencies": { "has": "^1.0.3" } @@ -11839,7 +11566,6 @@ "version": "1.2.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -12063,7 +11789,6 @@ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, - "peer": true, "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -12075,7 +11800,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -12121,7 +11845,6 @@ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dev": true, - "peer": true, "dependencies": { "debug": "^3.2.7" }, @@ -12139,7 +11862,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -12189,7 +11911,6 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.2.0.tgz", "integrity": "sha512-9dvv5CcvNjSJPqnS5uZkqb3xmbeqRLnvXKK7iI5+oK/yTusyc46zbBZKENGsOfojm/mKfszyZb+wNqNPAPeGXA==", "dev": true, - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.1.2", "@eslint-community/regexpp": "^4.6.0" @@ -12241,7 +11962,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -12251,7 +11971,6 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, - "peer": true, "dependencies": { "esutils": "^2.0.2" }, @@ -12264,7 +11983,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -12274,7 +11992,6 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.8.2.tgz", "integrity": "sha512-5TSnD018f3tUJNne4s4gDWQflbsgOycIKEUBoCLn6XtBMgNHxQFmV8vVxUtiPxAQq8lrX85OaSG/2gnctxw9uQ==", "dev": true, - "peer": true, "dependencies": { "@es-joy/jsdoccomment": "~0.40.1", "are-docs-informative": "^0.0.2", @@ -12298,7 +12015,6 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -12378,7 +12094,6 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, - "peer": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -12394,7 +12109,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -12405,7 +12119,6 @@ "node_modules/eslint-scope": { "version": "5.1.1", "license": "BSD-2-Clause", - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -12419,7 +12132,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, - "peer": true, "engines": { "node": ">=10" } @@ -12493,14 +12205,12 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -12516,7 +12226,6 @@ "version": "4.3.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -12531,7 +12240,6 @@ "version": "7.2.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -12543,7 +12251,6 @@ "version": "2.0.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -12554,15 +12261,13 @@ "node_modules/eslint/node_modules/color-name": { "version": "1.1.4", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -12575,7 +12280,6 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -12592,7 +12296,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -12605,7 +12308,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "peer": true, "engines": { "node": ">=4.0" } @@ -12615,7 +12317,6 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "peer": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -12628,7 +12329,6 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, - "peer": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -12643,7 +12343,6 @@ "version": "4.0.0", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -12654,7 +12353,6 @@ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -12667,7 +12365,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -12680,7 +12377,6 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, - "peer": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -12698,7 +12394,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -12724,7 +12419,6 @@ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, - "peer": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -12736,7 +12430,6 @@ "version": "5.2.0", "dev": true, "license": "BSD-2-Clause", - "peer": true, "engines": { "node": ">=4.0" } @@ -12745,7 +12438,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "peer": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -12757,7 +12449,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "peer": true, "engines": { "node": ">=4.0" } @@ -12765,7 +12456,6 @@ "node_modules/estraverse": { "version": "4.2.0", "license": "BSD-2-Clause", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -12798,7 +12488,6 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -12808,7 +12497,6 @@ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -12823,13 +12511,11 @@ "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/events": { "version": "3.3.0", "license": "MIT", - "peer": true, "engines": { "node": ">=0.8.x" } @@ -12839,7 +12525,6 @@ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, - "peer": true, "dependencies": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" @@ -12911,7 +12596,6 @@ "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -12958,7 +12642,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -12967,8 +12650,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", @@ -12988,8 +12670,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/exsolve": { "version": "1.0.8", @@ -13076,8 +12757,7 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/fast-shuffle": { "version": "6.1.1", @@ -13132,7 +12812,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "strnum": "^1.0.5" }, @@ -13145,7 +12824,6 @@ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, - "peer": true, "engines": { "node": ">= 4.9.1" } @@ -13163,7 +12841,6 @@ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "dev": true, - "peer": true, "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -13230,7 +12907,6 @@ "version": "6.0.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "flat-cache": "^3.0.4" }, @@ -13306,7 +12982,6 @@ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dev": true, - "peer": true, "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", @@ -13325,7 +13000,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -13334,8 +13008,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/find-cypress-specs": { "version": "1.54.12", @@ -13429,7 +13102,6 @@ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -13447,7 +13119,6 @@ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "bin": { "flat": "cli.js" } @@ -13456,7 +13127,6 @@ "version": "3.0.4", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "flatted": "^3.1.0", "rimraf": "^3.0.2" @@ -13598,17 +13268,21 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } }, + "node_modules/frappe-gantt": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/frappe-gantt/-/frappe-gantt-1.2.2.tgz", + "integrity": "sha512-1+uPNRa92LBIeKiZCVhJMiGIifJk5ONaoerXI8eBREXWRZGGoTJR5ATpMpsnAQcyBA6Gnq5wIht4eL+e4eHMBA==", + "license": "MIT" + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -13688,7 +13362,6 @@ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -13747,7 +13420,6 @@ "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -13825,7 +13497,6 @@ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -13933,7 +13604,6 @@ "version": "2.0.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "global-prefix": "^3.0.0" }, @@ -13945,7 +13615,6 @@ "version": "3.0.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -13959,7 +13628,6 @@ "version": "6.0.3", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -13969,7 +13637,6 @@ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, - "peer": true, "dependencies": { "define-properties": "^1.1.3" }, @@ -14003,8 +13670,7 @@ "node_modules/globjoin": { "version": "0.1.4", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/gonzales-pe": { "version": "4.3.0", @@ -14043,21 +13709,18 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "peer": true + "dev": true }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/has": { "version": "1.0.3", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -14099,7 +13762,6 @@ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -14139,7 +13801,6 @@ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", "dev": true, - "peer": true, "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -14159,7 +13820,6 @@ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "dev": true, - "peer": true, "dependencies": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" @@ -14171,7 +13831,6 @@ "integrity": "sha512-nhQ6ExaOIqti2FDWoEMWARUqIKyjr2VcZzXShrI+A3zpeiuPWzx6iPftt44LhP74E5sW36B75N6VHbvRtpvO6Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "hookified": "^1.14.0" }, @@ -14381,7 +14040,6 @@ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", "dev": true, - "peer": true, "dependencies": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -14399,8 +14057,7 @@ "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", "integrity": "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/hot-patcher": { "version": "2.0.1", @@ -14412,7 +14069,6 @@ "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "dev": true, - "peer": true, "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -14425,7 +14081,6 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -14441,7 +14096,6 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -14458,7 +14112,6 @@ "integrity": "sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=20.10" }, @@ -14479,7 +14132,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", @@ -14491,15 +14143,13 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, - "peer": true, "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -14515,15 +14165,13 @@ "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/http-proxy": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, - "peer": true, "dependencies": { "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", @@ -14539,7 +14187,6 @@ "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -14564,7 +14211,6 @@ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -14590,8 +14236,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/human-signals": { "version": "2.1.0", @@ -14617,7 +14262,6 @@ "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", "dev": true, - "peer": true, "engines": { "node": ">=10.18" } @@ -14634,7 +14278,6 @@ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -14647,7 +14290,6 @@ "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "dev": true, - "peer": true, "engines": { "node": "^10 || ^12 || >= 14" }, @@ -14689,8 +14331,7 @@ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.8.tgz", "integrity": "sha512-d/Ld9aLbKpNwyl0KiM2CT1WYvkitQ1TSvmRtkcV8FKStiDoA7Slzgjmb/1G2yhKM1p0XeNOieaTbFZmU1d3Xuw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/import-fresh": { "version": "3.3.0", @@ -14737,7 +14378,6 @@ "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", "dev": true, "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -14806,7 +14446,6 @@ "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10.13.0" } @@ -14816,7 +14455,6 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", "dev": true, - "peer": true, "engines": { "node": ">= 10" } @@ -14908,7 +14546,6 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, - "peer": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -14941,7 +14578,6 @@ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", "dev": true, - "peer": true, "dependencies": { "builtin-modules": "^3.3.0" }, @@ -14958,7 +14594,6 @@ "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "semver": "^7.6.3" } @@ -15023,7 +14658,6 @@ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", "dev": true, - "peer": true, "bin": { "is-docker": "cli.js" }, @@ -15073,7 +14707,6 @@ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dev": true, - "peer": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -15111,7 +14744,6 @@ "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", "dev": true, - "peer": true, "dependencies": { "is-docker": "^3.0.0" }, @@ -15159,7 +14791,6 @@ "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3" @@ -15176,7 +14807,6 @@ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -15189,7 +14819,6 @@ "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", "dev": true, - "peer": true, "engines": { "node": ">=16" }, @@ -15257,7 +14886,6 @@ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "isobject": "^3.0.1" }, @@ -15445,7 +15073,6 @@ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -15476,7 +15103,6 @@ "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==", "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=18" }, @@ -15497,7 +15123,6 @@ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "dev": true, - "peer": true, "dependencies": { "is-inside-container": "^1.0.0" }, @@ -15512,8 +15137,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/isexe": { "version": "2.0.0", @@ -15526,7 +15150,6 @@ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -15672,6 +15295,7 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -17294,7 +16918,6 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "peer": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -17308,7 +16931,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "peer": true, "engines": { "node": ">=8" } @@ -17317,7 +16939,6 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -17450,7 +17071,6 @@ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true, - "peer": true, "engines": { "node": ">=12.0.0" } @@ -17481,14 +17101,12 @@ "node_modules/json-schema-traverse": { "version": "0.4.1", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/json-stringify-safe": { "version": "5.0.1", @@ -17570,15 +17188,13 @@ "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.37.0.tgz", "integrity": "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/launch-editor": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", "dev": true, - "peer": true, "dependencies": { "picocolors": "^1.0.0", "shell-quote": "^1.8.1" @@ -17612,7 +17228,6 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, - "peer": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -17647,7 +17262,8 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.3.2.tgz", "integrity": "sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/listr2": { "version": "3.14.0", @@ -17681,7 +17297,6 @@ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "license": "MIT", - "peer": true, "engines": { "node": ">=6.11.5" }, @@ -17713,7 +17328,6 @@ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -17742,15 +17356,13 @@ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/lodash.once": { "version": "4.1.1", @@ -17767,8 +17379,7 @@ "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", @@ -18080,7 +17691,6 @@ "integrity": "sha512-aa6AU2Pcx0VP/XWnh8IGL0SYSgQHDT6Ucror2j2mXeFAlN3ahaNs8EZtG1YiticMkSLj3Gt6VPFfZogt7G5iFQ==", "dev": true, "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -18101,7 +17711,6 @@ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "dev": true, - "peer": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -18467,7 +18076,6 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -18477,7 +18085,6 @@ "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.12.0.tgz", "integrity": "sha512-74wDsex5tQDSClVkeK1vtxqYCAgCoXxx+K4NSHzgU/muYVYByFqa+0RnrPO9NM6naWm1+G9JmZ0p6QHhXmeYfA==", "dev": true, - "peer": true, "dependencies": { "@jsonjoy.com/json-pack": "^1.0.3", "@jsonjoy.com/util": "^1.3.0", @@ -18498,7 +18105,6 @@ "integrity": "sha512-EDYo6VlmtnumlcBCbh1gLJ//9jvM/ndXHfVXIFrZVr6fGcwTUyCTFNTLCKuY3ffbK8L/+3Mzqnd58RojiZqHVw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=20" }, @@ -18511,7 +18117,6 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -18551,7 +18156,6 @@ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -19012,7 +18616,6 @@ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "dev": true, - "peer": true, "dependencies": { "bn.js": "^4.0.0", "brorand": "^1.0.1" @@ -19025,15 +18628,13 @@ "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, - "peer": true, "bin": { "mime": "cli.js" }, @@ -19072,15 +18673,13 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/minimatch": { "version": "3.1.5", @@ -19119,8 +18718,7 @@ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "node_modules/mkdirp-classic": { "version": "0.5.3", @@ -19227,7 +18825,6 @@ "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "dev": true, - "peer": true, "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" @@ -19272,15 +18869,13 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } }, "node_modules/neo-async": { "version": "2.6.2", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/nested-property": { "version": "4.0.0", @@ -19291,8 +18886,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/node-domexception": { "version": "1.0.0", @@ -19339,7 +18933,6 @@ "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", "dev": true, "license": "(BSD-3-Clause OR GPL-2.0)", - "peer": true, "engines": { "node": ">= 6.13.0" } @@ -19355,7 +18948,6 @@ "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-4.0.0.tgz", "integrity": "sha512-WLk77vLpbcpmTekRj6s6vYxk30XoyaY5MDZ4+9g8OaKoG3Ij+TjOqhpQjVUlfDZBPBgpNATDltaQkzuXSnnkwg==", "dev": true, - "peer": true, "dependencies": { "assert": "^2.1.0", "browserify-zlib": "^0.2.0", @@ -19394,7 +18986,6 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, - "peer": true, "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -19411,7 +19002,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", "dev": true, - "peer": true, "engines": { "node": ">=16" }, @@ -19479,7 +19069,6 @@ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, - "peer": true, "dependencies": { "boolbase": "^1.0.0" }, @@ -19547,7 +19136,6 @@ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -19565,7 +19153,6 @@ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -19578,7 +19165,6 @@ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -19595,15 +19181,13 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, - "peer": true, "dependencies": { "ee-first": "1.1.1" }, @@ -19617,7 +19201,6 @@ "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -19649,7 +19232,6 @@ "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", "dev": true, - "peer": true, "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", @@ -19668,7 +19250,6 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, - "peer": true, "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", @@ -19685,8 +19266,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/ospath": { "version": "1.2.2", @@ -19716,7 +19296,6 @@ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -19768,7 +19347,6 @@ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", "dev": true, - "peer": true, "dependencies": { "@types/retry": "0.12.2", "is-network-error": "^1.0.0", @@ -19803,8 +19381,7 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/parent-module": { "version": "1.0.1", @@ -19822,7 +19399,6 @@ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", "dev": true, - "peer": true, "dependencies": { "asn1.js": "^4.10.1", "browserify-aes": "^1.2.0", @@ -19853,8 +19429,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/parse-entities": { "version": "4.0.2", @@ -19898,7 +19473,6 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -19907,8 +19481,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/path-exists": { "version": "4.0.0", @@ -19992,8 +19565,7 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", @@ -20016,7 +19588,6 @@ "integrity": "sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "create-hash": "~1.1.3", "create-hmac": "^1.1.7", @@ -20035,7 +19606,6 @@ "integrity": "sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -20049,7 +19619,6 @@ "integrity": "sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "inherits": "^2.0.1" } @@ -20060,7 +19629,6 @@ "integrity": "sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "hash-base": "^2.0.0", "inherits": "^2.0.1" @@ -20085,8 +19653,7 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/pcg": { "version": "1.1.0", @@ -20332,6 +19899,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -20347,7 +19915,6 @@ "integrity": "sha512-OLF6P7qctfAWayOhLpcVnTGqVeJzu2W3WpIYelfz2+JV5oGxfkcEvweN9U4XpeqE0P98dcD9ssusGwlF0TK0uQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "htmlparser2": "^8.0.0", "js-tokens": "^9.0.0", @@ -20363,23 +19930,20 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/postcss-modules-extract-imports": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", "dev": true, - "peer": true, "engines": { "node": "^10 || ^12 || >= 14" }, @@ -20392,7 +19956,6 @@ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", "dev": true, - "peer": true, "dependencies": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", @@ -20410,7 +19973,6 @@ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", "dev": true, - "peer": true, "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -20426,7 +19988,6 @@ "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", "dev": true, - "peer": true, "dependencies": { "icss-utils": "^5.0.0" }, @@ -20442,8 +20003,7 @@ "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/postcss-safe-parser": { "version": "6.0.0", @@ -20451,7 +20011,6 @@ "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12.0" }, @@ -20483,7 +20042,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=12.0" }, @@ -20508,8 +20066,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/postcss-values-parser": { "version": "6.0.2", @@ -20581,7 +20138,6 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8.0" } @@ -20676,8 +20232,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "peer": true + "dev": true }, "node_modules/prompts": { "version": "2.4.2", @@ -20737,7 +20292,6 @@ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, - "peer": true, "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -20751,7 +20305,6 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, - "peer": true, "engines": { "node": ">= 0.10" } @@ -20772,7 +20325,6 @@ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dev": true, - "peer": true, "dependencies": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", @@ -20786,8 +20338,7 @@ "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/pump": { "version": "3.0.0", @@ -20804,7 +20355,6 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -20839,7 +20389,6 @@ "integrity": "sha512-4q61YgkHbY6gmwkqm0BsxyLDO3UYdrdiJTJ7JiaZb3xpW1duxn135SB7KqUEkCiuu5O4W+TtwEWP2VjmSRanvA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "hookified": "^2.1.0" }, @@ -20852,8 +20401,7 @@ "resolved": "https://registry.npmjs.org/hookified/-/hookified-2.1.0.tgz", "integrity": "sha512-ootKng4eaxNxa7rx6FJv2YKef3DuhqbEj3l70oGXwddPQEEnISm50TEZQclqiLTAtilT2nu7TErtCO523hHkyg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/qs": { "version": "6.14.1", @@ -20861,7 +20409,6 @@ "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "side-channel": "^1.1.0" }, @@ -20893,7 +20440,6 @@ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", "dev": true, - "peer": true, "engines": { "node": ">=0.4.x" } @@ -20945,7 +20491,6 @@ "version": "2.1.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "safe-buffer": "^5.1.0" } @@ -20955,7 +20500,6 @@ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, - "peer": true, "dependencies": { "randombytes": "^2.0.5", "safe-buffer": "^5.1.0" @@ -20966,7 +20510,6 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -20977,7 +20520,6 @@ "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", @@ -20994,7 +20536,6 @@ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", @@ -21016,7 +20557,6 @@ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -21046,7 +20586,6 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", "dev": true, - "peer": true, "engines": { "node": ">= 14.16.0" }, @@ -21061,7 +20600,6 @@ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "resolve": "^1.20.0" }, @@ -21074,8 +20612,7 @@ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/regenerate-unicode-properties": { "version": "10.2.2", @@ -21083,7 +20620,6 @@ "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "regenerate": "^1.4.2" }, @@ -21119,7 +20655,6 @@ "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", @@ -21137,8 +20672,7 @@ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/regjsparser": { "version": "0.13.0", @@ -21146,7 +20680,6 @@ "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "jsesc": "~3.1.0" }, @@ -21680,7 +21213,6 @@ "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.5" } @@ -21804,7 +21336,6 @@ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "dev": true, - "peer": true, "engines": { "node": ">= 4" } @@ -21830,7 +21361,6 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, - "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -21846,7 +21376,6 @@ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, - "peer": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" @@ -21857,7 +21386,6 @@ "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", "dev": true, - "peer": true, "engines": { "node": ">=18" }, @@ -21902,7 +21430,6 @@ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1", @@ -21920,8 +21447,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/safe-buffer": { "version": "5.1.2", @@ -21933,7 +21459,6 @@ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", @@ -22065,6 +21590,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -22104,15 +21630,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/selfsigned": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", "dev": true, - "peer": true, "dependencies": { "@types/node-forge": "^1.3.0", "node-forge": "^1" @@ -22138,7 +21662,6 @@ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dev": true, - "peer": true, "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -22163,7 +21686,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -22172,15 +21694,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/send/node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -22190,7 +21710,6 @@ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", "dev": true, - "peer": true, "dependencies": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -22209,7 +21728,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -22219,7 +21737,6 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -22229,7 +21746,6 @@ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", "dev": true, - "peer": true, "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -22244,29 +21760,25 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/serve-index/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/serve-index/node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -22276,7 +21788,6 @@ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dev": true, - "peer": true, "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", @@ -22322,15 +21833,13 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/sha.js": { "version": "2.4.12", @@ -22338,7 +21847,6 @@ "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", "dev": true, "license": "(MIT AND BSD-3-Clause)", - "peer": true, "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1", @@ -22373,8 +21881,7 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/shallow-clone": { "version": "3.0.1", @@ -22382,7 +21889,6 @@ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "kind-of": "^6.0.2" }, @@ -22396,7 +21902,6 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -22406,7 +21911,6 @@ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -22586,7 +22090,6 @@ "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", "dev": true, - "peer": true, "dependencies": { "faye-websocket": "^0.11.3", "uuid": "^8.3.2", @@ -22615,7 +22118,6 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "peer": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -22625,7 +22127,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -22642,15 +22143,13 @@ "node_modules/spdx-exceptions": { "version": "2.2.0", "dev": true, - "license": "CC-BY-3.0", - "peer": true + "license": "CC-BY-3.0" }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "peer": true, "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -22659,15 +22158,13 @@ "node_modules/spdx-license-ids": { "version": "3.0.2", "dev": true, - "license": "CC0-1.0", - "peer": true + "license": "CC0-1.0" }, "node_modules/spdy": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "dev": true, - "peer": true, "dependencies": { "debug": "^4.1.0", "handle-thing": "^2.0.0", @@ -22684,7 +22181,6 @@ "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "dev": true, - "peer": true, "dependencies": { "debug": "^4.1.0", "detect-node": "^2.0.4", @@ -22700,7 +22196,6 @@ "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", "license": "BSD-3-Clause", "optional": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -22799,8 +22294,7 @@ "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/stack-utils": { "version": "2.0.6", @@ -22828,7 +22322,6 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -22852,7 +22345,6 @@ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", "dev": true, - "peer": true, "dependencies": { "inherits": "~2.0.4", "readable-stream": "^3.5.0" @@ -22863,7 +22355,6 @@ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", "dev": true, - "peer": true, "dependencies": { "builtin-status-codes": "^3.0.0", "inherits": "^2.0.4", @@ -22948,7 +22439,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -22966,7 +22456,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -22981,7 +22470,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -23087,8 +22575,7 @@ "url": "https://github.com/sponsors/NaturalIntelligence" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/strtok3": { "version": "10.3.4", @@ -23224,7 +22711,6 @@ "integrity": "sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^12 || >=14" }, @@ -23252,7 +22738,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=20.19.0" }, @@ -23314,7 +22799,6 @@ "integrity": "sha512-H88kCC+6Vtzj76NsC8rv6x/LW8slBzIbyeSjsKVlS+4qaEJoDrcJR4L+8JdrR2ORdTscrBzYWiiT2jq6leYR1Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "css-tree": "^3.0.1", "is-plain-object": "^5.0.0", @@ -23338,7 +22822,6 @@ "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "mdn-data": "2.27.1", "source-map-js": "^1.2.1" @@ -23353,7 +22836,6 @@ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -23363,8 +22845,7 @@ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", "dev": true, - "license": "CC0-1.0", - "peer": true + "license": "CC0-1.0" }, "node_modules/stylelint-scss/node_modules/postcss-selector-parser": { "version": "7.1.1", @@ -23372,7 +22853,6 @@ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -23474,7 +22954,6 @@ } ], "license": "MIT-0", - "peer": true, "peerDependencies": { "css-tree": "^3.2.1" }, @@ -23500,7 +22979,6 @@ } ], "license": "MIT-0", - "peer": true, "engines": { "node": ">=20.19.0" }, @@ -23524,7 +23002,6 @@ } ], "license": "MIT-0", - "peer": true, "engines": { "node": ">=20.19.0" }, @@ -23538,7 +23015,6 @@ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -23551,8 +23027,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, - "license": "Python-2.0", - "peer": true + "license": "Python-2.0" }, "node_modules/stylelint/node_modules/cosmiconfig": { "version": "9.0.1", @@ -23560,7 +23035,6 @@ "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", @@ -23603,7 +23077,6 @@ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -23622,7 +23095,6 @@ "integrity": "sha512-N2WFfK12gmrK1c1GXOqiAJ1tc5YE+R53zvQ+t5P8S5XhnmKYVB5eZEiLNZKDSmoG8wqqbF9EXYBBW/nef19log==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "flat-cache": "^6.1.20" } @@ -23633,7 +23105,6 @@ "integrity": "sha512-2u7cJfSf7Th7NxEk/VzQjnPoglok2YCsevS7TSbJjcDQWJPbqUUnSYtriHSvtnq+fRZHy1s0ugk4ApnQyhPGoQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cacheable": "^2.3.3", "flatted": "^3.4.1", @@ -23646,7 +23117,6 @@ "integrity": "sha512-dW7vl+yiAJSp6aCekaVnVJxurRv7DCOLyXqEG3RYMYUg7AuJ2jCqPkZTA8ooqC2vtnkaMcV5WfFBMuEnTu1OQg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "fast-glob": "^3.3.3", @@ -23668,7 +23138,6 @@ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 4" } @@ -23679,7 +23148,6 @@ "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -23692,7 +23160,6 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -23703,7 +23170,6 @@ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -23716,8 +23182,7 @@ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", "dev": true, - "license": "CC0-1.0", - "peer": true + "license": "CC0-1.0" }, "node_modules/stylelint/node_modules/postcss-safe-parser": { "version": "7.0.1", @@ -23739,7 +23204,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18.0" }, @@ -23768,7 +23232,6 @@ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "license": "ISC", - "peer": true, "engines": { "node": ">=14" }, @@ -23782,7 +23245,6 @@ "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=14.16" }, @@ -23796,7 +23258,6 @@ "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" @@ -23814,7 +23275,6 @@ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-regex": "^6.2.2" }, @@ -23831,7 +23291,6 @@ "integrity": "sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "signal-exit": "^4.0.1" }, @@ -23871,7 +23330,6 @@ "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==", "license": "MIT", "optional": true, - "peer": true, "dependencies": { "copy-anything": "^4" }, @@ -23906,7 +23364,6 @@ "integrity": "sha512-UKbpT93hN5Nr9go5UY7bopIB9YQlMz9nm/ct4IXt/irb5YRkn9WaqrOBJGZ5Pwvsd5FQzSVeYlGdXoCAPQZrPg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "has-flag": "^5.0.1", "supports-color": "^10.2.2" @@ -23924,7 +23381,6 @@ "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -23938,7 +23394,6 @@ "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -23960,8 +23415,7 @@ }, "node_modules/svg-tags": { "version": "1.0.0", - "dev": true, - "peer": true + "dev": true }, "node_modules/tabbable": { "version": "6.4.0", @@ -23975,7 +23429,6 @@ "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -23993,7 +23446,6 @@ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -24010,8 +23462,7 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/tapable": { "version": "2.3.0", @@ -24059,7 +23510,6 @@ "version": "5.31.6", "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", - "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", @@ -24078,7 +23528,6 @@ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.4.0.tgz", "integrity": "sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==", "license": "MIT", - "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", @@ -24110,8 +23559,7 @@ "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "peer": true + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "node_modules/test-exclude": { "version": "6.0.0", @@ -24130,15 +23578,13 @@ "node_modules/text-table": { "version": "0.2.0", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/thingies": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", "dev": true, - "peer": true, "engines": { "node": ">=10.18" }, @@ -24162,15 +23608,13 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/timers-browserify": { "version": "2.0.12", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", "dev": true, - "peer": true, "dependencies": { "setimmediate": "^1.0.4" }, @@ -24223,6 +23667,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -24270,7 +23715,6 @@ "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "isarray": "^2.0.5", "safe-buffer": "^5.2.1", @@ -24285,8 +23729,7 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/to-buffer/node_modules/safe-buffer": { "version": "5.2.1", @@ -24307,8 +23750,7 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -24332,7 +23774,6 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, - "peer": true, "engines": { "node": ">=0.6" } @@ -24361,7 +23802,6 @@ "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", "dev": true, - "peer": true, "engines": { "node": ">=10.0" }, @@ -24409,7 +23849,6 @@ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, - "peer": true, "engines": { "node": ">=16" }, @@ -24422,7 +23861,6 @@ "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.4.tgz", "integrity": "sha512-MLukxDHBl8OJ5Dk3y69IsKVFRA/6MwzEqBgh+OXMPB/OD01KQuWPFd1WAQP8a5PeSCAxfnkhiuWqfmFJzJQt9w==", "dev": true, - "peer": true, "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.0.0", @@ -24442,7 +23880,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -24458,7 +23895,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -24475,7 +23911,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -24487,15 +23922,13 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/ts-loader/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -24505,7 +23938,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -24539,7 +23971,6 @@ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", "dev": true, - "peer": true, "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -24552,7 +23983,6 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, - "peer": true, "dependencies": { "minimist": "^1.2.0" }, @@ -24565,7 +23995,8 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, - "license": "0BSD" + "license": "0BSD", + "peer": true }, "node_modules/tsx": { "version": "4.21.0", @@ -24591,8 +24022,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/tunnel": { "version": "0.0.6", @@ -24627,7 +24057,6 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "peer": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -24661,7 +24090,6 @@ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, - "peer": true, "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -24676,7 +24104,6 @@ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -24691,7 +24118,6 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -24710,7 +24136,6 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", "dev": true, - "peer": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -24730,7 +24155,6 @@ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -24746,6 +24170,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -24781,7 +24206,6 @@ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -24813,7 +24237,6 @@ "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=4" } @@ -24824,7 +24247,6 @@ "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -24839,7 +24261,6 @@ "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=4" } @@ -24850,7 +24271,6 @@ "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=4" } @@ -24861,7 +24281,6 @@ "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=20" }, @@ -25044,7 +24463,6 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -25147,7 +24565,6 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "peer": true, "dependencies": { "punycode": "^2.1.0" } @@ -25157,7 +24574,6 @@ "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", "dev": true, - "peer": true, "dependencies": { "punycode": "^1.4.1", "qs": "^6.12.3" @@ -25192,15 +24608,13 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", "dev": true, - "peer": true, "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -25219,7 +24633,6 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4.0" } @@ -25252,7 +24665,6 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -25325,14 +24737,14 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/vue": { "version": "2.7.16", "resolved": "https://registry.npmjs.org/vue/-/vue-2.7.16.tgz", "integrity": "sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==", "deprecated": "Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.", + "peer": true, "dependencies": { "@vue/compiler-sfc": "2.7.16", "csstype": "^3.1.0" @@ -25384,7 +24796,6 @@ "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz", "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==", "dev": true, - "peer": true, "dependencies": { "debug": "^4.3.4", "eslint-scope": "^7.1.1", @@ -25409,7 +24820,6 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -25426,7 +24836,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -25439,7 +24848,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "peer": true, "engines": { "node": ">=4.0" } @@ -25580,7 +24988,8 @@ "node_modules/vue-router": { "version": "3.6.5", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.6.5.tgz", - "integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==" + "integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==", + "peer": true }, "node_modules/vue-smooth-dnd": { "version": "0.8.1", @@ -25594,6 +25003,7 @@ "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", "dev": true, + "peer": true, "dependencies": { "de-indent": "^1.0.2", "he": "^1.2.0" @@ -25619,6 +25029,7 @@ "node_modules/vuex": { "version": "3.6.2", "license": "MIT", + "peer": true, "peerDependencies": { "vue": "^2.0.0" } @@ -25677,7 +25088,6 @@ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, - "peer": true, "dependencies": { "minimalistic-assert": "^1.0.0" } @@ -25926,7 +25336,6 @@ "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -25936,7 +25345,6 @@ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", "dev": true, - "peer": true, "dependencies": { "colorette": "^2.0.10", "memfs": "^4.6.0", @@ -25967,7 +25375,6 @@ "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", @@ -26026,7 +25433,6 @@ "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -26039,7 +25445,6 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "peer": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -26064,7 +25469,6 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "peer": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -26078,7 +25482,6 @@ "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", @@ -26093,7 +25496,6 @@ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "license": "MIT", - "peer": true, "engines": { "node": ">=10.13.0" } @@ -26109,7 +25511,6 @@ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, - "peer": true, "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -26124,7 +25525,6 @@ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true, - "peer": true, "engines": { "node": ">=0.8.0" } @@ -26144,7 +25544,6 @@ "version": "1.3.1", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "isexe": "^2.0.0" }, @@ -26214,8 +25613,7 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/wrap-ansi": { "version": "7.0.0", @@ -26345,7 +25743,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, - "peer": true, "engines": { "node": ">=10.0.0" }, @@ -26367,7 +25764,6 @@ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", "dev": true, - "peer": true, "engines": { "node": ">=12" } @@ -26377,7 +25773,6 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true, - "peer": true, "engines": { "node": ">=0.4" } diff --git a/package.json b/package.json index 1e95297266..2e8b5321cd 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "blueimp-md5": "^2.19.0", "chroma-js": "^3.2.0", "dompurify": "^3.4.0", + "frappe-gantt": "^1.2.2", "lodash": "^4.18.1", "markdown-it": "^14.1.1", "markdown-it-link-attributes": "^4.0.1", diff --git a/src/components/Controls.vue b/src/components/Controls.vue index ef7ee270dd..1fda52523c 100644 --- a/src/components/Controls.vue +++ b/src/components/Controls.vue @@ -226,6 +226,21 @@ + + + {{ t('deck', 'Kanban view') }} + + + + {{ t('deck', 'Gantt view') }} + + + + diff --git a/src/components/board/SwimlaneHeader.vue b/src/components/board/SwimlaneHeader.vue new file mode 100644 index 0000000000..5859f505a1 --- /dev/null +++ b/src/components/board/SwimlaneHeader.vue @@ -0,0 +1,166 @@ + + + + + + + diff --git a/src/components/cards/CardBadges.vue b/src/components/cards/CardBadges.vue index 1d88fe3112..e29fbb671e 100644 --- a/src/components/cards/CardBadges.vue +++ b/src/components/cards/CardBadges.vue @@ -33,6 +33,13 @@ {{ card.attachmentCount }} + +
+ + {{ laneCount }} +
@@ -51,6 +58,7 @@ import AttachmentIcon from 'vue-material-design-icons/Paperclip.vue' import CheckmarkIcon from 'vue-material-design-icons/CheckboxMarked.vue' import CommentIcon from 'vue-material-design-icons/CommentOutline.vue' import CommentUnreadIcon from 'vue-material-design-icons/CommentAccountOutline.vue' +import ArrowTopRightThinIcon from 'vue-material-design-icons/ArrowTopRightThin.vue' import DueDate from './badges/DueDate.vue' export default { @@ -64,6 +72,7 @@ export default { CommentIcon, CommentUnreadIcon, CardId, + ArrowTopRightThinIcon, }, props: { card: { @@ -72,6 +81,23 @@ export default { }, }, computed: { + laneCount() { + const board = this.$store.state.currentBoard + if (!board?.id) { + return 0 + } + const mode = board?.settings?.swimlaneMode || 'none' + if (mode === 'none') { + return 0 + } + if (mode === 'labels') { + return (this.card.labels && this.card.labels.length > 1) ? this.card.labels.length : 0 + } + if (mode === 'assignees') { + return (this.card.assignedUsers && this.card.assignedUsers.length > 1) ? this.card.assignedUsers.length : 0 + } + return 0 + }, checkListCount() { return (this.card.description.match(/^\s*([*+-]|(\d\.))\s+\[\s*(\s|x)\s*\](.*)$/gim) || []).length }, @@ -120,6 +146,10 @@ export default { &:deep(span) { padding: 2px; } + + &--lanes { + opacity: 0.7; + } } } diff --git a/src/store/card.js b/src/store/card.js index c0577f4d3c..fcee626d2f 100644 --- a/src/store/card.js +++ b/src/store/card.js @@ -186,6 +186,25 @@ export default function cardModuleFactory() { }) .sort((a, b) => a.order - b.order || a.createdAt - b.createdAt) }, + cardsByStackAndLane: (state, getters) => (stackId, laneType, laneKey) => { + const cards = getters.cardsByStack(stackId) + if (!laneType || laneType === 'none') { + return cards + } + if (laneType === 'label') { + if (laneKey === '__none__') { + return cards.filter(c => !c.labels || c.labels.length === 0) + } + return cards.filter(c => c.labels && c.labels.some(l => l.id === laneKey)) + } + if (laneType === 'assignee') { + if (laneKey === '__none__') { + return cards.filter(c => !c.assignedUsers || c.assignedUsers.length === 0) + } + return cards.filter(c => c.assignedUsers && c.assignedUsers.some(u => u?.participant?.uid === laneKey)) + } + return cards + }, cardById: state => (id) => { return state.cards.find((card) => card.id === id) }, diff --git a/src/store/main.js b/src/store/main.js index 0617fedb87..6421fa69fc 100644 --- a/src/store/main.js +++ b/src/store/main.js @@ -52,6 +52,8 @@ export default function storeFactory() { activity: [], activityLoadMore: true, filter: { tags: [], users: [], due: '', unassigned: false, completed: 'both' }, + swimlaneLabelOrder: {}, + swimlaneUserOrder: {}, shortcutLock: false, viewModeByBoard: {}, }, @@ -300,6 +302,15 @@ export default function storeFactory() { Vue.delete(state.currentBoard.acl, removeIndex) } }, + SET_SWIMLANE_MODE(state, { mode }) { + if (state.currentBoard?.settings) { + Vue.set(state.currentBoard.settings, 'swimlaneMode', mode) + } + }, + SET_SWIMLANE_ORDER(state, { boardId, type, order }) { + const key = type === 'labels' ? 'swimlaneLabelOrder' : 'swimlaneUserOrder' + Vue.set(state[key], boardId, order) + }, TOGGLE_SHORTCUT_LOCK(state, lock) { state.shortcutLock = lock }, @@ -339,6 +350,20 @@ export default function storeFactory() { const board = await apiClient.loadById(boardId) commit('setCurrentBoard', board) commit('setAssignableUsers', board.users) + if (board.settings) { + try { + const labelOrder = JSON.parse(board.settings.swimlaneLabelOrder || '[]') + if (labelOrder.length > 0) { + commit('SET_SWIMLANE_ORDER', { boardId, type: 'labels', order: labelOrder }) + } + } catch (e) { /* ignore parse errors */ } + try { + const userOrder = JSON.parse(board.settings.swimlaneUserOrder || '[]') + if (userOrder.length > 0) { + commit('SET_SWIMLANE_ORDER', { boardId, type: 'assignees', order: userOrder }) + } + } catch (e) { /* ignore parse errors */ } + } }, async refreshBoard({ commit, dispatch }, boardId) { @@ -535,6 +560,33 @@ export default function storeFactory() { newOwner, }) }, + async setSwimlaneMode({ commit, dispatch, state }, { boardId, mode }) { + // Optimistic update with rollback so the UI does not stay out of + // sync with the server when the config write is rejected (403, + // validation 400, network error). + const previous = state.currentBoard?.settings?.swimlaneMode || 'none' + commit('SET_SWIMLANE_MODE', { mode }) + try { + await dispatch('setConfig', { [`board:${boardId}:swimlaneMode`]: mode }) + } catch (e) { + commit('SET_SWIMLANE_MODE', { mode: previous }) + throw e + } + }, + async setSwimlaneOrder({ commit, dispatch, state }, { boardId, type, order }) { + const configKey = type === 'labels' ? 'swimlaneLabelOrder' : 'swimlaneUserOrder' + const stateKey = type === 'labels' ? 'swimlaneLabelOrder' : 'swimlaneUserOrder' + const previous = state[stateKey][boardId] ? [...state[stateKey][boardId]] : null + commit('SET_SWIMLANE_ORDER', { boardId, type, order }) + try { + await dispatch('setConfig', { [`board:${boardId}:${configKey}`]: JSON.stringify(order) }) + } catch (e) { + if (previous) { + commit('SET_SWIMLANE_ORDER', { boardId, type, order: previous }) + } + throw e + } + }, toggleShortcutLock({ commit }, lock) { commit('TOGGLE_SHORTCUT_LOCK', lock) }, diff --git a/tests/unit/Service/ConfigServiceTest.php b/tests/unit/Service/ConfigServiceTest.php new file mode 100644 index 0000000000..db04efbf3d --- /dev/null +++ b/tests/unit/Service/ConfigServiceTest.php @@ -0,0 +1,156 @@ +config = $this->createMock(IConfig::class); + $this->groupManager = $this->createMock(IGroupManager::class); + + $this->service = new ConfigService( + $this->config, + $this->groupManager, + ); + + // The service lazily reads userId from IUserSession via OCP\Server::get(). + // We bypass that by setting the private property directly so set() can run. + $ref = new \ReflectionProperty(ConfigService::class, 'userId'); + $ref->setValue($this->service, 'admin'); + } + + public function testSetSwimlaneModeIsStoredShared(): void { + $this->config->expects($this->once()) + ->method('setAppValue') + ->with(Application::APP_ID, 'board:5:swimlaneMode', 'labels'); + $this->config->expects($this->never()) + ->method('setUserValue'); + + $result = $this->service->set('board:5:swimlaneMode', 'labels'); + $this->assertSame('labels', $result); + } + + public function testSetSwimlaneLabelOrderIsShared(): void { + $this->config->expects($this->once()) + ->method('setAppValue') + ->with(Application::APP_ID, 'board:7:swimlaneLabelOrder', '[3,1,2]'); + $this->config->expects($this->never()) + ->method('setUserValue'); + + $result = $this->service->set('board:7:swimlaneLabelOrder', '[3,1,2]'); + $this->assertSame('[3,1,2]', $result); + } + + public function testSetSwimlaneUserOrderIsShared(): void { + $this->config->expects($this->once()) + ->method('setAppValue') + ->with(Application::APP_ID, 'board:7:swimlaneUserOrder', '["admin","alice"]'); + $this->config->expects($this->never()) + ->method('setUserValue'); + + $result = $this->service->set('board:7:swimlaneUserOrder', '["admin","alice"]'); + $this->assertSame('["admin","alice"]', $result); + } + + public function testSetBoardConfigRejectsEmptyKey(): void { + $this->config->expects($this->never())->method('setAppValue'); + $this->config->expects($this->never())->method('setUserValue'); + + $this->expectException(BadRequestException::class); + $this->service->set('board:5:', 'x'); + } + + public function testSetBoardConfigRejectsEmptyBoardId(): void { + $this->config->expects($this->never())->method('setAppValue'); + $this->config->expects($this->never())->method('setUserValue'); + + $this->expectException(BadRequestException::class); + $this->service->set('board::swimlaneMode', 'labels'); + } + + public function testSetSwimlaneConfigRejectsNonNumericBoardId(): void { + // ConfigController::setValue() only permission-checks keys matching + // board:(\d+): — a non-numeric id would bypass it, so the shared + // setAppValue path must refuse it. + $this->config->expects($this->never())->method('setAppValue'); + $this->config->expects($this->never())->method('setUserValue'); + + $this->expectException(BadRequestException::class); + $this->service->set('board:abc:swimlaneMode', 'labels'); + } + + public function testSetSwimlaneModeRejectsUnknownMode(): void { + $this->config->expects($this->never())->method('setAppValue'); + $this->config->expects($this->never())->method('setUserValue'); + + $this->expectException(BadRequestException::class); + $this->service->set('board:5:swimlaneMode', 'banana'); + } + + public function testSetSwimlaneOrderRejectsNonJsonValue(): void { + $this->config->expects($this->never())->method('setAppValue'); + $this->config->expects($this->never())->method('setUserValue'); + + $this->expectException(BadRequestException::class); + $this->service->set('board:5:swimlaneLabelOrder', 'not json'); + } + + public function testSetSwimlaneOrderRejectsJsonObject(): void { + $this->config->expects($this->never())->method('setAppValue'); + $this->config->expects($this->never())->method('setUserValue'); + + $this->expectException(BadRequestException::class); + $this->service->set('board:5:swimlaneLabelOrder', '{"a":1}'); + } + + public function testSetSwimlaneOrderRejectsInvalidEntries(): void { + $this->config->expects($this->never())->method('setAppValue'); + $this->config->expects($this->never())->method('setUserValue'); + + $this->expectException(BadRequestException::class); + $this->service->set('board:5:swimlaneUserOrder', '[true]'); + } + + public function testSetSwimlaneOrderAcceptsCatchAllLaneId(): void { + $this->config->expects($this->once()) + ->method('setAppValue') + ->with(Application::APP_ID, 'board:5:swimlaneLabelOrder', '[3,1,"__none__"]'); + $this->config->expects($this->never())->method('setUserValue'); + + $result = $this->service->set('board:5:swimlaneLabelOrder', '[3,1,"__none__"]'); + $this->assertSame('[3,1,"__none__"]', $result); + } + + public function testNonSwimlaneBoardSettingStaysPerUser(): void { + // board:5:calendar is a per-user setting (setUserValue path) + $this->config->expects($this->never())->method('setAppValue'); + $this->config->expects($this->once()) + ->method('setUserValue') + ->with('admin', Application::APP_ID, 'board:5:calendar', 'yes'); + + $this->service->set('board:5:calendar', 'yes'); + } + + public function testSetBoardConfigWithoutSettingPartIsIgnored(): void { + // upstream behavior: 'board:5' (fewer than 3 segments) is silently ignored + $this->config->expects($this->never())->method('setAppValue'); + $this->config->expects($this->never())->method('setUserValue'); + + $this->assertNull($this->service->set('board:5', 'x')); + } +}