diff --git a/client-v3/e2e/tests/10-show-config-script.spec.ts b/client-v3/e2e/tests/10-show-config-script.spec.ts index f942e51fa..d5420a8fc 100644 --- a/client-v3/e2e/tests/10-show-config-script.spec.ts +++ b/client-v3/e2e/tests/10-show-config-script.spec.ts @@ -97,11 +97,31 @@ test('saves a dialogue line to the script', async () => { await lineEditor.locator('select').nth(0).selectOption({ label: 'Act 1' }); await lineEditor.locator('select').nth(1).selectOption({ label: 'Scene 1' }); - await page.locator('select').filter({ hasText: 'Hamlet' }).selectOption({ label: 'Hamlet' }); + await lineEditor + .locator('select') + .filter({ hasText: 'Hamlet' }) + .selectOption({ label: 'Hamlet' }); await page.locator('input[type="text"]:visible').last().fill('To be or not to be'); await page.locator('button:has-text("Done")').first().click(); - // ScriptEditor auto-adds a blank dialogue line after Done — delete it before asserting + // ScriptEditor auto-adds a blank dialogue editor after Done — fill it in as a second line so + // the bulk edit tests below can use a two-line range without needing the split dropdown. + await expect(page.locator('button:has-text("Done")').first()).toBeVisible({ timeout: 5_000 }); + + const lineEditor2 = page + .locator('div.row') + .filter({ has: page.locator('button:has-text("Done")') }) + .first(); + await lineEditor2.locator('select').nth(0).selectOption({ label: 'Act 1' }); + await lineEditor2.locator('select').nth(1).selectOption({ label: 'Scene 1' }); + await lineEditor2 + .locator('select') + .filter({ hasText: 'Hamlet' }) + .selectOption({ label: 'Hamlet' }); + await page.locator('input[type="text"]:visible').last().fill('That is the question'); + + await page.locator('button:has-text("Done")').first().click(); + // Delete the third auto-added blank editor await page.locator('button.btn-danger:has-text("Delete")').first().click(); await expect(page.locator('button:has-text("Done")')).not.toBeVisible({ timeout: 5_000 }); @@ -118,6 +138,59 @@ test('saves a dialogue line to the script', async () => { await expect( page.locator('.viewable-line').filter({ hasText: 'To be or not to be' }) ).toBeVisible({ timeout: 10_000 }); + await expect( + page.locator('.viewable-line').filter({ hasText: 'That is the question' }) + ).toBeVisible({ timeout: 10_000 }); +}); + +// ── Bulk edit ───────────────────────────────────────────────────────────── + +test('bulk edit mode is accessible and shows Start/End buttons', async () => { + // Still in edit mode from the save test, which saved two viewable dialogue lines. + await page.click('button:has-text("Bulk Edit")'); + // Two ScriptLineViewer rows → two Start/End button pairs + await expect(page.getByRole('button', { name: 'Start', exact: true }).first()).toBeVisible({ + timeout: 5_000, + }); + await expect(page.getByRole('button', { name: 'End', exact: true }).first()).toBeVisible({ + timeout: 5_000, + }); +}); + +test('bulk edit opens the Bulk Edit modal when start and end span two different lines', async () => { + // Start on the first line, End on the last line (different indices → valid range) + await page.getByRole('button', { name: 'Start', exact: true }).first().click(); + await page.getByRole('button', { name: 'End', exact: true }).last().click(); + await waitForModal(page, 'Bulk Edit'); +}); + +test('bulk edit can assign a character to part 1', async () => { + await page.locator('.modal.show #bulk-part-input').selectOption({ label: 'Part 1' }); + // Select Alice — a different character from Hamlet (who is already assigned) so the apply + // produces a real change that scriptChanges can detect via deep equality. + await page.locator('.modal.show #bulk-char-input').selectOption({ label: 'Alice' }); + await confirmModal(page); + await waitForModalClosed(page); + // After apply, bulk edit mode exits automatically + await expect(page.getByRole('button', { name: 'Bulk Edit', exact: true })).toBeVisible({ + timeout: 5_000, + }); +}); + +test('bulk edit stops when Exit Bulk Edit is clicked', async () => { + await page.click('button:has-text("Bulk Edit")'); + await expect(page.getByRole('button', { name: 'Start', exact: true }).first()).toBeVisible({ + timeout: 5_000, + }); + await page.click('button:has-text("Exit Bulk Edit")'); + await expect(page.getByRole('button', { name: 'Start', exact: true })).not.toBeVisible({ + timeout: 3_000, + }); + await page.click('button:has-text("Stop Editing")'); + await confirmDialog(page); + await expect(page.getByRole('button', { name: 'Edit', exact: true })).toBeVisible({ + timeout: 10_000, + }); }); // ── Cut mode ────────────────────────────────────────────────────────────── @@ -228,11 +301,12 @@ test('navigates to cue editor with saved script content', async () => { test('adds a cue to the script line', async () => { await page.locator('.add-cue-btn').first().click(); - await waitForModal(page, 'Add New Cue'); + await waitForModal(page, 'Add Cue'); + // Individual Cue tab is active by default — no extra click needed // Scope to the visible modal's select to avoid matching the hidden "Add Cue Type" modal // dialog which BVN assigns id="new-cue-type" via its auto-ID scheme. await page.locator('.modal.show select#new-cue-type').selectOption({ index: 1 }); - await page.fill('#new-cue-ident', '001'); + await page.locator('.modal.show #new-cue-ident').fill('001'); await confirmModal(page); await waitForModalClosed(page); // Wait for the actual cue button (not the add-cue-btn which shares the cue-button class) @@ -246,7 +320,7 @@ test('edits the cue identifier', async () => { // Use :not(.add-cue-btn) to target the real cue button, not the add button await page.locator('.cue-button:not(.add-cue-btn)').first().click(); await waitForModal(page, 'Edit Cue'); - await page.fill('#edit-cue-ident', '002'); + await page.locator('.modal.show #edit-cue-ident').fill('002'); await confirmModal(page); await waitForModalClosed(page); await expect(page.locator('.cue-button:not(.add-cue-btn)').first()).toBeVisible({ @@ -256,11 +330,14 @@ test('edits the cue identifier', async () => { test('can add a cue using Enter key in Add New Cue modal', async () => { await page.locator('.add-cue-btn').first().click(); - await waitForModal(page, 'Add New Cue'); + await waitForModal(page, 'Add Cue'); + // Individual Cue tab is active by default — no extra click needed await page.locator('.modal.show select#new-cue-type').selectOption({ index: 1 }); - await page.fill('#new-cue-ident', '003'); + await page.locator('.modal.show #new-cue-ident').fill('003'); // Enter key submits the form (fix: BForm @submit bound to onSubmitNew) - await page.locator('#new-cue-ident').press('Enter'); + // Scope to .modal.show to avoid strict-mode violation from other Add New Cue modal instances + // in the DOM (one per viewable script line — BVN v-show keeps them all present). + await page.locator('.modal.show #new-cue-ident').press('Enter'); await waitForModalClosed(page); await expect(page.locator('.cue-button:not(.add-cue-btn)')).toHaveCount(2, { timeout: 5_000 }); }); @@ -269,9 +346,9 @@ test('can edit a cue identifier using Enter key in Edit Cue modal', async () => // Click the second cue button (003) await page.locator('.cue-button:not(.add-cue-btn)').last().click(); await waitForModal(page, 'Edit Cue'); - await page.fill('#edit-cue-ident', '004'); + await page.locator('.modal.show #edit-cue-ident').fill('004'); // Enter key submits the form (fix: BForm @submit bound to onSubmitEdit) - await page.locator('#edit-cue-ident').press('Enter'); + await page.locator('.modal.show #edit-cue-ident').press('Enter'); await waitForModalClosed(page); await expect(page.locator('.cue-button:not(.add-cue-btn)')).toHaveCount(2, { timeout: 5_000 }); }); @@ -318,3 +395,153 @@ test('deletes the cue', async () => { // After deletion only the add-cue-btn remains; no actual cue buttons should exist await expect(page.locator('.cue-button:not(.add-cue-btn)')).not.toBeVisible({ timeout: 5_000 }); }); + +// ── Cue Groups ──────────────────────────────────────────────────────────── + +test('opens Add Cue modal with Individual Cue and Cue Group tabs', async () => { + // After individual cue tests all cues have been deleted. Still on the cue config page. + await page.locator('.add-cue-btn').first().click(); + await waitForModal(page, 'Add Cue'); + await expect(page.locator('.modal.show .nav-link:has-text("Individual Cue")')).toBeVisible(); + await expect(page.locator('.modal.show .nav-link:has-text("Cue Group")')).toBeVisible(); + // Dismiss via the × close button (Escape is unreliable in BVN with BTabs in Firefox) + await page.locator('.modal.show .btn-close').click(); + await waitForModalClosed(page); +}); + +test('switches to Cue Group tab to show group form', async () => { + await page.locator('.add-cue-btn').first().click(); + await waitForModal(page, 'Add Cue'); + await page.locator('.modal.show .nav-link:has-text("Cue Group")').click(); + // Wait for tab content to be visible (BTabs lazy may delay mount) + await expect(page.locator('.modal.show input[placeholder="1 > 100"]')).toBeVisible({ + timeout: 10_000, + }); +}); + +test('selects cue type and adds range 1 > 5', async () => { + // Scope to .tab-pane.active to avoid matching hidden Individual Cue tab's select. + // CueGroupForm filters out the N/A option, so LX is at index 0 (not 1). + await page.locator('.modal.show .tab-pane.active select').selectOption({ index: 0 }); + await page.locator('.modal.show input[placeholder="1 > 100"]').fill('1 > 5'); + await page.locator('.modal.show button:has-text("Add Range")').click(); + // 5 cue ident inputs should appear (scoped to active tab pane to avoid hidden #new-cue-ident) + await expect( + page.locator('.modal.show .tab-pane.active input[placeholder="Identifier"]') + ).toHaveCount(5, { + timeout: 3_000, + }); +}); + +test('saves the cue group and shows a dashed group button with range label', async () => { + await page.locator('.modal.show button:has-text("Save Group")').click(); + await waitForModalClosed(page); + await expect(page.locator('.cue-group-btn').first()).toBeVisible({ timeout: 5_000 }); + await expect(page.locator('.cue-group-btn').first()).toContainText('LX 1 - LX 5'); +}); + +test('clicks group button to open Edit Cue Group modal with 5 cues listed', async () => { + await page.locator('.cue-group-btn').first().click(); + await waitForModal(page, 'Edit Cue Group'); + await expect(page.locator('.modal.show input[placeholder="Identifier"]')).toHaveCount(5, { + timeout: 5_000, + }); +}); + +test('adds label override and group button label updates on save', async () => { + await page.locator('.modal.show input[placeholder="e.g. Music Intro"]').fill('Music Intro'); + await page.locator('.modal.show button:has-text("Save Group")').click(); + await waitForModalClosed(page); + await expect(page.locator('.cue-group-btn').first()).toContainText('LX - Music Intro'); +}); + +test('deletes the cue group and column returns to empty', async () => { + await page.locator('.cue-group-btn').first().click(); + await waitForModal(page, 'Edit Cue Group'); + await page.locator('.modal.show button:has-text("Delete Group")').click(); + // useConfirm opens a stacked BVN modal — scope to its title to avoid intercepting the + // Edit Cue Group modal footer behind it. + await waitForModal(page, 'Delete Cue Group'); + await page + .locator('.modal.show') + .filter({ has: page.locator('.modal-title:has-text("Delete Cue Group")') }) + .locator('.modal-footer button.btn-danger') + .click(); + await expect(page.locator('.cue-group-btn')).not.toBeVisible({ timeout: 5_000 }); +}); + +// ── Line part removal ────────────────────────────────────────────────────── + +test('remove button is absent on a single-part dialogue line', async () => { + await page.goto(`${UI_BASE}/show-config/script`); + await waitForAppReady(page); + await page.getByRole('button', { name: 'Edit', exact: true }).click(); + await expect(page.locator('button:has-text("Stop Editing")')).toBeVisible({ timeout: 10_000 }); + + await page.click('button:has-text("Add Dialogue")'); + const lineEditor = page + .locator('div.row') + .filter({ has: page.locator('button:has-text("Done")') }) + .first(); + await expect(lineEditor.locator('button:has-text("Done")')).toBeVisible({ timeout: 5_000 }); + + // With only 1 part no remove button should be present + await expect(lineEditor.locator('button.btn-outline-danger')).not.toBeVisible(); +}); + +test('remove button appears when a second part is added', async () => { + const lineEditor = page + .locator('div.row') + .filter({ has: page.locator('button:has-text("Done")') }) + .first(); + + // btn-secondary is the add-line-part (+) button — only btn-secondary in the editor row + await lineEditor.locator('button.btn-secondary').click(); + + // One remove button per part + await expect(lineEditor.locator('button.btn-outline-danger')).toHaveCount(2, { timeout: 3_000 }); +}); + +test('clicking remove reduces to single part and hides the remove button', async () => { + const lineEditor = page + .locator('div.row') + .filter({ has: page.locator('button:has-text("Done")') }) + .first(); + + await lineEditor.locator('button.btn-outline-danger').first().click(); + + // Back to 1 part — remove button gone + await expect(lineEditor.locator('button.btn-outline-danger')).not.toBeVisible({ timeout: 3_000 }); +}); + +test('dialogue line with removed part saves correctly', async () => { + const lineEditor = page + .locator('div.row') + .filter({ has: page.locator('button:has-text("Done")') }) + .first(); + + await lineEditor.locator('select').nth(0).selectOption({ label: 'Act 1' }); + await lineEditor.locator('select').nth(1).selectOption({ label: 'Scene 1' }); + await lineEditor + .locator('select') + .filter({ hasText: 'Hamlet' }) + .selectOption({ label: 'Hamlet' }); + await lineEditor.locator('input[type="text"]').last().fill('Surviving part text'); + + await lineEditor.locator('button:has-text("Done")').click(); + // Delete the auto-added blank editor that appears after Done + await page.locator('button.btn-danger:has-text("Delete")').first().click(); + await expect(page.locator('button:has-text("Done")')).not.toBeVisible({ timeout: 5_000 }); + + await page.getByRole('button', { name: 'Save', exact: true }).click(); + await waitForModal(page, 'Saving Script'); + await expect(page.locator('.modal.show').getByText('Finished saving script.')).toBeVisible({ + timeout: 15_000, + }); + await confirmModal(page); + await waitForModalClosed(page); + + await expect( + page.locator('.viewable-line').filter({ hasText: 'Surviving part text' }) + ).toBeVisible({ timeout: 10_000 }); +}); diff --git a/client-v3/e2e/tests/13-live-show.spec.ts b/client-v3/e2e/tests/13-live-show.spec.ts index 3813d7a1a..c793e1659 100644 --- a/client-v3/e2e/tests/13-live-show.spec.ts +++ b/client-v3/e2e/tests/13-live-show.spec.ts @@ -12,6 +12,7 @@ import { UI_BASE, waitForAppReady, loginAsAdmin, + waitForModal, confirmModal, waitForModalClosed, confirmDialog, @@ -122,6 +123,63 @@ test('follower receives leader page navigation via WebSocket scroll sync', async ); }); +// ── Cue add mode in live view ───────────────────────────────────────────── + +test('pressing C enables cue add mode showing + buttons on the live page', async () => { + await expect(leaderPage.locator('.script-item').first()).toBeVisible({ timeout: 10_000 }); + await leaderPage.keyboard.press('C'); + await expect(leaderPage.locator('.add-cue-btn').first()).toBeVisible({ timeout: 5_000 }); +}); + +test('can add an individual cue from the live view', async () => { + await leaderPage.locator('.add-cue-btn').first().click(); + await waitForModal(leaderPage, 'Add Cue'); + await expect( + leaderPage.locator('.modal.show .nav-link:has-text("Individual Cue")') + ).toBeVisible(); + await leaderPage.locator('.modal.show #cue-type-input').selectOption({ index: 1 }); + await leaderPage.locator('.modal.show #ident-input').fill('101'); + await leaderPage.locator('.modal.show button:has-text("Add Cue")').click(); + await waitForModalClosed(leaderPage); + await expect(leaderPage.locator('.cue-button:not(.add-cue-btn)').first()).toBeVisible({ + timeout: 5_000, + }); +}); + +test('can add a cue group from the live view', async () => { + await leaderPage.locator('.add-cue-btn').first().click(); + await waitForModal(leaderPage, 'Add Cue'); + await leaderPage.locator('.modal.show .nav-link:has-text("Cue Group")').click(); + // Wait for CueGroupForm content (tab may be lazy in some BVN versions) + await expect(leaderPage.locator('.modal.show input[placeholder="1 > 100"]')).toBeVisible({ + timeout: 10_000, + }); + // CueGroupForm filters out N/A, so LX is at index 0 + await leaderPage.locator('.modal.show .tab-pane.active select').selectOption({ index: 0 }); + await leaderPage.locator('.modal.show input[placeholder="1 > 100"]').fill('200 > 202'); + await leaderPage.locator('.modal.show button:has-text("Add Range")').click(); + await expect( + leaderPage.locator('.modal.show .tab-pane.active input[placeholder="Identifier"]') + ).toHaveCount(3, { timeout: 3_000 }); + await leaderPage.locator('.modal.show button:has-text("Save Group")').click(); + await waitForModalClosed(leaderPage); + await expect(leaderPage.locator('.cue-group-btn').first()).toBeVisible({ timeout: 5_000 }); + await expect(leaderPage.locator('.cue-group-btn').first()).toContainText('LX 200 - LX 202'); +}); + +test('cue group buttons in live view are non-interactive display-only buttons', async () => { + // Group buttons in live view should NOT open an edit modal — editing is blocked server-side + // during live sessions. Verify clicking doesn't open any modal. + await leaderPage.locator('.cue-group-btn').first().click(); + await leaderPage.waitForTimeout(500); + await expect(leaderPage.locator('.modal.show')).not.toBeVisible(); +}); + +test('pressing C again disables cue add mode', async () => { + await leaderPage.keyboard.press('C'); + await expect(leaderPage.locator('.add-cue-btn').first()).not.toBeVisible({ timeout: 5_000 }); +}); + // ── Enable/disable Stage Manager mode ───────────────────────────────────── test('can toggle Stage Manager mode', async () => { diff --git a/client-v3/package-lock.json b/client-v3/package-lock.json index 34e7c7c58..d6128830f 100644 --- a/client-v3/package-lock.json +++ b/client-v3/package-lock.json @@ -1,17 +1,17 @@ { "name": "client-v3", - "version": "0.32.4", + "version": "0.33.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "client-v3", - "version": "0.32.4", + "version": "0.33.0", "dependencies": { "@vuelidate/core": "^2.0.3", "@vuelidate/validators": "^2.0.4", "bootstrap": "^5.3.8", - "bootstrap-vue-next": "^0.45.6", + "bootstrap-vue-next": "^0.45.7", "bootswatch": "^5.3.8", "contrast-color": "1.0.1", "core-js": "^3.49.0", @@ -37,11 +37,11 @@ "@emnapi/runtime": "1.11.1", "@eslint/js": "^10.0.1", "@iconify-json/mdi": "^1.2.3", - "@playwright/test": "^1.61.0", + "@playwright/test": "^1.61.1", "@types/lodash": "~4.17.24", "@types/node": ">=22.12.0", - "@typescript-eslint/eslint-plugin": "^8.61.1", - "@typescript-eslint/parser": "^8.61.1", + "@typescript-eslint/eslint-plugin": "^8.62.0", + "@typescript-eslint/parser": "^8.62.0", "@vitejs/plugin-vue": "^6.0.7", "@vitest/ui": "^4.1.9", "@vue/test-utils": "^2.4.11", @@ -49,16 +49,16 @@ "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.6", "eslint-plugin-vue": "^10.9.2", - "globals": "^17.6.0", + "globals": "^17.7.0", "jiti": "^2.7.0", "jsdom": "^29.1.1", "prettier": "^3.8.4", "sass": "1.101.0", "typescript": "^6.0.3", - "typescript-eslint": "^8.61.1", + "typescript-eslint": "^8.62.0", "unplugin-icons": "^23.0.1", "unplugin-vue-components": "^32.1.0", - "vite": "^8.0.16", + "vite": "^8.1.0", "vitest": "^4.1.9", "vue-eslint-parser": "^10.4.1" }, @@ -809,9 +809,9 @@ "license": "MIT" }, "node_modules/@oxc-project/types": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", - "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", + "version": "0.137.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.137.0.tgz", + "integrity": "sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==", "devOptional": true, "license": "MIT", "funding": { @@ -1142,13 +1142,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.61.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.61.0.tgz", - "integrity": "sha512-cKA5B6lpFEMyMGjxF54QihfYpB4FkEGH+qZhtArDEG+wezQAJY8Pq6C7T1SjWz+FFzt3TbyoXBQYk/0292TdJA==", + "version": "1.61.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.61.1.tgz", + "integrity": "sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.61.0" + "playwright": "1.61.1" }, "bin": { "playwright": "cli.js" @@ -1176,9 +1176,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", - "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.2.tgz", + "integrity": "sha512-2cZ+7xRS+DBcuJBJKnfzsbleumJhBqSlJVpuzHC0nTqfd3QQ7Vx2/x5YR/D7cBamKSeWplwo82Fn9lqYUDEMfA==", "cpu": [ "arm64" ], @@ -1193,9 +1193,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", - "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.2.tgz", + "integrity": "sha512-RkPMJnygxsgOYdkfqgpwY0/Fzm8d0VQe6HGU2/B00Xa9eqdLbrII+DOKAodbJAn3ZL1AJxGHkZRPYazgGY6Ljw==", "cpu": [ "arm64" ], @@ -1210,9 +1210,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", - "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.2.tgz", + "integrity": "sha512-Uiczh6vFhwyfd7WNe7Q7mCA4KxAiLdz7jPE/WGizfRpIieoyFuNVMmM8HqZ9HwudTkY6/AeMQwlNJ9NJijguWw==", "cpu": [ "x64" ], @@ -1227,9 +1227,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", - "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.2.tgz", + "integrity": "sha512-+TpdtTRgHiJFjCVFbw311SuLk3KfytPOQQn+VlAEv+gBxYPtL7E6JS9e/tk+8CwxhIZvemJKo4rTKgfWNsKkkA==", "cpu": [ "x64" ], @@ -1244,9 +1244,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", - "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.2.tgz", + "integrity": "sha512-4lv1/tkmi7ueIVHnyreaOeUpiZP26BH9rRy6hoYfR9310A2B9nUEVRDvBx69vx64Nr3eTPPRkyciqJJs+j9Jmw==", "cpu": [ "arm" ], @@ -1261,9 +1261,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", - "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.2.tgz", + "integrity": "sha512-gBSUVO0eaWgw1JMjK3gB8BMlX2Mk148s2lTiVT3e9vjVxbl7UDfMWWY8CfIaaqiXuM9fVTMxIpUz6CAo/B6Vlw==", "cpu": [ "arm64" ], @@ -1278,9 +1278,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", - "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.2.tgz", + "integrity": "sha512-LjQP/iZLBu8o8PjIfk4x3At0/mT6h282pvz8Z5LAyhGbu/kDezyO7ea62rF5uoqmgnIYqbN/MqJ3Si3Aymi7xQ==", "cpu": [ "arm64" ], @@ -1295,9 +1295,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", - "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.2.tgz", + "integrity": "sha512-X/7bVLWelEsbyWDUSXt7zVsTniLLPIY2n1rH58qr78l9i7MNbbxBWD8gI2vRfBWf4NUXJCUuQnfZDsp32LqsfQ==", "cpu": [ "ppc64" ], @@ -1312,9 +1312,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", - "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.2.tgz", + "integrity": "sha512-gb6dYKW/1KDorGXyy48glEBJs/sxVSC5pcVrox/pFGV4mvwSFeg2sK5L2tRkVsVlh7kueqOgg4GEcuipJcGuKg==", "cpu": [ "s390x" ], @@ -1329,9 +1329,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", - "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.2.tgz", + "integrity": "sha512-JY4w85pU3iAiJVMh5nuk4/Mh9GjMsupe8MrIN53rwxAZW64GKrWeJBuN6SxQg9QTU5uB1cxyhDzW8jqRn1EABw==", "cpu": [ "x64" ], @@ -1346,9 +1346,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", - "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.2.tgz", + "integrity": "sha512-xvpA7o5KCYLB0Rwscmuylb1/zHHSUx4g4xilm4prC5jP76pEUlzBmMbgpbh7bVDbId4NcfT96gN5i6mE6UDaiw==", "cpu": [ "x64" ], @@ -1363,9 +1363,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", - "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.2.tgz", + "integrity": "sha512-p/ts6KBLjuk49Bp21XH77poQGt02iNz7ChgHep7tudPOaLinR/De/RHdxF8w8Yj4r/bF/bqXwH6PZrB2sA+Nvw==", "cpu": [ "arm64" ], @@ -1380,9 +1380,9 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", - "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.2.tgz", + "integrity": "sha512-VMu/wmrZ9hJzYlRhbw7jK5PODlugyKZ5mOdX78+lS8OvuFkWNQdz1pFLrI2p3P0pjXOmUZ7B48o5VnMH9QOGtg==", "cpu": [ "wasm32" ], @@ -1390,52 +1390,18 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "1.10.0", - "@emnapi/runtime": "1.10.0", - "@napi-rs/wasm-runtime": "^1.1.4" + "@emnapi/core": "1.11.1", + "@emnapi/runtime": "1.11.1", + "@napi-rs/wasm-runtime": "^1.1.5" }, "engines": { "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", - "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.1", - "tslib": "^2.4.0" - } - }, - "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", - "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.2.tgz", + "integrity": "sha512-xtUJqs8qEkuSviS0n1tsohaPuz3a1SPhZywOji4Oo+sgrJs8daEDMZ0QtqL0OS7dx8PoVpg2J/ZZycPY5I2+Zg==", "cpu": [ "arm64" ], @@ -1450,9 +1416,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", - "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.2.tgz", + "integrity": "sha512-85YiLQqjUKgSO/Zjnf9e0XIn5Ymrh1fLDWBeAkZqpuBR/3R8TpfoHXuyblqyQrftSSgWO9qpcHN8mkyKsLraoA==", "cpu": [ "x64" ], @@ -1516,9 +1482,9 @@ } }, "node_modules/@tybys/wasm-util": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", - "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", "dev": true, "license": "MIT", "optional": true, @@ -1603,17 +1569,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.61.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.61.1.tgz", - "integrity": "sha512-ZPlVl3PB3et/59Ne0fv/sci6ZXz4T4Hp4nTJ56i/Y0gR89ARb+KphojTq6j+56E5PIezmOIOOWyY+aWQFd+IkQ==", + "version": "8.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.62.0.tgz", + "integrity": "sha512-o+mpz7EYiMzXoySXiKmzlabIvTVqUuK5yLrAedRPRDA0IpPFMUV1IXt6OqljIxX/kumN6EjUYp41Hqelh6p/Dw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.61.1", - "@typescript-eslint/type-utils": "8.61.1", - "@typescript-eslint/utils": "8.61.1", - "@typescript-eslint/visitor-keys": "8.61.1", + "@typescript-eslint/scope-manager": "8.62.0", + "@typescript-eslint/type-utils": "8.62.0", + "@typescript-eslint/utils": "8.62.0", + "@typescript-eslint/visitor-keys": "8.62.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -1626,23 +1592,23 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.61.1", + "@typescript-eslint/parser": "^8.62.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.61.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.61.1.tgz", - "integrity": "sha512-PJ5vePq5/ognBbrIcoC5+SHO5dfpeLPzP9FpLkzWrguoYQEeeSjlJpVwOpo1JRSTEi7dRcwNy4h4dzV70PqHcg==", + "version": "8.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.62.0.tgz", + "integrity": "sha512-dzHeT2gySzZtLDsuqxU9AkYgIsQoHAHtRBpOqM+Ofzx1Bwrd2RcCjQJ+6iQbsHOIR6NS33bF2W1k3blN1zLDrA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.61.1", - "@typescript-eslint/types": "8.61.1", - "@typescript-eslint/typescript-estree": "8.61.1", - "@typescript-eslint/visitor-keys": "8.61.1", + "@typescript-eslint/scope-manager": "8.62.0", + "@typescript-eslint/types": "8.62.0", + "@typescript-eslint/typescript-estree": "8.62.0", + "@typescript-eslint/visitor-keys": "8.62.0", "debug": "^4.4.3" }, "engines": { @@ -1658,14 +1624,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.61.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.61.1.tgz", - "integrity": "sha512-PrC4JYGmR241lYnfhmKGTXkFqv8+ymbTFgSAY0fVXpY82/QkMw5TZPl+vGzuDDU2QYJk9fIDOBTntF+yDv9LEA==", + "version": "8.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.0.tgz", + "integrity": "sha512-wexnCqiTg7BOGtbLDftYpRWlmLq4xfoMd7BKFR6Y75sZS3QmRKLdN3yWLhmIYgqMmP/OXWpj3H8odkb5nGURCQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.61.1", - "@typescript-eslint/types": "^8.61.1", + "@typescript-eslint/tsconfig-utils": "^8.62.0", + "@typescript-eslint/types": "^8.62.0", "debug": "^4.4.3" }, "engines": { @@ -1680,14 +1646,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.61.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.61.1.tgz", - "integrity": "sha512-L2bdIeoQS8FlKAvONAr20w6OcLXeB+qiDKbAooS9A0Ben+iSIkBef0FxqwKWYqt5sa0i4KJtxVyVmhMylKzF5w==", + "version": "8.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.62.0.tgz", + "integrity": "sha512-1lX38kNxXIRb8mEc3lbq5mdHq1Pf2+U0nFU65KfT18mtPxxl0fvjuEE92mHuXPuCtElJhOrddOpyMlM3Z0umEA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.61.1", - "@typescript-eslint/visitor-keys": "8.61.1" + "@typescript-eslint/types": "8.62.0", + "@typescript-eslint/visitor-keys": "8.62.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1698,9 +1664,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.61.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.1.tgz", - "integrity": "sha512-UN/H4di+OO7EWx2ovME+8t31YO+KVnK0RRKEHR3kOt21/Ay8BOq3M1OMvWs5vNiqcFCYGYoxK3MXPZzmMUE+yg==", + "version": "8.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.0.tgz", + "integrity": "sha512-y2GAdB6ykaXUvuspbYnizQc4oDDz0Tz/Yc7iWrXf9mx8vm/L/0vLHCe0tS2boG96Zy+DivnVDQ9ZUEWoHqqx1g==", "dev": true, "license": "MIT", "engines": { @@ -1715,15 +1681,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.61.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.61.1.tgz", - "integrity": "sha512-GYRicKmVK0C4fsKgaACaknOUAq9Oa2kwsjnpFhFcS/5p4Ht5IP9OVLbgIgcK4SRk92nVHFluurg1lumD9dBcLw==", + "version": "8.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.62.0.tgz", + "integrity": "sha512-+g5O3j0w2ldzC86Pv6fvbO/xhAonbJFIdf/MKQ1d30gndlsVzUOE83ldfSE15Qrl9fhFjK6AovHs5Wpp6vx86w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.61.1", - "@typescript-eslint/typescript-estree": "8.61.1", - "@typescript-eslint/utils": "8.61.1", + "@typescript-eslint/types": "8.62.0", + "@typescript-eslint/typescript-estree": "8.62.0", + "@typescript-eslint/utils": "8.62.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -1740,9 +1706,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.61.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.61.1.tgz", - "integrity": "sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA==", + "version": "8.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.0.tgz", + "integrity": "sha512-KvAclkktORPvM54TgLgA4z9HIV1M8zOgw9ZVNXl9f/8dLYfXYX1wkMXP7qmabpijQRV5bHJLOmoyGQbLMaUYeg==", "dev": true, "license": "MIT", "engines": { @@ -1754,16 +1720,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.61.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.61.1.tgz", - "integrity": "sha512-u+oQD3BqYWPc8YV9Zab4vaJElJuwOLPRc10Jm1o/qS+6Qwen14HCWwx0Seo4LnSn2wxea2Ik8DxPt2/FHmuhrg==", + "version": "8.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.0.tgz", + "integrity": "sha512-+hVbNxtW64pIcZWDPGbyaKF7vp2IBTVY5ma1blwwksrjdsbdqqEKvJWMGbBofei4F6Dovx1M0RJgoFeNu2279A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.61.1", - "@typescript-eslint/tsconfig-utils": "8.61.1", - "@typescript-eslint/types": "8.61.1", - "@typescript-eslint/visitor-keys": "8.61.1", + "@typescript-eslint/project-service": "8.62.0", + "@typescript-eslint/tsconfig-utils": "8.62.0", + "@typescript-eslint/types": "8.62.0", + "@typescript-eslint/visitor-keys": "8.62.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -1782,16 +1748,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.61.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.61.1.tgz", - "integrity": "sha512-1+P/3Dj6jvtybE1q0HQ6yBt/gq+oKJyLdEv4HdnqasaEXRSYCAsD59mXEVQnM/ULNdQxbX77tdG4jPRjIS6knA==", + "version": "8.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.62.0.tgz", + "integrity": "sha512-82r66fi9zYwZ+mTq3vKgwjbZ1PVk/DJzrXFLpG6RnBbdvH8TEGVHIs9H4d2drhkOzf0syZuD/OZvvlu6GDbP4g==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.61.1", - "@typescript-eslint/types": "8.61.1", - "@typescript-eslint/typescript-estree": "8.61.1" + "@typescript-eslint/scope-manager": "8.62.0", + "@typescript-eslint/types": "8.62.0", + "@typescript-eslint/typescript-estree": "8.62.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1806,13 +1772,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.61.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.61.1.tgz", - "integrity": "sha512-6fJ9MHWtK14C1DSkiMlHUSOmrVebL7150xZJBlJiL62jjhIA4JmOq6flwBgDxIdBKKdoiZRel+dfPD5MLfny3w==", + "version": "8.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.62.0.tgz", + "integrity": "sha512-CY3uyFSRbcQv3nnSv8S0+lDftMVz6P963PoRlxrV7ew/Md564g9ut60PYzdLM5qW4jFn93GBF+Soi90ISAN+GQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.61.1", + "@typescript-eslint/types": "8.62.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -2470,9 +2436,9 @@ } }, "node_modules/bootstrap-vue-next": { - "version": "0.45.6", - "resolved": "https://registry.npmjs.org/bootstrap-vue-next/-/bootstrap-vue-next-0.45.6.tgz", - "integrity": "sha512-/o9MfHbZ6bjCvQPSsRlsqcHqdhJG5K3mzC5pKlo+9bVn2Nq0GUGjd4Pk+KIMhnG6nlUdIcBzcoT2BBbMOabuNg==", + "version": "0.45.7", + "resolved": "https://registry.npmjs.org/bootstrap-vue-next/-/bootstrap-vue-next-0.45.7.tgz", + "integrity": "sha512-+xu9d/Luuc5JJQgDVnhFsIVruOwnl/YDIFl/bLE8OgkzR078zm66RQ8dtBSxPP+lxT3RmkW+UoYiDbwCBHfLmg==", "license": "MIT", "dependencies": { "@floating-ui/core": "^1.7.5", @@ -3245,9 +3211,9 @@ } }, "node_modules/exsolve": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", - "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.1.0.tgz", + "integrity": "sha512-D+42+T12DdIlJM3uepa55qGiL3sYdLBOxIl2ifQCzCHz4c7eiolaHsi3BIqEr7JxBzxv2pYZQX9kw16ziMcEmw==", "license": "MIT" }, "node_modules/fast-deep-equal": { @@ -3413,9 +3379,9 @@ } }, "node_modules/globals": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", - "integrity": "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==", + "version": "17.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.7.0.tgz", + "integrity": "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==", "dev": true, "license": "MIT", "engines": { @@ -3455,9 +3421,9 @@ } }, "node_modules/immutable": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.6.tgz", - "integrity": "sha512-q1swsS8K7L8usSHuOqF2TAoCCkonYz0SG38wLAggaa4Wml70zixIvt2ql4coQ2C2B3hTjltJry4r6bULwgAXLQ==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.7.tgz", + "integrity": "sha512-47Xb+LFbZ/ZIjQMj6Q5J3IfK7PJFuqRdFOC9FpGgRTK6U2dAEVmkR9hp58qU4FpYux5YXpneDwkj2EP6lppzFA==", "dev": true, "license": "MIT" }, @@ -4149,9 +4115,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.13", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.13.tgz", - "integrity": "sha512-sPdqC6ByMVVGvF1ynvvMo0/o+oD1VX7DaHhijt1bFgjvBkHBib4t49GoNDhf2NDta4oeUNlaGbSt5K7qjZ955Q==", + "version": "3.3.15", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", + "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", "funding": [ { "type": "github", @@ -4439,13 +4405,13 @@ } }, "node_modules/playwright": { - "version": "1.61.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.61.0.tgz", - "integrity": "sha512-Z+7BeeqQPRRzklHsVFP4KTGIyMxKUmfeRA4WisM6G3/XW6nwGeX6fX9qYaDa+CiUqpOkb2f6X3nar05R3kSuJQ==", + "version": "1.61.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.61.1.tgz", + "integrity": "sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.61.0" + "playwright-core": "1.61.1" }, "bin": { "playwright": "cli.js" @@ -4458,9 +4424,9 @@ } }, "node_modules/playwright-core": { - "version": "1.61.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.61.0.tgz", - "integrity": "sha512-caX7TrY3Ml6egyDX0WUcTHDxodl/b51y5wJOdCEA36QviK/s2g081hvmGs8eaE3DWb6NYZQ6BjO/QkNRPenoPA==", + "version": "1.61.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.61.1.tgz", + "integrity": "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -4599,9 +4565,9 @@ } }, "node_modules/reka-ui": { - "version": "2.9.10", - "resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.9.10.tgz", - "integrity": "sha512-yuvZVTp4fWH2G3qk+ze/x6YYlyc2Xl1d+eMUlIYrKqzTowBKteoDoN17fitURmqSUck3mc7JbcYgp49DnGu2EQ==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.10.0.tgz", + "integrity": "sha512-HIUVfSBM/AyGkcUI7aiOxxMc4N+0UD2ZEun8dcrT0H4fveotEoeDdvzyZu97eeEvEa1H9oGHoOpApkfxlgnC7g==", "license": "MIT", "dependencies": { "@floating-ui/dom": "^1.6.13", @@ -4640,13 +4606,13 @@ "license": "MIT" }, "node_modules/rolldown": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", - "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.2.tgz", + "integrity": "sha512-x0CrQQqCXWGeI8dTvFfN/Dnv3yMKT9hv5jFjlOreKAx9wqLq9wz7VvLLHyaAXC90/CpggTu9SisSbsJJTPSjNQ==", "devOptional": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.133.0", + "@oxc-project/types": "=0.137.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -4656,21 +4622,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.3", - "@rolldown/binding-darwin-arm64": "1.0.3", - "@rolldown/binding-darwin-x64": "1.0.3", - "@rolldown/binding-freebsd-x64": "1.0.3", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", - "@rolldown/binding-linux-arm64-gnu": "1.0.3", - "@rolldown/binding-linux-arm64-musl": "1.0.3", - "@rolldown/binding-linux-ppc64-gnu": "1.0.3", - "@rolldown/binding-linux-s390x-gnu": "1.0.3", - "@rolldown/binding-linux-x64-gnu": "1.0.3", - "@rolldown/binding-linux-x64-musl": "1.0.3", - "@rolldown/binding-openharmony-arm64": "1.0.3", - "@rolldown/binding-wasm32-wasi": "1.0.3", - "@rolldown/binding-win32-arm64-msvc": "1.0.3", - "@rolldown/binding-win32-x64-msvc": "1.0.3" + "@rolldown/binding-android-arm64": "1.1.2", + "@rolldown/binding-darwin-arm64": "1.1.2", + "@rolldown/binding-darwin-x64": "1.1.2", + "@rolldown/binding-freebsd-x64": "1.1.2", + "@rolldown/binding-linux-arm-gnueabihf": "1.1.2", + "@rolldown/binding-linux-arm64-gnu": "1.1.2", + "@rolldown/binding-linux-arm64-musl": "1.1.2", + "@rolldown/binding-linux-ppc64-gnu": "1.1.2", + "@rolldown/binding-linux-s390x-gnu": "1.1.2", + "@rolldown/binding-linux-x64-gnu": "1.1.2", + "@rolldown/binding-linux-x64-musl": "1.1.2", + "@rolldown/binding-openharmony-arm64": "1.1.2", + "@rolldown/binding-wasm32-wasi": "1.1.2", + "@rolldown/binding-win32-arm64-msvc": "1.1.2", + "@rolldown/binding-win32-x64-msvc": "1.1.2" } }, "node_modules/sass": { @@ -4715,9 +4681,9 @@ "license": "MIT" }, "node_modules/semver": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", - "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, "license": "ISC", "bin": { @@ -4895,22 +4861,22 @@ } }, "node_modules/tldts": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.3.tgz", - "integrity": "sha512-A3BDQBeeukYPzB4QdQ1DtdlUmp4x2OCH8n5UVhEWbyANxNep8GavottKzd1xYKFJKjUgMyPT7EzOfnBO55s8Sg==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.4.tgz", + "integrity": "sha512-kFXFK7O4WPextIUAOk8qtnw9dxR9UIXP9CjuH1cTBVBZMDeQcUPgr/IazGiw1B0Yiw5L75gHLWeW4iD793r90g==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^7.4.3" + "tldts-core": "^7.4.4" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.3.tgz", - "integrity": "sha512-27ep5H9PzdBrNd5OFM/j3WCU8F3kPwM9D0BOaOf7uYfxMJfyr0K5Tjj69Gri+sZlh2WXd5buIm47NuPF29CDiw==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.4.tgz", + "integrity": "sha512-vwVLJVvvpslm7vqAH7+XNj/neA/Ynq7DT2EEcMuwc5YzN5XaMyRAqxwU+uX3azZ1FQtB2gvrvnLnAEkvYlVdfg==", "dev": true, "license": "MIT" }, @@ -4998,16 +4964,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.61.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.61.1.tgz", - "integrity": "sha512-V7PayAfJokV3pEHgN7/v03D1SpujhRfQtYLbLIiBfDDncdg4PAiRBfoS4cnCANK4jmAPncczi59QO3afiXUlNw==", + "version": "8.62.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.62.0.tgz", + "integrity": "sha512-8QxXi+ZACKX0kaqO4gY8kn0RSD9gFfaHDWwjqtEN48aWCBkX4MJaufWN+c3BzlrXLOxfywDL8CaoqUwcRq4j4Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.61.1", - "@typescript-eslint/parser": "8.61.1", - "@typescript-eslint/typescript-estree": "8.61.1", - "@typescript-eslint/utils": "8.61.1" + "@typescript-eslint/eslint-plugin": "8.62.0", + "@typescript-eslint/parser": "8.62.0", + "@typescript-eslint/typescript-estree": "8.62.0", + "@typescript-eslint/utils": "8.62.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5179,9 +5145,9 @@ "license": "MIT" }, "node_modules/vite": { - "version": "8.0.16", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", - "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.0.tgz", + "integrity": "sha512-BuJcQK/56NQTWDGn4ABea3q4SSBdNPWwNZKTkkUpcMPnLoquSYH8llRtSUIgoL1KSCpHt5eghLShn50mH36y7Q==", "devOptional": true, "license": "MIT", "peer": true, @@ -5189,7 +5155,7 @@ "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.15", - "rolldown": "1.0.3", + "rolldown": "~1.1.2", "tinyglobby": "^0.2.17" }, "bin": { @@ -5206,7 +5172,7 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.1.18", + "@vitejs/devtools": "^0.3.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", diff --git a/client-v3/package.json b/client-v3/package.json index d24693e2f..256c770da 100644 --- a/client-v3/package.json +++ b/client-v3/package.json @@ -1,6 +1,6 @@ { "name": "client-v3", - "version": "0.32.4", + "version": "0.33.0", "description": "DigiScript front end (Vue 3)", "author": "DreamTeamProd", "private": true, @@ -34,7 +34,7 @@ "@vuelidate/core": "^2.0.3", "@vuelidate/validators": "^2.0.4", "bootstrap": "^5.3.8", - "bootstrap-vue-next": "^0.45.6", + "bootstrap-vue-next": "^0.45.7", "bootswatch": "^5.3.8", "contrast-color": "1.0.1", "core-js": "^3.49.0", @@ -62,8 +62,8 @@ "@iconify-json/mdi": "^1.2.3", "@types/lodash": "~4.17.24", "@types/node": ">=22.12.0", - "@typescript-eslint/eslint-plugin": "^8.61.1", - "@typescript-eslint/parser": "^8.61.1", + "@typescript-eslint/eslint-plugin": "^8.62.0", + "@typescript-eslint/parser": "^8.62.0", "@vitejs/plugin-vue": "^6.0.7", "@vitest/ui": "^4.1.9", "@vue/test-utils": "^2.4.11", @@ -71,19 +71,19 @@ "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.6", "eslint-plugin-vue": "^10.9.2", - "globals": "^17.6.0", + "globals": "^17.7.0", "jiti": "^2.7.0", "jsdom": "^29.1.1", "prettier": "^3.8.4", "sass": "1.101.0", "typescript": "^6.0.3", - "typescript-eslint": "^8.61.1", + "typescript-eslint": "^8.62.0", "unplugin-icons": "^23.0.1", "unplugin-vue-components": "^32.1.0", - "vite": "^8.0.16", + "vite": "^8.1.0", "vitest": "^4.1.9", "vue-eslint-parser": "^10.4.1", - "@playwright/test": "^1.61.0" + "@playwright/test": "^1.61.1" }, "overrides": { "glob": "^13.0.6" diff --git a/client-v3/src/components/show/config/cues/CueGroupEditModal.vue b/client-v3/src/components/show/config/cues/CueGroupEditModal.vue new file mode 100644 index 000000000..49326d45c --- /dev/null +++ b/client-v3/src/components/show/config/cues/CueGroupEditModal.vue @@ -0,0 +1,109 @@ + + + diff --git a/client-v3/src/components/show/config/cues/CueGroupForm.vue b/client-v3/src/components/show/config/cues/CueGroupForm.vue new file mode 100644 index 000000000..18ddf9a6b --- /dev/null +++ b/client-v3/src/components/show/config/cues/CueGroupForm.vue @@ -0,0 +1,297 @@ + + + + + diff --git a/client-v3/src/components/show/config/cues/ScriptLineCueEditor.vue b/client-v3/src/components/show/config/cues/ScriptLineCueEditor.vue index 9c2853d87..ed65da230 100644 --- a/client-v3/src/components/show/config/cues/ScriptLineCueEditor.vue +++ b/client-v3/src/components/show/config/cues/ScriptLineCueEditor.vue @@ -23,7 +23,7 @@