From 918e9259516071f551173e31bc0a3bf05468f39a Mon Sep 17 00:00:00 2001 From: Bob Lee Date: Thu, 16 Jul 2026 10:20:35 +0800 Subject: [PATCH 1/4] fix(ssh-remote): keep reconnecting remote workspaces for 180s Fast connect failures previously exhausted a single retry and removed the workspace immediately. Use a deadline-driven reconnect budget so remote workspaces stay until the full timeout elapses. --- .../ssh-remote/SSHRemoteProvider.test.tsx | 70 +++++++++++++ .../features/ssh-remote/SSHRemoteProvider.tsx | 99 ++++++++++--------- .../remoteWorkspaceReconnect.test.ts | 91 +++++++++++++++++ .../ssh-remote/remoteWorkspaceReconnect.ts | 61 ++++++++++++ 4 files changed, 275 insertions(+), 46 deletions(-) create mode 100644 src/web-ui/src/features/ssh-remote/remoteWorkspaceReconnect.test.ts create mode 100644 src/web-ui/src/features/ssh-remote/remoteWorkspaceReconnect.ts diff --git a/src/web-ui/src/features/ssh-remote/SSHRemoteProvider.test.tsx b/src/web-ui/src/features/ssh-remote/SSHRemoteProvider.test.tsx index d0421bf66f..503113dc03 100644 --- a/src/web-ui/src/features/ssh-remote/SSHRemoteProvider.test.tsx +++ b/src/web-ui/src/features/ssh-remote/SSHRemoteProvider.test.tsx @@ -4,6 +4,9 @@ import React, { act } from 'react'; import { createRoot, type Root } from 'react-dom/client'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { WorkspaceKind, WorkspaceType } from '@/shared/types/global-state'; +import { notificationService } from '@/shared/notification-system'; + import { SSHRemoteProvider } from './SSHRemoteProvider'; globalThis.IS_REACT_ACT_ENVIRONMENT = true; @@ -21,6 +24,7 @@ const sshApiMock = vi.hoisted(() => ({ listSavedConnections: vi.fn(), hasStoredPassword: vi.fn(), isConnected: vi.fn(), + connect: vi.fn(), openWorkspace: vi.fn(), disconnect: vi.fn(), closeWorkspace: vi.fn(), @@ -79,8 +83,17 @@ describe('SSHRemoteProvider startup restore', () => { activeWorkspaceId: null, }); workspaceManagerMock.addEventListener.mockReturnValue(() => undefined); + workspaceManagerMock.consumeStartupLegacyRemoteWorkspaceSnapshot.mockReturnValue({ + available: true, + workspace: null, + }); sshApiMock.getWorkspaceInfo.mockResolvedValue(null); sshApiMock.listSavedConnections.mockResolvedValue([]); + sshApiMock.isConnected.mockResolvedValue(false); + sshApiMock.connect.mockResolvedValue({ success: false, error: 'connection refused' }); + sshApiMock.openWorkspace.mockResolvedValue(undefined); + sshApiMock.removeWorkspace.mockResolvedValue(undefined); + workspaceManagerMock.removeRemoteWorkspace.mockResolvedValue(undefined); }); afterEach(() => { @@ -88,6 +101,7 @@ describe('SSHRemoteProvider startup restore', () => { root.unmount(); }); container.remove(); + vi.useRealTimers(); }); async function renderProvider(): Promise { @@ -125,4 +139,60 @@ describe('SSHRemoteProvider startup restore', () => { expect(sshApiMock.getWorkspaceInfo).toHaveBeenCalledTimes(1); }); + + it('does not remove a disconnected remote workspace until the 180s reconnect budget elapses', async () => { + vi.useFakeTimers(); + + const remoteWorkspace = { + id: 'ws-remote-1', + name: 'repos', + rootPath: '/root/repos', + workspaceType: WorkspaceType.SingleProject, + workspaceKind: WorkspaceKind.Remote, + languages: [] as string[], + openedAt: new Date().toISOString(), + lastAccessed: new Date().toISOString(), + tags: [] as string[], + connectionId: 'conn-1', + connectionName: 'dev-box', + sshHost: 'example.com', + }; + + workspaceManagerMock.getState.mockReturnValue({ + loading: false, + openedWorkspaces: new Map([[remoteWorkspace.id, remoteWorkspace]]), + activeWorkspaceId: remoteWorkspace.id, + }); + sshApiMock.listSavedConnections.mockResolvedValue([ + { + id: 'conn-1', + name: 'dev-box', + host: 'example.com', + port: 22, + username: 'root', + authType: { type: 'PrivateKey', keyPath: '/tmp/id_rsa' }, + }, + ]); + + await renderProvider(); + + // Fast connect failures must keep retrying; workspace must stay until budget ends. + await act(async () => { + await vi.advanceTimersByTimeAsync(60_000); + }); + expect(workspaceManagerMock.removeRemoteWorkspace).not.toHaveBeenCalled(); + expect(sshApiMock.removeWorkspace).not.toHaveBeenCalled(); + expect(sshApiMock.connect.mock.calls.length).toBeGreaterThan(1); + + await act(async () => { + await vi.advanceTimersByTimeAsync(120_000); + }); + + expect(workspaceManagerMock.removeRemoteWorkspace).toHaveBeenCalledWith('conn-1', '/root/repos'); + expect(sshApiMock.removeWorkspace).toHaveBeenCalledWith('conn-1', '/root/repos'); + expect(notificationService.error).toHaveBeenCalledWith( + 'Remote workspace could not reconnect within 180 seconds and was removed: /root/repos', + { duration: 8000 } + ); + }); }); diff --git a/src/web-ui/src/features/ssh-remote/SSHRemoteProvider.tsx b/src/web-ui/src/features/ssh-remote/SSHRemoteProvider.tsx index bf8405dd6a..9b2a0005ef 100644 --- a/src/web-ui/src/features/ssh-remote/SSHRemoteProvider.tsx +++ b/src/web-ui/src/features/ssh-remote/SSHRemoteProvider.tsx @@ -17,10 +17,15 @@ import { type ConnectionStatus, type SSHContextValue, } from './SSHRemoteContext'; +import { + REMOTE_WORKSPACE_RECONNECT_TIMEOUT_MS, + reconnectUntilDeadline, + remoteReconnectTimeoutSeconds, +} from './remoteWorkspaceReconnect'; const log = createLogger('SSHRemoteProvider'); const pendingAcpCapabilityRefreshes = new Set(); -const REMOTE_WORKSPACE_RECONNECT_TIMEOUT_MS = 60_000; +const RECONNECT_TIMEOUT_SECONDS = remoteReconnectTimeoutSeconds(); function refreshRemoteAcpCapabilities(connectionId: string): void { const normalized = connectionId.trim(); @@ -198,8 +203,8 @@ export const SSHRemoteProvider: React.FC = ({ children } notificationService.error( pathList - ? `Remote workspace connection timed out after 60 seconds and was removed: ${pathList}` - : 'Remote workspace connection timed out after 60 seconds.', + ? `Remote workspace connection timed out after ${RECONNECT_TIMEOUT_SECONDS} seconds and was removed: ${pathList}` + : `Remote workspace connection timed out after ${RECONNECT_TIMEOUT_SECONDS} seconds.`, { duration: 8000 } ); @@ -248,7 +253,7 @@ export const SSHRemoteProvider: React.FC = ({ children } const reportRemoteWorkspaceReconnectFailure = useCallback((workspace: RemoteWorkspace) => { const path = normalizeRemoteWorkspacePath(workspace.remotePath); notificationService.error( - `Remote workspace could not reconnect within 60 seconds and was removed: ${path}`, + `Remote workspace could not reconnect within ${RECONNECT_TIMEOUT_SECONDS} seconds and was removed: ${path}`, { duration: 8000 } ); }, []); @@ -267,17 +272,13 @@ export const SSHRemoteProvider: React.FC = ({ children } }; }, []); - // Try to reconnect a single remote workspace with retries. - // Returns the reconnected workspace info on success, false on failure. - // Waits RETRY_WAIT_MS between each attempt (fixed, not exponential). - const RETRY_WAIT_MS = 10_000; - + // Try to reconnect a single remote workspace until the reconnect budget expires. + // Fast connection failures must keep retrying inside the budget; only then remove. const tryReconnectWithRetry = useCallback(async ( workspace: RemoteWorkspace, - maxRetries: number, - timeoutMs: number + timeoutMs: number = REMOTE_WORKSPACE_RECONNECT_TIMEOUT_MS ): Promise => { - log.info('tryReconnectWithRetry: starting', { workspace, maxRetries, timeoutMs }); + log.info('tryReconnectWithRetry: starting', { workspace, timeoutMs }); const savedConnections = await sshApi.listSavedConnections(); const savedConn = savedConnections.find(c => c.id === workspace.connectionId); @@ -305,11 +306,13 @@ export const SSHRemoteProvider: React.FC = ({ children } auth: authMethod, }; - for (let attempt = 1; attempt <= maxRetries; attempt++) { - try { - log.info(`Attempting to reconnect (${attempt}/${maxRetries})`, { + return reconnectUntilDeadline({ + totalTimeoutMs: timeoutMs, + attempt: async (attemptTimeoutMs, attempt) => { + log.info(`Attempting to reconnect (attempt ${attempt})`, { connectionId: workspace.connectionId, host: reconnectConfig.host, + attemptTimeoutMs, }); const connectWithTimeout = async (): Promise<{ connectionId: string }> => { @@ -320,36 +323,44 @@ export const SSHRemoteProvider: React.FC = ({ children } return { connectionId: result.connectionId }; }; - const timeoutPromise = new Promise((_, reject) => { - setTimeout(() => reject(new Error('Connection timeout')), timeoutMs); - }); + let timeoutId: number | undefined; + try { + const timeoutPromise = new Promise((_, reject) => { + timeoutId = window.setTimeout( + () => reject(new Error('Connection timeout')), + attemptTimeoutMs + ); + }); - const result = await Promise.race([connectWithTimeout(), timeoutPromise]); + const result = await Promise.race([connectWithTimeout(), timeoutPromise]); - // Successfully connected — open the workspace in SSH state manager - await sshApi.openWorkspace(result.connectionId, workspace.remotePath); - const reconnectedWorkspace: RemoteWorkspace = { - connectionId: result.connectionId, - connectionName: savedConn.name, - remotePath: workspace.remotePath, - sshHost: reconnectConfig.host?.trim() || workspace.sshHost?.trim() || undefined, - }; + // Successfully connected — open the workspace in SSH state manager + await sshApi.openWorkspace(result.connectionId, workspace.remotePath); + const reconnectedWorkspace: RemoteWorkspace = { + connectionId: result.connectionId, + connectionName: savedConn.name, + remotePath: workspace.remotePath, + sshHost: reconnectConfig.host?.trim() || workspace.sshHost?.trim() || undefined, + }; - log.info('Successfully reconnected to remote workspace', { - originalConnectionId: workspace.connectionId, - newConnectionId: result.connectionId, - }); - return { workspace: reconnectedWorkspace, connectionId: result.connectionId }; - } catch (err) { - log.warn(`Reconnect attempt ${attempt}/${maxRetries} failed`, { connectionId: workspace.connectionId, error: err }); - if (attempt < maxRetries) { - // Fixed 10-second wait between retries - await new Promise(resolve => setTimeout(resolve, RETRY_WAIT_MS)); + log.info('Successfully reconnected to remote workspace', { + originalConnectionId: workspace.connectionId, + newConnectionId: result.connectionId, + }); + return { workspace: reconnectedWorkspace, connectionId: result.connectionId }; + } catch (err) { + log.warn(`Reconnect attempt ${attempt} failed`, { + connectionId: workspace.connectionId, + error: err, + }); + throw err; + } finally { + if (timeoutId !== undefined) { + window.clearTimeout(timeoutId); + } } - } - } - - return false; + }, + }); }, []); const statusRef = useRef(status); @@ -542,11 +553,7 @@ export const SSHRemoteProvider: React.FC = ({ children } connectionId: workspace.connectionId, remotePath: workspace.remotePath, }); - const result = await tryReconnectWithRetry( - workspace, - 1, - REMOTE_WORKSPACE_RECONNECT_TIMEOUT_MS - ); + const result = await tryReconnectWithRetry(workspace); if (result !== false) { log.info('Reconnection successful', { newConnectionId: result.connectionId }); diff --git a/src/web-ui/src/features/ssh-remote/remoteWorkspaceReconnect.test.ts b/src/web-ui/src/features/ssh-remote/remoteWorkspaceReconnect.test.ts new file mode 100644 index 0000000000..99510de121 --- /dev/null +++ b/src/web-ui/src/features/ssh-remote/remoteWorkspaceReconnect.test.ts @@ -0,0 +1,91 @@ +import { describe, expect, it, vi } from 'vitest'; + +import { + REMOTE_WORKSPACE_RECONNECT_TIMEOUT_MS, + reconnectUntilDeadline, + remoteReconnectTimeoutSeconds, +} from './remoteWorkspaceReconnect'; + +describe('remoteWorkspaceReconnect', () => { + it('exposes a 180-second reconnect budget', () => { + expect(REMOTE_WORKSPACE_RECONNECT_TIMEOUT_MS).toBe(180_000); + expect(remoteReconnectTimeoutSeconds()).toBe(180); + }); + + it('keeps retrying after fast failures until the deadline', async () => { + let clock = 0; + const attempts: number[] = []; + const sleepCalls: number[] = []; + + const result = await reconnectUntilDeadline({ + totalTimeoutMs: 180_000, + attemptTimeoutMs: 30_000, + retryWaitMs: 10_000, + now: () => clock, + sleep: async ms => { + sleepCalls.push(ms); + clock += ms; + }, + attempt: async (_timeoutMs, attempt) => { + attempts.push(attempt); + // Instant failure — must not exhaust the budget on the first try. + throw new Error('connection refused'); + }, + }); + + expect(result).toBe(false); + expect(attempts.length).toBeGreaterThan(1); + expect(attempts.length).toBeGreaterThanOrEqual(10); + expect(sleepCalls.length).toBe(attempts.length); + expect(clock).toBeGreaterThanOrEqual(180_000); + }); + + it('returns success as soon as an attempt succeeds within the budget', async () => { + let clock = 0; + let attemptCount = 0; + + const result = await reconnectUntilDeadline({ + totalTimeoutMs: 180_000, + attemptTimeoutMs: 30_000, + retryWaitMs: 10_000, + now: () => clock, + sleep: async ms => { + clock += ms; + }, + attempt: async () => { + attemptCount += 1; + if (attemptCount < 3) { + throw new Error('temporary failure'); + } + return { connectionId: 'conn-ok' }; + }, + }); + + expect(result).toEqual({ connectionId: 'conn-ok' }); + expect(attemptCount).toBe(3); + expect(clock).toBeLessThan(180_000); + }); + + it('does not wait past the deadline after the final failed attempt', async () => { + let clock = 0; + const sleepCalls: number[] = []; + + const result = await reconnectUntilDeadline({ + totalTimeoutMs: 12_000, + attemptTimeoutMs: 30_000, + retryWaitMs: 10_000, + now: () => clock, + sleep: async ms => { + sleepCalls.push(ms); + clock += ms; + }, + attempt: async () => { + throw new Error('still down'); + }, + }); + + expect(result).toBe(false); + expect(sleepCalls).toEqual([10_000, 2_000]); + expect(clock).toBe(12_000); + }); +}); diff --git a/src/web-ui/src/features/ssh-remote/remoteWorkspaceReconnect.ts b/src/web-ui/src/features/ssh-remote/remoteWorkspaceReconnect.ts new file mode 100644 index 0000000000..938bb4afc5 --- /dev/null +++ b/src/web-ui/src/features/ssh-remote/remoteWorkspaceReconnect.ts @@ -0,0 +1,61 @@ +/** + * Remote workspace auto-reconnect timing and deadline-driven retry. + * + * The reconnect budget is a wall-clock window: keep attempting until the + * deadline, then give up and allow callers to remove the workspace. + * A single fast-failing connect must not exhaust the budget. + */ + +export const REMOTE_WORKSPACE_RECONNECT_TIMEOUT_MS = 180_000; +export const REMOTE_WORKSPACE_RECONNECT_RETRY_WAIT_MS = 10_000; +/** Cap for one connect attempt so fast failures can still retry within the budget. */ +export const REMOTE_WORKSPACE_RECONNECT_ATTEMPT_TIMEOUT_MS = 30_000; + +export function remoteReconnectTimeoutSeconds( + timeoutMs: number = REMOTE_WORKSPACE_RECONNECT_TIMEOUT_MS +): number { + return Math.round(timeoutMs / 1000); +} + +export type ReconnectUntilDeadlineOptions = { + totalTimeoutMs: number; + attemptTimeoutMs?: number; + retryWaitMs?: number; + now?: () => number; + sleep?: (ms: number) => Promise; + attempt: (attemptTimeoutMs: number, attempt: number) => Promise; +}; + +export async function reconnectUntilDeadline( + options: ReconnectUntilDeadlineOptions +): Promise { + const now = options.now ?? Date.now; + const sleep = + options.sleep ?? + ((ms: number) => new Promise(resolve => setTimeout(resolve, ms))); + const attemptTimeoutMs = + options.attemptTimeoutMs ?? REMOTE_WORKSPACE_RECONNECT_ATTEMPT_TIMEOUT_MS; + const retryWaitMs = options.retryWaitMs ?? REMOTE_WORKSPACE_RECONNECT_RETRY_WAIT_MS; + const deadline = now() + options.totalTimeoutMs; + + let attempt = 0; + while (now() < deadline) { + attempt += 1; + const remaining = deadline - now(); + if (remaining <= 0) { + break; + } + const timeoutForAttempt = Math.min(attemptTimeoutMs, remaining); + try { + return await options.attempt(timeoutForAttempt, attempt); + } catch { + const waitBudget = deadline - now(); + if (waitBudget <= 0) { + break; + } + await sleep(Math.min(retryWaitMs, waitBudget)); + } + } + + return false; +} From 7401d117f0510e529d9611f7ea68fece8d90c6d9 Mon Sep 17 00:00:00 2001 From: Bob Lee Date: Thu, 16 Jul 2026 10:20:40 +0800 Subject: [PATCH 2/4] fix(agent): tolerate trailing-newline gaps in file-read freshness Read-tool cache reconstruction drops a trailing newline while remote SFTP re-reads preserve it. Normalize that gap so remote Edit/Write no longer false-fail freshness checks on unchanged files. --- .../agent-runtime/src/file_read_state.rs | 18 +++++++++++ .../tool-contracts/src/file_read_freshness.rs | 16 ++++++++-- .../tool-contracts/tests/tool_contracts.rs | 31 ++++++++++++++++++- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/crates/execution/agent-runtime/src/file_read_state.rs b/src/crates/execution/agent-runtime/src/file_read_state.rs index 9b0283a9d1..4d75a96c50 100644 --- a/src/crates/execution/agent-runtime/src/file_read_state.rs +++ b/src/crates/execution/agent-runtime/src/file_read_state.rs @@ -442,6 +442,24 @@ mod tests { .is_none()); } + #[test] + fn validate_edit_content_freshness_allows_remote_content_missing_cached_trailing_newline() { + // Regression test: the Read tool's cached content is reconstructed via + // a line-split/join that drops a trailing newline, while a remote + // SFTP re-read of the same unchanged file preserves it. Remote + // workspaces have no mtime to short-circuit the comparison, so this + // must not be reported as "no longer matches the last Read result". + let state = read_state("alpha\nbeta", 100); + + assert!(validate_edit_content_freshness_against_read_state( + "Caddyfile", + &state, + "alpha\nbeta\n", + None, + ) + .is_none()); + } + #[test] fn validate_edit_content_freshness_rejects_changed_remote_content_without_mtime() { let state = read_state("alpha\n", 100); diff --git a/src/crates/execution/tool-contracts/src/file_read_freshness.rs b/src/crates/execution/tool-contracts/src/file_read_freshness.rs index bf2e30297c..b8f78ae65f 100644 --- a/src/crates/execution/tool-contracts/src/file_read_freshness.rs +++ b/src/crates/execution/tool-contracts/src/file_read_freshness.rs @@ -7,12 +7,24 @@ pub struct FileReadFreshnessFacts<'a> { pub is_full_file_read: bool, } +/// Normalize file content for freshness comparison only (not for diffing or +/// content substitution). +/// +/// The cached "last Read result" content is reconstructed from formatted +/// `cat -n`-style tool output via a line-split/join, which always drops a +/// trailing newline even when the real file ends with one. A fresh re-read +/// (local `fs::read_to_string` or remote SFTP `read_file_text`) preserves it. +/// Without normalizing this away, every full-file Edit/Write on a file that +/// ends with a newline (the common case) would look "changed" purely from +/// that reconstruction gap. This is most visible on remote workspaces, where +/// there is no mtime to short-circuit the content comparison. pub fn normalize_tool_file_content(content: &str) -> String { - if content.contains("\r\n") { + let normalized = if content.contains("\r\n") { content.replace("\r\n", "\n") } else { content.to_string() - } + }; + normalized.trim_end_matches('\n').to_string() } pub fn file_read_facts_content_matches( diff --git a/src/crates/execution/tool-contracts/tests/tool_contracts.rs b/src/crates/execution/tool-contracts/tests/tool_contracts.rs index 5795871b28..396506c6f7 100644 --- a/src/crates/execution/tool-contracts/tests/tool_contracts.rs +++ b/src/crates/execution/tool-contracts/tests/tool_contracts.rs @@ -735,7 +735,7 @@ fn file_read_freshness_policy_preserves_read_edit_write_guardrails() { is_full_file_read: true, }; - assert_eq!(normalize_tool_file_content("alpha\r\n"), "alpha\n"); + assert_eq!(normalize_tool_file_content("alpha\r\n"), "alpha"); assert!(file_read_facts_content_matches(full_read, "alpha\n")); assert!(file_read_facts_are_fresh(full_read, "alpha\n", Some(200))); assert!(!file_read_facts_are_fresh(full_read, "beta\n", Some(200))); @@ -756,6 +756,35 @@ fn file_read_freshness_policy_preserves_read_edit_write_guardrails() { assert!(file_read_facts_are_fresh(partial_read, "full file\n", None)); } +#[test] +fn file_read_freshness_tolerates_read_tool_trailing_newline_reconstruction_gap() { + // The cached "last Read result" content is rebuilt from cat -n-style + // output via a line-split/join, which drops a trailing newline even when + // the file on disk ends with one. Remote workspaces have no mtime to + // short-circuit this comparison, so every full-file Edit/Write on a + // trailing-newline file (the common case) must still be considered fresh. + let cached_without_trailing_newline = FileReadFreshnessFacts { + content: "alpha\nbeta", + timestamp_ms: 100, + is_full_file_read: true, + }; + + assert!(file_read_facts_content_matches( + cached_without_trailing_newline, + "alpha\nbeta\n" + )); + assert!(file_read_facts_are_fresh( + cached_without_trailing_newline, + "alpha\nbeta\n", + None + )); + assert!(!file_read_facts_are_fresh( + cached_without_trailing_newline, + "alpha\ngamma\n", + None + )); +} + #[test] fn persisted_tool_output_message_keeps_reference_preview_and_metadata_shape() { let rendered = build_persisted_tool_output_message( From 8de6344774e65a16f3cb837c6d75ea75a9f9faf2 Mon Sep 17 00:00:00 2001 From: Bob Lee Date: Thu, 16 Jul 2026 10:20:46 +0800 Subject: [PATCH 3/4] fix(ppt-live): harden generation contract and editable PPTX export Tighten the project.json/slides file protocol with retries and targeted repair, auto-fix export DOM issues, prefer native editable PPTX objects with layered SVG/PNG fallbacks, and add OOXML/CI regression coverage. --- .github/workflows/ci.yml | 3 + package.json | 1 + .../core/builtin_skills/ppt-design/SKILL.md | 10 +- .../product-domains/src/miniapp/builtin.rs | 24 +- .../builtin/assets/ppt-live/bundle.json | 2 +- .../builtin/assets/ppt-live/dist/ui.bundle.js | 3711 ++++++++++++++--- .../miniapp/builtin/assets/ppt-live/meta.json | 2 +- .../assets/ppt-live/src/agent-prompt.js | 91 + .../ppt-live/src/bitfun-backend-adapter.js | 131 +- .../ppt-live/src/deck-project-contract.js | 327 ++ .../assets/ppt-live/src/element-model-html.js | 163 + .../assets/ppt-live/src/export-diagnostics.js | 133 + .../assets/ppt-live/src/export-html.js | 3 +- .../ppt-live/src/export-slide-browser.js | 296 +- .../ppt-live/src/fallback-layer-render.js | 516 +++ .../assets/ppt-live/src/html2pptx-dom-core.js | 791 +++- .../builtin/assets/ppt-live/src/i18n.js | 28 + .../assets/ppt-live/src/paint-order.js | 9 + .../assets/ppt-live/src/pptx-html-build.js | 119 +- .../builtin/assets/ppt-live/src/render.js | 109 +- .../ppt-live/src/sanitize-slide-html.js | 347 +- .../ppt-live/src/sanitize-slide-markup.js | 260 ++ .../test/dom-repair-diagnostics.test.mjs | 1777 ++++++++ .../test/generated-file-protocol.test.mjs | 706 ++++ .../test/pptx-ooxml-artifact.test.mjs | 623 +++ .../src/miniapp/builtin/assets/ppt-live/ui.js | 216 +- 26 files changed, 9427 insertions(+), 971 deletions(-) create mode 100644 src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/agent-prompt.js create mode 100644 src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/deck-project-contract.js create mode 100644 src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/element-model-html.js create mode 100644 src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-diagnostics.js create mode 100644 src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/fallback-layer-render.js create mode 100644 src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/paint-order.js create mode 100644 src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/sanitize-slide-markup.js create mode 100644 src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test/dom-repair-diagnostics.test.mjs create mode 100644 src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test/generated-file-protocol.test.mjs create mode 100644 src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test/pptx-ooxml-artifact.test.mjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index efca8434d8..ff095d49b4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -162,6 +162,9 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile + - name: Validate PPT Live generated-file contract + run: pnpm run test:ppt-live + - name: Validate GitHub config run: pnpm run check:github-config diff --git a/package.json b/package.json index 723bba02e1..4d430ddeb3 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "i18n:generate": "node scripts/generate-i18n-contract.mjs", "i18n:contract:test": "node --test scripts/i18n-contract.test.mjs", "i18n:contract:test:ci": "cross-env BITFUN_I18N_CONTRACT_TEST_PROFILE=ci node --test scripts/i18n-contract.test.mjs", + "test:ppt-live": "node --test src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test/*.test.mjs", "i18n:audit": "node scripts/i18n-audit.mjs", "theme:color-audit": "node scripts/audit-theme-colors.mjs", "theme:color-audit:mobile": "node scripts/audit-theme-colors.mjs --root src/mobile-web/src --baseline scripts/theme-color-governance-baseline.mobile-web.json", diff --git a/src/crates/assembly/core/builtin_skills/ppt-design/SKILL.md b/src/crates/assembly/core/builtin_skills/ppt-design/SKILL.md index b84787b835..95308771bf 100644 --- a/src/crates/assembly/core/builtin_skills/ppt-design/SKILL.md +++ b/src/crates/assembly/core/builtin_skills/ppt-design/SKILL.md @@ -12,10 +12,10 @@ license: MIT ## 项目约定 -`{{ppt_project_dir}}` 为当前 deck 根目录,**只在此目录读写**。 +Agent 启动时的**当前工作区根目录就是当前 deck 根目录**,不是待替换的模板变量,也不是工作区下另建的同名子目录。所有交付路径都相对当前工作区根目录,且**只在此工作区读写**。 - **页文件**:`slides/slide-01.html` …(两位数编号,与 `outline[].slide_id` 对应) -- **大纲**:`project.json` → `outline[]`:`{ id, title, bullets[], slide_id }` +- **大纲**:`project.json` → `outline[]`:`{ id, title, bullets[], slide_id }`;规划时 `status: "planning"`,仅在全部引用页面完整写入后改为 `status: "complete"` - **品牌图**:`brand/` ## 核心原则(严格遵守) @@ -64,7 +64,7 @@ license: MIT | 既要复杂视觉又要可改字 pptx | **不可兼得**——说明限制;保留 1920 演讲版或另做简化 960 版 | ``` -{{ppt_project_dir}}/ +当前工作区根目录/ ├── project.json # outline[], slide_order[], style, assumptions ├── brand/ ├── slides/slide-XX.html @@ -161,10 +161,10 @@ DNA 与样例 → `references/design-styles.md`。 ## 工作流 -1. **假设 + 纲**:更新 `project.json` 的 `outline[]` / `slide_order`;顺带识别可能受益于图表、图示或更强视觉表达的页面,先不批量写 HTML。**若主题涉及技术方案/工程/系统/项目分析,必须在 outline 阶段就识别出哪些页是「系统组成」「处理流程」「多角色协作」「根因分析」,并标注用架构图/流程图/泳道图/因果链**(参考上方「技术方案类内容的特别触发」)。 +1. **假设 + 纲**:先写 `project.json`,设置 `status: "planning"` 并完成 `outline[]` / `slide_order`,再开始任何 `slides/slide-NN.html`;顺带识别可能受益于图表、图示或更强视觉表达的页面,先不批量写 HTML。**若主题涉及技术方案/工程/系统/项目分析,必须在 outline 阶段就识别出哪些页是「系统组成」「处理流程」「多角色协作」「根因分析」,并标注用架构图/流程图/泳道图/因果链**(参考上方「技术方案类内容的特别触发」)。 2. **≥5 页先打样**:做 2 页视觉差异最大的 showcase,定 grammar 再批量(见 slide-decks.md)。 3. **逐页 HTML**:封面 `slide-01`(标题/副标题/作者或日期)→ 按 outline 生成其余页;根据内容与风格自由选择图表、图示、文字、图片或混合构图,每页完整内联 CSS。**写每页时一次写对**:写之前先做垂直预算心算(见「防溢出预算」),写的时候同时遵守四条 OOXML 硬约束(文字用 p/h\* 包裹、纯色无渐变、背景/边框只在 DIV、不用 background-image),写完即止。 -4. **禁止事后审计**:所有页面写完后**不得**再回头逐页 Read → Edit 返工,也不得用 Grep 批量检查约束。约束在写时遵守,不事后补救。写完最后一页后直接输出完成总结即可。 +4. **有界完成检查**:最后一页写完后仅检查一次生成文件协议:`outline[].slide_id` 与 `slide_order` 一一对应、每个 `slides/slide-NN.html` 存在且完整。只补写缺失或不完整文件,不做逐页内容审计,不用 Grep 批量检查设计约束;全部满足后将 `project.json.status` 改为 `"complete"` 并结束。 5. **改稿范围**(输入里若有 `scope`): - `deck`:可改 outline 与任意 `slides/*.html` - `current_slide` / `slide_index`:**只改指定页**,不动其他 slide 文件 diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin.rs b/src/crates/contracts/product-domains/src/miniapp/builtin.rs index 6cc6aa19f2..b27b9a0fa8 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin.rs +++ b/src/crates/contracts/product-domains/src/miniapp/builtin.rs @@ -151,7 +151,7 @@ pub const BUILTIN_APPS: &[BuiltinMiniAppBundle] = &[ }, BuiltinMiniAppBundle { id: "builtin-ppt-live", - version: 203, + version: 216, meta_json: include_str!("builtin/assets/ppt-live/meta.json"), html: include_str!("builtin/assets/ppt-live/index.html"), css: include_str!("builtin/assets/ppt-live/style.css"), @@ -560,20 +560,22 @@ mod tests { ); assert!(app.ui_js.contains("Unsupported PPT Live action")); // A single cowork agent turn loads the ppt-design skill and produces - // the whole deck end to end. The prompt is intentionally minimal — the - // skill owns all design rules via progressive disclosure. + // the whole deck end to end. Prompt construction is isolated from the + // host adapter so its generated-file contract can be tested directly. let adapter_source = include_str!("builtin/assets/ppt-live/src/bitfun-backend-adapter.js"); + let prompt_source = include_str!("builtin/assets/ppt-live/src/agent-prompt.js"); assert!(adapter_source.contains("sessionId: options.sessionId")); - assert!(adapter_source.contains("user::bitfun-system::ppt-design")); assert!(adapter_source.contains("buildAgentPrompt")); + assert!(prompt_source.contains("user::bitfun-system::ppt-design")); + assert!(prompt_source.contains("export function buildAgentPrompt")); assert!(!adapter_source.contains("app.ai")); assert!(!adapter_source.contains("installFallbackBackend")); // The prompt must delegate design rules to the skill, not restate them. - assert!(!adapter_source.contains("EDITABLE_PPTX_HARD_RULES")); - assert!(!adapter_source.contains("PPT_DESIGN_REQUIRED_REFERENCES")); - assert!(!adapter_source.contains("comparisons -> tables/matrices")); - assert!(!adapter_source.contains("Design quality bar")); - assert!(!adapter_source.contains("Müller-Brockmann")); + assert!(!prompt_source.contains("EDITABLE_PPTX_HARD_RULES")); + assert!(!prompt_source.contains("PPT_DESIGN_REQUIRED_REFERENCES")); + assert!(!prompt_source.contains("comparisons -> tables/matrices")); + assert!(!prompt_source.contains("Design quality bar")); + assert!(!prompt_source.contains("Müller-Brockmann")); assert!(app.ui_js.contains("Unknown MiniApp agent session")); // Generation follows the ppt-design skill's native file protocol: the // agent works inside a deck project directory under the app's appdata @@ -599,8 +601,8 @@ mod tests { assert!(!meta["permissions"]["ai"]["enabled"] .as_bool() .unwrap_or(true)); - // The single cowork agent turn loads the ppt-design skill itself. - assert!(adapter_source.contains("user::bitfun-system::ppt-design")); + // The single cowork agent turn loads the stable ppt-design skill key. + assert!(prompt_source.contains("user::bitfun-system::ppt-design")); let ppt_live_source = include_str!("builtin/assets/ppt-live/ui.js"); // Single-turn cowork generation: one agent turn produces the whole deck. assert!(ppt_live_source.contains("runCoworkDeckGeneration")); diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/bundle.json b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/bundle.json index 6fcea9d583..a69b03a547 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/bundle.json +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/bundle.json @@ -1,5 +1,5 @@ { "schemaVersion": 1, "id": "builtin-ppt-live", - "version": 203 + "version": 216 } diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/dist/ui.bundle.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/dist/ui.bundle.js index 9c46448bac..50c880c75a 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/dist/ui.bundle.js +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/dist/ui.bundle.js @@ -30,9 +30,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge mod )); -// ../../../../../../../../../../../../node_modules/pako/lib/utils/common.js +// ../../../node_modules/pako/lib/utils/common.js var require_common = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/utils/common.js"(exports) { + "../../../node_modules/pako/lib/utils/common.js"(exports) { "use strict"; var TYPED_OK = typeof Uint8Array !== "undefined" && typeof Uint16Array !== "undefined" && typeof Int32Array !== "undefined"; function _has(obj, key) { @@ -121,9 +121,9 @@ var require_common = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/lib/zlib/trees.js +// ../../../node_modules/pako/lib/zlib/trees.js var require_trees = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/zlib/trees.js"(exports) { + "../../../node_modules/pako/lib/zlib/trees.js"(exports) { "use strict"; var utils = require_common(); var Z_FIXED = 4; @@ -763,9 +763,9 @@ var require_trees = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/lib/zlib/adler32.js +// ../../../node_modules/pako/lib/zlib/adler32.js var require_adler32 = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/zlib/adler32.js"(exports, module) { + "../../../node_modules/pako/lib/zlib/adler32.js"(exports, module) { "use strict"; function adler32(adler, buf, len, pos) { var s1 = adler & 65535 | 0, s2 = adler >>> 16 & 65535 | 0, n = 0; @@ -785,9 +785,9 @@ var require_adler32 = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/lib/zlib/crc32.js +// ../../../node_modules/pako/lib/zlib/crc32.js var require_crc32 = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/zlib/crc32.js"(exports, module) { + "../../../node_modules/pako/lib/zlib/crc32.js"(exports, module) { "use strict"; function makeTable() { var c, table = []; @@ -813,9 +813,9 @@ var require_crc32 = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/lib/zlib/messages.js +// ../../../node_modules/pako/lib/zlib/messages.js var require_messages = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/zlib/messages.js"(exports, module) { + "../../../node_modules/pako/lib/zlib/messages.js"(exports, module) { "use strict"; module.exports = { 2: "need dictionary", @@ -840,9 +840,9 @@ var require_messages = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/lib/zlib/deflate.js +// ../../../node_modules/pako/lib/zlib/deflate.js var require_deflate = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/zlib/deflate.js"(exports) { + "../../../node_modules/pako/lib/zlib/deflate.js"(exports) { "use strict"; var utils = require_common(); var trees = require_trees(); @@ -1889,9 +1889,9 @@ var require_deflate = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/lib/utils/strings.js +// ../../../node_modules/pako/lib/utils/strings.js var require_strings = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/utils/strings.js"(exports) { + "../../../node_modules/pako/lib/utils/strings.js"(exports) { "use strict"; var utils = require_common(); var STR_APPLY_OK = true; @@ -2031,9 +2031,9 @@ var require_strings = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/lib/zlib/zstream.js +// ../../../node_modules/pako/lib/zlib/zstream.js var require_zstream = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/zlib/zstream.js"(exports, module) { + "../../../node_modules/pako/lib/zlib/zstream.js"(exports, module) { "use strict"; function ZStream() { this.input = null; @@ -2053,9 +2053,9 @@ var require_zstream = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/lib/deflate.js +// ../../../node_modules/pako/lib/deflate.js var require_deflate2 = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/deflate.js"(exports) { + "../../../node_modules/pako/lib/deflate.js"(exports) { "use strict"; var zlib_deflate = require_deflate(); var utils = require_common(); @@ -2214,9 +2214,9 @@ var require_deflate2 = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/lib/zlib/inffast.js +// ../../../node_modules/pako/lib/zlib/inffast.js var require_inffast = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/zlib/inffast.js"(exports, module) { + "../../../node_modules/pako/lib/zlib/inffast.js"(exports, module) { "use strict"; var BAD = 30; var TYPE = 12; @@ -2443,9 +2443,9 @@ var require_inffast = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/lib/zlib/inftrees.js +// ../../../node_modules/pako/lib/zlib/inftrees.js var require_inftrees = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/zlib/inftrees.js"(exports, module) { + "../../../node_modules/pako/lib/zlib/inftrees.js"(exports, module) { "use strict"; var utils = require_common(); var MAXBITS = 15; @@ -2759,9 +2759,9 @@ var require_inftrees = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/lib/zlib/inflate.js +// ../../../node_modules/pako/lib/zlib/inflate.js var require_inflate = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/zlib/inflate.js"(exports) { + "../../../node_modules/pako/lib/zlib/inflate.js"(exports) { "use strict"; var utils = require_common(); var adler32 = require_adler32(); @@ -3998,9 +3998,9 @@ var require_inflate = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/lib/zlib/constants.js +// ../../../node_modules/pako/lib/zlib/constants.js var require_constants = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/zlib/constants.js"(exports, module) { + "../../../node_modules/pako/lib/zlib/constants.js"(exports, module) { "use strict"; module.exports = { /* Allowed flush values; see deflate() and inflate() below for details */ @@ -4045,9 +4045,9 @@ var require_constants = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/lib/zlib/gzheader.js +// ../../../node_modules/pako/lib/zlib/gzheader.js var require_gzheader = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/zlib/gzheader.js"(exports, module) { + "../../../node_modules/pako/lib/zlib/gzheader.js"(exports, module) { "use strict"; function GZheader() { this.text = 0; @@ -4065,9 +4065,9 @@ var require_gzheader = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/lib/inflate.js +// ../../../node_modules/pako/lib/inflate.js var require_inflate2 = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/lib/inflate.js"(exports) { + "../../../node_modules/pako/lib/inflate.js"(exports) { "use strict"; var zlib_inflate = require_inflate(); var utils = require_common(); @@ -4239,9 +4239,9 @@ var require_inflate2 = __commonJS({ } }); -// ../../../../../../../../../../../../node_modules/pako/index.js +// ../../../node_modules/pako/index.js var require_pako = __commonJS({ - "../../../../../../../../../../../../node_modules/pako/index.js"(exports, module) { + "../../../node_modules/pako/index.js"(exports, module) { "use strict"; var assign = require_common().assign; var deflate = require_deflate2(); @@ -4253,9 +4253,9 @@ var require_pako = __commonJS({ } }); -// ../../../../../../../../../node_modules/jszip/dist/jszip.min.js +// node_modules/jszip/dist/jszip.min.js var require_jszip_min = __commonJS({ - "../../../../../../../../../node_modules/jszip/dist/jszip.min.js"(exports, module) { + "node_modules/jszip/dist/jszip.min.js"(exports, module) { !(function(e) { if ("object" == typeof exports && "undefined" != typeof module) module.exports = e(); else if ("function" == typeof define && define.amd) define([], e); @@ -6619,9 +6619,9 @@ var require_jszip_min = __commonJS({ } }); -// ../../../../../../../../../node_modules/.pnpm/jszip@3.10.1/node_modules/jszip/dist/jszip.min.js +// node_modules/.pnpm/jszip@3.10.1/node_modules/jszip/dist/jszip.min.js var require_jszip_min2 = __commonJS({ - "../../../../../../../../../node_modules/.pnpm/jszip@3.10.1/node_modules/jszip/dist/jszip.min.js"(exports, module) { + "node_modules/.pnpm/jszip@3.10.1/node_modules/jszip/dist/jszip.min.js"(exports, module) { !(function(e) { if ("object" == typeof exports && "undefined" != typeof module) module.exports = e(); else if ("function" == typeof define && define.amd) define([], e); @@ -8997,7 +8997,7 @@ var require_node_https = __commonJS({ } }); -// src/i18n.js +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/i18n.js var STRINGS = { "en-US": { eyebrow: "AI Deck Studio", @@ -9258,6 +9258,20 @@ var STRINGS = { exportPptxWorking: "Rendering editable PPTX...", exportPptxDone: "Editable PPTX downloaded.", exportPptxFailed: "PPTX export failed:", + exportDiagnosticsSummary: "Exported with visual adjustments: {{counts}}. {{locations}}", + exportDiagnosticsRepaired: "{{count}} automatic repairs", + exportDiagnosticsSvg: "{{count}} local SVG layers", + exportDiagnosticsLocalPng: "{{count}} local PNG layers", + exportDiagnosticsPageVisual: "{{count}} page visual layers", + exportDiagnosticsFullPage: "{{count}} full-page fallbacks", + exportDiagnosticsBlocking: "{{count}} blocking failures", + exportDiagnosticsLocation: "Slide {{slide}}, element {{source}} ({{phase}}): {{reason}}", + exportDiagnosticsPhaseRepair: "automatic repair", + exportDiagnosticsPhaseSvg: "local SVG", + exportDiagnosticsPhaseLocalPng: "local PNG", + exportDiagnosticsPhasePageVisual: "page visual fallback", + exportDiagnosticsPhaseFullPage: "full-page fallback", + exportDiagnosticsPhaseBlocking: "blocking failure", exportPdfWorking: "Rendering PDF...", exportPdfDone: "PDF downloaded.", exportPdfFailed: "PDF export failed:", @@ -9634,6 +9648,20 @@ var STRINGS = { exportPptxWorking: "\u6B63\u5728\u6E32\u67D3\u53EF\u7F16\u8F91 PPTX...", exportPptxDone: "\u53EF\u7F16\u8F91 PPTX \u5DF2\u4E0B\u8F7D\u3002", exportPptxFailed: "PPTX \u5BFC\u51FA\u5931\u8D25\uFF1A", + exportDiagnosticsSummary: "\u5DF2\u5B8C\u6210\u5BFC\u51FA\uFF0C\u5E76\u8FDB\u884C\u4E86\u89C6\u89C9\u8C03\u6574\uFF1A{{counts}}\u3002{{locations}}", + exportDiagnosticsRepaired: "\u81EA\u52A8\u4FEE\u590D {{count}} \u5904", + exportDiagnosticsSvg: "\u5C40\u90E8 SVG \u5C42 {{count}} \u4E2A", + exportDiagnosticsLocalPng: "\u5C40\u90E8 PNG \u5C42 {{count}} \u4E2A", + exportDiagnosticsPageVisual: "\u9875\u9762\u89C6\u89C9\u5C42 {{count}} \u4E2A", + exportDiagnosticsFullPage: "\u6574\u9875\u515C\u5E95 {{count}} \u9875", + exportDiagnosticsBlocking: "\u963B\u65AD\u5931\u8D25 {{count}} \u5904", + exportDiagnosticsLocation: "\u7B2C {{slide}} \u9875\uFF0C\u5143\u7D20 {{source}}\uFF08{{phase}}\uFF09\uFF1A{{reason}}", + exportDiagnosticsPhaseRepair: "\u81EA\u52A8\u4FEE\u590D", + exportDiagnosticsPhaseSvg: "\u5C40\u90E8 SVG", + exportDiagnosticsPhaseLocalPng: "\u5C40\u90E8 PNG", + exportDiagnosticsPhasePageVisual: "\u9875\u9762\u89C6\u89C9\u515C\u5E95", + exportDiagnosticsPhaseFullPage: "\u6574\u9875\u515C\u5E95", + exportDiagnosticsPhaseBlocking: "\u963B\u65AD\u5931\u8D25", exportPdfWorking: "\u6B63\u5728\u6E32\u67D3 PDF...", exportPdfDone: "PDF \u5DF2\u4E0B\u8F7D\u3002", exportPdfFailed: "PDF \u5BFC\u51FA\u5931\u8D25\uFF1A", @@ -9767,7 +9795,7 @@ function translate(key, params = {}) { return value2; } -// src/style-presets.js +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/style-presets.js var STYLE_PRESET_UI_KEYS = ["clean-business", "insight-report"]; var STYLE_PRESETS = { // === 商务/极简 === @@ -10034,7 +10062,7 @@ function getAllStylePresets(locale) { }); } -// src/state.js +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/state.js var STORAGE_KEY = "pptLiveStudioStateV6"; var HISTORY_KEY = "pptLiveDeckHistoryV1"; var SCHEMA_VERSION = 6; @@ -10775,7 +10803,7 @@ function pointsFor(title, index, state2) { return picks; } -// src/flat-select.js +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/flat-select.js var OPEN_SELECTS = /* @__PURE__ */ new Set(); function closeSelect(wrap) { const menu = wrap.querySelector(".ppt-flat-select__menu"); @@ -10956,7 +10984,584 @@ if (!window.__pptLiveFlatSelectBound) { document.addEventListener("scroll", handleOutsideScroll, true); } -// src/render.js +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/element-model-html.js +var escapeHtml2 = (value2) => String(value2 ?? "").replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'"); +var DEFAULT_THEME = { + background: "#ffffff", + ink: "#111111", + muted: "#666666", + primary: "#0f766e", + accent: "#f97316", + panel: "#ffffff" +}; +function colorMix(hex2, alpha) { + const raw = String(hex2 || DEFAULT_THEME.primary).replace("#", ""); + const normalized = raw.length === 3 ? raw.split("").map((value2) => value2 + value2).join("") : raw; + const parsed = Number.parseInt(normalized, 16); + if (!Number.isFinite(parsed)) return `rgba(15, 118, 110, ${alpha})`; + return `rgba(${parsed >> 16 & 255}, ${parsed >> 8 & 255}, ${parsed & 255}, ${alpha})`; +} +function resolveElementColor(value2, theme = {}) { + const palette = { ...DEFAULT_THEME, ...theme }; + if (!value2 || value2 === "transparent") return "transparent"; + if (value2 === "soft") return colorMix(palette.primary, 0.1); + if (Object.hasOwn(palette, value2)) return palette[value2]; + return String(value2); +} +function editorFontSize(value2) { + const size = Math.max(8, Number(value2) || 24); + const cqw = Math.round(size / 10.2 * 1e3) / 1e3; + return `clamp(8px, ${cqw}cqw, ${size}px)`; +} +function elementStyle(element2, theme, mode) { + const style = element2?.style || {}; + const fontSize = Math.max(8, Number(style.fontSize) || 24); + return [ + `left:${Number(element2?.x) || 0}%`, + `top:${Number(element2?.y) || 0}%`, + `width:${Number(element2?.w) || 0}%`, + `height:${Number(element2?.h) || 0}%`, + `font-size:${mode === "editor" ? editorFontSize(fontSize) : `${fontSize}px`}`, + `font-weight:${Number(style.fontWeight) || 600}`, + `color:${resolveElementColor(style.color || "ink", theme)}`, + `text-align:${style.align || "left"}`, + `background:${resolveElementColor(style.background || "transparent", theme)}`, + `opacity:${Number.isFinite(Number(style.opacity)) ? Number(style.opacity) : 1}`, + `border-radius:${Math.max(0, Number(style.borderRadius) || 0)}px` + ].join(";"); +} +function semanticElementContent(element2, mediaPlaceholder) { + const type = String(element2?.type || "text"); + if (type === "list") { + return `
    ${(element2.items || []).map((item) => `
  • ${escapeHtml2(item)}

  • `).join("")}
`; + } + if (type === "metric") { + return `

${escapeHtml2(element2.text || "")}

${escapeHtml2(element2.label || "")}

`; + } + if (type === "chart") { + const points = Array.isArray(element2.data) ? element2.data : []; + const max = Math.max(1, ...points.map((point) => Math.abs(Number(point?.value) || 0))); + return `

${escapeHtml2(element2.text || "")}

${points.map((point) => { + const value2 = Number(point?.value) || 0; + const height = Math.max(8, Math.abs(value2) / max * 100); + return `

${escapeHtml2(point?.label || "")}

${escapeHtml2(value2)}

`; + }).join("")}
`; + } + if (type === "media") { + const source = element2.src || element2.url || element2.dataUrl || element2.imageUrl || ""; + const caption = element2.text || element2.label || mediaPlaceholder; + return `
${source ? `${escapeHtml2(caption)}` : ""}

${escapeHtml2(caption)}

`; + } + const text2 = element2.text || ""; + return text2 ? `

${escapeHtml2(text2)}

` : ""; +} +function editorElementContent(element2, mediaPlaceholder, editable) { + const type = String(element2?.type || "text"); + if (type === "list") { + return `
    ${(element2.items || []).map((item, index) => editable ? `
  • ${escapeHtml2(item)}
  • ` : `
  • ${escapeHtml2(item)}
  • `).join("")}
`; + } + if (type === "metric") { + return `${escapeHtml2(element2.text)}${escapeHtml2(element2.label)}`; + } + if (type === "chart") { + const points = Array.isArray(element2.data) ? element2.data : []; + const max = Math.max(1, ...points.map((point) => Number(point?.value) || 0)); + return `${escapeHtml2(element2.text)}
${points.map((point) => `${escapeHtml2(point?.label)}`).join("")}
`; + } + if (type === "media") return `${escapeHtml2(element2.text || mediaPlaceholder)}`; + return editable ? `${escapeHtml2(element2.text || "")}` : escapeHtml2(element2.text || ""); +} +function elementModelElementHtml(element2 = {}, theme = {}, { + mode = "semantic", + editable = false, + selectedId = "", + mediaPlaceholder = "Media placeholder" +} = {}) { + const type = String(element2.type || "text"); + const selected = mode === "editor" && editable && selectedId === element2.id; + const content = mode === "editor" ? editorElementContent(element2, mediaPlaceholder, editable) : semanticElementContent(element2, mediaPlaceholder); + return `
${content}${selected ? '' : ""}
`; +} +function buildElementSlideHtml(slide = {}) { + const theme = { ...DEFAULT_THEME, ...slide.theme || {} }; + const elements = Array.isArray(slide.elements) ? slide.elements : []; + const fallback = elements.length ? "" : `

${escapeHtml2(slide.title || "Slide")}

${slide.subtitle || slide.claim ? `

${escapeHtml2(slide.subtitle || slide.claim)}

` : ""}
`; + return ` + + + + +${escapeHtml2(slide.title || "Slide")} + + + + ${elements.map((element2) => elementModelElementHtml(element2, theme)).join("\n ")} + ${fallback} + +`; +} + +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/sanitize-slide-markup.js +var SVG_NAMESPACE = "http://www.w3.org/2000/svg"; +var DELETE_WITH_CONTENT_TAGS = /* @__PURE__ */ new Set([ + "script", + "iframe", + "object", + "embed", + "base", + "meta", + "link", + "template", + "frame", + "frameset", + "portal" +]); +var HTML_ALLOWED_TAGS = /* @__PURE__ */ new Set([ + "html", + "head", + "body", + "title", + "style", + "div", + "section", + "article", + "main", + "header", + "footer", + "nav", + "aside", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "p", + "span", + "strong", + "b", + "em", + "i", + "u", + "s", + "small", + "mark", + "sub", + "sup", + "code", + "pre", + "blockquote", + "ul", + "ol", + "li", + "dl", + "dt", + "dd", + "br", + "hr", + "a", + "table", + "caption", + "colgroup", + "col", + "thead", + "tbody", + "tfoot", + "tr", + "th", + "td", + "figure", + "figcaption", + "img", + "label", + "time" +]); +var SVG_ALLOWED_TAGS = /* @__PURE__ */ new Set([ + "svg", + "g", + "defs", + "desc", + "title", + "rect", + "circle", + "ellipse", + "line", + "polyline", + "polygon", + "path", + "text", + "tspan", + "textpath", + "use", + "foreignobject", + "symbol", + "marker", + "lineargradient", + "radialgradient", + "stop", + "pattern", + "clippath", + "mask", + "filter", + "feblend", + "fecolormatrix", + "fecomponenttransfer", + "fecomposite", + "feconvolvematrix", + "fediffuselighting", + "fedisplacementmap", + "fedistantlight", + "fedropshadow", + "feflood", + "fefunca", + "fefuncb", + "fefuncg", + "fefuncr", + "fegaussianblur", + "feimage", + "femerge", + "femergenode", + "femorphology", + "feoffset", + "fepointlight", + "fespecularlighting", + "fespotlight", + "fetile", + "feturbulence" +]); +var GLOBAL_ALLOWED_ATTRIBUTES = /* @__PURE__ */ new Set([ + "id", + "class", + "style", + "title", + "role", + "lang", + "dir", + "hidden", + "tabindex", + "draggable", + "spellcheck", + "contenteditable" +]); +var TAG_ALLOWED_ATTRIBUTES = Object.freeze({ + img: /* @__PURE__ */ new Set(["src", "alt", "width", "height", "loading", "decoding"]), + ol: /* @__PURE__ */ new Set(["start", "reversed", "type"]), + li: /* @__PURE__ */ new Set(["value"]), + col: /* @__PURE__ */ new Set(["span"]), + th: /* @__PURE__ */ new Set(["colspan", "rowspan", "scope", "headers", "abbr"]), + td: /* @__PURE__ */ new Set(["colspan", "rowspan", "headers"]), + label: /* @__PURE__ */ new Set(["for"]), + time: /* @__PURE__ */ new Set(["datetime"]) +}); +var SVG_GLOBAL_ALLOWED_ATTRIBUTES = /* @__PURE__ */ new Set([ + "id", + "class", + "style", + "transform", + "fill", + "fill-opacity", + "fill-rule", + "stroke", + "stroke-width", + "stroke-opacity", + "stroke-linecap", + "stroke-linejoin", + "stroke-dasharray", + "stroke-dashoffset", + "opacity", + "filter", + "clip-path", + "clip-rule", + "mask", + "color", + "color-interpolation", + "color-interpolation-filters", + "visibility", + "display", + "font-family", + "font-size", + "font-style", + "font-weight", + "text-anchor", + "dominant-baseline", + "pointer-events", + "vector-effect", + "paint-order", + "shape-rendering", + "text-rendering", + "stop-color", + "stop-opacity", + "flood-color", + "flood-opacity", + "lighting-color", + "marker-start", + "marker-mid", + "marker-end" +]); +var SVG_RESOURCE_PRESENTATION_ATTRIBUTES = /* @__PURE__ */ new Set([ + "fill", + "stroke", + "filter", + "clip-path", + "mask", + "marker-start", + "marker-mid", + "marker-end" +]); +var SVG_GEOMETRY_ATTRIBUTES = /* @__PURE__ */ new Set([ + "x", + "y", + "x1", + "y1", + "x2", + "y2", + "cx", + "cy", + "r", + "rx", + "ry", + "width", + "height", + "d", + "points", + "pathlength" +]); +var SVG_FILTER_ATTRIBUTES = /* @__PURE__ */ new Set([ + "in", + "in2", + "result", + "operator", + "k1", + "k2", + "k3", + "k4", + "mode", + "type", + "values", + "tablevalues", + "slope", + "intercept", + "amplitude", + "exponent", + "offset", + "stddeviation", + "edgemode", + "kernelmatrix", + "kernelunitlength", + "targetx", + "targety", + "order", + "preservealpha", + "surfacescale", + "diffuseconstant", + "specularconstant", + "specularexponent", + "limitingconeangle", + "azimuth", + "elevation", + "pointsatx", + "pointsaty", + "pointsatz", + "basefrequency", + "numoctaves", + "seed", + "stitchtiles", + "scale", + "xchannelselector", + "ychannelselector", + "radius", + "dx", + "dy" +]); +var SVG_TAG_ALLOWED_ATTRIBUTES = Object.freeze({ + svg: /* @__PURE__ */ new Set(["viewbox", "width", "height", "x", "y", "preserveaspectratio", "xmlns", "xmlns:xlink"]), + symbol: /* @__PURE__ */ new Set(["viewbox", "x", "y", "width", "height", "preserveaspectratio"]), + marker: /* @__PURE__ */ new Set(["viewbox", "markerwidth", "markerheight", "markerunits", "orient", "preserveaspectratio", "refx", "refy"]), + rect: /* @__PURE__ */ new Set([...SVG_GEOMETRY_ATTRIBUTES]), + circle: /* @__PURE__ */ new Set([...SVG_GEOMETRY_ATTRIBUTES]), + ellipse: /* @__PURE__ */ new Set([...SVG_GEOMETRY_ATTRIBUTES]), + line: /* @__PURE__ */ new Set([...SVG_GEOMETRY_ATTRIBUTES]), + polyline: /* @__PURE__ */ new Set([...SVG_GEOMETRY_ATTRIBUTES]), + polygon: /* @__PURE__ */ new Set([...SVG_GEOMETRY_ATTRIBUTES]), + path: /* @__PURE__ */ new Set([...SVG_GEOMETRY_ATTRIBUTES]), + text: /* @__PURE__ */ new Set(["x", "y", "dx", "dy", "rotate", "textlength", "lengthadjust"]), + tspan: /* @__PURE__ */ new Set(["x", "y", "dx", "dy", "rotate", "textlength", "lengthadjust"]), + textpath: /* @__PURE__ */ new Set(["href", "xlink:href", "startoffset", "method", "spacing", "side", "textlength", "lengthadjust"]), + use: /* @__PURE__ */ new Set(["x", "y", "width", "height", "href", "xlink:href"]), + foreignobject: /* @__PURE__ */ new Set(["x", "y", "width", "height"]), + lineargradient: /* @__PURE__ */ new Set(["x1", "y1", "x2", "y2", "gradientunits", "gradienttransform", "spreadmethod", "href", "xlink:href"]), + radialgradient: /* @__PURE__ */ new Set(["cx", "cy", "r", "fx", "fy", "fr", "gradientunits", "gradienttransform", "spreadmethod", "href", "xlink:href"]), + stop: /* @__PURE__ */ new Set(["offset"]), + pattern: /* @__PURE__ */ new Set(["x", "y", "width", "height", "patternunits", "patterncontentunits", "patterntransform", "viewbox", "preserveaspectratio", "href", "xlink:href"]), + clippath: /* @__PURE__ */ new Set(["clippathunits"]), + mask: /* @__PURE__ */ new Set(["x", "y", "width", "height", "maskunits", "maskcontentunits"]), + filter: /* @__PURE__ */ new Set(["x", "y", "width", "height", "filterunits", "primitiveunits"]) +}); +function canonicalizeCssEscapes(value2) { + let current = String(value2 || ""); + for (let pass = 0; pass < 4; pass += 1) { + const decoded = current.replace(/\\([0-9a-f]{1,6})(?:\r\n|[ \n\r\t\f])?/gi, (_match, hex2) => String.fromCodePoint(Number.parseInt(hex2, 16) || 0)).replace(/\\([^\n\r\f0-9a-f])/gi, "$1"); + if (decoded === current) break; + current = decoded; + } + return current; +} +function hasUnsafeCss(value2) { + const css = canonicalizeCssEscapes(value2).toLowerCase(); + return /url\s*\(|@import\b|@font-face\b|expression\s*\(|behavior\s*:|-moz-binding\b|(?:-webkit-)?image-set\s*\(|(?:image|cross-fade|element|src)\s*\(/.test(css); +} +function isSafeRasterDataImage(value2) { + const candidate = String(value2 || "").trim(); + const match = candidate.match(/^data:image\/(png|jpeg|gif|webp)((?:;[a-z0-9._-]+=[a-z0-9._-]+)*)(;base64)?,([\s\S]*)$/i); + if (!match) return false; + const payload = match[4]; + if (!payload) return false; + return match[3] ? /^[a-z0-9+/=\s]+$/i.test(payload) : !/[<>"'`]/.test(payload) && /^(?:%[0-9a-f]{2}|[a-z0-9!$&()*+,\-./:;=?@_~\s])+$/i.test(payload); +} +function isAllowedResource(node, name, value2) { + const localName = String(node.localName || "").toLowerCase(); + const isSvg = node.namespaceURI === SVG_NAMESPACE || node.closest?.("svg"); + if ((name === "href" || name === "xlink:href") && isSvg) { + return /^#[a-z_][\w:.-]*$/i.test(canonicalizeCssEscapes(value2).trim()); + } + if (name === "src") return localName === "img" && isSafeRasterDataImage(value2); + return false; +} +function normalizedLocalPaintServer(value2) { + const canonical = canonicalizeCssEscapes(value2).trim(); + const match = canonical.match(/^url\(\s*(#[a-z_][\w:.-]*)\s*\)$/i); + return match ? `url(${match[1]})` : null; +} +function normalizedSvgResourceAttribute(name, value2) { + const canonical = canonicalizeCssEscapes(value2).trim(); + const lower = canonical.toLowerCase(); + if (name === "href" || name === "xlink:href") { + return /^#[a-z_][\w:.-]*$/i.test(canonical) ? canonical : null; + } + if (!SVG_RESOURCE_PRESENTATION_ATTRIBUTES.has(name)) return canonical; + if (/\burl\s*\(/i.test(canonical)) return normalizedLocalPaintServer(canonical); + if (name === "fill" || name === "stroke") { + if (/(?:javascript|vbscript|file|data|blob|https?):|(?:^|[\s"'(])\/\//i.test(lower)) return null; + if (/(?:-webkit-)?image-set\s*\(|(?:image|cross-fade|element|src)\s*\(/i.test(lower)) return null; + return canonical || null; + } + return /^(?:none|inherit|initial|unset)$/i.test(canonical) ? canonical : null; +} +function hasSafeCustomAttributeValue(value2) { + const canonical = canonicalizeCssEscapes(value2).trim().toLowerCase(); + return !/(?:javascript|vbscript|file|data|blob|https?):|(?:^|[\s"'(])\/\//.test(canonical) && !hasUnsafeCss(canonical); +} +function isSvgElement(node) { + return node.namespaceURI === SVG_NAMESPACE; +} +function allowedAttributeName(node, name) { + const tag = String(node.localName || "").toLowerCase(); + if (name.startsWith("data-") || name.startsWith("aria-")) return true; + if (isSvgElement(node)) { + if (GLOBAL_ALLOWED_ATTRIBUTES.has(name) || SVG_GLOBAL_ALLOWED_ATTRIBUTES.has(name)) return true; + if (SVG_TAG_ALLOWED_ATTRIBUTES[tag]?.has(name)) return true; + return tag.startsWith("fe") && (SVG_GEOMETRY_ATTRIBUTES.has(name) || SVG_FILTER_ATTRIBUTES.has(name)); + } + return GLOBAL_ALLOWED_ATTRIBUTES.has(name) || Boolean(TAG_ALLOWED_ATTRIBUTES[tag]?.has(name)); +} +function isAllowedSanitizedAttribute(node, rawName, value2) { + const name = String(rawName || "").toLowerCase(); + if (!name || name.startsWith("on") || !allowedAttributeName(node, name)) return false; + if (name.startsWith("data-") || name.startsWith("aria-")) { + return hasSafeCustomAttributeValue(value2); + } + if (name === "style") return !hasUnsafeCss(value2); + if (name === "src" || name === "href" || name === "xlink:href") { + return isAllowedResource(node, name, value2); + } + if (isSvgElement(node) && SVG_RESOURCE_PRESENTATION_ATTRIBUTES.has(name)) { + return normalizedSvgResourceAttribute(name, value2) !== null; + } + if (name === "xmlns") return value2 === SVG_NAMESPACE; + if (name === "xmlns:xlink") return value2 === "http://www.w3.org/1999/xlink"; + return true; +} +function unwrapNode(node) { + node.replaceWith(...node.childNodes); +} +function sanitizeSlideDocument(parsed) { + let repaired = false; + [...parsed.querySelectorAll("*")].forEach((node) => { + const tag = String(node.localName || node.tagName || "").toLowerCase(); + const allowedTags = isSvgElement(node) ? SVG_ALLOWED_TAGS : HTML_ALLOWED_TAGS; + if (DELETE_WITH_CONTENT_TAGS.has(tag)) { + repaired = true; + node.remove(); + } else if (!allowedTags.has(tag)) { + repaired = true; + unwrapNode(node); + } + }); + parsed.querySelectorAll("style").forEach((style) => { + if (hasUnsafeCss(style.textContent)) { + repaired = true; + style.remove(); + } + }); + parsed.querySelectorAll("*").forEach((node) => { + for (const attribute of [...node.attributes]) { + if (!isAllowedSanitizedAttribute(node, attribute.name, attribute.value)) { + repaired = true; + node.removeAttribute(attribute.name); + } else if (isSvgElement(node)) { + const name = attribute.name.toLowerCase(); + if (SVG_RESOURCE_PRESENTATION_ATTRIBUTES.has(name) || name === "href" || name === "xlink:href") { + const normalized = normalizedSvgResourceAttribute(name, attribute.value); + if (normalized !== attribute.value) { + repaired = true; + node.setAttribute(attribute.name, normalized); + } + } + } + } + }); + parsed._pptxSecurityDiagnostics = repaired ? [{ + severity: "repaired", + code: "active_content_removed", + message: "Unsafe active content and resource references were removed.", + sourceId: "slide-document", + phase: "security-repair" + }] : []; + return parsed; +} +function sanitizeSlideMarkup(markup) { + const parsed = new DOMParser().parseFromString(String(markup || ""), "text/html"); + sanitizeSlideDocument(parsed); + return `${parsed.documentElement.outerHTML}`; +} + +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/render.js function applyI18n() { document.documentElement.lang = getLocale(); document.querySelectorAll("[data-i18n]").forEach((node) => { @@ -11105,19 +11710,21 @@ function scopeSlideAuthorStyles(cssText, rootSelector, bodySelector) { var HTML_SLIDE_PREVIEW_HOST_CLASS = "html-slide-preview-host"; var HTML_SLIDE_PREVIEW_SCALER_CLASS = "html-slide-preview-scaler"; var DEFAULT_SLIDE_DESIGN = { width: 1280, height: 720 }; -function writeSandboxIframeDocument(frame, html) { +function writeSandboxIframeDocument(frame, sanitizedHtml) { const doc = frame.contentDocument; if (!doc) return false; doc.open(); - doc.write(normalizeSlideDocument(html)); + doc.write(sanitizedHtml); doc.close(); return true; } function mountSandboxIframeHtml(frame, html, onMounted) { + const sanitizedHtml = sanitizeSlideMarkup(normalizeSlideDocument(html)); frame.setAttribute("sandbox", "allow-same-origin"); + frame.srcdoc = sanitizedHtml; frame.src = "about:blank"; const mount = () => { - if (!writeSandboxIframeDocument(frame, html)) return false; + if (!writeSandboxIframeDocument(frame, sanitizedHtml)) return false; onMounted?.(); return true; }; @@ -11263,20 +11870,6 @@ function fitHtmlSlidePreviewSurface(host) { } var SLIDE_SHADOW_ROOT_CLASS = "ppt-slide-shadow-root"; var SLIDE_SHADOW_BODY_CLASS = "ppt-slide-shadow-body"; -function sanitizeParsedSlideDocument(parsed) { - parsed.querySelectorAll('script, iframe, object, embed, meta[http-equiv="refresh" i]').forEach((node) => node.remove()); - parsed.querySelectorAll("*").forEach((node) => { - for (const attr of [...node.attributes]) { - const name = attr.name.toLowerCase(); - if (name.startsWith("on")) { - node.removeAttribute(attr.name); - } else if ((name === "href" || name === "src" || name === "xlink:href") && /^\s*javascript:/i.test(attr.value)) { - node.removeAttribute(attr.name); - } - } - }); - return parsed; -} function createEditableSlideStage(html, frameClass) { const stage = document.createElement("div"); stage.className = frameClass; @@ -11284,9 +11877,8 @@ function createEditableSlideStage(html, frameClass) { stampFrameDesignSize(stage, html); const designW = Number(stage.dataset.designW); const designH = Number(stage.dataset.designH); - const parsed = sanitizeParsedSlideDocument( - new DOMParser().parseFromString(normalizeSlideDocument(html), "text/html") - ); + const sanitizedMarkup = sanitizeSlideMarkup(normalizeSlideDocument(html)); + const parsed = new DOMParser().parseFromString(sanitizedMarkup, "text/html"); const shadow = stage.attachShadow({ mode: "open" }); const rootEl = document.createElement("div"); rootEl.className = SLIDE_SHADOW_ROOT_CLASS; @@ -11335,7 +11927,7 @@ function createEditableSlideStage(html, frameClass) { bodyEl.style.margin = "0"; rootEl.appendChild(bodyEl); shadow.appendChild(rootEl); - stage._pptLiveSourceHtml = String(html || ""); + stage._pptLiveSourceHtml = sanitizedMarkup; return stage; } function createHtmlSlidePreviewSurface({ hostClass = "", frameClass, html, onReady, interactive = false }) { @@ -12059,7 +12651,7 @@ function hydrateHtmlSlideIframes(root = document) { function slideHtml(slide, options = {}) { if (slide?.html) { const mountId = `slide-${++pendingSlideHtmlMountSeq}`; - pendingSlideHtmlMounts.set(mountId, normalizeSlideDocument(slide.html)); + pendingSlideHtmlMounts.set(mountId, sanitizeSlideMarkup(normalizeSlideDocument(slide.html))); return ``; } const editable = Boolean(options.editable); @@ -12076,7 +12668,12 @@ function slideHtml(slide, options = {}) { ${slide.kicker ? `
${escapeHtml(slide.kicker)}
` : ""} ${slide.proofObject ? `
${escapeHtml(slide.proofObject)}
` : ""} ${slideQualityBadge(slide)} - ${(slide.elements || []).map((element2) => elementHtml(element2, slide.theme, editable, selectedId)).join("")} + ${(slide.elements || []).map((element2) => elementModelElementHtml(element2, slide.theme, { + mode: "editor", + editable, + selectedId, + mediaPlaceholder: translate("mediaPlaceholder") + })).join("")} ${slide.sourceNote ? `
${escapeHtml(slide.sourceNote)}
` : ""} `; } @@ -12169,60 +12766,6 @@ function normalizeSlideDocument(html) { if (/]/i.test(source)) return source; return `${source}`; } -function elementHtml(element2, theme, editable, selectedId) { - const selected = editable && selectedId === element2.id; - const style = [ - `left:${element2.x}%`, - `top:${element2.y}%`, - `width:${element2.w}%`, - `height:${element2.h}%`, - `font-size:${fontSizeCss(element2.style.fontSize)}`, - `font-weight:${element2.style.fontWeight}`, - `color:${resolveColor(element2.style.color, theme)}`, - `text-align:${element2.style.align || "left"}`, - `background:${resolveColor(element2.style.background, theme)}`, - `opacity:${element2.style.opacity}`, - `border-radius:${element2.style.borderRadius}px` - ].join(";"); - let content = ""; - if (element2.type === "list") { - content = `
    ${(element2.items || []).map((item, index) => editable ? `
  • ${escapeHtml(item)}
  • ` : `
  • ${escapeHtml(item)}
  • `).join("")}
`; - } else if (element2.type === "metric") { - content = `${escapeHtml(element2.text)}${escapeHtml(element2.label)}`; - } else if (element2.type === "chart") { - const max = Math.max(1, ...(element2.data || []).map((point) => Number(point.value) || 0)); - content = `${escapeHtml(element2.text)}
${(element2.data || []).map((point) => `${escapeHtml(point.label)}`).join("")}
`; - } else if (element2.type === "media") { - content = `${escapeHtml(element2.text || translate("mediaPlaceholder"))}`; - } else { - content = editable ? `${escapeHtml(element2.text || "")}` : escapeHtml(element2.text || ""); - } - return `
${content}${selected ? '' : ""}
`; -} -function resolveColor(value2, theme) { - if (!value2 || value2 === "transparent") return "transparent"; - if (value2 === "ink") return theme.ink; - if (value2 === "muted") return theme.muted; - if (value2 === "primary") return theme.primary; - if (value2 === "accent") return theme.accent; - if (value2 === "panel") return theme.panel || "#ffffff"; - if (value2 === "soft") return colorMix(theme.primary, 0.1); - if (value2 === "background") return theme.background; - return value2; -} -function colorMix(hex2, alpha) { - const raw = String(hex2 || "#0f766e").replace("#", ""); - const int = parseInt(raw.length === 3 ? raw.split("").map((x) => x + x).join("") : raw, 16); - const r = int >> 16 & 255; - const g = int >> 8 & 255; - const b = int & 255; - return `rgba(${r}, ${g}, ${b}, ${alpha})`; -} -function fontSizeCss(value2) { - const size = Math.max(8, Number(value2) || 24); - const cqw = Math.round(size / 10.2 * 1e3) / 1e3; - return `clamp(8px, ${cqw}cqw, ${size}px)`; -} function byId(id) { return document.getElementById(id); } @@ -12241,13 +12784,102 @@ function round(value2) { return Math.round(Number(value2) * 10) / 10; } -// src/sanitize-slide-html.js +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/sanitize-slide-html.js function sanitizeSlideDocumentRoot(doc = document, aggressive = false) { const document2 = doc; const view = document2.defaultView || window; + const diagnostics = []; + const seenDiagnostics = /* @__PURE__ */ new Set(); const skipTags = /* @__PURE__ */ new Set(["SCRIPT", "STYLE", "PRE", "CODE", "SVG", "TEXTAREA"]); const inlineSelector = "strong,b,em,i,u,span,a,small,mark,sub,sup,code"; const textSelector = "p,h1,h2,h3,h4,h5,h6,li"; + const textContainerSelector = "p,h1,h2,h3,h4,h5,h6,li"; + const manualBulletPattern = /^(\s*)([•●○▪‣·▸◆◇■□–—*-])\s+/u; + const ambiguousBulletSymbols = /* @__PURE__ */ new Set(["-", "*", "\u2013", "\u2014"]); + function sourceIdOf(element2) { + return element2?.dataset?.pptxSourceId || element2?.id || null; + } + function assignSourceIds() { + const body = document2.body; + if (!body) return; + const elements = [body, ...body.querySelectorAll("*")]; + const reserved = new Set( + elements.map((element2) => element2.dataset.pptxSourceId?.trim()).filter(Boolean) + ); + const used = /* @__PURE__ */ new Set(); + elements.forEach((element2) => { + const sourceId = element2.dataset.pptxSourceId?.trim(); + if (!sourceId) return; + if (!used.has(sourceId)) { + element2.dataset.pptxSourceId = sourceId; + used.add(sourceId); + return; + } + let suffix = 2; + let candidate = `${sourceId}-${suffix}`; + while (used.has(candidate) || reserved.has(candidate)) { + suffix += 1; + candidate = `${sourceId}-${suffix}`; + } + element2.dataset.pptxSourceId = candidate; + used.add(candidate); + reserved.add(candidate); + addDiagnostic( + "repaired", + "duplicate_source_id_repaired", + `Duplicate source element id "${sourceId}" was reassigned to "${candidate}".`, + element2 + ); + }); + let sequence = 1; + elements.forEach((element2) => { + if (element2.dataset?.pptxSourceId) return; + while (used.has(`pptx-source-${sequence}`) || reserved.has(`pptx-source-${sequence}`)) { + sequence += 1; + } + const sourceId = `pptx-source-${sequence}`; + sequence += 1; + element2.dataset.pptxSourceId = sourceId; + used.add(sourceId); + }); + } + function derivedSourceId(element2, suffix) { + const base = sourceIdOf(element2) || "pptx-source"; + let candidate = `${base}-${suffix}`; + let sequence = 2; + while (document2.querySelector(`[data-pptx-source-id="${candidate}"]`)) { + candidate = `${base}-${suffix}-${sequence}`; + sequence += 1; + } + return candidate; + } + function addDiagnostic(severity, code, message, element2 = null) { + const sourceId = sourceIdOf(element2); + const key = `${severity}:${code}:${sourceId || ""}`; + if (seenDiagnostics.has(key)) return; + seenDiagnostics.add(key); + const diagnostic = { + severity, + kind: severity === "blocking" ? "blocking" : void 0, + code, + message, + sourceId, + tag: element2?.tagName?.toLowerCase?.() || null + }; + try { + const rect = element2?.getBoundingClientRect?.(); + if (rect && rect.width > 0 && rect.height > 0) { + diagnostic.bbox = { + x: rect.left, + y: rect.top, + width: rect.width, + height: rect.height + }; + } + } catch { + } + diagnostics.push(diagnostic); + } function inferBlockTag(node) { const cls = String(node.className || "").toLowerCase(); const role = String(node.getAttribute?.("role") || "").toLowerCase(); @@ -12282,19 +12914,84 @@ function sanitizeSlideDocumentRoot(doc = document, aggressive = false) { body.style.backgroundColor = rootBg; } } + function repairNestedParagraphs(root) { + root.querySelectorAll(textContainerSelector).forEach((outer) => { + const nested = [...outer.children].filter((child) => child.matches(textContainerSelector)); + if (!nested.length || !outer.parentNode) return; + const fragments = []; + let current = document2.createElement(outer.tagName.toLowerCase()); + const copyOuterAttributes = (target) => { + [...outer.attributes].forEach((attribute) => { + if (attribute.name !== "data-pptx-source-id") target.setAttribute(attribute.name, attribute.value); + }); + }; + copyOuterAttributes(current); + current.dataset.pptxSourceId = sourceIdOf(outer); + [...outer.childNodes].forEach((node) => { + if (node.nodeType === view.Node.ELEMENT_NODE && node.matches(textContainerSelector)) { + if (current.textContent.trim() || current.children.length) fragments.push(current); + fragments.push(node); + current = document2.createElement(outer.tagName.toLowerCase()); + copyOuterAttributes(current); + current.dataset.pptxSourceId = derivedSourceId(outer, `split-${fragments.length + 1}`); + } else { + current.appendChild(node); + } + }); + if (current.textContent.trim() || current.children.length) fragments.push(current); + outer.replaceWith(...fragments); + addDiagnostic( + "repaired", + "nested_paragraph_repaired", + "Nested paragraph structure was split into ordered sibling paragraphs.", + fragments[0] || nested[0] + ); + }); + } function wrapDirectTextNodes(root) { root.querySelectorAll("div").forEach((div) => { if (skipTags.has(div.tagName)) return; - [...div.childNodes].forEach((node) => { - if (node.nodeType !== Node.TEXT_NODE) return; - const text2 = node.textContent.replace(/\s+/g, " ").trim(); - if (!text2) { - node.remove(); - return; - } + let sequence = 1; + let nodes = [...div.childNodes]; + while (nodes.length) { + const firstDirectText = nodes.findIndex( + (node) => node.nodeType === view.Node.TEXT_NODE && node.textContent.trim() + ); + if (firstDirectText < 0) break; + let start = firstDirectText; + while (start > 0) { + const previous = nodes[start - 1]; + if (previous.nodeType === view.Node.ELEMENT_NODE && !previous.matches(inlineSelector) && previous.tagName !== "BR") break; + start -= 1; + } + let end = firstDirectText; + while (end + 1 < nodes.length) { + const next = nodes[end + 1]; + if (next.nodeType === view.Node.ELEMENT_NODE && !next.matches(inlineSelector) && next.tagName !== "BR") break; + end += 1; + } + const group = nodes.slice(start, end + 1); const block = document2.createElement(inferBlockTag(div)); - block.textContent = text2; - div.replaceChild(block, node); + block.dataset.pptxSourceId = derivedSourceId(div, `text-${sequence}`); + sequence += 1; + group[0].before(block); + group.forEach((node) => { + if (node.nodeType === view.Node.TEXT_NODE) { + node.textContent = node.textContent.replace(/\s+/g, " "); + } + block.appendChild(node); + }); + block.normalize(); + addDiagnostic( + "repaired", + "direct_text_wrapped", + "Direct container text was wrapped in a semantic text block.", + block + ); + nodes = [...div.childNodes]; + } + [...div.childNodes].forEach((node) => { + if (node.nodeType === view.Node.TEXT_NODE && !node.textContent.trim()) node.remove(); }); }); } @@ -12304,11 +13001,94 @@ function sanitizeSlideDocumentRoot(doc = document, aggressive = false) { const hasBg = computed.backgroundColor && computed.backgroundColor !== "rgba(0, 0, 0, 0)"; const hasBorder = hasVisibleBorder(computed); if (!hasBg && !hasBorder) return; + if (span.closest(textContainerSelector)) return; const block = document2.createElement("p"); if (span.className) block.className = span.className; if (span.getAttribute("style")) block.setAttribute("style", span.getAttribute("style")); - block.textContent = span.textContent; + block.dataset.pptxSourceId = sourceIdOf(span); + while (span.firstChild) block.appendChild(span.firstChild); span.replaceWith(block); + addDiagnostic( + "repaired", + "decorated_inline_promoted", + "Decorated inline text was promoted to a block that can be exported as shape plus text.", + block + ); + }); + } + function removeManualBullet(element2) { + const symbol = element2.textContent.match(manualBulletPattern)?.[2]; + if (!symbol) return; + const walker = document2.createTreeWalker(element2, view.NodeFilter.SHOW_TEXT); + let textNode = walker.nextNode(); + let removed = false; + while (textNode) { + if (!removed) { + const symbolIndex = textNode.textContent.search(/\S/u); + if (symbolIndex >= 0) { + if (textNode.textContent.slice(symbolIndex).startsWith(symbol)) { + textNode.textContent = textNode.textContent.slice(symbolIndex + symbol.length).replace(/^\s+/u, ""); + removed = true; + if (textNode.textContent) return; + } else { + return; + } + } + } else if (textNode.textContent) { + textNode.textContent = textNode.textContent.replace(/^\s+/u, ""); + return; + } + textNode = walker.nextNode(); + } + } + function normalizeManualBulletBlocks(root) { + root.querySelectorAll("body, div, section, article, aside, main, td, th").forEach((parent) => { + let group = []; + const flush = () => { + if (!group.length) return; + const first = group[0]; + const firstSymbol = first.textContent.match(manualBulletPattern)?.[2]; + if (group.length === 1 && ambiguousBulletSymbols.has(firstSymbol)) { + group = []; + return; + } + const list = document2.createElement("ul"); + list.dataset.pptxSourceId = derivedSourceId(first, "list"); + const firstComputed = view.getComputedStyle(first); + const authoredIndent = parseFloat(firstComputed.marginLeft || first.style.marginLeft || "0") || 0; + list.style.margin = "0"; + list.style.paddingLeft = `${Math.max(24, authoredIndent + 24)}px`; + first.parentNode.insertBefore(list, first); + group.forEach((block) => { + const item = document2.createElement("li"); + [...block.attributes].forEach((attribute) => { + if (!["id", "data-pptx-source-id"].includes(attribute.name)) { + item.setAttribute(attribute.name, attribute.value); + } + }); + item.dataset.pptxSourceId = sourceIdOf(block); + while (block.firstChild) item.appendChild(block.firstChild); + removeManualBullet(item); + list.appendChild(item); + block.remove(); + }); + addDiagnostic( + "repaired", + "manual_bullet_list", + `${group.length} consecutive manual bullet paragraph(s) were converted to a semantic list.`, + list + ); + group = []; + }; + [...parent.children].forEach((child) => { + const isTextBlock = /^(P|H[1-6])$/.test(child.tagName); + if (isTextBlock && manualBulletPattern.test(child.textContent || "")) { + group.push(child); + } else { + flush(); + } + }); + flush(); }); } function normalizeInlineLists(root) { @@ -12328,6 +13108,72 @@ function sanitizeSlideDocumentRoot(doc = document, aggressive = false) { } }); } + function collectFallbackDiagnostics(root) { + root.querySelectorAll("*").forEach((element2) => { + const computed = view.getComputedStyle(element2); + const backgroundImage = String(computed.backgroundImage || element2.style?.backgroundImage || ""); + if (backgroundImage.includes("gradient")) { + addDiagnostic( + "fallback", + "css_gradient", + "CSS gradient requires fallback rendering; native gradient mapping is not available.", + element2 + ); + } + const filter = String(computed.filter || element2.style?.filter || ""); + if (filter && filter !== "none") { + addDiagnostic( + "fallback", + "css_filter", + "CSS filter requires fallback rendering.", + element2 + ); + } + }); + root.querySelectorAll("svg").forEach((svg) => { + if (svg.querySelector("filter,mask,foreignObject,use,pattern,textPath,clipPath,image")) { + addDiagnostic( + "fallback", + "complex_svg_raster", + "SVG filter, mask, or foreignObject requires local browser raster rendering.", + svg + ); + } else if (svg.querySelector("path")) { + addDiagnostic( + "fallback", + "complex_svg_vector", + "Complex SVG geometry will be preserved as a local SVG image.", + svg + ); + } + }); + root.querySelectorAll("style").forEach((style) => { + let rules = []; + try { + rules = [...style.sheet?.cssRules || []]; + } catch { + return; + } + rules.forEach((rule) => { + const selector = rule.selectorText || ""; + const content = rule.style?.content; + if (!/::(before|after)/.test(selector) || !content || ["none", "normal", '""', "''"].includes(content)) return; + const baseSelector = selector.replace(/::(before|after)/g, "").trim(); + let matches = []; + try { + matches = [...root.querySelectorAll(baseSelector)]; + } catch { + return; + } + matches.forEach((element2) => addDiagnostic( + "fallback", + "generated_content", + "Pseudo-element generated content requires fallback rendering.", + element2 + )); + }); + }); + } function hasVisibleBorder(computed) { return ["Top", "Right", "Bottom", "Left"].some((side) => parseFloat(computed[`border${side}Width`] || 0) > 0); } @@ -12495,13 +13341,17 @@ function sanitizeSlideDocumentRoot(doc = document, aggressive = false) { `; (root.head || root.documentElement).appendChild(style); } + assignSourceIds(); + collectFallbackDiagnostics(document2); ensureExportCanvas(); - wrapDirectTextNodes(document2); + repairNestedParagraphs(document2); promoteDecoratedSpans(document2); + wrapDirectTextNodes(document2); + normalizeManualBulletBlocks(document2); normalizeInlineLists(document2); - flattenGradients(document2); - stripUnsupportedDivBackgrounds(document2); if (aggressive) { + flattenGradients(document2); + stripUnsupportedDivBackgrounds(document2); hoistTextDecorations(document2); resetInlineBoxModel(document2); enforceInlineElementsSafe(document2); @@ -12517,9 +13367,21 @@ function sanitizeSlideDocumentRoot(doc = document, aggressive = false) { } else { inlineSnapshotLayoutStyles(document2); } + return { diagnostics }; } -// src/html2pptx-dom-core.js +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/paint-order.js +function buildDomPaintOrderMap(doc) { + const map = /* @__PURE__ */ new Map(); + if (!doc?.body) return map; + [doc.body, ...doc.body.querySelectorAll("*")].forEach((element2, index) => { + const sourceId = element2.dataset?.pptxSourceId || element2.id || null; + if (sourceId && !map.has(sourceId)) map.set(sourceId, index); + }); + return map; +} + +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/html2pptx-dom-core.js var PT_PER_PX = 0.75; function measureBodyDimensions(doc = document) { const view = doc.defaultView || window; @@ -12547,7 +13409,54 @@ function measureBodyDimensions(doc = document) { } function extractSlideDataFromDocument(doc = document) { const document2 = doc; - const view = document2.defaultView || window; + const view = document2?.defaultView || globalThis.window; + const diagnostics = []; + const diagnosticKeys = /* @__PURE__ */ new Set(); + const addDiagnostic = (severity, code, message, element2 = null) => { + const sourceId = element2?.dataset?.pptxSourceId || element2?.id || null; + const key = `${severity}:${code}:${sourceId || ""}`; + if (diagnosticKeys.has(key)) return; + diagnosticKeys.add(key); + const diagnostic = { + severity, + kind: severity === "blocking" ? "blocking" : void 0, + code, + message, + sourceId, + tag: element2?.tagName?.toLowerCase?.() || null + }; + try { + const rect = element2?.getBoundingClientRect?.(); + if (rect && rect.width > 0 && rect.height > 0) { + diagnostic.bbox = { + x: rect.left, + y: rect.top, + width: rect.width, + height: rect.height + }; + } + } catch { + } + diagnostics.push(diagnostic); + }; + if (!document2?.body || !view?.getComputedStyle) { + addDiagnostic( + "blocking", + "unreadable_document", + "Slide document has no readable body or computed-style view.", + document2?.documentElement || null + ); + const unreadableDiagnostic = diagnostics[diagnostics.length - 1]; + unreadableDiagnostic.sourceId = unreadableDiagnostic.sourceId || "slide-document"; + unreadableDiagnostic.tag = "document"; + return { + background: { type: "color", value: "FFFFFF" }, + elements: [], + placeholders: [], + diagnostics, + errors: diagnostics.map((item) => item.message) + }; + } const PT_PER_PX2 = 0.75; const PX_PER_IN2 = 96; const SINGLE_WEIGHT_FONTS = ["impact"]; @@ -12699,7 +13608,7 @@ function extractSlideDataFromDocument(doc = document) { let prevNodeIsText = false; element2.childNodes.forEach((node) => { let textTransform = baseTextTransform; - const isText = node.nodeType === Node.TEXT_NODE || node.tagName === "BR"; + const isText = node.nodeType === view.Node.TEXT_NODE || node.tagName === "BR"; if (isText) { const text2 = node.tagName === "BR" ? "\n" : textTransform(node.textContent.replace(/\s+/g, " ")); const prevRun = runs[runs.length - 1]; @@ -12708,7 +13617,7 @@ function extractSlideDataFromDocument(doc = document) { } else { runs.push({ text: text2, options: { ...baseOptions } }); } - } else if (node.nodeType === Node.ELEMENT_NODE && node.textContent.trim()) { + } else if (node.nodeType === view.Node.ELEMENT_NODE && node.textContent.trim()) { const options = { ...baseOptions }; const computed = view.getComputedStyle(node); if (["SPAN", "B", "STRONG", "I", "EM", "U", "SMALL", "LABEL", "A", "CODE", "MARK", "SUB", "SUP"].includes(node.tagName)) { @@ -12727,16 +13636,16 @@ function extractSlideDataFromDocument(doc = document) { textTransform = (text2) => applyTextTransform(text2, transformStr); } if (computed.marginLeft && parseFloat(computed.marginLeft) > 0) { - errors.push(`Inline element <${node.tagName.toLowerCase()}> has margin-left which is not supported in PowerPoint. Remove margin from inline elements.`); + addDiagnostic("fallback", "inline_margin", `Inline element <${node.tagName.toLowerCase()}> has margin-left; fallback layout may be needed.`, node); } if (computed.marginRight && parseFloat(computed.marginRight) > 0) { - errors.push(`Inline element <${node.tagName.toLowerCase()}> has margin-right which is not supported in PowerPoint. Remove margin from inline elements.`); + addDiagnostic("fallback", "inline_margin", `Inline element <${node.tagName.toLowerCase()}> has margin-right; fallback layout may be needed.`, node); } if (computed.marginTop && parseFloat(computed.marginTop) > 0) { - errors.push(`Inline element <${node.tagName.toLowerCase()}> has margin-top which is not supported in PowerPoint. Remove margin from inline elements.`); + addDiagnostic("fallback", "inline_margin", `Inline element <${node.tagName.toLowerCase()}> has margin-top; fallback layout may be needed.`, node); } if (computed.marginBottom && parseFloat(computed.marginBottom) > 0) { - errors.push(`Inline element <${node.tagName.toLowerCase()}> has margin-bottom which is not supported in PowerPoint. Remove margin from inline elements.`); + addDiagnostic("fallback", "inline_margin", `Inline element <${node.tagName.toLowerCase()}> has margin-bottom; fallback layout may be needed.`, node); } parseInlineFormatting(node, options, runs, textTransform); } @@ -12760,7 +13669,7 @@ function extractSlideDataFromDocument(doc = document) { const style = view.getComputedStyle(el); const bgImage = style.backgroundImage || ""; if (bgImage.includes("linear-gradient") || bgImage.includes("radial-gradient")) { - return { gradient: true }; + return { gradient: true, element: el }; } if (bgImage && bgImage !== "none") { const urlMatch = bgImage.match(/url\(["']?([^"')]+)["']?\)/); @@ -12775,6 +13684,14 @@ function extractSlideDataFromDocument(doc = document) { }; const body = document2.body; const bodyRect = body.getBoundingClientRect(); + if (!(bodyRect.width > 0) || !(bodyRect.height > 0)) { + addDiagnostic( + "blocking", + "unmeasurable_canvas", + "Slide canvas has no measurable width or height.", + body + ); + } const boxFor = (rect) => ({ left: rect.left - bodyRect.left, top: rect.top - bodyRect.top, @@ -12813,13 +13730,51 @@ function extractSlideDataFromDocument(doc = document) { return { x, y, w, h }; }; const readZIndex = (el) => { - const raw = view.getComputedStyle(el).zIndex; - if (!raw || raw === "auto") return 0; - const parsed = parseInt(raw, 10); - return Number.isFinite(parsed) ? parsed : 0; + let current = el; + while (current && current !== body) { + const raw = view.getComputedStyle(current).zIndex; + if (raw && raw !== "auto") { + const parsed = parseInt(raw, 10); + if (Number.isFinite(parsed)) return parsed; + } + current = current.parentElement; + } + return 0; + }; + const domPaintOrder = buildDomPaintOrderMap(document2); + const sourceSubOrders = /* @__PURE__ */ new Map(); + let unmappedPaintOrder = Math.max(-1, ...domPaintOrder.values()) + 1; + const nextPaintMetadata = (el) => { + const sourceId = el?.dataset?.pptxSourceId || el?.id || null; + const subOrder = sourceSubOrders.get(sourceId) || 0; + sourceSubOrders.set(sourceId, subOrder + 1); + return { + sourceId, + paintOrder: domPaintOrder.get(sourceId) ?? unmappedPaintOrder++, + subOrder + }; }; const pushElement = (entry, el) => { - if (el) entry.zIndex = readZIndex(el); + const paintMetadata = nextPaintMetadata(el); + entry.kind = entry.kind || "native"; + entry.paintOrder = entry.paintOrder ?? paintMetadata.paintOrder; + entry.subOrder = entry.subOrder ?? paintMetadata.subOrder; + if (!entry.bbox) { + if (entry.position) { + entry.bbox = { ...entry.position }; + } else if (entry.type === "line") { + entry.bbox = { + x: Math.min(entry.x1, entry.x2), + y: Math.min(entry.y1, entry.y2), + w: Math.abs(entry.x2 - entry.x1), + h: Math.abs(entry.y2 - entry.y1) + }; + } + } + if (el) { + entry.zIndex = readZIndex(el); + entry.sourceId = paintMetadata.sourceId; + } elements.push(entry); }; const resolveListBulletColor = (ul, liElements, textHex) => { @@ -12841,16 +13796,19 @@ function extractSlideDataFromDocument(doc = document) { } return null; }; - const errors = []; const bgResolved = resolveSlideBackground(body); if (bgResolved.gradient) { - errors.push( - "CSS gradients are not supported. Use Sharp to rasterize gradients as PNG images first, then reference with background-image: url('gradient.png')" + addDiagnostic( + "fallback", + "css_gradient", + "CSS gradient requires fallback rendering; native gradient mapping is not available.", + bgResolved.element || body ); } const background = bgResolved.gradient ? { type: "color", value: "FFFFFF" } : { type: bgResolved.type, ...bgResolved.path ? { path: bgResolved.path } : { value: bgResolved.value } }; const slideBackdropHex = background.value || "0E0E12"; const elements = []; + const slideDataFallbackLayers = []; const placeholders = []; const textTags = ["P", "H1", "H2", "H3", "H4", "H5", "H6", "UL", "OL", "LI"]; const genericInlineTextTags = /* @__PURE__ */ new Set([ @@ -12881,7 +13839,7 @@ function extractSlideDataFromDocument(doc = document) { return false; }; const hasDirectText = (el) => Array.from(el.childNodes).some( - (node) => node.nodeType === Node.TEXT_NODE && node.textContent.replace(/\s+/g, " ").trim() + (node) => node.nodeType === view.Node.TEXT_NODE && node.textContent.replace(/\s+/g, " ").trim() ); const isGenericTextElement = (el) => { if (!el.textContent.replace(/\s+/g, " ").trim() || hasTextOwnerAncestor(el)) return false; @@ -12931,11 +13889,13 @@ function extractSlideDataFromDocument(doc = document) { const rect = rectOverride || rectFor(el); const text2 = el.textContent.replace(/\s+/g, " ").trim(); if (rect.width === 0 || rect.height === 0 || !text2) return false; - if (type !== "text" && el.tagName !== "LI" && /^[•\-\*▪▸○●◆◇■□]\s/.test(text2.trimStart())) { - errors.push( - `Text element <${el.tagName.toLowerCase()}> starts with bullet symbol "${text2.substring(0, 20)}...". Use
    or
      lists instead of manual bullet symbols.` + if (type !== "text" && el.tagName !== "LI" && /^[•●○▪‣·▸◆◇■□]\s/u.test(text2.trimStart())) { + addDiagnostic( + "fallback", + "manual_bullet_unrepaired", + `Text element <${el.tagName.toLowerCase()}> still starts with a manual bullet; exporting as editable text.`, + el ); - return false; } const computed = view.getComputedStyle(el); if (computed.display === "none" || computed.visibility === "hidden" || parseFloat(computed.opacity || "1") <= 0) { @@ -13020,8 +13980,481 @@ function extractSlideDataFromDocument(doc = document) { } return true; }; + const svgColor = (value2, fallback = null) => { + if (!value2 || value2 === "none" || value2 === "transparent") return fallback; + return rgbToHex2(value2); + }; + const svgNumber = (value2, fallback = 0) => { + const parsed = parseFloat(String(value2 || "")); + return Number.isFinite(parsed) ? parsed : fallback; + }; + const identityMatrix = () => [1, 0, 0, 1, 0, 0]; + const multiplyMatrix = (left, right) => [ + left[0] * right[0] + left[2] * right[1], + left[1] * right[0] + left[3] * right[1], + left[0] * right[2] + left[2] * right[3], + left[1] * right[2] + left[3] * right[3], + left[0] * right[4] + left[2] * right[5] + left[4], + left[1] * right[4] + left[3] * right[5] + left[5] + ]; + const parseSvgTransform = (value2 = "") => { + const raw = String(value2 || "").trim(); + let matrix = identityMatrix(); + let layoutMatrix = identityMatrix(); + let rotation = 0; + if (!raw || raw === "none") { + return { matrix, layoutMatrix, rotation, reliable: true }; + } + if (/(?:skew|perspective|matrix3d)\s*\(/i.test(raw)) { + return { matrix, layoutMatrix, rotation, reliable: false }; + } + const functions = raw.matchAll(/(matrix|translate|scale|rotate)\s*\(([^)]*)\)/gi); + let matched = false; + for (const match of functions) { + matched = true; + const name = match[1].toLowerCase(); + const values2 = match[2].trim().split(/[\s,]+/).filter(Boolean).map((item) => parseFloat(item)); + let next = identityMatrix(); + let nextLayout = identityMatrix(); + if (name === "matrix" && values2.length >= 6) { + if (Math.abs(values2[1]) > 1e-6 || Math.abs(values2[2]) > 1e-6) { + return { matrix, layoutMatrix, rotation, reliable: false }; + } + next = values2.slice(0, 6); + nextLayout = next; + } else if (name === "translate") { + next = [1, 0, 0, 1, values2[0] || 0, values2[1] || 0]; + nextLayout = next; + } else if (name === "scale") { + const x = Number.isFinite(values2[0]) ? values2[0] : 1; + const y = Number.isFinite(values2[1]) ? values2[1] : x; + next = [x, 0, 0, y, 0, 0]; + nextLayout = next; + } else if (name === "rotate") { + const angle = values2[0] || 0; + rotation += angle; + const radians = angle * Math.PI / 180; + const cos2 = Math.cos(radians); + const sin2 = Math.sin(radians); + const rotationMatrix = [cos2, sin2, -sin2, cos2, 0, 0]; + if (Number.isFinite(values2[1]) && Number.isFinite(values2[2])) { + next = multiplyMatrix( + multiplyMatrix([1, 0, 0, 1, values2[1], values2[2]], rotationMatrix), + [1, 0, 0, 1, -values2[1], -values2[2]] + ); + } else { + next = rotationMatrix; + } + } + matrix = multiplyMatrix(matrix, next); + layoutMatrix = multiplyMatrix(layoutMatrix, nextLayout); + } + return { matrix, layoutMatrix, rotation, reliable: matched }; + }; + const transformForSvgNode = (node, svg) => { + if (typeof node.getCTM === "function") { + try { + const ctm = node.getCTM(); + const matrix2 = ctm ? [ctm.a, ctm.b, ctm.c, ctm.d, ctm.e, ctm.f].map(Number) : null; + if (matrix2?.every(Number.isFinite)) { + const scaleX = Math.hypot(matrix2[0], matrix2[1]); + const scaleY = Math.hypot(matrix2[2], matrix2[3]); + const orthogonality = scaleX > 0 && scaleY > 0 ? Math.abs((matrix2[0] * matrix2[2] + matrix2[1] * matrix2[3]) / (scaleX * scaleY)) : Infinity; + if (orthogonality > 1e-5 || matrix2[0] * matrix2[3] - matrix2[1] * matrix2[2] <= 0) { + return { + matrix: matrix2, + layoutMatrix: identityMatrix(), + rotation: 0, + reliable: false, + coordinateSpace: "viewport" + }; + } + return { + matrix: matrix2, + layoutMatrix: [scaleX, 0, 0, scaleY, matrix2[4], matrix2[5]], + rotation: Math.atan2(matrix2[1], matrix2[0]) * 180 / Math.PI, + reliable: true, + coordinateSpace: "viewport" + }; + } + } catch { + } + } + const chain = []; + let current = node; + while (current && current !== svg) { + chain.unshift(current); + current = current.parentElement; + } + let matrix = identityMatrix(); + let layoutMatrix = identityMatrix(); + let rotation = 0; + for (const item of chain) { + const attributeTransform = parseSvgTransform(item.getAttribute("transform")); + if (!attributeTransform.reliable) { + return { matrix, layoutMatrix, rotation, reliable: false }; + } + matrix = multiplyMatrix(matrix, attributeTransform.matrix); + layoutMatrix = multiplyMatrix(layoutMatrix, attributeTransform.layoutMatrix); + rotation += attributeTransform.rotation; + const computedTransformValue = view.getComputedStyle(item).transform; + if (computedTransformValue && computedTransformValue !== "none" && computedTransformValue !== item.getAttribute("transform")) { + const computedTransform = parseSvgTransform(computedTransformValue); + if (!computedTransform.reliable) { + return { matrix, layoutMatrix, rotation, reliable: false }; + } + let computedMatrix = computedTransform.matrix; + const originValues = String(view.getComputedStyle(item).transformOrigin || "").split(/\s+/).map((value2) => parseFloat(value2)); + if (Number.isFinite(originValues[0]) && Number.isFinite(originValues[1]) && computedTransform.rotation) { + computedMatrix = multiplyMatrix( + multiplyMatrix( + [1, 0, 0, 1, originValues[0], originValues[1]], + computedMatrix + ), + [1, 0, 0, 1, -originValues[0], -originValues[1]] + ); + } + matrix = multiplyMatrix(matrix, computedMatrix); + layoutMatrix = multiplyMatrix(layoutMatrix, computedTransform.layoutMatrix); + rotation += computedTransform.rotation; + } + } + return { + matrix, + layoutMatrix, + rotation, + reliable: true, + coordinateSpace: "viewBox" + }; + }; + const transformPoint = (point, matrix) => ({ + x: matrix[0] * point.x + matrix[2] * point.y + matrix[4], + y: matrix[1] * point.x + matrix[3] * point.y + matrix[5] + }); + const parseSvgPoints = (value2) => { + const numbers = String(value2 || "").trim().split(/[\s,]+/).filter(Boolean).map(Number); + const points = []; + for (let index = 0; index + 1 < numbers.length; index += 2) { + if (Number.isFinite(numbers[index]) && Number.isFinite(numbers[index + 1])) { + points.push({ x: numbers[index], y: numbers[index + 1] }); + } + } + return points; + }; + const svgStyleProperties = [ + "fill", + "fill-opacity", + "fill-rule", + "stroke", + "stroke-width", + "stroke-opacity", + "stroke-linecap", + "stroke-linejoin", + "stroke-dasharray", + "stroke-dashoffset", + "opacity", + "color", + "vector-effect" + ]; + const resolvedSvgStyle = (element2, property) => { + let current = element2; + while (current) { + const value2 = String( + view.getComputedStyle(current).getPropertyValue(property) || "" + ).trim(); + if (value2 && !["inherit", "unset", "initial"].includes(value2)) return value2; + if (["opacity", "vector-effect"].includes(property)) break; + current = current.parentElement; + } + return ""; + }; + const inlineComputedSvgStyles = (original, clone2) => { + svgStyleProperties.forEach((property) => { + const value2 = resolvedSvgStyle(original, property); + if (value2) clone2.style.setProperty(property, value2); + }); + const originalChildren = [...original.children]; + const cloneChildren = [...clone2.children]; + originalChildren.forEach((child, index) => { + if (cloneChildren[index]) inlineComputedSvgStyles(child, cloneChildren[index]); + }); + }; + const serializeSvgVisual = (svg, node) => { + const rootClone = svg.cloneNode(false); + rootClone.setAttribute("xmlns", "http://www.w3.org/2000/svg"); + if (!rootClone.getAttribute("width")) rootClone.setAttribute("width", "100%"); + if (!rootClone.getAttribute("height")) rootClone.setAttribute("height", "100%"); + inlineComputedSvgStyles(svg, rootClone); + [...svg.querySelectorAll("defs")].forEach((defs) => { + const defsClone = defs.cloneNode(true); + inlineComputedSvgStyles(defs, defsClone); + rootClone.appendChild(defsClone); + }); + const ancestors = []; + let current = node.parentElement; + while (current && current !== svg) { + ancestors.unshift(current); + current = current.parentElement; + } + let targetParent = rootClone; + ancestors.forEach((ancestor) => { + const ancestorClone = ancestor.cloneNode(false); + inlineComputedSvgStyles(ancestor, ancestorClone); + targetParent.appendChild(ancestorClone); + targetParent = ancestorClone; + }); + const targetClone = node.cloneNode(true); + inlineComputedSvgStyles(node, targetClone); + targetClone.querySelectorAll?.("text").forEach((text2) => text2.remove()); + targetParent.appendChild(targetClone); + return `data:image/svg+xml,${encodeURIComponent(rootClone.outerHTML)}`; + }; + const boundsOfPoints = (points) => { + const xs = points.map((point) => point.x); + const ys = points.map((point) => point.y); + return { + left: Math.min(...xs), + top: Math.min(...ys), + width: Math.max(...xs) - Math.min(...xs), + height: Math.max(...ys) - Math.min(...ys) + }; + }; + const isDiamondPoints = (points) => { + if (points.length !== 4) return false; + const bounds = boundsOfPoints(points); + const cx2 = bounds.left + bounds.width / 2; + const cy2 = bounds.top + bounds.height / 2; + const tolerance = Math.max(bounds.width, bounds.height) * 0.08 + 0.01; + return points.every((point) => Math.abs(point.x - cx2) <= tolerance || Math.abs(point.y - cy2) <= tolerance); + }; + const emitNativeSvg = (svg) => { + const svgRect = rectFor(svg); + if (svgRect.width <= 0 || svgRect.height <= 0) return; + const viewBox = String(svg.getAttribute("viewBox") || `0 0 ${svgRect.width} ${svgRect.height}`).trim().split(/[\s,]+/).map(Number); + const [vbX = 0, vbY = 0, vbW = svgRect.width, vbH = svgRect.height] = viewBox; + const xScale = svgRect.width / (vbW || svgRect.width); + const yScale = svgRect.height / (vbH || svgRect.height); + const fallbackLayers = slideDataFallbackLayers; + const toSlidePoint = (point) => ({ + x: svgRect.left + (point.x - vbX) * xScale, + y: svgRect.top + (point.y - vbY) * yScale + }); + const pushLine = (start, end, node, stroke2, width, coordinateSpace = "viewBox") => { + const toLinePoint = (point) => coordinateSpace === "viewport" ? { x: svgRect.left + point.x, y: svgRect.top + point.y } : toSlidePoint(point); + const first = toLinePoint(start); + const second = toLinePoint(end); + pushElement({ + type: "line", + kind: "native", + x1: pxToInch(first.x), + y1: pxToInch(first.y), + x2: pxToInch(second.x), + y2: pxToInch(second.y), + color: stroke2 || "000000", + width + }, node); + }; + const hasBrowserOnlySvg = Boolean( + svg.querySelector("filter,mask,foreignObject,use,pattern,textPath,clipPath,image") + ); + const canSerializeSvgVisual = (node) => !svg.querySelector("script") && !/(?:href|src)\s*=\s*["']\s*(?:https?:)?\/\//i.test(node.outerHTML || ""); + const pushSvgImageLayer = (node, code, message) => { + if (!canSerializeSvgVisual(node)) { + addDiagnostic( + "fallback", + "complex_svg_raster", + "Complex SVG cannot be safely serialized and requires local browser raster rendering.", + svg + ); + return; + } + const paintMetadata = nextPaintMetadata(node); + fallbackLayers.push({ + sourceId: paintMetadata.sourceId, + zIndex: readZIndex(node), + paintOrder: paintMetadata.paintOrder, + subOrder: paintMetadata.subOrder, + kind: "svg-image", + captureStrategy: "local-svg", + bbox: { + x: pxToInch(svgRect.left), + y: pxToInch(svgRect.top), + w: pxToInch(svgRect.width), + h: pxToInch(svgRect.height) + }, + data: serializeSvgVisual(svg, node), + diagnostics: [{ + severity: "fallback", + code, + message, + sourceId: node.dataset?.pptxSourceId || node.id || null + }] + }); + }; + svg.querySelectorAll("rect,circle,ellipse,line,polyline,polygon,text,path").forEach((node) => { + const tag = node.tagName.toLowerCase(); + if (tag === "path") { + if (!hasBrowserOnlySvg) { + pushSvgImageLayer( + node, + "complex_svg_vector", + "Complex SVG geometry is preserved as a local movable vector image." + ); + } + return; + } + const transform = transformForSvgNode(node, svg); + if (!transform.reliable) { + pushSvgImageLayer( + node, + "svg_transform_vector", + "SVG transform cannot be represented reliably as a native shape; preserving it as SVG." + ); + return; + } + const transformedToSlidePoint = (transformed) => transform.coordinateSpace === "viewport" ? { x: svgRect.left + transformed.x, y: svgRect.top + transformed.y } : toSlidePoint(transformed); + const transformToSlidePoint = (point, matrix) => transformedToSlidePoint(transformPoint(point, matrix)); + const mapPoint = (x, y) => transformToSlidePoint( + { x: svgNumber(x), y: svgNumber(y) }, + transform.matrix + ); + const mapLayoutPoint = (x, y) => transformToSlidePoint( + { x: svgNumber(x), y: svgNumber(y) }, + transform.layoutMatrix + ); + const fill2 = svgColor(node.getAttribute("fill") || view.getComputedStyle(node).fill); + const stroke2 = svgColor(node.getAttribute("stroke") || view.getComputedStyle(node).stroke); + const opacity = svgNumber(node.getAttribute("opacity") || view.getComputedStyle(node).opacity, 1); + const lineWidth = svgNumber(node.getAttribute("stroke-width"), 1) * 0.75; + const common = { + type: tag === "text" ? "svg-text" : "svg-shape", + kind: "native", + svgType: tag, + position: null, + shape: { fill: fill2, line: stroke2 ? { color: stroke2, width: lineWidth } : null, transparency: Math.round((1 - opacity) * 100), rectRadius: 0 } + }; + if (tag === "rect") { + const x = svgNumber(node.getAttribute("x")); + const y = svgNumber(node.getAttribute("y")); + const width = svgNumber(node.getAttribute("width")); + const height = svgNumber(node.getAttribute("height")); + const points = [ + mapPoint(x, y), + mapPoint(x + width, y), + mapPoint(x + width, y + height), + mapPoint(x, y + height) + ]; + const bounds = boundsOfPoints(points); + const layoutBounds = boundsOfPoints([ + mapLayoutPoint(x, y), + mapLayoutPoint(x + width, y), + mapLayoutPoint(x + width, y + height), + mapLayoutPoint(x, y + height) + ]); + common.position = { x: pxToInch(layoutBounds.left), y: pxToInch(layoutBounds.top), w: pxToInch(layoutBounds.width), h: pxToInch(layoutBounds.height) }; + common.bbox = { x: pxToInch(bounds.left), y: pxToInch(bounds.top), w: pxToInch(bounds.width), h: pxToInch(bounds.height) }; + if (transform.rotation) common.shape.rotate = transform.rotation; + } else if (tag === "circle" || tag === "ellipse") { + const rx = tag === "circle" ? svgNumber(node.getAttribute("r")) : svgNumber(node.getAttribute("rx")); + const ry = tag === "circle" ? rx : svgNumber(node.getAttribute("ry")); + const cx2 = svgNumber(node.getAttribute("cx")); + const cy2 = svgNumber(node.getAttribute("cy")); + const points = [ + mapPoint(cx2 - rx, cy2), + mapPoint(cx2 + rx, cy2), + mapPoint(cx2, cy2 - ry), + mapPoint(cx2, cy2 + ry) + ]; + const bounds = boundsOfPoints(points); + const layoutBounds = boundsOfPoints([ + mapLayoutPoint(cx2 - rx, cy2), + mapLayoutPoint(cx2 + rx, cy2), + mapLayoutPoint(cx2, cy2 - ry), + mapLayoutPoint(cx2, cy2 + ry) + ]); + common.position = { x: pxToInch(layoutBounds.left), y: pxToInch(layoutBounds.top), w: pxToInch(layoutBounds.width), h: pxToInch(layoutBounds.height) }; + common.bbox = { x: pxToInch(bounds.left), y: pxToInch(bounds.top), w: pxToInch(bounds.width), h: pxToInch(bounds.height) }; + if (transform.rotation) common.shape.rotate = transform.rotation; + } else if (tag === "line") { + pushLine( + transformPoint({ x: svgNumber(node.getAttribute("x1")), y: svgNumber(node.getAttribute("y1")) }, transform.matrix), + transformPoint({ x: svgNumber(node.getAttribute("x2")), y: svgNumber(node.getAttribute("y2")) }, transform.matrix), + node, + stroke2, + lineWidth, + transform.coordinateSpace + ); + return; + } else if (tag === "text") { + common.text = node.textContent || ""; + const fontSize = svgNumber(node.getAttribute("font-size"), 16); + const origin = mapPoint(node.getAttribute("x"), svgNumber(node.getAttribute("y")) - fontSize); + common.position = { x: pxToInch(origin.x), y: pxToInch(origin.y), w: pxToInch(Math.max(1, svgRect.width)), h: pxToInch(Math.max(1, fontSize * yScale * 1.3)) }; + common.style = { fontSize: svgNumber(node.getAttribute("font-size"), 16) * 0.75, fontFace: "Arial", color: fill2 || "000000", align: "left" }; + if (transform.rotation) common.style.rotate = transform.rotation; + } else { + const points = parseSvgPoints(node.getAttribute("points")).map((point) => transformPoint(point, transform.matrix)); + if (tag === "polygon" && (points.length === 3 || isDiamondPoints(points))) { + const slidePoints = points.map(transformedToSlidePoint); + const bounds = boundsOfPoints(slidePoints); + common.svgType = points.length === 3 ? "triangle" : "diamond"; + common.position = { + x: pxToInch(bounds.left), + y: pxToInch(bounds.top), + w: pxToInch(bounds.width), + h: pxToInch(bounds.height) + }; + common.bbox = { ...common.position }; + if (transform.rotation) common.shape.rotate = transform.rotation; + } else { + const closed = tag === "polygon" && points.length > 2 ? [...points, points[0]] : points; + for (let index = 0; index + 1 < closed.length; index += 1) { + pushLine( + closed[index], + closed[index + 1], + node, + stroke2 || fill2, + lineWidth, + transform.coordinateSpace + ); + } + if (tag === "polygon" && fill2 && points.length > 2) { + const sourceId = node.dataset?.pptxSourceId || node.id || null; + fallbackLayers.push({ + sourceId, + zIndex: readZIndex(node), + paintOrder: domPaintOrder.get(sourceId) ?? unmappedPaintOrder++, + subOrder: -1, + kind: "svg-image", + bbox: { + x: pxToInch(svgRect.left), + y: pxToInch(svgRect.top), + w: pxToInch(svgRect.width), + h: pxToInch(svgRect.height) + }, + data: serializeSvgVisual(svg, node), + diagnostics: [{ + severity: "fallback", + code: "svg_polygon_fill", + message: "Polygon fill is preserved as a local SVG layer over an editable outline.", + sourceId: node.dataset?.pptxSourceId || node.id || null + }] + }); + } + return; + } + } + if (common.position || common.type === "line") pushElement(common, node); + }); + processed.add(svg); + svg.querySelectorAll("*").forEach((node) => processed.add(node)); + }; document2.querySelectorAll("*").forEach((el) => { if (processed.has(el)) return; + if (el.tagName === "svg") { + emitNativeSvg(el); + return; + } if (el.tagName === "DIV" && el.dataset && el.dataset.pptxMerge === "true") { const containerRect = rectFor(el); if (containerRect.width === 0 || containerRect.height === 0) { @@ -13029,18 +14462,23 @@ function extractSlideDataFromDocument(doc = document) { return; } if (el.querySelector('[data-pptx-merge="true"]')) { - errors.push( - `data-pptx-merge container cannot contain another data-pptx-merge container. Nested merge is not supported.` + addDiagnostic( + "fallback", + "nested_merge_container", + "Nested data-pptx-merge containers require fallback handling.", + el ); processed.add(el); return; } const mergeComputed = view.getComputedStyle(el); if (mergeComputed.backgroundImage && mergeComputed.backgroundImage !== "none") { - errors.push( - "Background images on data-pptx-merge container are not supported. Use solid colors or borders, or layer images via slide.addImage()." + addDiagnostic( + "fallback", + "merge_background_image", + "Background image on data-pptx-merge requires fallback rendering.", + el ); - return; } const mHasBg = mergeComputed.backgroundColor && mergeComputed.backgroundColor !== "rgba(0, 0, 0, 0)"; const mBorders = [ @@ -13052,7 +14490,7 @@ function extractSlideDataFromDocument(doc = document) { const mHasBorder = mBorders.some((b) => b > 0); const mHasUniformBorder = mHasBorder && mBorders.every((b) => b === mBorders[0]); if (mHasBg || mHasUniformBorder) { - elements.push({ + pushElement({ type: "shape", text: "", position: { @@ -13082,12 +14520,15 @@ function extractSlideDataFromDocument(doc = document) { })(), shadow: parseBoxShadow(mergeComputed.boxShadow) } - }); + }, el); } const textDescendants = Array.from(el.querySelectorAll("p, h1, h2, h3, h4, h5, h6")); if (textDescendants.length === 0) { - errors.push( - `data-pptx-merge container has no

      / children to merge. Remove the data-pptx-merge attribute or add text elements.` + addDiagnostic( + "fallback", + "empty_merge_container", + "data-pptx-merge container has no semantic text children.", + el ); processed.add(el); return; @@ -13151,7 +14592,7 @@ function extractSlideDataFromDocument(doc = document) { processed.add(el); return; } - elements.push({ + pushElement({ type: "merged-text", items: mergedRuns, position: { @@ -13161,7 +14602,7 @@ function extractSlideDataFromDocument(doc = document) { h: pxToInch(containerRect.height) }, style: baseStyle - }); + }, el); processed.add(el); return; } @@ -13221,8 +14662,11 @@ function extractSlideDataFromDocument(doc = document) { if (el.classList && el.classList.contains("placeholder")) { const rect = rectFor(el); if (rect.width === 0 || rect.height === 0) { - errors.push( - `Placeholder "${el.id || "unnamed"}" has ${rect.width === 0 ? "width: 0" : "height: 0"}. Check the layout CSS.` + addDiagnostic( + "fallback", + "unmeasurable_placeholder", + `Placeholder "${el.id || "unnamed"}" has ${rect.width === 0 ? "width: 0" : "height: 0"}.`, + el ); } else { placeholders.push({ @@ -13239,7 +14683,7 @@ function extractSlideDataFromDocument(doc = document) { if (el.tagName === "IMG") { const rect = rectFor(el); if (rect.width > 0 && rect.height > 0) { - elements.push({ + pushElement({ type: "image", src: el.src, position: { @@ -13248,7 +14692,45 @@ function extractSlideDataFromDocument(doc = document) { w: pxToInch(rect.width), h: pxToInch(rect.height) } - }); + }, el); + processed.add(el); + return; + } + } + if (el.tagName === "DIV") { + const computed = view.getComputedStyle(el); + const isZeroBox = svgNumber(computed.width) === 0 && svgNumber(computed.height) === 0; + const sides = ["Top", "Right", "Bottom", "Left"].map((side) => ({ + side, + width: svgNumber(computed[`border${side}Width`]), + color: computed[`border${side}Color`] + })); + const opaqueSides = sides.filter((side) => side.width > 0 && !isTransparentBg(side.color)); + if (isZeroBox && opaqueSides.length === 1 && sides.filter((side) => side.width > 0).length >= 3) { + const active = opaqueSides[0]; + const rect = rectFor(el); + const horizontal = sides.find((side) => side.side === "Left").width + sides.find((side) => side.side === "Right").width; + const vertical = sides.find((side) => side.side === "Top").width + sides.find((side) => side.side === "Bottom").width; + const rotations = { Bottom: 0, Left: 90, Top: 180, Right: 270 }; + pushElement({ + type: "svg-shape", + svgType: "triangle", + kind: "native", + text: "", + position: { + x: pxToInch(rect.left - sides.find((side) => side.side === "Left").width), + y: pxToInch(rect.top - sides.find((side) => side.side === "Top").width), + w: pxToInch(Math.max(1, horizontal)), + h: pxToInch(Math.max(1, vertical)) + }, + shape: { + fill: rgbToHex2(active.color), + line: null, + transparency: extractAlpha(active.color), + rectRadius: 0, + rotate: rotations[active.side] + } + }, el); processed.add(el); return; } @@ -13259,10 +14741,12 @@ function extractSlideDataFromDocument(doc = document) { const hasBg = computed.backgroundColor && computed.backgroundColor !== "rgba(0, 0, 0, 0)"; const bgImage = computed.backgroundImage; if (bgImage && bgImage !== "none") { - errors.push( - "Background images on DIV elements are not supported. Use solid colors or borders for shapes, or use slide.addImage() in PptxGenJS to layer images." + addDiagnostic( + "fallback", + "container_background_image", + "Container background image requires fallback rendering.", + el ); - return; } const borderTop = computed.borderTopWidth; const borderRight = computed.borderRightWidth; @@ -13461,46 +14945,528 @@ function extractSlideDataFromDocument(doc = document) { if (!textTags.includes(el.tagName)) return; emitTextElement(el); }); - const paintRank = (type) => { - if (type === "shape") return 0; - if (type === "line") return 1; - if (type === "image") return 2; - return 3; - }; elements.sort((a, b) => { const z = (a.zIndex ?? 0) - (b.zIndex ?? 0); if (z !== 0) return z; - return paintRank(a.type) - paintRank(b.type); + const paint = (a.paintOrder ?? 0) - (b.paintOrder ?? 0); + if (paint !== 0) return paint; + const sub = (a.subOrder ?? 0) - (b.subOrder ?? 0); + if (sub !== 0) return sub; + return (a.stableOrder ?? 0) - (b.stableOrder ?? 0); + }); + document2.querySelectorAll("*").forEach((element2) => { + const computed = view.getComputedStyle(element2); + const filter = String(computed.filter || element2.style?.filter || ""); + if (filter && filter !== "none") { + addDiagnostic("fallback", "css_filter", "CSS filter requires fallback rendering.", element2); + } + if (String(element2.tagName).toUpperCase() === "SVG") { + if (element2.querySelector("filter,mask,foreignObject,use,pattern,textPath,clipPath,image")) { + addDiagnostic( + "fallback", + "complex_svg_raster", + "SVG filter, mask, or foreignObject requires local browser raster rendering.", + element2 + ); + } else if (element2.querySelector("path")) { + addDiagnostic( + "fallback", + "complex_svg_vector", + "Complex SVG geometry is preserved as a local SVG image.", + element2 + ); + } + } + }); + const blockingErrors = diagnostics.filter((diagnostic) => diagnostic.severity === "blocking").map((diagnostic) => diagnostic.message); + slideDataFallbackLayers.sort((a, b) => { + const z = (a.zIndex ?? 0) - (b.zIndex ?? 0); + if (z !== 0) return z; + const order = (a.paintOrder ?? 0) - (b.paintOrder ?? 0); + if (order !== 0) return order; + const sub = (a.subOrder ?? 0) - (b.subOrder ?? 0); + if (sub !== 0) return sub; + return (a.stableOrder ?? 0) - (b.stableOrder ?? 0); }); - return { background, elements, placeholders, errors }; + return { + background, + elements, + fallbackLayers: slideDataFallbackLayers, + placeholders, + diagnostics, + errors: blockingErrors + }; } -// src/export-slide-browser.js -var EXPORT_VIEWPORT = { width: 1280, height: 720 }; -var RASTER_TEXT_TYPES = /* @__PURE__ */ new Set(["p", "h1", "h2", "h3", "h4", "h5", "h6", "text", "list", "merged-text"]); -function countVectorTextElements(slideData) { - return (slideData?.elements || []).filter((el) => RASTER_TEXT_TYPES.has(el.type)).length; -} -function slideHtmlForRasterBackdrop(html) { - const markup = normalizeSlideDocument(html); - if (markup.includes('data-pptx-raster="1"') && markup.includes("pptx-raster-hide-text")) { - return markup; +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/fallback-layer-render.js +var EXPORT_WIDTH = 1280; +var EXPORT_HEIGHT = 720; +var LOCAL_RASTER_CODES = /* @__PURE__ */ new Set([ + "css_gradient", + "css_filter", + "computed_gradient", + "generated_content", + "container_background_image", + "merge_background_image", + "complex_svg_raster" +]); +function rasterLayerZIndex(element2, view) { + let current = element2; + while (current) { + const raw = view.getComputedStyle(current).zIndex; + if (raw && raw !== "auto") { + const parsed = parseInt(raw, 10); + if (Number.isFinite(parsed)) return parsed; + } + current = current.parentElement; } - const hideCss = `body[data-pptx-raster="1"], body[data-pptx-raster="1"] * { + return 0; +} +function escapedAttributeValue(value2) { + return String(value2).replace(/["\\]/g, "\\$&"); +} +function serializeRasterTargetDocument(doc, targetSpecs) { + const targets = (Array.isArray(targetSpecs) ? targetSpecs : [targetSpecs]).map((target) => typeof target === "string" ? { sourceId: target, captureStrategy: "visual-subtree" } : target); + const sourceRoot = doc._exportRoot || doc.documentElement; + const sourceBody = doc.body; + const bodyClone = sourceBody.cloneNode(true); + let targetCount = 0; + targets.forEach(({ sourceId, captureStrategy }) => { + const target = bodyClone.querySelector( + `[data-pptx-source-id="${escapedAttributeValue(sourceId)}"]` + ) || (bodyClone.dataset?.pptxSourceId === sourceId ? bodyClone : null); + if (!target) return; + target.setAttribute("data-pptx-raster-target", "1"); + target.setAttribute("data-pptx-capture-strategy", captureStrategy); + targetCount += 1; + }); + if (!targetCount) return null; + const authorStyles = [...sourceRoot.querySelectorAll("style")].map((style) => style.textContent || "").join("\n"); + const bodyAttributes = [...bodyClone.attributes].filter((attribute) => !["class", "style"].includes(attribute.name)).map((attribute) => ` ${attribute.name}="${String(attribute.value).replace(/"/g, """)}"`).join(""); + const isolationCss = ` +html, body, .ppt-export-root, .ppt-export-body { + margin: 0 !important; + padding: 0 !important; + width: ${EXPORT_WIDTH}px !important; + height: ${EXPORT_HEIGHT}px !important; + overflow: hidden !important; + background: transparent !important; + background-color: transparent !important; +} +.ppt-export-body [data-pptx-source-id] { + visibility: hidden !important; +} +.ppt-export-body [data-pptx-raster-target="1"], +.ppt-export-body [data-pptx-capture-strategy="visual-subtree"] * { + visibility: visible !important; +} +.ppt-export-body [data-pptx-capture-strategy="self-decoration"] > *, +.ppt-export-body [data-pptx-capture-strategy="pseudo-only"] > * { + visibility: hidden !important; +} +.ppt-export-body [data-pptx-capture-strategy="pseudo-only"] { + background: none !important; + background-image: none !important; + border-color: transparent !important; + box-shadow: none !important; + filter: none !important; +} +.ppt-export-body [data-pptx-raster-target="1"] :is(p,h1,h2,h3,h4,h5,h6,li,span,a,small,label,code,b,strong,i,em,u,mark,sub,sup), +.ppt-export-body [data-pptx-raster-target="1"]:is(p,h1,h2,h3,h4,h5,h6,li,span,a,small,label,code,b,strong,i,em,u,mark,sub,sup) { color: transparent !important; -webkit-text-fill-color: transparent !important; text-shadow: none !important; } -body[data-pptx-raster="1"] ::marker { +.ppt-export-body [data-pptx-raster-target="1"] ::marker { color: transparent !important; -webkit-text-fill-color: transparent !important; -}`; - const styleTag = ``; - if (/<\/head>/i.test(markup)) { - return markup.replace(/<\/head>/i, `${styleTag}`).replace(/

      ${bodyClone.innerHTML}
      `; +} +function buildRasterFallbackRequests(doc, diagnostics = []) { + const bodyRect = doc.body.getBoundingClientRect(); + const view = doc.defaultView || globalThis.window; + const sourceOrder = buildDomPaintOrderMap(doc); + const grouped = /* @__PURE__ */ new Map(); + diagnostics.forEach((diagnostic) => { + if (!LOCAL_RASTER_CODES.has(diagnostic.code) || !diagnostic.sourceId) return; + const captureStrategy = diagnostic.code === "generated_content" ? "pseudo-only" : ["css_filter", "complex_svg_raster"].includes(diagnostic.code) ? "visual-subtree" : "self-decoration"; + const key = `${diagnostic.sourceId}:${captureStrategy}`; + if (!grouped.has(key)) { + grouped.set(key, { + sourceId: diagnostic.sourceId, + captureStrategy, + diagnostics: [] + }); + } + grouped.get(key).diagnostics.push(diagnostic); + }); + const requests = []; + grouped.forEach(({ sourceId, captureStrategy, diagnostics: sourceDiagnostics }) => { + const element2 = doc.body.dataset?.pptxSourceId === sourceId ? doc.body : doc.body.querySelector( + `[data-pptx-source-id="${escapedAttributeValue(sourceId)}"]` + ); + const failureRequest = (code, reason, details = {}) => ({ + sourceId, + zIndex: details.zIndex ?? 0, + paintOrder: sourceOrder.get(sourceId) ?? requests.length, + subOrder: 0, + kind: "raster", + phase: "local-visual", + canvas: "full-page", + captureStrategy, + suppressedNativeVisualIds: [], + bbox: details.bbox || { x: 0, y: 0, w: 0, h: 0 }, + diagnostics: sourceDiagnostics, + buildFailure: { + code, + stage: "request-build", + reason + } + }); + if (!element2) { + requests.push(failureRequest( + "local_raster_target_missing", + `Raster fallback source "${sourceId}" is not present in the export document.` + )); + return; + } + let rect; + try { + rect = element2.getBoundingClientRect(); + } catch (error2) { + requests.push(failureRequest( + "local_raster_serialize_failed", + `Raster fallback source "${sourceId}" could not be measured: ${String(error2?.message || error2)}`, + { zIndex: rasterLayerZIndex(element2, view) } + )); + return; + } + const bbox = { + x: (rect.left - bodyRect.left) / 96, + y: (rect.top - bodyRect.top) / 96, + w: rect.width / 96, + h: rect.height / 96 + }; + if (!(rect.width > 0) || !(rect.height > 0)) { + requests.push(failureRequest( + "local_raster_unmeasurable", + `Raster fallback source "${sourceId}" has no measurable width or height.`, + { zIndex: rasterLayerZIndex(element2, view), bbox } + )); + return; + } + try { + if (!serializeRasterTargetDocument(doc, { sourceId, captureStrategy })) { + throw new Error("Raster target was not retained in the export document."); + } + } catch (error2) { + requests.push(failureRequest( + "local_raster_serialize_failed", + `Raster fallback source "${sourceId}" could not be serialized: ${String(error2?.message || error2)}`, + { zIndex: rasterLayerZIndex(element2, view), bbox } + )); + return; + } + const suppressedNativeVisualIds = captureStrategy === "pseudo-only" ? [] : captureStrategy === "self-decoration" ? [sourceId] : [element2, ...element2.querySelectorAll("[data-pptx-source-id]")].map((item) => item.dataset?.pptxSourceId).filter(Boolean); + requests.push({ + sourceId, + zIndex: rasterLayerZIndex(element2, view), + paintOrder: sourceOrder.get(sourceId) ?? requests.length, + subOrder: 0, + kind: "raster", + phase: "local-visual", + canvas: "full-page", + captureStrategy, + suppressedNativeVisualIds: [...new Set(suppressedNativeVisualIds)], + bbox, + buildHtml: () => serializeRasterTargetDocument(doc, { sourceId, captureStrategy }), + diagnostics: sourceDiagnostics + }); + }); + return requests.sort((a, b) => a.zIndex - b.zIndex || a.paintOrder - b.paintOrder); +} +function buildPageVisualFallbackRequest(doc, localRequests = []) { + const sourceIds = [...new Set(localRequests.map((request2) => request2.sourceId).filter(Boolean))]; + if (!sourceIds.length) return null; + const targetSpecs = localRequests.map((request2) => ({ + sourceId: request2.sourceId, + captureStrategy: request2.captureStrategy + })); + const request = { + sourceId: "slide-visuals", + sourceIds, + captureStrategy: "page-visual", + suppressedNativeVisualIds: [...new Set( + localRequests.flatMap((request2) => request2.suppressedNativeVisualIds || []) + )], + zIndex: Math.min(...localRequests.map((request2) => request2.zIndex ?? 0)), + paintOrder: Math.min(...localRequests.map((request2) => request2.paintOrder ?? 0)), + subOrder: Math.min(...localRequests.map((request2) => request2.subOrder ?? 0)), + kind: "raster", + phase: "page-visual", + canvas: "full-page", + bbox: { x: 0, y: 0, w: 13.333, h: 7.5 }, + diagnostics: localRequests.flatMap((request2) => request2.diagnostics || []) + }; + const missingSourceIds = localRequests.filter((localRequest) => localRequest.buildFailure?.code === "local_raster_target_missing").map((localRequest) => localRequest.sourceId); + if (missingSourceIds.length) { + return { + ...request, + buildFailure: { + code: "page_visual_target_missing", + stage: "request-build", + reason: `Page-visual fallback cannot cover missing sources: ${missingSourceIds.join(", ")}.` + } + }; + } + try { + if (!serializeRasterTargetDocument(doc, targetSpecs)) { + return { + ...request, + buildFailure: { + code: "page_visual_target_missing", + stage: "request-build", + reason: `Page-visual fallback could not locate any requested sources: ${sourceIds.join(", ")}.` + } + }; + } + return { + ...request, + buildHtml: () => serializeRasterTargetDocument(doc, targetSpecs) + }; + } catch (error2) { + return { + ...request, + buildFailure: { + code: "page_visual_serialize_failed", + stage: "request-build", + reason: `Page-visual fallback could not be serialized: ${String(error2?.message || error2)}` + } + }; + } +} +function buildWholePageVisualFallbackRequest(doc, diagnostics = [], suppressedNativeVisualIds = []) { + const bodySourceId = doc?.body?.dataset?.pptxSourceId; + if (!bodySourceId) { + return { + sourceId: "slide-visuals", + phase: "page-visual", + kind: "raster", + bbox: { x: 0, y: 0, w: 13.333, h: 7.5 }, + diagnostics, + suppressedNativeVisualIds: [...new Set(suppressedNativeVisualIds)], + buildFailure: { + code: "page_visual_target_missing", + stage: "request-build", + reason: "Whole-page visual source is unavailable." + } + }; + } + const request = buildPageVisualFallbackRequest(doc, [{ + sourceId: bodySourceId, + captureStrategy: "visual-subtree", + suppressedNativeVisualIds: [...new Set(suppressedNativeVisualIds)], + zIndex: 0, + paintOrder: 0, + subOrder: 0, + diagnostics + }]); + return { + ...request, + sourceId: "slide-visuals", + sourceIds: [bodySourceId], + captureStrategy: "whole-page-visual" + }; +} +async function renderRasterFallbackLayers(requests, renderRaster, slideIndex) { + const layers = []; + const failures = []; + if (typeof renderRaster !== "function") { + return { layers, failures: [...requests] }; + } + for (const request of requests) { + if (request.buildFailure) { + failures.push({ + ...request, + error: request.buildFailure.reason + }); + continue; + } + try { + const html = typeof request.buildHtml === "function" ? request.buildHtml() : request.html; + if (!html) throw new Error("Raster fallback HTML could not be generated"); + const rendered = await renderRaster(html, slideIndex, { + sourceId: request.sourceId, + bbox: request.bbox, + zIndex: request.zIndex, + paintOrder: request.paintOrder, + subOrder: request.subOrder, + phase: request.phase, + captureStrategy: request.captureStrategy, + suppressedNativeVisualIds: request.suppressedNativeVisualIds || [] + }); + const raw = String(rendered || "").replace(/^data:.*;base64,/, ""); + if (!raw) throw new Error("Raster renderer returned no PNG data"); + layers.push({ + ...request, + buildHtml: void 0, + html: void 0, + data: `data:image/png;base64,${raw}` + }); + } catch (error2) { + failures.push({ ...request, error: String(error2?.message || error2) }); + } } - return `${styleTag}${markup.replace(/ failureDiagnostic("page_visual_raster_failed", failure, slideIndex))); + const fullResult = await renderRasterFallbackLayers( + plan.fullPageRequest ? [plan.fullPageRequest] : [], + renderRaster, + slideIndex + ); + if (fullResult.layers.length) { + return { + layers: [], + fullPageFallback: fullResult.layers[0], + diagnostics: [ + ...diagnostics, + { + severity: "fallback", + code: "full_page_fallback", + message: `Slide ${slideIndex + 1} used a full-page fallback.`, + sourceId: fullResult.layers[0].sourceId, + slideNumber: slideIndex + 1, + phase: "full-page" + } + ], + blocking: false + }; + } + diagnostics.push(...fullResult.failures.map((failure) => failureDiagnostic("full_page_raster_failed", failure, slideIndex, "blocking"))); + return { layers: [], fullPageFallback: null, diagnostics, blocking: true }; + } + const localResult = await renderRasterFallbackLayers( + plan.localRequests || [], + renderRaster, + slideIndex + ); + if (!localResult.failures.length) { + return { + layers: localResult.layers, + fullPageFallback: null, + diagnostics, + blocking: false + }; + } + diagnostics.push(...localResult.failures.map((failure) => failureDiagnostic("local_raster_failed", failure, slideIndex))); + if (plan.pageVisualRequest) { + const pageResult = await renderRasterFallbackLayers( + [plan.pageVisualRequest], + renderRaster, + slideIndex + ); + if (pageResult.layers.length) { + const layer = pageResult.layers[0]; + diagnostics.push({ + severity: "fallback", + code: "page_visual_fallback", + message: `Slide ${slideIndex + 1} used a transparent page visual fallback.`, + sourceId: layer.sourceId, + slideNumber: slideIndex + 1, + phase: "page-visual", + reason: "One or more local visual layers could not be rendered." + }); + return { + layers: [layer], + fullPageFallback: null, + diagnostics, + blocking: false + }; + } + diagnostics.push(...pageResult.failures.map((failure) => failureDiagnostic("page_visual_raster_failed", failure, slideIndex))); + } + if (plan.fullPageRequest) { + const fullResult = await renderRasterFallbackLayers( + [plan.fullPageRequest], + renderRaster, + slideIndex + ); + if (fullResult.layers.length) { + const fullPageFallback = fullResult.layers[0]; + diagnostics.push({ + severity: "fallback", + code: "full_page_fallback", + message: `Slide ${slideIndex + 1} was exported as a full-page PNG fallback.`, + sourceId: fullPageFallback.sourceId, + slideNumber: slideIndex + 1, + phase: "full-page", + reason: "Local and transparent page visual fallback rendering failed." + }); + return { + layers: [], + fullPageFallback, + diagnostics, + blocking: false + }; + } + diagnostics.push(...fullResult.failures.map((failure) => failureDiagnostic("full_page_raster_failed", failure, slideIndex, "blocking"))); + } + return { + layers: [], + fullPageFallback: null, + diagnostics, + blocking: true + }; +} + +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-slide-browser.js +var EXPORT_VIEWPORT = { width: 1280, height: 720 }; +var RASTER_TEXT_TYPES = /* @__PURE__ */ new Set(["p", "h1", "h2", "h3", "h4", "h5", "h6", "text", "list", "merged-text"]); +var EDITABLE_TEXT_TYPES = /* @__PURE__ */ new Set([...RASTER_TEXT_TYPES, "svg-text"]); var exportSessionHost = null; function getExportSessionHost() { if (!exportSessionHost?.isConnected) { @@ -13536,11 +15502,14 @@ function wrapExportDocument(root, body) { body, documentElement: root, defaultView: window, + querySelector: (sel) => root.querySelector(sel), querySelectorAll: (sel) => root.querySelectorAll(sel), createElement: (tag) => document.createElement(tag), + createTreeWalker: (...args) => document.createTreeWalker(...args), getElementById: (id) => root.querySelector(`#${id}`), head: root.querySelector("style")?.parentElement || root, - _exportRoot: root + _exportRoot: root, + _pptxSecurityDiagnostics: body._pptxSecurityDiagnostics || [] }; } function createExportRoot() { @@ -13575,7 +15544,7 @@ async function waitForExportPaint() { }); } function mountMarkupOnRoot(root, markup) { - const parsed = new DOMParser().parseFromString(markup, "text/html"); + const parsed = sanitizeSlideDocument(new DOMParser().parseFromString(markup, "text/html")); root.replaceChildren(); parsed.querySelectorAll("style").forEach((node) => { const style = document.createElement("style"); @@ -13583,6 +15552,7 @@ function mountMarkupOnRoot(root, markup) { root.appendChild(style); }); const body = document.createElement("div"); + body._pptxSecurityDiagnostics = parsed._pptxSecurityDiagnostics || []; body.className = "ppt-export-body"; if (parsed.body) { for (const attr of parsed.body.attributes) { @@ -13613,25 +15583,130 @@ async function loadHtmlInExportRoot(html) { await waitForExportPaint(); return wrapExportDocument(root, body); } +function analyzeMountedSlideForPptx(doc, source = "") { + if (!doc?.body) { + return { + valid: false, + issues: [{ + severity: "blocking", + kind: "blocking", + code: "unreadable_document", + message: "The slide document could not be read.", + sourceId: "slide-document" + }] + }; + } + const issues = [...doc._pptxSecurityDiagnostics || []]; + const seen = new Set(issues.map((item) => `${item.code}:${item.sourceId || ""}`)); + const add = (code, message, element2 = null, severity = "fallback") => { + const sourceId = element2?.dataset?.pptxSourceId || element2?.id || null; + const key = `${code}:${sourceId || ""}`; + if (seen.has(key)) return; + seen.add(key); + issues.push({ + severity, + kind: severity === "blocking" ? "blocking" : void 0, + code, + message, + sourceId, + tag: element2?.tagName?.toLowerCase?.() || null + }); + }; + const body = doc.body; + if (body.querySelector('script,iframe,object,embed,base,meta[http-equiv="refresh" i],foreignObject,maction')) { + add("active_content_residual", "Active content remained after sanitization.", body, "blocking"); + } + if (!String(source || "").trim() || !/<\/html>\s*$/i.test(String(source || "").trim())) { + add("incomplete_html", "The slide document is incomplete.", body, "blocking"); + } + let bodyRect; + try { + bodyRect = body.getBoundingClientRect(); + if (!(bodyRect.width > 0) || !(bodyRect.height > 0)) { + add("unmeasurable_canvas", "The slide canvas could not be measured.", body, "blocking"); + } + } catch { + add("unmeasurable_canvas", "The slide canvas could not be measured.", body, "blocking"); + } + if (bodyRect) { + if (Math.abs(bodyRect.width - EXPORT_VIEWPORT.width) > 2 || Math.abs(bodyRect.height - EXPORT_VIEWPORT.height) > 2) { + add("canvas_size", "The slide canvas size requires page visual fallback.", body); + } + const dimensions = measureBodyDimensions(doc); + if (dimensions.errors?.length) { + add("canvas_overflow", "Slide content exceeds the canvas.", body); + } + const view = doc.defaultView || window; + body.querySelectorAll("p,h1,h2,h3,h4,h5,h6,li").forEach((element2) => { + const rect = element2.getBoundingClientRect(); + if (rect.width <= 0 || rect.height <= 0) return; + if (rect.left < bodyRect.left - 1 || rect.top < bodyRect.top - 1 || rect.right > bodyRect.right + 1 || rect.bottom > bodyRect.bottom + 1) { + add("text_out_of_bounds", "Text extends outside the slide canvas.", element2); + } + const computed = view.getComputedStyle(element2); + if (parseFloat(computed.fontSize || 0) > 12 && rect.bottom > bodyRect.bottom - 48) { + add("bottom_safety_margin", "Text enters the bottom safety margin.", element2); + } + }); + } + return { valid: issues.length === 0, issues: issues.slice(0, 32) }; +} async function prepareSlideOnce(html, aggressive, options = {}) { let exportRoot = null; try { const doc = await loadHtmlInExportRoot(html); exportRoot = doc._exportRoot; - sanitizeSlideDocumentRoot(doc, aggressive); + const repairResult = sanitizeSlideDocumentRoot(doc, aggressive); await waitForExportPaint(); const bodyDimensions = measureBodyDimensions(doc); const slideData = extractSlideDataFromDocument(doc); + const analysis = analyzeMountedSlideForPptx(doc, html); + const mergedDiagnostics = [ + ...analysis.issues || [], + ...repairResult?.diagnostics || [], + ...slideData.diagnostics || [] + ]; + const diagnosticKeys = /* @__PURE__ */ new Set(); + const diagnostics = mergedDiagnostics.filter((diagnostic) => { + const key = `${diagnostic.severity}:${diagnostic.code}:${diagnostic.sourceId || ""}`; + if (diagnosticKeys.has(key)) return false; + diagnosticKeys.add(key); + return true; + }); + slideData.diagnostics = diagnostics; + const rasterRequests = buildRasterFallbackRequests(doc, diagnostics); + const pageFallbackCodes = /* @__PURE__ */ new Set([ + "canvas_size", + "canvas_overflow", + "text_out_of_bounds", + "bottom_safety_margin" + ]); + const pageFallbackDiagnostics = diagnostics.filter((item) => pageFallbackCodes.has(item.code)); + const nativeVisualSourceIds = [...new Set( + (slideData.elements || []).filter((element2) => !EDITABLE_TEXT_TYPES.has(element2.type)).map((element2) => element2.sourceId).filter(Boolean) + )]; + const pageVisualRequest = pageFallbackDiagnostics.length ? buildWholePageVisualFallbackRequest( + doc, + pageFallbackDiagnostics, + nativeVisualSourceIds + ) : buildPageVisualFallbackRequest(doc, rasterRequests); const overflowWarnings = bodyDimensions.errors || []; - if (overflowWarnings.length) { - console.warn("[ppt-live-export] slide overflows canvas; exporting anyway:", overflowWarnings.join("; ")); - } const safeBodyDimensions = { ...bodyDimensions, errors: [] }; - const errors = slideData.errors || []; - if (!errors.length || options.allowValidationErrors) { - return { slideData, bodyDimensions: safeBodyDimensions, aggressive, warnings: overflowWarnings }; + const blocking = diagnostics.filter((diagnostic) => diagnostic.severity === "blocking"); + if (!blocking.length || options.allowValidationErrors) { + return { + slideData, + bodyDimensions: safeBodyDimensions, + diagnostics, + rasterRequests, + pageVisualRequest, + aggressive, + warnings: overflowWarnings + }; } - return { error: new Error(errors.join("\n")) }; + const error2 = new Error(blocking.map((diagnostic) => diagnostic.message).join("\n")); + error2.diagnostics = blocking; + return { error: error2 }; } finally { if (exportRoot) removeExportRoot(exportRoot); } @@ -13649,27 +15724,45 @@ async function prepareSlidesForPptxExport(slides, options = {}) { for (const [index, slide] of slides.entries()) { if (!slide?.html) continue; const item = await prepareSlideForPptxExport(slide.html, options); - let rasterBase64 = null; - const vectorTextCount = countVectorTextElements(item.slideData); - const rasterOnly = vectorTextCount === 0; - if (typeof options.renderRaster === "function") { - try { - if (typeof options.onRasterProgress === "function") { - options.onRasterProgress(index, slide); - } - const rasterHtml = rasterOnly ? slideExportHtml(slide) : slideHtmlForRasterBackdrop(slide.html); - rasterBase64 = await options.renderRaster(rasterHtml, index); - } catch { - rasterBase64 = null; - } + if (item.rasterRequests?.length && typeof options.onRasterProgress === "function") { + options.onRasterProgress(index, slide); + } + const rasterResult = await renderRasterFallbackPlan({ + localRequests: item.rasterRequests || [], + pageVisualRequest: item.pageVisualRequest, + fullPageRequest: { + sourceId: `slide-${index + 1}`, + zIndex: 0, + paintOrder: 0, + kind: "raster", + phase: "full-page", + bbox: { x: 0, y: 0, w: 13.333, h: 7.5 }, + buildHtml: () => slideExportHtml(slide), + diagnostics: [] + } + }, options.renderRaster, index); + if (rasterResult.blocking) { + const error2 = new Error( + rasterResult.diagnostics.map((diagnostic) => diagnostic.message).join("\n") || `Slide ${index + 1} fallback rendering failed` + ); + error2.diagnostics = rasterResult.diagnostics; + throw error2; } + item.slideData.fallbackLayers = [ + ...item.slideData.fallbackLayers || [], + ...rasterResult.layers + ]; + item.slideData.fullPageFallback = rasterResult.fullPageFallback; + item.slideData.diagnostics = [ + ...item.slideData.diagnostics || [], + ...rasterResult.diagnostics + ]; prepared.push({ index, slideId: slide.id, notes: slide, ...item, - rasterBase64, - rasterOnly: Boolean(rasterBase64 && rasterOnly) + fallbackDiagnostics: rasterResult.diagnostics }); } return prepared; @@ -13677,53 +15770,12 @@ async function prepareSlidesForPptxExport(slides, options = {}) { clearExportSessionHost(); } } -function buildElementSlideHtml(slide = {}) { - const theme = slide.theme || {}; - const title = String(slide.title || "Slide").replace(/[<>&]/g, (ch) => ({ - "<": "<", - ">": ">", - "&": "&" - })[ch] || ch); - const subtitle = String(slide.subtitle || slide.claim || "").replace(/[<>&]/g, (ch) => ({ - "<": "<", - ">": ">", - "&": "&" - })[ch] || ch); - const background = theme.background || "#ffffff"; - const ink = theme.ink || "#111111"; - const muted = theme.muted || "#666666"; - return ` - - - - - - -

      ${title}

      - ${subtitle ? `

      ${subtitle}

      ` : ""} - -`; -} function slideExportHtml(slide) { - if (slide?.html) return normalizeSlideDocument(slide.html); - return buildElementSlideHtml(slide); + if (slide?.html) return sanitizeSlideMarkup(normalizeSlideDocument(slide.html)); + return sanitizeSlideMarkup(buildElementSlideHtml(slide)); } -// ../../../../../../../../../../../../node_modules/tslib/tslib.es6.js +// ../../../node_modules/tslib/tslib.es6.js var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -13864,7 +15916,7 @@ function __spreadArrays() { return r; } -// ../../../../../../../../../../../../node_modules/pdf-lib/es/utils/base64.js +// ../../../node_modules/pdf-lib/es/utils/base64.js var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var lookup = new Uint8Array(256); for (i = 0; i < chars.length; i++) { @@ -13926,7 +15978,7 @@ var decodeFromBase64DataUri = function(dataUri) { return decodeFromBase64(data); }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/utils/strings.js +// ../../../node_modules/pdf-lib/es/utils/strings.js var toCharCode = function(character) { return character.charCodeAt(0); }; @@ -14064,7 +16116,7 @@ var findLastMatch = function(value2, regex) { return { match: lastMatch, pos: position }; }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/utils/arrays.js +// ../../../node_modules/pdf-lib/es/utils/arrays.js var last = function(array) { return array[array.length - 1]; }; @@ -14185,7 +16237,7 @@ var toUint8Array = function(input) { } }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/utils/async.js +// ../../../node_modules/pdf-lib/es/utils/async.js var waitForTick = function() { return new Promise(function(resolve) { setTimeout(function() { @@ -14194,7 +16246,7 @@ var waitForTick = function() { }); }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/utils/unicode.js +// ../../../node_modules/pdf-lib/es/utils/unicode.js var utf16Encode = function(input, byteOrderMark) { if (byteOrderMark === void 0) { byteOrderMark = true; @@ -14292,7 +16344,7 @@ var hasUtf16BOM = function(bytes) { return hasUtf16BigEndianBOM(bytes) || hasUtf16LittleEndianBOM(bytes); }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/utils/numbers.js +// ../../../node_modules/pdf-lib/es/utils/numbers.js var numberToString = function(num) { var numStr = String(num); if (Math.abs(num) < 1) { @@ -14327,12 +16379,12 @@ var bytesFor = function(n) { return bytes; }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/utils/errors.js +// ../../../node_modules/pdf-lib/es/utils/errors.js var error = function(msg) { throw new Error(msg); }; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/utils.js +// ../../../node_modules/@pdf-lib/standard-fonts/es/utils.js var import_pako = __toESM(require_pako()); var chars2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var lookup2 = new Uint8Array(256); @@ -14385,49 +16437,49 @@ var padStart2 = function(value2, length, padChar) { return padding + value2; }; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Courier-Bold.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/Courier-Bold.compressed.json var Courier_Bold_compressed_default = "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"; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Courier-BoldOblique.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/Courier-BoldOblique.compressed.json var Courier_BoldOblique_compressed_default = "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"; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Courier-Oblique.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/Courier-Oblique.compressed.json var Courier_Oblique_compressed_default = "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"; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Courier.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/Courier.compressed.json var Courier_compressed_default = "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"; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Helvetica-Bold.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/Helvetica-Bold.compressed.json var Helvetica_Bold_compressed_default = "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"; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Helvetica-BoldOblique.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/Helvetica-BoldOblique.compressed.json var Helvetica_BoldOblique_compressed_default = "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"; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Helvetica-Oblique.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/Helvetica-Oblique.compressed.json var Helvetica_Oblique_compressed_default = "eJyNnVtzG8mxrf+KAk/nRGh8eBWleZPnItsaD0dXWNvhB5BsUdgC0TLAFgjt2P/9AI2uzJUrV7X8olB/q4CuyspaVX0p8H8mP7V3d83yfvLj5P3fu/Xstnl0fPbsydGjJ89Oz55MHk9+bZf3v8/uml2BvzSLr839/Hr2w+XVYv7vrtnL3WLB8iOQZ3fzxZYL7IRpM7/9tD/r35ubeXe3I3+9ny3m18+Xt4td2R+OT3Zk/ev8obn5Y35//Wny4/2qax5Pfvo0W82u75vVm2b/6V8e7pvlTXPzur2bLYfa/vnP7cPkx3/+cHxx9PiHk5Pzx8fHx08ePzs9/tfjybtd4dVivmz+aNfz+3m73J/q6AiEt5/m15+XzXo9+fF8x983q3VfbHJ0dPKno6Oj3Ul+b3eN2Dfop/bLdrVvx6P/c/1/Hx0/e3r+eP/vRf/vs/2/z476fy8ePb9pr5pHb7br++Zu/eivy+t29aVdze6bmz89evR8sXj0ev8960evm3Wz+rqjHs35+tHs0f1qdtPczVafH7UfH/02X7b32y/ND7tCi0fPXzyaLW/+X7t6NN99wbq7Ws9v5rPVvFn/aVfZX3anupkvb99cf2r6Xuhr8uZ+95HZ6qaou4I/zb78ZeiUi+Onjyf/KEfnJ6ePJ8/X1/tArwbx58aOfzg5ung8eXN/85fpTnzS//f97r9Pnx566+/N/Wp+vQvnP/9nMv3H5MeTi53w+64i6y+zXRT/9zHh5uF6Mbszfnp+fuD/7tpdtK4WppyfPzkoy+7uat9Nt8us3bSLxWxl/OmuW3r+pVld79O+CE+eXByE2d1OWu+i4zU7OYEa9P3ttTs9Hb5vtmqWi+ZjTaKPlWrM1vtvXH/2ij89Gz616NY5ONe70TrLp/i0/fKpWebiu6bM25vM14vZ+lMO1rdm1WbaLpsM7zei5P2nVSPKfmy7laDzr6Lsev4gYPO1EX3bhJh6OsyXIq2u20UrIrRu7uZRsh5Y7E0g0ebf3WyR8e2q2Q1m0cydD657oynK8dHxkNEzkX7PM/qzoYuSiT9l9HP+4C+Ojo8P6Ff/YInAi/xdf8lx+qu3bG+Xe/S3fMaXuf2/+dgr2fr3fMbfc70u89f/kUu9yt/1On/wTY7E2/zBd/mD7w09Oxt6eppL/SOjD/mM/5WjerWbyz4398E3XNxpcaDy56KpnD0xU7mez6/nq+vuLvdHt3ft9W76gTESDC5Uxj42y+gqp8S1MGAxbnODPuZStxl9ylWeZ/TfuV6fc6lFzksRLeE6wve+iGGfTXqV6yUcXsS+yx/8mrN3k0s9ZLTN6BtU9czzKybCyZOjkpWrSvmYjeaMfTbezxc3TQ7JYa6/aTcizmF69qngvl+meXIclxH3cb8uRKO1z2zV5PFx0a7mgq+byrdcd6vdPH7tATx+dgzDZj3vV66piWXZoofVbTffKXftvV467OX+i78jU+hLz36cCyYWULuVnFwP3Mxub9WcduC4FqMVx77vmlUDY//0whZDs9vV7Iuf7fS8ZNbuUqKBjAuu1DfzarYeifC4utKLBeuAqO+uCYZa7VbY8y/r+VpIu7bef2q7sFg0ty/zfkhu77nV7Kuo7Oy6uxf44OUfF81D1ioj6252vWrFia9WjTrxTXs/uw4jzqX5ricxAG5oOA69srsLut2aWyxSu+XtbNXdLWadOE17u1tnfhZfN1uFxZP1y13IWRee+7Ln9GJg7erm426hF1aGvkKJk6wvQCL3M1zCGZ6c2xnudk7XLfAUdrUxE1PezX7Qr9diAlvEE1tKtZHbiqRtctnd+NxdEe/yXkwxf01d6k4QM9Cn/5g3PjXJTvWvi73nq6NcgzJd3My/ziGh/SOxZr5gFoPDqx0/5Cs99SGbIikGNln3F180TKCp+Sv9fGGoOK53xIzGg3+m0kMdfcCvAtJJ/Jph5xFwEXJSnFg19KI4+HW56SFORa7j68KYB95KHZffVQV8eNRyNJqqr/Rlc+xSqvZt0VghnMkqIUNmsvlr9kQbivN49rOLoc6L9luzvBWZ+zqewq/iRpOzGx0kQvThVZtIVpW2XnNb/fonR85O8/ZTuxKtuqSzexgqbvCG+FmZxChsNpo4Yy1ienLr73Csu36VsxL1pRS0KNY42WoxwbtucT//stiKelEDPclDA88uyqXJbHU/ny1u5h8/5r7a1q3h93geT9ixZPllNM1GZp0sWTpVhueyZoO1jPk9BsgnQ/oivP+2WzHgTTi7BFq1n5slXgiZOa6a2/k6Ln19iMbOhuk4jwtzjm43qsP1iAe7soZcVSLTUmR8XFZS6r9ohJ89K2vX/lZXvBFmcf7l/lOGPyUDNDNXvnV6PLTxvjJvNNXZsTYLPq8tH0ayMgbYr5dpaNitCK6UuUKtR2pTT20aXdcGZR7Hdu7RZQnPmGVd0CzuxQ2f+2DS7ombdsQR6/G960RLKOYWKrnO9LFAofcr1bjCeVpuWPQ+vkvg1S6R1/n73qR8ffas5Kte0b4cnX9/ix3nlxL2WEeZYrIFt4wYJue16ey3WG2Lwy5qn2YLmBrKIN9fmtCtbuuLMZdfxmWTp9p3OrAyFJpag26jmWKDhm5Vvar77o1cIFoGy5qflR682dmEeujRxi4CK9SW1sXyZ+dm5zfza2W0P8cvgoXZ2HL399g/Xt1Kv70ez2ulurdWltDPqyYdLwesB6jOZsQjC8pfatM9O4XdIpYNtQVZXAnYt40OhUoV7kfPtGhv9/29bEW427qZdlkqQ3n3VZWRfDt+RQszuce8kr5LOY/bzZ1lXjS759fG+C/d/nHkvx5PXjar5R+z+Wr/EPmfk+f7h9WTxz+cHv3r8XB0cI+ADvWMaDB1hC/i0cFVAsKGoXAZj3IVcOoN3Loq0MP4Dyg4T1CGkAV2uDsU0GHgIHoVjt7ujo5P/LAELbDQflDe7Q7P/agEAFAIAHAIANASAEAUAFAsAMCGoR1Y7yhI3u+OLuxoGrQP+wYe+WFpEjKoO+AuhLXLydBVkqGTydDlZOiqydCJZOgsFsCGWDj5ujs6s6NNONrGo9IiQFDzgQ6FcHQaopAYp3HqnAdrUV4IRMPWuBy7Rb0UqFJLOZRNzF1oEvWjcd2ZJnOPmkBj3DgN9MJfZYRD3hiPexfk4C8yOIAhsgHjygtMzIZgErmCcW0NJrM/mMAmYUJ0ioLBLgqa5lJoHMbYPUwQFlK0LncYm4nxsZwUtmJSJScrBmNyLSeT1ZgQ/aZgMJ2CNhltBSIPMp6NaPADNCJDFE7jZETO2YiK8kIgMiLj0oiKeilQpZbSiEzMnW4Sdbpx3ekmc6ebQEZknIyo8FcZoREZYyNyQRpRkcGIDJERGVdGZGI2IpPIiIxrIzKZjcgENiITohEVDEZU0DSXQiMyxkZkgjCionW5w9iIjI/lpDAikyo5WTEik2s5mYzIhGhEBYMRFbTJaCsQGZHxbEQYGnSjyCmwUSRfIpHNKcgvapxsKorSq0KRyxofa4i0rlgi50rUKWGiqLMmluHUiSp5WhTJ2IL4qsLR4qLAPkeqNLtQBhwvcrK9KCrviyWyAUadXDCK2gpjGfbDqLIpRjU6Y9DAHgOfVsqjUUaB3TKqwjJDga6SCmyeUfzu0BA2GvWxoVEx1FhmdGgka41q9NeggckGvqnwbY2T50YxG68TtF2k1CEokeUGiQ0XxBeaktmiJK0WClxqWq+6NFnUcx6hSlmEks4hLMEZhBpZK0pkrCC9khRNFTFbatCkoUIJsFOkZKYoKStFPRspqmSjKGkTxRJsoaixgaIW7RMUME+gU1kWjRMx2yZqwjRB7mQ3s2Gi9J0kF2aJaj3JK0aJJUaSPJkkatEiQQGDBLqRdKspWSNK2RiH1qMrGqKQGyc/dM5mWJQXApENGpceWNRLgSq1lNZnYk4JkygfjOtkMJkzwQTyOuNkdIW/yggtzhj7mwvS3IoMzmaIbM248jQTs6GZRG5mXFuZyexjJrCJmRAdrGCwr4KmuRQalzF2LROEZRWtyx3GZmV8LCeFTZlUycmKQZlcy8lkTSZEXyoYTKmgTUZbgciLjGcjKnVFJ3JGAXWBvAgENiOTXihGduSC9COTLxWrVVZakqu5/12jBHBBZ4DrnAKukC+5QMZkwivB0JocsjeBIs3JdHAnZ2RPLih/cjUblGvkUC5oi3KdPcoVNilXoksZB5syNhXl0KgcslO5IqzKxE50IZuVC6PpKuzKtVq6VgzL9Wq6JstyJXqWcTAtYxvBtoqRb7mQjatUDI3LGQXXBTIuENi4THqhGBmXC9K4TL5UrFZZaVyu5kxwjTLBBZ0JrnMmuELG5QIZlwmvBEPjcsjGBYo0LtPBuJyRcbmgjMvVbFyukXG5oI3LdTYuV9i4XInGZRyMy9hUlEPjcsjG5YowLhM70YVsXC6MpqswLtdq6VoxLter6ZqMy5VoXMbBuIxtBNsqRsblQjau1fBDH16FQiiwBZNlGWbDGoQXmZBZFSytahAvM9HVkyZVtNznRaEeL1j3d1G5twsnayqYjGnArxJBUyqILcm4NKRBBTsqhMyoYGVFRctGVBSyoYK1CRWVLahwNqDCo/0MFMxnINNUBo2nILadwoXpDFKXuocNp+CRxBNmUxSdeBWjKWol8ZLJFB4tZqBgMAPZJLLNhKyl4GwsQ7qjsxiiEBonb3HO5lKUFwKRvRiX/lLUS4EqtZQWY2LuapOor43rzjaZe9sE8hnjZDSFv8oIrcYYe40L0myKDG5jiOzGuPIbE7PhmESOY1xbjsnsOSaw6ZgQXadgsJ2CprkUGo8xdh4ThPUUrcsdxuZjfCwnhf2YVMnJigGZXMvJZEEmRA8qGEyooE1GW4HIh4wnI/rzkJvHfuSdYSjED3joHqMlaoAoYKBYrIBZmIANEXJy+F2vxz+cGBl+uqugn6DQqRErNKDyShyVLJiLD8OfixecihdrTh8wgT7y8w49t+7pj2Jn9qi4OKDQR8BTl/e09BEg6wlg1hPAhp4AUizVkXvBz4MNuLZ3gGd+VFoHCKrstATQv9YiN6DSCRA+QxRD4xRI4yqaJuaQmkRxNc7BNYEjbEIMs2GKdeHvcximuRSE3hDF33juBM59Ol/qjn4fYeyOgrg7CufuKFx2RxFFdxSJu6Pw1B1FSN1RBOqOgrk7Bv4+h2GaS2F3FMTdUbjojkHi7hgwdcevQ0889aNyKkAl/oBC6IFDhYCWgAOyWAOzMAMbIgykBNfRzBYU/VFcQfWotACQWE/1PC2lehpXUT2iFVLPaHHUs7Au6klpgaPSW8eOfIXRH8VFTI/iyv+A8pKm52k1c6C27S/guL7pEa1dekbLlj1r41Guc1upYCsr2OaatHKR1Suijm1c7vcorvR/xTEB0V/tx+W5HZkzOSrRRxQW+wfhb8MIO6w+/oYjDFDJT0AhUsAhUkBLpABZPIBZnwEb8hNICZGjWTzKLZjlFswqLZjJFsxyC2aiBTPRgllqwSy3IK60/paXWHvUhY90uZldpU2dbFOX28QXCaCI1naitV1o7cvJ4Tr83I+i/fVIeF3Pk9f1NHpdj+TFYq+QC/asjDpA0fJeDv525kdx7n+J/oYoz/gvyd+Qgr8BjtP/y+BvwGjSfzn4GxzlOreVCraygm2uCfsbKKKO5m+A4trj5QSviV9O0uXwy5TVwJMrv5yk69+XIqtBIVd+OckXvC8nfK27J9uQLduc1ducvcGAcVyQQF9GqhotVOS7p6YxRKoeTlSIRxbJNMhIpfEWVUgPEiijSaUByapIfSqSRwEXyCOWStCQIZXHCMk8pKPcVoXRsMgxT0W+13B2AlK1KVCh8bazVZBKrhFVMBASyEtIVbZCRbLDUAEyG1K171AhtiCS2Y1IjsYUxW1thLFdkZrs47fJcGP52A/tnjKyeDvZlffxcH9ZeWFH/d3VMz+0e3nA8Kad4/ijr1ky/sT41oL1GwYCUOrz38Ke6mNiHIfanmqS3wsGYQk7js+IcYDkjmPSaqEKOscLd+lSLDhyapfuIJV7LRg+Yxw+F2T48NYRMwgf3jsqLU03j5Igwle0WviCzuEr4jbHgsNnXIQvDM4QxKikUJKsAxoKva8qGNwghBBHJQU6yircoUQ16LlUCn0yQhnN1A1VIxwKDNNU6AZj3AEuyNAX+b1gEO6CMNDGOMQmiOAWrRbWoHNAi7jNseAgGk/h2y154W5DfxQvYnsUr9V7JK5re56ua3sar2t7RFevPaOr156Fq9eexGv1y6Hvz/woLjsvc3+78N5m1Muhjz0u/9gdPbGjD9b/l9jNgKDpTsttBD+l3UYYUPFp6AZD1BfGqUOMq14xMXeNSdQ/xrmTTOCeMiF2l2HqM5y/KQzce5XZm1ToR5y7TyOCHsXp/IIQ9a2azEmiXk6P/QYe9k5Cf0dOnR5F6vkoqu6PJXIORJ0SIYqcDVHllIhqzIuoUXKkndwqepwmY/u4VRFImLRt+VRwSJ20nflCcUqi6mZmpVM6BY1zCjadQUYhpXxCibIJJZVLqOdMQpXyCCXOItQ4h1CLGYQK5Q9tWc1x4typb1jNBSBvaMfmaaKQM7SP8yJTypfKLs6sUq6AwplStgRBmhiiHDFOCWJcZYeJOTVMorwwzklhAmeECTEdDFMu4MY+CgNnQWVbH6nQ/7jl7TQi6HncBXdBiPpc7YEjiXq7YO7qeJsDe5wV6niWqf9ZVmnAZXI2cAlKCpY5N1jnFGE9ZgqrlDAkv63GlNMnySqLqBAkEymQU6RAapECGcYKJRrLOd+oBKUdqZx9tocH8s4ZZZwLlGsuqCxzNeeXa5RZLnBOucLZ5ErMI+eUQWHHHkeEs6a2X49lyJSwhe2UGGRH2NZ2wYwyQm5qY42ywDj3f7nchO43RL1vnDrfuOp7E3PXm0Q9b5w73gTudxNitxumXsfbEBQG7vPKTQhSocfxFsRpRNDfeFfighD1tronQRL1dcHc1eWVUOhqQ9TVxqmrjauuNjF3tUnU1ca5q03grjYhdrVh6mp8sZvCwF1dea2bVOhqfOX5NCLoanwL+oIQdbV6B5ok6uqCqav/GHp5eCX9D+xhZKV3kcUXf0HAe2KA7dVfYP6GL0B/xRdgeccXUOlBYLPQMntDBVB8i7BH4sldz9Pjup7GZ3Q9omduPaOHjD0L7wn2JD5w+wP67fipocYyqT+KD5V6VBIUUX583fP00OlA4Ykr4Pj8ukf0PLpn9L7bnrXxKNe5rVSwlRVsc034cSgooo724BNQfDr+B46OIfqvJvgGfH8U34DvkXgDvufpDfiexjfgeyTfgO8VegO+Z/QGfM/CG/CvJ4e3Hk78KLp2j4Qx9zx5ck+jHfdIvsPUK+TRPSvxBxQd+PVgvqd+FF9tfJ0t14V3NoheYy8BEqP8NfUS0DjKX4teAoXG/+vQS8DC+H8d5ojXYXp4PUwDrn2II+g1mf9Ayy1K6H1DlALGVR6YmJPBJMoI4zotTObcMIESxDhlCd5kPiVE+VK5yUwqZI4hSh/jKodMzIlkEmWTcZ1SJnNemcDJZULMsHwf3dA0B+JDLsVZp26aD1J5sgqpZ4hSz7hKPRNz6plEqWdcp57JnHomUOoZp9TDB+ynhCj1Ko/XSYXUM0SpZ1ylnok59Uyi1DOuU89kTj0TOPVMiKmHLxBQhkxzID7kUpx66u2BIqX3/U6kwGk48r6fLiJSUr/vp9VKelbe99Myp6p+30+qmLb6jYaKKlM4lMFEjgKnc1RlUsciIrVjAU7wqFbSPBZKyR7llPJRpsRPL3rILJ3WQvmh9ok0IKpveRwKvJnwPsg3k7QP8g0/6yTMxXmbF+FUPG1xTEL6SGgWfyyI9NFdfuO1bH9I17I9o2vZnqlr2V7I17I9pmvZnvG1bA/5WraH8Vq2R3Qt+3YwsjM/iiPpbbIs4GnMvEVzAiRHx9tgQ8Diu6Nv0XAczWIjZqIH7Br8iaNaB8x0B8xEB/hlOHyviv8sx98uxP2j1+0CfPgtJCN8jqrQiNbaxXlgleY2urnh+hx5CYNXuxFRaFQUPm2/fGr6ennntbFIK5rT1qre6qq3oqf40h0lUX27dsdyucP84t2LrehQNGgl+of2cIGybu7mOTO6WKgTp+lqcet03DoRN37RGSURt051e5eTfxMPt3QoGoOvnA3nww3WpWTaYZ0E9mK9xzqpImRpl3USkj/nfdZJoWClndYsgGenqx/myr3V1Q9L5OO1qx+W2dHT1Q9z8vbCZ6LZyeVNIKs3Ptq/yvRNq/Vvsn8Tqt3LE4FxMhdf9YSBz4sh/hpVyzRDmMA25MJYqNSE4ZqYNUykqcN4LYx5EilKmkmK0IrCaU4xYbSdanYxrZYStXnG9Fpb04xjQiUz0txThJVitRCkqcgFOR8VWUxKRepE8TQ9mTDaBWqiMq3WBbUpy/RaF+TJy5TKqN0ItlWs1nw1q4ULjjC3RSV9Z5TTPBdlHfdYRkU/lkh9EOU8/0U9BzzqHPaophkx3ZQ5kwLPjiM3ZXQRMVPqmzJarcyalZsyWuYZVN+UkeqsGrI8p0aZZ9ao/gcZJWfZWGI8o/KMG+XvJFSafaPKTkv3BaLbyZsG+ovr7clzc5STO5P8/ZDL2ZpKqDk7FuGZO6rjnSJm8aDnuTzIbfWDeV6P8n8QHTnHxxLjCVmd72Op8QjluT/Ko3mZ1wFBXtWV8fDllQHJen0QCqlVQijQVT+aVwxR/g86V64eYonxzq2uJGKp8c4Vq4qoj3rSpqps68p46PKa492w0DjzozhHvsMFBSAxV76jhQPQOCu+CwsEYHTv+x0sBIDEKe7dhF8/ejdJbx6VJwPY1rRDijm1Wu+QYjG3P+2QYs6RyDukWIgxSTukiFN0KjuLwuMRjJPeWSRFitjIziJZIsdO7yySIkexsrNIqjGeemeREimyY5ts4NESBldtshESBba6yUboOahqk42QOKByk43QYjDVJpssUSDrO1DKAziMYdqBwpyip3egsJjjlnagMOeI5R0oLMRYpR0oxClKlZ0b73h7Ql2hgNV2blRkFb6RnRuVEhTM6s6Nis6hrezcqKgU6NEtC6xy2MOWhcQo1HnLQhJUeOWWhaRRSMWWhaRwGNOWhcQpdJU3/J1zuOyPHTxXjMLlAoXLBRUuV3O4XKNwucDhcoXD5UoMl3MKlwkULuMcruEH3J9nQqEqmAJVsApT0XKQikIhKpgDVDiHp/AYnEIpNAOmwAyUwvJ+CMlTPyrhABR/S/R9CgPw9Fui77H5gOi3RN+HZgMLvyX6Hpvr6EVoz4vYcz2KV1wuXMajmAo9Ev3d89TXPY393CN5y6pXqPd7Fm9O9Sh27x75b8T2R3G7QY9KCACFhgBPmxJ6WhoCyKoLzHoM2NBjQEoLHJUr2zMg5TbQeUGxk5ucmHaPB5FOzEYmZrh/AzjnayPytRH5andkHLXxKDejrdS5lXVuc+X4Tgoootp2ywRQHlNwb8Q6BO9JeM91oWe7nI1dJfU6mXpdTj2+mQCKSMpOJGUXknI6uN65H8XXtaboeoDELogpuR7QuAtiGlwPGO3HmILrAYnbH6YTfHVyit4FSLwkOSXvAhpfh5wK7wKFXnyconcBiq84Tie452eK3gUo2vc0eRfwZMJT9C5AZLXT4F3AwgQ7Re9yVJzqqZG9fupHpU2A4jub02RUwNPvA03ZqADHX9qbBqMCRj+XN0Wj8oa1oUCbm6F+CXpKRgU0V07/EvQ0GBWw+EvQUzQqR2ZU3h9dKNDlhqhfOZySIwHNDdE/YjgNjgRMxD/+RuGebMM42ebxvE3j9sNgZMMPZX1AJ0NmDzSBxbvAIOCtX8B2vxeYP6QE6DdtAZY7tYDsGaSzvaU9PbcjmyodxanSOU6VTm2qdMRTpSs+VTqzqdKRTZWG+mXLmTXCHwUCiwuyD8nUsGz+lbIPaGvIaPr7EHwNC5b4A7L4OyuT+xMgw7LMC9FnGtFcf/iGrNLeRrc3PlsDLuLQiDg0Kg78wGzP5mE4zeO46xFtVv4weCV8RyuC0NYa3OoGt6Jh6RkZSD74ANrjMGCio3115wxXd54AXRyhnbCXrmYlnbaSTlhJel4EknKZTrlMRy6DDy0S44akxxZJkM1UDy6Sxg3Ojy6SktrHDy8SZz/F7YWDWaXthcyVvarthSyR0da2F7LMlpu2FzIn8y0cHcoYD0kTyIuNy/Fqqhi0pvHINYF9yYRkTqaQUxuPF9HGacTyMyv+GlXL5OAmsI27MBYqZeiuCVc3sRbH5O8mVOOYnL4IYPeGyPONs/EXoRXfm6YAE0aDpSYD02rxqE0LptfileYHE3iSSE85WRDTRZFwzjBW81s9e5g6YqtpHjGhMpmYXrXdPK2YQrZLjyMV5harB5JKkwGpPJJUModFPpRUYmq8eCypJJ55QIPJBynNPyipKQj1PAuhShMRSnouwhI8HaFGMxJKNCmBhA6MmK0CNZqdUJJGggWEl6DMdoIaOwZqyWRRpPkKJZqywvPqYBziSbb4vkrV0/SFGs9gQftOONU8FmQxlaE+Eu40oaE2Fu40rYEGMxtSmtxQ4vkNtFafI81yqH0voGquQ3kkYLUZD4ukCyIUeeJDjec+9fqE0MQMCCpOgohHZgU9FWKBcedPEyJqlTkRi4xNDnlmRDFODvudwl8tq/ZHm3DkP5feH8X7cz1K9+GKZeL3FrTJaJs/yKcxns81WDCeq6BNRtv8QT6X8Xyu8M4TnDDwTYVvK9/D549irgR0JVQB6EbSrfwGPjlK+dTlJRw4b0GbjLb5g3w64/lc9i4FnMzYRrCt+Cyfz4V8QnsbAU5obCPYVnyWT+hCPiH8zfuTQDaJbNOn+ETib94PCv5Z65OINhlt8wf5VOrPWh+kqx292luLHcUXG/ZkYefsj+KE16P4/B+E+MzqapLekLia4J8YvEIHBySetF2RXwONT9quhDuDQk/aroIXAws/nHgVOudqgk8XrjD+gFJdr3E5dl7I56B/VpG9TnchzgP+nEvq70l7Ns8D/pxLVr4n/bJF+SYTPqvS+tsOU/5k/WV2vQ/h+UD7L85/R+Qoy6TlSMULb0NfbVTEkbY/egjaNmjU2zzQBqo7zTDXByfk0/gNm/ylD7nUNpfiiqo5epB0ahjm2hYOtcWdiPSlD7nUNpfi2qqdiUVSbz2Xqsm3npWIldfLg8gfKuW3lfKpQbVlw6Cry7ZzVrhFtNY4TV+1kSd4kGW3siy3o7ICKapfxqVmgJTaARo2BPBGn+RBl97q0qkxqOXW8LvOQ23Tu87EoQV5+WXoIZfa5lJcY7UiG6T01utQrfzWKwtQYbGEc/Ygym1FOa60XNYNWnr5dKhcfvmUBai1WAc6exDltqIc11quDQ/ax8nhftSpH8VFWI/K3SdA4l2JnqelWk/juxI9ojciekZvRPQsvBHRk/i2x0eIuJPdeFg063V/8+NpgfFDTW4ovZFzQLqh+Y2cA01v5PQ4t5/fyOmZaH8bj3Kd1es3PZcVbHNN9Os3vSLqSK/f9Ch3CP1F7o95CfQkCgM9rJr21xf9Nks/svsjjuwmHqC4hfIglMvslUD0tcbpu52rE4j9oVKgk9V2h2pVnDj+jTnx5+X0X5b7PIyEEz+KfvEZRwKifDnzmUYCUhgJgONVzucwEoDRtcznYSTAUa5zW6lgKyvY5prwSABF1LGNV4mfcSQMKO9a1wK1pbJnvaKKRtd3rFcK5L6q7FfXKkentl9dym1VGA2L7O36ZnRdYLRZlXSo7UTXMiVJZSP6Qb2bDDeI/Sh6Ro/ET5X3HO8CO40/Vd4j+VPlvUI/Vd4z+qnynoWfKr8bbOiwqrlDGwKEtevpMjR2mRu7rDR2KRu7zI1dVhu7FI1disYuU2PjfcJlaPoyN52XigMNj8SPIqIgVB6Ik5jDkR+HE9eBEQ/DSeAQpUfhEUOw8BKfAsFhU5f4gxR+FekoIopd5TeRSMyxy7+IRFzHLv8eEgscu/RzSBFD7MKPIcVAcOzUDYci5d+KOFICx3HslyJkERHTyu9ESLUS38qvRGg5xVr/SIQSMe75JyJUKFMfVH8gYihQbm1DHxii6BtXcTcxR9wkirVxHWWTOb4mcGRNiDHNjwOWeO+fAsERVPf+D9JuvUB3+/eEbtC3w4n9I5tw5NdKbVhFt3kV3cpVdFmccFXSjVHiUCm8MUroIZ9nKxBVtP7wspW3Gs+ExvVOtxqHmqZbjYo/VCqwrXFq0HeeUML6jtukbjVmCdpDtxozfZCn3WpK7Rh92NnyzbmziLn+eHNuqCbenCP0kM+zFYgqXH9c2o7u5meV604yNIGUTVV5qFZlW1eoeSznVlY23rf5FiQL0KZwC5LZgzjZVjGq+8iT5XKx0d/ROz+PqHwNc9vQSDzuaiQRTs2S7W8k7pscSfCdjiSU7Y6Ebc9j5FcZXQtUCUN5VJh5eeyXlCExnkV8k0ve7Bo+u89cVKOpVK+pVK8Z66Wm3kvxj4WRVunBptaDTa0HP2YkOvS2koHxFhirnzKaC1SJ53wsbvN63OaV2MxrsZnXYvPfGYlSn0djsBCo0uDF+BfZX1aL/C4j0cZl5ZzLStIuR+uyrIzvVqDKidux3m3rvdtWejf9mTqSa53fVsLaVpr4RaAyzZDN/DsXXQlUCdCq0jOr0Z4REVtXTrCunGBdtdP16KkVGv1AJ1Clrt1YtnT1bOkq2cLXVSzXsqWrWUWnJ8L9QuMizvubjPx9eUPbXMoWGcyh+SR9yzX6Vonwt0o2fBOzkP7bp4Z52YUXmcfxGzYZwZorv4bWVl5Da+uvoX2Bip6eF+IPvwxtw0foBF/0dw/fUnt3KOo1sbyOdHjcRl9l6pmri+bjffnSw/9/OL8wtXywX+UcZWwrnayFaoqvXOmPuYUJzfJKadEecol1BY+ccD1yQrQ2pX63OkNfHIbZaljFH/tRvC20wrU7IHGTaEUrdqDx1tAqrNOB0R2fFazOgdgL84aGl+JOARwGy7mR3aLtMEhXsFwDgu0B7M0BOLQGSGkMoNIWR/EgdJTzRThI9VzUPjZ4nZPdmurEDpbhYPhWIEO+IcHzAB+C7+QLxt0syQMP+xS83O47z/wgnMt5h83pUig63WWd6rIudRnNniDkvuxyXw5zpYOv2LxtOBhqDsSrOMByRw2GoiEaj8ZpUBpXI9PEPDxNojFqnAeqCTxaTYhD1jCNW7+xicnBtzvPI/ZhbCQmhmGRHaalFDEl5olhygnjlBjwijETNW6LuMhEN0qOfhOjBRTsPlDIMpPoCIajLTgW3mBiNAi7TZ06mK2i8OwXRXFzMKKcAx56Uig6HVVlJOKJJys6VbSvpMedzCuJFG0G7u1TaLaZRNcRt+wHJfytJkJkPekvNTFX1iP/UBNJZD35zzSxwNaT/koTYbIe+iNNp0yD9RTs1mMk5pNhkU+mpXwyJeaTYcoY45QxsCuBiTKNIi4y0Y2S1mNitJ6C3XoKWWYSrcdwtB7HwnpMjNZjL+OnDmbrEX8biT7h7mJEWQ+8M0Ch6HRUlfWIFwZY0amirSe9LcC8kkjReuBVAQrNNpNoPeI9gaKEp9doQFFgG4oqm1FUpSXFIsKYYgG2p6gmk4pysqook2FFkW0rqJSppEULCyIYWeSUo1FUmRpL5HyNOmVtFDk7o8o5GtQql5YViixqfCwU2gpjETLEIIItBr6scbLIKJJRkqjsMhYh0wzil0p6JQMNqrDRoINfRi4tlV8lkiFle62/SKRLfCd12XDH3iLSZUbTO1mweoVIal8rId7WOFlz7fWhg563VoktVeVNhuEjfP02FEqrfuLwDXpv3TpN3sTxGyobLtfiT4knBb9Hemr5hB4RUoXv9LFBWziHo/3fzGUS7wY6Frf6ivg+kandfy1k/+fjn0VSZlrCMENGpdzoHe7gnmZxUA73hb8O0/zBbL7i3A6oTOiA4jvYzvHFa6f2trUjf3vamb8u7qzsY3Zir04bKonw1NoU9Sa3yd+tB6Tb1Mg2xVfnHeemNqKpjWhqG49yndtKBVtZwTbXJL3X7oqoo7/B7ijHnn5vd1PWjed2FN/v24QVoqO4LHSe3gLchAWgI1/1OfOlnrOyvnNiizpDJaGeWJt80bfBhAIUt/FsUkIBT+vbDScU4LjW3YSEAkar2s2QUHCU69xWKtjKCra5JulneFwRdfQf3XEUF9QbTKhD8B8muH3vAYMPKG7fe0jBB56etz1w8AHHTXMPIfjAaPvetriqH9lodmSu6kjsbNmyqzqNe1i20VWd0SacLbqqk7ghZYvT65GhWKDJjaItS9tsq85lo8SOpG2wVUeirbzhaFts1Y9yndV+oi3bqtNcE71daBtt1VncGLQNtmrIly9D9PGBxAkhalN6IMFcNVg9kGCJmp4fSLDA3cEPJBhTHNLSlWIhinJOGqfEdD4SC5GiLuU8Na0Sp5SxJtTi1ApUaaDMYhPrDeF8Nq6T2uRaWzi9jVf6NiU6vDINuY6UIoASZTxKKj6o5xChSlFCiSOBGncsanEMoEKhUr+rkYOlP8DjASUaEkEaD5YYGEHNYwPleizTCEFtJJatpvW2y9GC+mgDecygpIcNlhhpIw8elOpJwUPoW1mvnttRXIN/C+tVQHkN/o3Xq0Bxveo4Ls2/xfWqM1qafyvrVT/KdW4rFWxlBdtck7RedUXU0derjuK1wjeciRhR/dNMlLhonJqJkpT7Ic1EzLm1eSYioRWo0kDZS2omYqlS2Uqn5ZmIBeq+NBMNvNyvUoiaaJz60Llouom56S7lPjSNwmKc220C92ERWoEqDZR9aGK9IdyHxnUfmlxrC/ehcepD/BWkGqamBo36M2oiFKFADkeUc98GnUIWNI5LELmfUWwreCQIss9DgfGGct8HTfd/KDLWVs6DoEEu/Ot//z8nhUqv"; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Helvetica.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/Helvetica.compressed.json var Helvetica_compressed_default = "eJyNnVtzG8mxrf+KAk/nRGh8eBWleZPnItsaj0ZXWNvhB5BsUdgE0TLAFgjt2P/9AI2uzJUrV7X8olB/q4CuyspaVX0p8H8mP7V3d83yfvLj5MPfu/Xspnl0enH05Nmjs6dHz84mjye/tsv732d3za7AX5rF1+Z+fjXb426xUHh2N19shTBt5jef92f5e3M97+525K/3s8X86vnyZrEre7Q7Xv86f2iu/5jfX32e/Hi/6prHk58+z1azq/tm9bbZf/aXh/tmed1cv2nvZsuhbn/+c/sw+fGfPxw/efL4h5OT88fHR0dHj5+dHv/r8eT9rvBqMV82f7Tr+f28XU5+/GEng/Du8/zqdtms15Mfz3f8Q7Na98UmR0cnf9p90e4kv7e7Juyb81P7Zbvat+LR/7n6v4+Onz09f7z/96L/99n+32dH/b8Xj55ft5fNo7fb9X1zt3701+VVu/rSrmb3zfWfHj16vlg8erP/nvWjN826WX3dUQvVo/n60ezR/Wp23dzNVreP2k+Pfpsv2/vtl+aHXaHFo+cvHs2W1/+vXT2a775g3V2u59fz2WrerP+0q+wvu1Ndz5c3b68+N30f9DV5e7/7yGx1XdRdwZ9mX/4ydMnF8dPHk3+Uo/OT08eT5+urfaBXg/hzY8c/nBxdPJ68vb/+y3QnPun/+2H336dPD7319+Z+Nb/ahfOf/zOZ/mPy48nFTvh9V5H1l9kuiv/7mHDzcLWY3Rk/PT8/8H937S5alwtTzs+fHJRld3e576abZdau28VitjL+dNctPf/SrK72SV6EJ08uDsLsbietd9Hxmp2cQA36/vbanZ4O3zdbNctF86km0cdKNWbr/Teub73iT8+GTy26dQ7O1W5szvIpPm+/fG6WufiuKfP2OvP1Yrb+nIP1rVm1mbbLJsP7jSh5/3nViLKf2m4l6PyrKLuePwjYfG1E3zYhpp4O86VIq6t20YoIrZu7eZSsBxZ7E0i0+Xc3W2R8s2p2g1k0899ds+6NpijHR8dDRs9E+j3P6M+GLkom/pTRz/mDvzg6Pj6gX/2DJQIv8nf9Jcfpr96yvV3u0d/yGV/m9v/mY69k69/zGX/P9XqVv/6PXOp1/q43+YNvcyTe5Q++zx/8YOjZ2dDT01zqHxl9zGf8rxzVy91cdtvcB99wcafFgcqfi6Zy9sRM5Wo+v5qvrrq73B/d3rXXu+kHxkgwuFAZ+9gso8ucElfCgMW4zQ36lEvdZPQ5V3me0X/net3mUouclyJawnWE730Rwz6b9CrXSzi8iH2XP/g1Z+8ml3rIaJvRN6jqmedXTISTJ0clK1eV8jEbzRn7bLyfL66bHJLDXH/dbkScw/TsU8F9v0zz5DguI+7Tfl2IRmuf2arJ49OiXc0FXzeVb7nqVrt5/MoDePzsGIbNet6vW1MTy7JFD6ubbr5T7tp7vXTYy/0Xf0em0Jee/TQXTCygdis5uR64nt3cqDntwHEtRiuOfd81qwbG/umFLYZmN6vZFz/b6XnJrN0FRAMZF1ypb+blbD0S4XF1pRcL1gFR7y8ZDrFZLOZf1vO1kHZtvf/cdmGxaG5f5v2Q3N5zq9lXUdnZVXcv8MHLPy2ah6xVRtbd7GrVihNfrhp14uv2fnYVRpxL811PYgDc0HAcemV3l3O7NbdYpHbLm9mqu1vMOnGa9ma3zrwVXzdbhcWT9ctdyFkXnvuyZ3fdOnz56vrTbqEXVoa+QomTrC9AIvczvIIzPDm3M9ztnK5b4CnsamMmprzr/aBfr8UEtogntpRqI7cVSdvksrvxubsi3uW9mGL+mrrUnSBmoE//MW98apKd6l8Xe89XR7kGZbq4nn+dQ0L7R2LNfMEsBodXO37IV3rqQzZFUgxssu4vvmiYQFPzV/r5wlBxXO+IGY0H/0ylhzr6gF8FpJP4NcPOI+Ai5KQ4sWroRXHwq3LTQ5yKXMfXhTEPvJU6Lr+rCvjwqOVoNFVf6cvm2KVU7duisUI4k1VChsxk89fsiTYU5/HsZxdDnRftt2Z5IzL3TTyFX8WNJmc3OkiE6MOrNpGsKm294rb69U+OnJ3m3ed2JVr1is7uYai4wVviZ2USo7DZaOKMtYjpya2/w7Hu+lXOStSXUtCiWONkq8UE77rF/fzLYivqRQ30JA8NPLsolyaz1f18trief/qU+2pbt4bf43k8YceS5ZfRNBuZdbJk6VQZnsuaDdYy5vcYIJ8M6Yvw/ttuxYA34ewSaNXeNku8EDJzXDU383Vc+voQjZ0N03EeF+Yc3W5Uh+sRD3ZlDbmqRKalyPi4rKTUf9EIP3tW1q79ra54I8zi/Mv95wx/SgZoZq586/R4aON9Zd5oqrNjbRZ8Xls+jGRlDLBfL9PQsFsRXClzhVqP1Kae2jS6rg3KPI7t3KPLEp4xy7qgWdyLGz73waTdEzftiCPW43vXiZZQzC1Ucp3pY4FC71eqcYXztNyw6H18l8CrXSKv8/e9Tfn67FnJV72ifTk6//4WO84vJeyxjjLFZAtuGTFMzmvT2W+x2haHXdQ+zxYwNZRBvr80oVvd1hdjLr+MyyZPte90YGUoNLUG3UQzxQYN3ap6VffdW7lAtAyWNT8rPXi9swn10KONXQRWqC2ti+XPzs3Or+dXymh/jl8EC7Ox5e7vsX+8upV+ezOe10p1b60soZ9XTTpeDlgPUJ3NiEcWlL/Upnt2CrtFLBtqC7K4ErBvGx0KlSrcj55p0d7s+3vZinC3dTPtslSG8u6rKiP5ZvyKFmZyj3klfZdyHrebO8u8aHbPr43xX7r948h/PZ68bFbLP2bz1f4h8j8nz/cPqyePfzg9+tfj4ejgHgEd6hnRYOoIX8Sjg6sEhA1D4VU8ylXAqTdw66pAD+M/oOA8QRlCFtjh7lBAh4GD6HU4erc7Oj7xwxK0wEL7QXm/Ozz3oxIAQCEAwCEAQEsAAFEAQLEAABuGdmC9oyD5sDu6sKNp0D7uG3jkh6VJyKDugLsQ1i4nQ1dJhk4mQ5eToasmQyeSobNYABti4eTr7ujMjjbhaBuPSosAQc0HOhTC0WmIQmKcxqlzHqxFeSEQDVvjcuwW9ZVAlVrKoWxi7kKTqB+N6840mXvUBBrjxmmgF/46IxzyxnjcuyAHf5HBAQyRDRhXXmBiNgSTyBWMa2swmf3BBDYJE6JTFAx2UdA0l0LjMMbuYYKwkKJ1ucPYTIyP5aSwFZMqOVkxGJNrOZmsxoToNwWD6RS0yWgrEHmQ8WxEgx+gERmicBonI3LORlSUFwKRERmXRlTUVwJVaimNyMTc6SZRpxvXnW4yd7oJZETGyYgKf50RGpExNiIXpBEVGYzIEBmRcWVEJmYjMomMyLg2IpPZiExgIzIhGlHBYEQFTXMpNCJjbEQmCCMqWpc7jI3I+FhOCiMyqZKTFSMyuZaTyYhMiEZUMBhRQZuMtgKRERnPRoShQTeKnAIbRfIlEtmcgvyixsmmoii9KhR5VeNjDZHWFUvkXIk6JUwUddbEMpw6USVPiyIZWxBfVzhaXBTY50iVZhfKgONFTrYXReV9sUQ2wKiTC0ZRW2Esw34YVTbFqEZnDBrYY+DTSnk0yiiwW0ZVWGYo0FVSgc0zit8dGsJGoz42NCqGGsuMDo1krVGN/ho0MNnANxW+rXHy3Chm43WCtouUOgQlstwgseGC+EJTMluUpNVCgVea1qsuTRb1nEeoUhahpHMIS3AGoUbWihIZK0ivJUVTRcyWGjRpqFAC7BQpmSlKykpRz0aKKtkoStpEsQRbKGpsoKhF+wQFzBPoVJZF40TMtomaME2QO9nNbJgofSfJhVmiWk/yilFiiZEkTyaJWrRIUMAggW4k3WpK1ohSNsah9eiKhijkxskPnbMZFuWFQGSDxqUHFvWVQJVaSuszMaeESZQPxnUymMyZYAJ5nXEyusJfZ4QWZ4z9zQVpbkUGZzNEtmZceZqJ2dBMIjczrq3MZPYxE9jETIgOVjDYV0HTXAqNyxi7lgnCsorW5Q5jszI+lpPCpkyq5GTFoEyu5WSyJhOiLxUMplTQJqOtQORFxrMRlbqiEzmjgLpAXgQCm5FJLxQjO3JB+pHJrxSrVVZakqu5/12jBHBBZ4DrnAKukC+5QMZkwmvB0JocsjeBIs3JdHAnZ2RPLih/cjUblGvkUC5oi3KdPcoVNilXoksZB5syNhXl0KgcslO5IqzKxE50IZuVC6PpKuzKtVq6VgzL9Wq6JstyJXqWcTAtYxvBtoqRb7mQjatUDI3LGQXXBTIuENi4THqhGBmXC9K4TH6lWK2y0rhczZngGmWCCzoTXOdMcIWMywUyLhNeC4bG5ZCNCxRpXKaDcTkj43JBGZer2bhcI+NyQRuX62xcrrBxuRKNyzgYl7GpKIfG5ZCNyxVhXCZ2ogvZuFwYTVdhXK7V0rViXK5X0zUZlyvRuIyDcRnbCLZVjIzLhWxcq+GHPrwKhVBgCybLMsyGNQgvMiGzKlha1SC+ykRXT5pU0XKfF4V6vGDd30Xl3i6crKlgMqYBv04ETakgtiTj0pAGFeyoEDKjgpUVFS0bUVHIhgrWJlRUtqDC2YAKj/YzUDCfgUxTGTSegth2ChemM0hd6h42nIJHEk+YTVF04lWMpqiVxEsmU3i0mIGCwQxkk8g2E7KWgrOxDOmOzmKIQmicvMU5m0tRXghE9mJc+ktRXwlUqaW0GBNzV5tEfW1cd7bJ3NsmkM8YJ6Mp/HVGaDXG2GtckGZTZHAbQ2Q3xpXfmJgNxyRyHOPackxmzzGBTceE6DoFg+0UNM2l0HiMsfOYIKynaF3uMDYf42M5KezHpEpOVgzI5FpOJgsyIXpQwWBCBW0y2gpEPmQ8GdGfh9w89iPvDEMhfsBD9xgtUQNEAQPFYgXMwgRsiJCTw+96Pf7hxMjw010F/QSFTo1YoQGVV+KoZMFcfBj+XLzgVLxYc/qACfSRn3fouXVPfxQ7s0fFxQGFPgKeurynpY8AWU8As54ANvQEkGKpjtwLfh5swLW9Azzzo9I6QFBlpyWA/rUWuQGVToDwGaIYGqdAGlfRNDGH1CSKq3EOrgkcYRNimA1TrAv/kMMwzaUg9IYo/sZzJ3Du0/lSd/T7CGN3FMTdUTh3R+GyO4oouqNI3B2Fp+4oQuqOIlB3FMzdMfAPOQzTXAq7oyDujsJFdwwSd8eAqTt+HXriqR+VUwEq8QcUQg8cKgS0BByQxRqYhRnYEGEgJbiOZrag6I/iCqpHpQWAxHqq52kp1dO4iuoRrZB6RoujnoV1UU9KCxyV3jp25CuM/iguYnoUV/4HlJc0PU+rmQO1bX8Bx/VNj2jt0jNatuxZG49yndtKBVtZwTbXpJWLrF4RdWzjcr9HcaX/K44JiP5qPy7P7cicyVGJPqKw2D8IfxtG2GH18TccYYBKfgIKkQIOkQJaIgXI4gHM+gzYkJ9ASogczeJRbsEst2BWacFMtmCWWzATLZiJFsxSC2a5BXGl9be8xNqjLnyky83sKm3qZJu63Ca+SABFtLYTre1Ca19ODtfh534U7a9Hwut6nryup9HreiQvFnuFXLBnZdQBipb3cvC3Mz+Kc/9L9DdEecZ/Sf6GFPwNcJz+XwZ/A0aT/svB3+Ao17mtVLCVFWxzTdjfQBF1NH8DFNceLyd4Tfxyki6HX6asBp5c+eUkXf++FFkNCrnyy0m+4H054WvdPdmGbNnmrN7m7A0GjOOCBPoyUtVooSLfPTWNIVL1cKJCPLJIpkFGKo23qEJ6kEAZTSoNSFZF6lORPAq4QB6xVIKGDKk8RkjmIR3ltiqMhkWOeSryvYazE5CqTYEKjbedrYJUco2ogoGQQF5CqrIVKpIdhgqQ2ZCqfYcKsQWRzG5EcjSmKG5rI4ztitRkH79NhhvLx35o95SRxdvJrnyIh/vLygs76u+unvmh3csDhjftHMcffc2S8SfGtxas3zAQgFKf/xb2VB8T4zjU9lST/EEwCEvYcXxGjAMkdxyTVgtV0DleuEuXYsGRU7t0B6nca8HwGePwuSDDh7eOmEH48N5RaWm6eZQEEb6i1cIXdA5fEbc5Fhw+4yJ8YXCGIEYlhZJkHdBQ6ENVweAGIYQ4KinQUVbhDiWqQc+lUuiTEcpopm6oGuFQYJimQjcY4w5wQYa+yB8Eg3AXhIE2xiE2QQS3aLWwBp0DWsRtjgUH0XgK327JC3cb+qN4EdujeK3eI3Fd2/N0XdvTeF3bI7p67RldvfYsXL32JF6rvxr6/syP4rLzVe5vFz7YjPpq6GOPyz92R0/s6KP1/yvsZkDQdKflNoKf0m4jDKj4NHSDIeoL49QhxlWvmJi7xiTqH+PcSSZwT5kQu8sw9RnO3xQG7r3K7E0q9CPO3acRQY/idH5BiPpWTeYkUS+nx34DD3snob8jp06PIvV8FFX3xxI5B6JOiRBFzoaockpENeZF1Cg50k5uFT1Ok7F93KoIJEzatnwqOKRO2s58oTglUXUzs9IpnYLGOQWbziCjkFI+oUTZhJLKJdRzJqFKeYQSZxFqnEOoxQxChfKHtqzmOHHu1Des5gKQN7Rj8zRRyBnax3mRKeVLZRdnVilXQOFMKVuCIE0MUY4YpwQxrrLDxJwaJlFeGOekMIEzwoSYDoYpF3BjH4WBs6CyrY9U6H/c8nYaEfQ87oK7IER9rvbAkUS9XTB3dbzNgT3OCnU8y9T/LKs04DI5G7gEJQXLnBusc4qwHjOFVUoYkt9VY8rpk2SVRVQIkokUyClSILVIgQxjhRKN5ZxvVILSjlTOPtvDA3nnjDLOBco1F1SWuZrzyzXKLBc4p1zhbHIl5pFzyqCwY48jwllT26/HMmRK2MJ2SgyyI2xru2BGGSE3tbFGWWCc+79cbkL3G6LeN06db1z1vYm5602injfOHW8C97sJsdsNU6/jbQgKA/d55SYEqdDjeAviNCLob7wrcUGIelvdkyCJ+rpg7urySih0tSHqauPU1cZVV5uYu9ok6mrj3NUmcFebELvaMHU1vthNYeCurrzWTSp0Nb7yfBoRdDW+BX1BiLpavQNNEnV1wdTVfwy9PLyS/gf2MLLSu8jii78g4D0xwPbqLzB/wxegv+ILsLzjC6j0ILBZaJm9oQIovkXYI/HkrufpcV1P4zO6HtEzt57RQ8aehfcEexIfuP0B/Xb81FBjmdQfxYdKPSoJiig/vu55euh0oPDEFXB8ft0jeh7dM3rfbc/aeJTr3FYq2MoKtrkm/DgUFFFHe/AJKD4d/wNHxxD91xN8A74/im/A90i8Ad/z9AZ8T+Mb8D2Sb8D3Cr0B3zN6A75n4Q34N5PDWw8nfhRdu0fCmHuePLmn0Y57JN9h6hXy6J6V+AOKDvxmMN9TP4qvNr7JluvCextEb7CXAIlR/oZ6CWgc5W9EL4FC4/9N6CVgYfy/CXPEmzA9vBmmAdc+xhH0hsx/oOUWJfS+IUoB4yoPTMzJYBJlhHGdFiZzbphACWKcsgRvMp8Sonyp3GQmFTLHEKWPcZVDJuZEMomyybhOKZM5r0zg5DIhZli+j25omgPxMZfirFM3zQepPFmF1DNEqWdcpZ6JOfVMotQzrlPPZE49Eyj1jFPq4QP2U0KUepXH66RC6hmi1DOuUs/EnHomUeoZ16lnMqeeCZx6JsTUwxcIKEOmORAfcylOPfX2QJHS+34nUuA0HHnfTxcRKanf99NqJT0r7/tpmVNVv+8nVUxb/UZDRZUpHMpgIkeB0zmqMqljEZHasQAneFQraR4LpWSPckr5KFPipxc9ZJZOa6H8WPtEGhDVtzwOBd5OeB/k20naB/mWn3US5uK8zYtwKp62OCYhfSQ0iz8WRProLr/xWrY/pGvZntG1bM/UtWwv5GvZHtO1bM/4WraHfC3bw3gt2yO6ln03GNmZH8WR9C5ZFvA0Zt6hOQGSo+NdsCFg8d3Rd2g4jmaxETPRA3YN/sRRrQNmugNmogP8Mhy+V8V/luNvF+L+0at2AT78DpIRPkdVaERr7eI8sEpzG93ccH2OvITBq92IKDQqCp+3Xz43fb2889pYpBXNaWtVb3XVW9FTfOmOkqi+XbtjudxhfvHuxVZ0KBq0Ev1De7hAWTd385wZXSzUidN0tbh1Om6diBu/6IySiFunur3Lyb+Jh1s6FI3BV86G8+EG61Iy7bBOAnux3mOdVBGytMs6Ccmf8z7rpFCw0k5rFsCz09UPc+Xe6uqHJfLx2tUPy+zo6eqHOXl74TPR7OTyJpDVGx/tX2X6ptX6N9m/CdXu5YnAOJmLr3rCwOfFEH+NqmWaIUxgG3JhLFRqwnBNzBom0tRhvBbGPIkUJc0kRWhF4TSnmDDaTjW7mFZLido8Y3qtrWnGMaGSGWnuKcJKsVoI0lTkgpyPiiwmpSJ1oniankwY7QI1UZlW64LalGV6rQvy5GVKZdRuBNsqVmu+mtXCBUeY26KSvjPKaZ6Lso57LKOiH0ukPohynv+ingMedQ57VNOMmG7KnEmBZ8eRmzK6iJgp9U0ZrVZmzcpNGS3zDKpvykh1Vg1ZnlOjzDNrVP+DjJKzbCwxnlF5xo3ydxIqzb5RZael+wLR7eRNA/3F9fbkuTnKyZ1J/n7I5WxNJdScHYvwzB3V8U4Rs3jQ81we5Lb6wTyvR/k/iI6c42OJ8YSszvex1HiE8twf5dG8zOuAIK/qynj48sqAZL0+CIXUKiEU6KofzSuGKP8HnStXD7HEeOdWVxKx1HjnilVF1Ec9aVNVtnVlPHR5zfF+WGic+VGcI9/jggKQmCvf08IBaJwV34cFAjC69/0eFgJA4hT3fsKvH72fpDePypMBbGvaIcWcWq13SLGY2592SDHnSOQdUizEmKQdUsQpOpWdReHxCMZJ7yySIkVsZGeRLJFjp3cWSZGjWNlZJNUYT72zSIkU2bFNNvBoCYOrNtkIiQJb3WQj9BxUtclGSBxQuclGaDGYapNNliiQ9R0o5QEcxjDtQGFO0dM7UFjMcUs7UJhzxPIOFBZirNIOFOIUpcrOjfe8PaGuUMBqOzcqsgrfyM6NSgkKZnXnRkXn0FZ2blRUCvTolgVWOexhy0JiFOq8ZSEJKrxyy0LSKKRiy0JSOIxpy0LiFLrKG/7OOVz2xw6eK0bhcoHC5YIKl6s5XK5RuFzgcLnC4XIlhss5hcsECpdxDtfwA+7PM6FQFUyBKliFqWg5SEWhEBXMASqcw1N4DE6hFJoBU2AGSmH5MITkqR+VcACKvyX6IYUBePot0Q/YfED0W6IfQrOBhd8S/YDNdfQitOdF7LkexSsuF17Fo5gKPRL93fPU1z2N/dwjecuqV6j3exZvTvUodu8e+W/E9kdxu0GPSggAhYYAT5sSeloaAsiqC8x6DNjQY0BKCxyVK9szIOU20HlBsZObnJh2jweRTsxGJma4fwM452sj8rUR+Wp3ZBy18Sg3o63UuZV1bnPl+E4KKKLadssEUB5TcG/EOgTvSXjPdaFnu5yNXSX1Opl6XU49vpkAikjKTiRlF5JyOrjeuR/F17Wm6HqAxC6IKbke0LgLYhpcDxjtx5iC6wGJ2x+mE3x1coreBUi8JDkl7wIaX4ecCu8ChV58nKJ3AYqvOE4nuOdnit4FKNr3NHkX8GTCU/QuQGS10+BdwMIEO0XvclSc6qmRvX7qR6VNgOI7m9NkVMDT7wNN2agAx1/amwajAkY/lzdFo/KGtaFAm5uhfgl6SkYFNFdO/xL0NBgVsPhL0FM0KkdmVN4fXSjQ5YaoXzmckiMBzQ3RP2I4DY4ETMQ//kbhnmzDONnm8bxN4/bjYGTDD2V9RCdDZg80gcW7wCDgrV/Adr8XmD+kBOg3bQGWO7WA7Bmks72lPT23I5sqHcWp0jlOlU5tqnTEU6UrPlU6s6nSkU2Vhvply5k1wh8FAosLso/J1LBs/pWyj2hryGj6+xh8DQuW+AOy+Dsrk/sTIMOyzAvRZxrRXH/4hqzS3ka3Nz5bAy7i0Ig4NCoO/MBsz+ZhOM3juOsRbVb+OHglfEcrgtDWGtzqBreiYekZGUg++ADa4zBgoqN9decMV3eeAF0coZ2wl65mJZ22kk5YSXpeBJJymU65TEcugw8tEuOGpMcWSZDNVA8uksYNzo8ukpLaxw8vEmc/xe2Fg1ml7YXMlb2q7YUskdHWtheyzJabthcyJ/MtHB3KGA9JE8iLjcvxaqoYtKbxyDWBfcmEZE6mkFMbjxfRxmnE8jMr/hpVy+TgJrCNuzAWKmXorglXN7EWx+TvJlTjmJy+CGD3hsjzjbPxF6EV35umABNGg6UmA9Nq8ahNC6bX4pXmBxN4kkhPOVkQ00WRcM4wVvNbPXuYOmKraR4xoTKZmF613TytmEK2S48jFeYWqweSSpMBqTySVDKHRT6UVGJqvHgsqSSeeUCDyQcpzT8oqSkI9TwLoUoTEUp6LsISPB2hRjMSSjQpgYQOjJitAjWanVCSRoIFhJegzHaCGjsGaslkUaT5CiWassLz6mAc4km2+L5K1dP0hRrPYEH7TjjVPBZkMZWhPhLuNKGhNhbuNK2BBjMbUprcUOL5DbRWnyPNcqh9L6BqrkN5JGC1GQ+LpAsiFHniQ43nPvX6hNDEDAgqToKIR2YFPRVigXHnTxMiapU5EYuMTQ55ZkQxTg77ncJfLav2R5tw5D+X3h/F+3M9SvfhimXi9xa0yWibP8inMZ7PNVgwnqugTUbb/EE+l/F8rvDOE5ww8E2Fbyvfw+ePYq4EdCVUAehG0q38Bj45SvnU5SUcOG9Bm4y2+YN8OuP5XPYuBZzM2Eawrfgsn8+FfEJ7GwFOaGwj2FZ8lk/oQj4h/M37k0A2iWzTp/hE4m/eDwr+WeuTiDYZbfMH+VTqz1ofpMsdvdxbix3FFxv2ZGHn7I/ihNej+PwfhPjM6nKS3pC4nOCfGLxEBwcknrRdkl8DjU/aLoU7g0JP2i6DFwMLP5x4GTrncoJPFy4x/oBSXa9wOXZeyG3Qb1Vkr9JdiPOAb3NJ/T1pz+Z5wLe5ZOV70i9blG8y4VaV1t92mPIn6y+zq30Izwfaf3H+OyJHWSYtRypeeBv6aqMijrT90UPQtkGj3uaBNlDdaYa5Pjghn8Zv2OQvfciltrkUV1TN0YOkU8Mw17ZwqC3uRKQvfciltrkU11btTCySeuu5VE2+9axErLxeHkT+UCm/rZRPDaotGwZdXbads8ItorXGafqqjTzBgyy7lWW5HZUVSFH9Mi41A6TUDtCwIYA3+iQPuvRWl06NQS23ht91Hmqb3nUmDi3Iyy9DD7nUNpfiGqsV2SClt16HauW3XlmACoslnLMHUW4rynGl5bJu0NLLp0Pl8sunLECtxTrQ2YMotxXluNZybXjQPk0O96NO/SguwnpU7j4BEu9K9Dwt1Xoa35XoEb0R0TN6I6Jn4Y2InsS3PT5BxJ3sxsOiWa/7mx9PC4wfanJD6Y2cA9INzW/kHGh6I6fHuf38Rk7PRPvbeJTrrF6/6bmsYJtrol+/6RVRR3r9pke5Q+gvcn/KS6AnURjoYdW0v77ot1n6kd0fcWQ38QDFLZQHoVxmrwSirzVO3+1cnUDsD5UCnay2O1Sr4sTxb8yJPy+n/7Lc7TASTvwo+sUtjgRE+XLmlkYCUhgJgONVzm0YCcDoWuZ2GAlwlOvcVirYygq2uSY8EkARdWzjVeItjoQB5V3rWqC2VPasV1TR6PqO9UqB3FeV/epa5ejU9qtLua0Ko2GRvV3fjK4LjDarkg61nehapiSpbEQ/qHeT4QaxH0XP6JH4qfKe411gp/Gnynskf6q8V+inyntGP1Xes/BT5XeDDR1WNXdoQ4Cwdj1dhsYuc2OXlcYuZWOXubHLamOXorFL0dhlamy8T7gMTV/mpvNScaDhkfhRRBSEygNxEnM48uNw4jow4mE4CRyi9Cg8YggWXuJTIDhs6hJ/kMKvIh1FRLGr/CYSiTl2+ReRiOvY5d9DYoFjl34OKWKIXfgxpBgIjp264VCk/FsRR0rgOI79UoQsImJa+Z0IqVbiW/mVCC2nWOsfiVAixj3/RIQKZeqD6g9EDAXKrW3oA0MUfeMq7ibmiJtEsTauo2wyx9cEjqwJMab5ccAS7/1TIDiC6t7/QdqtF+hu/57QDfp2OLF/ZBOO/FqpDavoNq+iW7mKLosTrkq6MUocKoU3Rgk95PNsBaKK1h9etvJW45nQuN7pVuNQ03SrUfGHSgW2NU4N+s4TSljfcZvUrcYsQXvoVmOmD/K0W02pHaMPO1u+OXcWMdcfb84N1cSbc4Qe8nm2AlGF649L29Hd/Kxy3UmGJpCyqSoP1aps6wo1j+XcysrG+zbfgmQB2hRuQTJ7ECfbKkZ1H3myXC42+jt65+cRla9hbhsaicddjSTCqVmy/Y3EfZMjCb7TkYSy3ZGw7XmM/DKjK4EqYSiPCjMvj/2SMiTGs4ivc8nrXcNn95mLajSV6jWV6jVjvdTUeyn+sTDSKj3Y1HqwqfXgp4xEh95UMjDeAmP1c0ZzgSrxnI/FbV6P27wSm3ktNvNabP47I1HqdjQGC4EqDV6Mf5H9ZbXI7zISbVxWzrmsJO1ytC7LyvhuBaqcuB3r3bbeu22ld9OfqSO51vltJaxtpYlfBCrTDNnMv3PRlUCVAK0qPbMa7RkRsXXlBOvKCdZVO12Pnlqh0Q90AlXq2o1lS1fPlq6SLXxdxXItW7qaVXR6ItwvNC7ivL/JyN+XN7TNpWyRwRyaT9K3XKNvlQh/q2TDNzEL6b99apiXXXiReRy/YZMRrLnya2ht5TW0tv4a2heo6Ol5If7wy9A2fIRO8EV/9/AttXeHol4Ty+tIh8dt9FWmnrm6aD7dly89/P+H8wtTywf7Vc5RxrbSyVqopvjKlf6YW5jQLK+UFu0hl1hX8MgJ1yMnRGtT6nerM/TFYZithlX8sR/F20IrXLsDEjeJVrRiBxpvDa3COh0Y3fFZweociL0wb2h4Ke4UwGGwnBvZLdoOg3QFyzUg2B7A3hyAQ2uAlMYAKm1xFA9CRzlfhINUz0XtY4PXOdmtqU7sYBkOhm8FMuQbEjwP8CH4Tr5g3M2SPPCwT8HL7b7zzA/CuZx32JwuhaLTXdapLutSl9HsCULuyy735TBXOviKzduGg6HmQLyKAyx31GAoGqLxaJwGpXE1Mk3Mw9MkGqPGeaCawKPVhDhkDdO49RubmBx8u/M8Yh/GRmJiGBbZYVpKEVNinhimnDBOiQGvGDNR47aIi0x0o+ToNzFaQMHuA4UsM4mOYDjagmPhDSZGg7Db1KmD2SoKz35RFDcHI8o54KEnhaLTUVVGIp54sqJTRftKetzJvJJI0Wbg3j6FZptJdB1xy35Qwt9qIkTWk/5SE3NlPfIPNZFE1pP/TBMLbD3przQRJuuhP9J0yjRYT8FuPUZiPhkW+WRayidTYj4ZpowxThkDuxKYKNMo4iIT3ShpPSZG6ynYraeQZSbRegxH63EsrMfEaD32Mn7qYLYe8beR6BPuLkaU9cA7AxSKTkdVWY94YYAVnSraetLbAswriRStB14VoNBsM4nWI94TKEp4eo0GFAW2oaiyGUVVWlIsIowpFmB7imoyqSgnq4oyGVYU2baCSplKWrSwIIKRRU45GkWVqbFEzteoU9ZGkbMzqpyjQa1yaVmhyKLGx0KhrTAWIUMMIthi4MsaJ4uMIhklicouYxEyzSB+qaRXMtCgChsNOvhl5NJS+VUiGVK21/qLRLrEd1KXDXfsLSJdZjS9kwWrV4ik9rUS4m2NkzXXXh866HlrldhSVd5kGD7C129DobTqJw7foPfWrdPkTRy/obLhci3+lHhS8Hukp5ZP6BEhVfhOHxu0hXM42v/NXCbxbqBjcauviB8Smdr910L2fz7+WSRlpiUMM2RUyo3e4Q7uaRYH5XBf+OswzR/M5ivO7YDKhA4ovoPtHF+8dmpvWzvyt6ed+evizso+Zif26rShkghPrU1Rb3Kb/N16QLpNjWxTfHXecW5qI5raiKa28SjXua1UsJUVbHNN0nvtrog6+hvsjnLs6fd2N2XdeG5H8f2+TVghOorLQufpLcBNWAA68lWfM1/qOSvrOye2qDNUEuqJtckXfRtMKEBxG88mJRTwtL7dcEIBjmvdTUgoYLSq3QwJBUe5zm2lgq2sYJtrkn6GxxVRR//RHUdxQb3BhDoE/2GC2/ceMPiA4va9hxR84Ol52wMHH3DcNPcQgg+Mtu9ti6v6kY1mR+aqjsTOli27qtO4h2UbXdUZbcLZoqs6iRtStji9HhmKBZrcKNqytM226lw2SuxI2gZbdSTayhuOtsVW/SjXWe0n2rKtOs010duFttFWncWNQdtgq4Z8+TJEHx9InBCiNqUHEsxVg9UDCZao6fmBBAvcHfxAgjHFIS1dKRaiKOekcUpM5yOxECnqUs5T0ypxShlrQi1OrUCVBsosNrHeEM5n4zqpTa61hdPbeKVvU6LDK9OQ60gpAihRxqOk4oN6DhGqFCWUOBKocceiFscAKhQq9bsaOVj6AzweUKIhEaTxYImBEdQ8NlCuxzKNENRGYtlqWm+7HC2ojzaQxwxKethgiZE28uBBqZ4UPIS+lfXquR3FNfi3sF4FlNfg33i9ChTXq47j0vxbXK86o6X5t7Je9aNc57ZSwVZWsM01SetVV0Qdfb3qKF4rfMOZiBHVP81EiYvGqZkoSbkf0kzEnFubZyISWoEqDZS9pGYiliqVrXRanolYoO5LM9HAy/0qhaiJxqkPnYumm5ib7lLuQ9MoLMa53SZwHxahFajSQNmHJtYbwn1oXPehybW2cB8apz7EX0GqYWpq0Kg/oyZCEQrkcEQ5923QKWRB47gEkfsZxbaCR4Ig+zwUGG8o933QdP+HImNt5TwIGuTCv/73/wO+9kRf"; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Times-Bold.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/Times-Bold.compressed.json var Times_Bold_compressed_default = "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"; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Times-BoldItalic.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/Times-BoldItalic.compressed.json var Times_BoldItalic_compressed_default = "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"; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Times-Italic.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/Times-Italic.compressed.json var Times_Italic_compressed_default = "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"; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Times-Roman.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/Times-Roman.compressed.json var Times_Roman_compressed_default = "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"; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Symbol.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/Symbol.compressed.json var Symbol_compressed_default = "eJx9WFlv2zgQ/iuGnnYBt5DkS85bmk13g27SoEkPbNEHWqIlIhSpklSuov99R7JIkSLtFyGZjxzN8c0h/4oueF1jpqKz6Mt1K1GJZ4s4S+PZYrvdbqJ59J4zdYNqDAfuXuodp52spdSToZrQl6n0KyZl1Sm/xgVpa5BcKURJfs5KCgdj+F++J8+4uCUqr6IzJVo8jy4qJFCusLjD3d27BucE0cGYd+/4c3T2/U2SxfM36XYxT+JtDI8k/jGPPrMCC0oYvuWSKMJZdPYmiWMLuK9I/sCwlNHZCuRfsJD9sSiOk7dxnMFbbrgieefGBW9eROfA7I/8z1myzVbz7rnpn9vuCW/unpvZecF3eHb3IhWu5eyK5Vw0XCCFi7ezc0pnvRo5E1hi8QhCeM0lHCoIK+/yCvdR67zrfd2THPA7VfzzNTrbpv2fX+BPeH8fm2usBMnBg++/oq/forO08+QGNMgGgeG/5wfxYrE4iPFzTlFt5JtkkLeMPIL/EFoNreJBE2vrXReako3YcqvVEXCTKWJdzPS7Gizyjk/mZZvsAKC66d7FCgMtF4NC2eaVqpDyLW+QwIzi/TGoD6tvPQL7BJEPNVKVb39DW2mkJnY5FALyD9eEhU6DL4SPrqTaS0mRrHyDXrHgvpQz7AvVU+CkqgQOnN3zVgSkkFVfKslzQIgfMfPFOBxWRiyDjcs5p5wFIoFr4kImprQrP59WP1ubiVpcCgxlNLq5XC4PwM8Wy77EvSs5ZyU0EpuFaXqAzmlTjVlerzcH8TuskH/4oiLj0WQQ/oWpdXadJAfxZSOJ7exmPfD01lYSD8K/kU0288JLS7Mh+hW337dINCPA5MRX8QE1jXU8Wx/E/6J6V4zyLBtCdd36Km4Cso+QTOG4N6T5dvRusxxsu6/scK5Wgw2fKovZ20HxHSnrQDjv0WjEejvw7/MkxmMD6ZQkvnEfa1xayperg/ibZfN2kN1K4lvxHw4lZAfD6QErpy1lOt2QF4H3XATa8HDP7VnrVWY6SoNZQfKWokBRt90Ak7mt2GACwTVE8bNPE+Tw3VTIzkmQqRuLqsvtUGaFw3cTcjzJxSod3tjYSnQgS4fvpgyc8KaDZuLwXR8FtYlv8YPD9rHBuGxfbQYG1q1vL2v9+3zC9nF0EF+BqoLBFBbbjRfSYbsJprLYboxtpx1Fj23esXoMhqlx7rB9uR2OPxP/aCMDmX61/Vhm8cha7HA91bzbWUR1z0/m8tLUKSyJ1qWNHqeXrTUf16lb76Or6XIzTmWFA4mHyeLOkUS3+H23UpJQPAnbE0bUS2CSUi6IdWM13Mhpu/OlBUE1t/YbA1QYCeWLYVsrRh+SeDm0RCQEf9pxa3Xpds4RcpJhqNVDbXPkzqTpOJcK/mT1VO17gUtn57C3J3cpMlUucW77Px3hRwZ83VJFGvriJ6YRHJboLmnWPUNXWAC7FbQg+/0IrjUL4RMFBxhYkEdSBLxiXB0xD8TkEZorywPXoP0I/jxhXGzWKEoJUFgeiTvs3srq2eO9Hq2Aeq92S9eDIgeYwIeawKoVY+KyVOumuBmpY0r+CgrgQVn7ohl9n6aIoc4TJjB0lEDWvmaGa05ETrGfPRd3lm1jI64b9SKtBJlbhAFTgEhuqWoUvlhCFdwRBW613cNWqnGYyDAdj+OQfdnugpBWHUa14jAKbbN2tlDrfR6mXUT9p7F3peyGvHNBb0UCl933GHgmyN6Hc/0R6+KZxiG7Ba6ReJjg6RiAos0DpTRsHWNz1s284Mr58DI+UF52N8B7vyIGzP4+nGJcWLXiNMtiR0/0S0BPtExAj3ZNwE42zh11e6duTZS/YlZaK6DebfrkOsb4aURMnsqiA+viHpPowDrwsoX1y6moRTZ20cMXtmpOgFYf8sGd8kFrRw4ptuCQagu2lJvwmpXEUu2DNSlOoEf12vY4aXOZkG6WY8OC4hzrwHRcjVhWepjd4KdYKK7jrx5H89WjRxPWoycydlS3jZ/I2VS/G9yp9gB6PG1T1aY4YAp3LfPHPPqABbtFRHS/jf34/T82FAfb"; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/ZapfDingbats.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/ZapfDingbats.compressed.json var ZapfDingbats_compressed_default = "eJxtmNtu20YQhl+F4FULyMGeD7pz3AY1ChtG7NpFA18w1NomIlECSRcxgrx7SVk7+wOdG8H5OJydf2Z2d5gf9cV+t0v9VK/r+6vXsXlOlbHe28paq229qj/t++m62aXZ4J/m8PRb1z9/baZxefK63Z6eXN5dVMvTCh83u277xr/6kLrnl2XNq7TpXnczuZyabdee98/b2VzM/x4/dd/T5qab2pd6PQ2vaVVfvDRD005puE3Lu7eH1HbN9hTjx4/77/X6y5lcnUmjVzHIVVDicVX/1W/SsO36dLMfu6nb9/X6TAoBD+5euvZbn8axXtuZ36dhPJrVQqgPQoh5hev91LWLkIv94W1Ygq9+aX+tZAx2tfz64284/sblN/rqfLP/mqrbt3FKu7G67Nv9cNgPzZQ2H6rz7bb6vLgZq89pTMO/M/xfEqturJpqSM/d7GJIm2oamk3aNcO3av80O5xh3yyKmm1193ZIT02bqovTKjP+MAf++7zsZvZ3276kYyWWXB0z99S18/PbafPHQ71W4fjn/fxnFO+ZvkrT0LVzTr78qB/+nk38bHM9exgP8zr1z9U7jt6840YW5uSJKcZOCaBBnKgm5mU8MVNYyMwWFvO7Ukagkmgg6sDWQ5yFFqjzUrLEaQ3BEmiwNsMSaZS0vgWfOkPHWQowNeTUc0kumnxZvsgPxlGai6VTGUqAVCTQ6QkWnc77DKEiLktSUBJKqHIQZ86d8gCpHYoiEzMsb1ubYy8vW50DChB5ZhGqrijD0EqUIeiaEHIfCg5Kpuu0ApiToaGPSY0uaQsyr65L2oKi1yFt1PLaQ3lzfXTgXodGoJYzglndSLDMPg1sTPJpQJHJigw0QrGERqD9YhyTOgONQDUyuF1zaxuokc/BW2ztXCMrGZ9WMW1oQZHIXWNBkSCfRZEL5BMUiZw6CzVSFCfUSGZFNjIldoKDkonTKQiJIGzWmFd3BizJJ9SINoLDriOfUCOZS+zg+KGD1qGiLNMLxtJD1/ns00ON6EzyUCM6vbxhoBKaqbG3DFQCNiL1iHccBPV0DHhQH/JW8EW90dkyFKGywCJU0WkVSvSGeiSUODWFFD0HYdPQVoiRgfPMA+/nnRgiAyNYSjpWNQcNSMrtFCUH4ZIRpSCWocFCSuhCEY6hoUClc0WC52BJlCYYLQdhN+hygRRRlo5BKRRLS6oihSqh+ZzzRGG1Mo4Iz1LoP0qsxDGFzk0JE42ji0jCPejomJKCuwil4m5CiRMEUMVSzVLDUstSx1Juc0oVWMpqY295qVltmtWmWW2a1aZZbZrVplltmtWmWW2G1WZYbYbVZlhthtVmWG2G1WZYbYbVZlhtltVmWW2W1WZZbZbVZlltltVmWW2W1QYjQCh7E2aAQHeGhCFgPoNoy8KNb2wxBhmGKBxoUZXlLGsLI6AsftEDHV0wIURVbANLcTKlGGBIKPOAxCmhePCKUwFzAmpDFRQvjA9R06Hq8TONvshgKDCuRAZTXigUxjxNFfKRo3CLhnIJBMFRvMZpqpNBMlQJzGT5WFQMVQI/AikPMIhEU1aDjqJvQwmjSHB05cC9jbYwc5UtAHNLhDw41ha+lEqF4JaH3gmB61SYcqInxTDmQK8v08vjqv4zDf1N0w3Lf4A8/vwPpfK11w=="; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Font.js +// ../../../node_modules/@pdf-lib/standard-fonts/es/Font.js var compressedJsonForFontName = { "Courier": Courier_compressed_default, "Courier-Bold": Courier_Bold_compressed_default, @@ -14498,10 +16550,10 @@ var Font = ( })() ); -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/all-encodings.compressed.json +// ../../../node_modules/@pdf-lib/standard-fonts/es/all-encodings.compressed.json var all_encodings_compressed_default = "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"; -// ../../../../../../../../../../../../node_modules/@pdf-lib/standard-fonts/es/Encoding.js +// ../../../node_modules/@pdf-lib/standard-fonts/es/Encoding.js var decompressedEncodings = decompressJson(all_encodings_compressed_default); var allUnicodeMappings = JSON.parse(decompressedEncodings); var Encoding = ( @@ -14537,7 +16589,7 @@ var Encodings = { WinAnsi: new Encoding("WinAnsi", allUnicodeMappings.win1252) }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/utils/objects.js +// ../../../node_modules/pdf-lib/es/utils/objects.js var values = function(obj) { return Object.keys(obj).map(function(k) { return obj[k]; @@ -14551,7 +16603,7 @@ var rectanglesAreEqual = function(a, b) { return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height; }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/utils/validators.js +// ../../../node_modules/pdf-lib/es/utils/validators.js var backtick = function(val2) { return "`" + val2 + "`"; }; @@ -14728,7 +16780,7 @@ var assertPositive = function(value2, valueName) { } }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/utils/pdfDocEncoding.js +// ../../../node_modules/pdf-lib/es/utils/pdfDocEncoding.js var pdfDocEncodingToUnicode = new Uint16Array(256); for (idx = 0; idx < 256; idx++) { pdfDocEncodingToUnicode[idx] = idx; @@ -14786,7 +16838,7 @@ var pdfDocEncodingDecode = function(bytes) { return String.fromCodePoint.apply(String, codePoints); }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/utils/Cache.js +// ../../../node_modules/pdf-lib/es/utils/Cache.js var Cache = ( /** @class */ (function() { @@ -14813,7 +16865,7 @@ var Cache = ( ); var Cache_default = Cache; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/errors.js +// ../../../node_modules/pdf-lib/es/core/errors.js var MethodNotImplementedError = ( /** @class */ (function(_super) { @@ -15186,7 +17238,7 @@ var MissingKeywordError = ( })(PDFParsingError) ); -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/syntax/CharCodes.js +// ../../../node_modules/pdf-lib/es/core/syntax/CharCodes.js var CharCodes; (function(CharCodes2) { CharCodes2[CharCodes2["Null"] = 0] = "Null"; @@ -15250,10 +17302,10 @@ var CharCodes; })(CharCodes || (CharCodes = {})); var CharCodes_default = CharCodes; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/PDFContext.js +// ../../../node_modules/pdf-lib/es/core/PDFContext.js var import_pako3 = __toESM(require_pako()); -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/document/PDFHeader.js +// ../../../node_modules/pdf-lib/es/core/document/PDFHeader.js var PDFHeader = ( /** @class */ (function() { @@ -15294,7 +17346,7 @@ var PDFHeader = ( ); var PDFHeader_default = PDFHeader; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/objects/PDFObject.js +// ../../../node_modules/pdf-lib/es/core/objects/PDFObject.js var PDFObject = ( /** @class */ (function() { @@ -15317,7 +17369,7 @@ var PDFObject = ( ); var PDFObject_default = PDFObject; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/objects/PDFNumber.js +// ../../../node_modules/pdf-lib/es/core/objects/PDFNumber.js var PDFNumber = ( /** @class */ (function(_super) { @@ -15355,7 +17407,7 @@ var PDFNumber = ( ); var PDFNumber_default = PDFNumber; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/objects/PDFArray.js +// ../../../node_modules/pdf-lib/es/core/objects/PDFArray.js var PDFArray = ( /** @class */ (function(_super) { @@ -15471,7 +17523,7 @@ var PDFArray = ( ); var PDFArray_default = PDFArray; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/objects/PDFBool.js +// ../../../node_modules/pdf-lib/es/core/objects/PDFBool.js var ENFORCER = {}; var PDFBool = ( /** @class */ @@ -15520,7 +17572,7 @@ var PDFBool = ( ); var PDFBool_default = PDFBool; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/syntax/Delimiters.js +// ../../../node_modules/pdf-lib/es/core/syntax/Delimiters.js var IsDelimiter = new Uint8Array(256); IsDelimiter[CharCodes_default.LeftParen] = 1; IsDelimiter[CharCodes_default.RightParen] = 1; @@ -15533,7 +17585,7 @@ IsDelimiter[CharCodes_default.RightCurly] = 1; IsDelimiter[CharCodes_default.ForwardSlash] = 1; IsDelimiter[CharCodes_default.Percent] = 1; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/syntax/Whitespace.js +// ../../../node_modules/pdf-lib/es/core/syntax/Whitespace.js var IsWhitespace = new Uint8Array(256); IsWhitespace[CharCodes_default.Null] = 1; IsWhitespace[CharCodes_default.Tab] = 1; @@ -15542,7 +17594,7 @@ IsWhitespace[CharCodes_default.FormFeed] = 1; IsWhitespace[CharCodes_default.CarriageReturn] = 1; IsWhitespace[CharCodes_default.Space] = 1; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/syntax/Irregular.js +// ../../../node_modules/pdf-lib/es/core/syntax/Irregular.js var IsIrregular = new Uint8Array(256); for (idx = 0, len = 256; idx < len; idx++) { IsIrregular[idx] = IsWhitespace[idx] || IsDelimiter[idx] ? 1 : 0; @@ -15551,7 +17603,7 @@ var idx; var len; IsIrregular[CharCodes_default.Hash] = 1; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/objects/PDFName.js +// ../../../node_modules/pdf-lib/es/core/objects/PDFName.js var decodeName = function(name) { return name.replace(/#([\dABCDEF]{2})/g, function(_, hex2) { return charFromHexCode(hex2); @@ -15674,7 +17726,7 @@ var PDFName = ( ); var PDFName_default = PDFName; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/objects/PDFNull.js +// ../../../node_modules/pdf-lib/es/core/objects/PDFNull.js var PDFNull = ( /** @class */ (function(_super) { @@ -15706,7 +17758,7 @@ var PDFNull = ( ); var PDFNull_default = new PDFNull(); -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/objects/PDFDict.js +// ../../../node_modules/pdf-lib/es/core/objects/PDFDict.js var PDFDict = ( /** @class */ (function(_super) { @@ -15839,7 +17891,7 @@ var PDFDict = ( ); var PDFDict_default = PDFDict; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/objects/PDFStream.js +// ../../../node_modules/pdf-lib/es/core/objects/PDFStream.js var PDFStream = ( /** @class */ (function(_super) { @@ -15910,7 +17962,7 @@ var PDFStream = ( ); var PDFStream_default = PDFStream; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/objects/PDFRawStream.js +// ../../../node_modules/pdf-lib/es/core/objects/PDFRawStream.js var PDFRawStream = ( /** @class */ (function(_super) { @@ -15943,7 +17995,7 @@ var PDFRawStream = ( ); var PDFRawStream_default = PDFRawStream; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/objects/PDFRef.js +// ../../../node_modules/pdf-lib/es/core/objects/PDFRef.js var ENFORCER3 = {}; var pool2 = /* @__PURE__ */ new Map(); var PDFRef = ( @@ -15990,7 +18042,7 @@ var PDFRef = ( ); var PDFRef_default = PDFRef; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/operators/PDFOperator.js +// ../../../node_modules/pdf-lib/es/core/operators/PDFOperator.js var PDFOperator = ( /** @class */ (function() { @@ -16045,7 +18097,7 @@ var PDFOperator = ( ); var PDFOperator_default = PDFOperator; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/operators/PDFOperatorNames.js +// ../../../node_modules/pdf-lib/es/core/operators/PDFOperatorNames.js var PDFOperatorNames; (function(PDFOperatorNames2) { PDFOperatorNames2["NonStrokingColor"] = "sc"; @@ -16124,7 +18176,7 @@ var PDFOperatorNames; })(PDFOperatorNames || (PDFOperatorNames = {})); var PDFOperatorNames_default = PDFOperatorNames; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/structures/PDFFlateStream.js +// ../../../node_modules/pdf-lib/es/core/structures/PDFFlateStream.js var import_pako2 = __toESM(require_pako()); var PDFFlateStream = ( /** @class */ @@ -16156,7 +18208,7 @@ var PDFFlateStream = ( ); var PDFFlateStream_default = PDFFlateStream; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/structures/PDFContentStream.js +// ../../../node_modules/pdf-lib/es/core/structures/PDFContentStream.js var PDFContentStream = ( /** @class */ (function(_super) { @@ -16219,7 +18271,7 @@ var PDFContentStream = ( ); var PDFContentStream_default = PDFContentStream; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/utils/rng.js +// ../../../node_modules/pdf-lib/es/utils/rng.js var SimpleRNG = ( /** @class */ (function() { @@ -16237,7 +18289,7 @@ var SimpleRNG = ( })() ); -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/PDFContext.js +// ../../../node_modules/pdf-lib/es/core/PDFContext.js var byAscendingObjectNumber = function(_a, _b) { var a = _a[0]; var b = _b[0]; @@ -16412,7 +18464,7 @@ var PDFContext = ( ); var PDFContext_default = PDFContext; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/structures/PDFPageLeaf.js +// ../../../node_modules/pdf-lib/es/core/structures/PDFPageLeaf.js var PDFPageLeaf = ( /** @class */ (function(_super) { @@ -16614,7 +18666,7 @@ var PDFPageLeaf = ( ); var PDFPageLeaf_default = PDFPageLeaf; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/PDFObjectCopier.js +// ../../../node_modules/pdf-lib/es/core/PDFObjectCopier.js var PDFObjectCopier = ( /** @class */ (function() { @@ -16698,7 +18750,7 @@ var PDFObjectCopier = ( ); var PDFObjectCopier_default = PDFObjectCopier; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/document/PDFCrossRefSection.js +// ../../../node_modules/pdf-lib/es/core/document/PDFCrossRefSection.js var PDFCrossRefSection = ( /** @class */ (function() { @@ -16817,7 +18869,7 @@ var PDFCrossRefSection = ( ); var PDFCrossRefSection_default = PDFCrossRefSection; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/document/PDFTrailer.js +// ../../../node_modules/pdf-lib/es/core/document/PDFTrailer.js var PDFTrailer = ( /** @class */ (function() { @@ -16859,7 +18911,7 @@ var PDFTrailer = ( ); var PDFTrailer_default = PDFTrailer; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/document/PDFTrailerDict.js +// ../../../node_modules/pdf-lib/es/core/document/PDFTrailerDict.js var PDFTrailerDict = ( /** @class */ (function() { @@ -16893,7 +18945,7 @@ var PDFTrailerDict = ( ); var PDFTrailerDict_default = PDFTrailerDict; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/structures/PDFObjectStream.js +// ../../../node_modules/pdf-lib/es/core/structures/PDFObjectStream.js var PDFObjectStream = ( /** @class */ (function(_super) { @@ -16967,7 +19019,7 @@ var PDFObjectStream = ( ); var PDFObjectStream_default = PDFObjectStream; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/writers/PDFWriter.js +// ../../../node_modules/pdf-lib/es/core/writers/PDFWriter.js var PDFWriter = ( /** @class */ (function() { @@ -17106,7 +19158,7 @@ var PDFWriter = ( ); var PDFWriter_default = PDFWriter; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/objects/PDFInvalidObject.js +// ../../../node_modules/pdf-lib/es/core/objects/PDFInvalidObject.js var PDFInvalidObject = ( /** @class */ (function(_super) { @@ -17140,7 +19192,7 @@ var PDFInvalidObject = ( ); var PDFInvalidObject_default = PDFInvalidObject; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/structures/PDFCrossRefStream.js +// ../../../node_modules/pdf-lib/es/core/structures/PDFCrossRefStream.js var EntryType; (function(EntryType2) { EntryType2[EntryType2["Deleted"] = 0] = "Deleted"; @@ -17320,7 +19372,7 @@ var PDFCrossRefStream = ( ); var PDFCrossRefStream_default = PDFCrossRefStream; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/writers/PDFStreamWriter.js +// ../../../node_modules/pdf-lib/es/core/writers/PDFStreamWriter.js var PDFStreamWriter = ( /** @class */ (function(_super) { @@ -17425,7 +19477,7 @@ var PDFStreamWriter = ( ); var PDFStreamWriter_default = PDFStreamWriter; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/objects/PDFHexString.js +// ../../../node_modules/pdf-lib/es/core/objects/PDFHexString.js var PDFHexString = ( /** @class */ (function(_super) { @@ -17496,7 +19548,7 @@ var PDFHexString = ( ); var PDFHexString_default = PDFHexString; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/embedders/StandardFontEmbedder.js +// ../../../node_modules/pdf-lib/es/core/embedders/StandardFontEmbedder.js var StandardFontEmbedder = ( /** @class */ (function() { @@ -17579,7 +19631,7 @@ var StandardFontEmbedder = ( ); var StandardFontEmbedder_default = StandardFontEmbedder; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/embedders/CMap.js +// ../../../node_modules/pdf-lib/es/core/embedders/CMap.js var createCmap = function(glyphs, glyphId) { var bfChars = new Array(glyphs.length); for (var idx = 0, len = glyphs.length; idx < len; idx++) { @@ -17619,7 +19671,7 @@ var cmapCodePointFormat = function(codePoint) { throw new Error(msg); }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/embedders/FontFlags.js +// ../../../node_modules/pdf-lib/es/core/embedders/FontFlags.js var makeFontFlags = function(options) { var flags = 0; var flipBit = function(bit) { @@ -17657,7 +19709,7 @@ var deriveFontFlags = function(font) { return flags; }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/objects/PDFString.js +// ../../../node_modules/pdf-lib/es/core/objects/PDFString.js var PDFString = ( /** @class */ (function(_super) { @@ -17767,7 +19819,7 @@ var PDFString = ( ); var PDFString_default = PDFString; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/embedders/CustomFontEmbedder.js +// ../../../node_modules/pdf-lib/es/core/embedders/CustomFontEmbedder.js var CustomFontEmbedder = ( /** @class */ (function() { @@ -17998,7 +20050,7 @@ var CustomFontEmbedder = ( ); var CustomFontEmbedder_default = CustomFontEmbedder; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/embedders/CustomFontSubsetEmbedder.js +// ../../../node_modules/pdf-lib/es/core/embedders/CustomFontSubsetEmbedder.js var CustomFontSubsetEmbedder = ( /** @class */ (function(_super) { @@ -18064,7 +20116,7 @@ var CustomFontSubsetEmbedder = ( ); var CustomFontSubsetEmbedder_default = CustomFontSubsetEmbedder; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/embedders/FileEmbedder.js +// ../../../node_modules/pdf-lib/es/core/embedders/FileEmbedder.js var AFRelationship; (function(AFRelationship2) { AFRelationship2["Source"] = "Source"; @@ -18134,7 +20186,7 @@ var FileEmbedder = ( ); var FileEmbedder_default = FileEmbedder; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/embedders/JpegEmbedder.js +// ../../../node_modules/pdf-lib/es/core/embedders/JpegEmbedder.js var MARKERS = [ 65472, 65473, @@ -18246,7 +20298,7 @@ var JpegEmbedder = ( ); var JpegEmbedder_default = JpegEmbedder; -// ../../../../../../../../../../../../node_modules/@pdf-lib/upng/UPNG.js +// ../../../node_modules/@pdf-lib/upng/UPNG.js var import_pako4 = __toESM(require_pako()); var UPNG = {}; UPNG.toRGBA8 = function(out) { @@ -19602,7 +21654,7 @@ UPNG.encode.concatRGBA = function(bufs) { }; var UPNG_default = UPNG; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/utils/png.js +// ../../../node_modules/pdf-lib/es/utils/png.js var getImageType = function(ctype) { if (ctype === 0) return PngType.Greyscale; @@ -19667,7 +21719,7 @@ var PNG = ( })() ); -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/embedders/PngEmbedder.js +// ../../../node_modules/pdf-lib/es/core/embedders/PngEmbedder.js var PngEmbedder = ( /** @class */ (function() { @@ -19733,7 +21785,7 @@ var PngEmbedder = ( ); var PngEmbedder_default = PngEmbedder; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/streams/Stream.js +// ../../../node_modules/pdf-lib/es/core/streams/Stream.js var Stream = ( /** @class */ (function() { @@ -19834,7 +21886,7 @@ var Stream = ( ); var Stream_default = Stream; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/streams/DecodeStream.js +// ../../../node_modules/pdf-lib/es/core/streams/DecodeStream.js var emptyBuffer = new Uint8Array(0); var DecodeStream = ( /** @class */ @@ -19972,7 +22024,7 @@ var DecodeStream = ( ); var DecodeStream_default = DecodeStream; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/streams/Ascii85Stream.js +// ../../../node_modules/pdf-lib/es/core/streams/Ascii85Stream.js var isSpace = function(ch) { return ch === 32 || ch === 9 || ch === 13 || ch === 10; }; @@ -20047,7 +22099,7 @@ var Ascii85Stream = ( ); var Ascii85Stream_default = Ascii85Stream; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/streams/AsciiHexStream.js +// ../../../node_modules/pdf-lib/es/core/streams/AsciiHexStream.js var AsciiHexStream = ( /** @class */ (function(_super) { @@ -20104,7 +22156,7 @@ var AsciiHexStream = ( ); var AsciiHexStream_default = AsciiHexStream; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/streams/FlateStream.js +// ../../../node_modules/pdf-lib/es/core/streams/FlateStream.js var codeLenCodeMap = new Int32Array([ 16, 17, @@ -20983,7 +23035,7 @@ var FlateStream = ( ); var FlateStream_default = FlateStream; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/streams/LZWStream.js +// ../../../node_modules/pdf-lib/es/core/streams/LZWStream.js var LZWStream = ( /** @class */ (function(_super) { @@ -21106,7 +23158,7 @@ var LZWStream = ( ); var LZWStream_default = LZWStream; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/streams/RunLengthStream.js +// ../../../node_modules/pdf-lib/es/core/streams/RunLengthStream.js var RunLengthStream = ( /** @class */ (function(_super) { @@ -21148,7 +23200,7 @@ var RunLengthStream = ( ); var RunLengthStream_default = RunLengthStream; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/streams/decode.js +// ../../../node_modules/pdf-lib/es/core/streams/decode.js var decodeStream = function(stream2, encoding, params) { if (encoding === PDFName_default.of("FlateDecode")) { return new FlateStream_default(stream2); @@ -21191,7 +23243,7 @@ var decodePDFRawStream = function(_a) { return stream2; }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/embedders/PDFPageEmbedder.js +// ../../../node_modules/pdf-lib/es/core/embedders/PDFPageEmbedder.js var fullPageBoundingBox = function(page) { var mediaBox = page.MediaBox(); var width = mediaBox.lookup(2, PDFNumber_default).asNumber() - mediaBox.lookup(0, PDFNumber_default).asNumber(); @@ -21271,7 +23323,7 @@ var PDFPageEmbedder = ( ); var PDFPageEmbedder_default = PDFPageEmbedder; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/interactive/ViewerPreferences.js +// ../../../node_modules/pdf-lib/es/core/interactive/ViewerPreferences.js var asEnum = function(rawValue, enumType) { if (rawValue === void 0) return void 0; @@ -21505,7 +23557,7 @@ var ViewerPreferences = ( ); var ViewerPreferences_default = ViewerPreferences; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/PDFAcroField.js +// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroField.js var tfRegex = /\/([^\0\t\n\f\r\ ]+)[\0\t\n\f\r\ ]*(\d*\.\d+|\d+)?[\0\t\n\f\r\ ]+Tf/; var PDFAcroField = ( /** @class */ @@ -21636,7 +23688,7 @@ var PDFAcroField = ( ); var PDFAcroField_default = PDFAcroField; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/annotation/BorderStyle.js +// ../../../node_modules/pdf-lib/es/core/annotation/BorderStyle.js var BorderStyle = ( /** @class */ (function() { @@ -21665,7 +23717,7 @@ var BorderStyle = ( ); var BorderStyle_default = BorderStyle; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/annotation/PDFAnnotation.js +// ../../../node_modules/pdf-lib/es/core/annotation/PDFAnnotation.js var PDFAnnotation = ( /** @class */ (function() { @@ -21781,7 +23833,7 @@ var PDFAnnotation = ( ); var PDFAnnotation_default = PDFAnnotation; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/annotation/AppearanceCharacteristics.js +// ../../../node_modules/pdf-lib/es/core/annotation/AppearanceCharacteristics.js var AppearanceCharacteristics = ( /** @class */ (function() { @@ -21898,7 +23950,7 @@ var AppearanceCharacteristics = ( ); var AppearanceCharacteristics_default = AppearanceCharacteristics; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/annotation/PDFWidgetAnnotation.js +// ../../../node_modules/pdf-lib/es/core/annotation/PDFWidgetAnnotation.js var PDFWidgetAnnotation = ( /** @class */ (function(_super) { @@ -22001,7 +24053,7 @@ var PDFWidgetAnnotation = ( ); var PDFWidgetAnnotation_default = PDFWidgetAnnotation; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/PDFAcroTerminal.js +// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroTerminal.js var PDFAcroTerminal = ( /** @class */ (function(_super) { @@ -22057,7 +24109,7 @@ var PDFAcroTerminal = ( ); var PDFAcroTerminal_default = PDFAcroTerminal; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/PDFAcroButton.js +// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroButton.js var PDFAcroButton = ( /** @class */ (function(_super) { @@ -22142,7 +24194,7 @@ var PDFAcroButton = ( ); var PDFAcroButton_default = PDFAcroButton; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/PDFAcroCheckBox.js +// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroCheckBox.js var PDFAcroCheckBox = ( /** @class */ (function(_super) { @@ -22190,7 +24242,7 @@ var PDFAcroCheckBox = ( ); var PDFAcroCheckBox_default = PDFAcroCheckBox; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/flags.js +// ../../../node_modules/pdf-lib/es/core/acroform/flags.js var flag = function(bitIndex) { return 1 << bitIndex; }; @@ -22227,7 +24279,7 @@ var AcroChoiceFlags; AcroChoiceFlags2[AcroChoiceFlags2["CommitOnSelChange"] = flag(27 - 1)] = "CommitOnSelChange"; })(AcroChoiceFlags || (AcroChoiceFlags = {})); -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/PDFAcroChoice.js +// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroChoice.js var PDFAcroChoice = ( /** @class */ (function(_super) { @@ -22344,7 +24396,7 @@ var PDFAcroChoice = ( ); var PDFAcroChoice_default = PDFAcroChoice; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/PDFAcroComboBox.js +// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroComboBox.js var PDFAcroComboBox = ( /** @class */ (function(_super) { @@ -22369,7 +24421,7 @@ var PDFAcroComboBox = ( ); var PDFAcroComboBox_default = PDFAcroComboBox; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/PDFAcroNonTerminal.js +// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroNonTerminal.js var PDFAcroNonTerminal = ( /** @class */ (function(_super) { @@ -22402,7 +24454,7 @@ var PDFAcroNonTerminal = ( ); var PDFAcroNonTerminal_default = PDFAcroNonTerminal; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/PDFAcroSignature.js +// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroSignature.js var PDFAcroSignature = ( /** @class */ (function(_super) { @@ -22418,7 +24470,7 @@ var PDFAcroSignature = ( ); var PDFAcroSignature_default = PDFAcroSignature; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/PDFAcroText.js +// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroText.js var PDFAcroText = ( /** @class */ (function(_super) { @@ -22483,7 +24535,7 @@ var PDFAcroText = ( ); var PDFAcroText_default = PDFAcroText; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/PDFAcroPushButton.js +// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroPushButton.js var PDFAcroPushButton = ( /** @class */ (function(_super) { @@ -22508,7 +24560,7 @@ var PDFAcroPushButton = ( ); var PDFAcroPushButton_default = PDFAcroPushButton; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/PDFAcroRadioButton.js +// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroRadioButton.js var PDFAcroRadioButton = ( /** @class */ (function(_super) { @@ -22562,7 +24614,7 @@ var PDFAcroRadioButton = ( ); var PDFAcroRadioButton_default = PDFAcroRadioButton; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/PDFAcroListBox.js +// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroListBox.js var PDFAcroListBox = ( /** @class */ (function(_super) { @@ -22586,7 +24638,7 @@ var PDFAcroListBox = ( ); var PDFAcroListBox_default = PDFAcroListBox; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/utils.js +// ../../../node_modules/pdf-lib/es/core/acroform/utils.js var createPDFAcroFields = function(kidDicts) { if (!kidDicts) return []; @@ -22673,7 +24725,7 @@ var ascend = function(startNode, visitor) { ascend(Parent, visitor); }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/acroform/PDFAcroForm.js +// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroForm.js var PDFAcroForm = ( /** @class */ (function() { @@ -22749,7 +24801,7 @@ var PDFAcroForm = ( ); var PDFAcroForm_default = PDFAcroForm; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/structures/PDFCatalog.js +// ../../../node_modules/pdf-lib/es/core/structures/PDFCatalog.js var PDFCatalog = ( /** @class */ (function(_super) { @@ -22818,7 +24870,7 @@ var PDFCatalog = ( ); var PDFCatalog_default = PDFCatalog; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/structures/PDFPageTree.js +// ../../../node_modules/pdf-lib/es/core/structures/PDFPageTree.js var PDFPageTree = ( /** @class */ (function(_super) { @@ -22960,7 +25012,7 @@ var PDFPageTree = ( ); var PDFPageTree_default = PDFPageTree; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/syntax/Numeric.js +// ../../../node_modules/pdf-lib/es/core/syntax/Numeric.js var IsDigit = new Uint8Array(256); IsDigit[CharCodes_default.Zero] = 1; IsDigit[CharCodes_default.One] = 1; @@ -22983,7 +25035,7 @@ for (idx = 0, len = 256; idx < len; idx++) { var idx; var len; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/parser/BaseParser.js +// ../../../node_modules/pdf-lib/es/core/parser/BaseParser.js var Newline = CharCodes_default.Newline; var CarriageReturn = CharCodes_default.CarriageReturn; var BaseParser = ( @@ -23086,7 +25138,7 @@ var BaseParser = ( ); var BaseParser_default = BaseParser; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/parser/ByteStream.js +// ../../../node_modules/pdf-lib/es/core/parser/ByteStream.js var ByteStream = ( /** @class */ (function() { @@ -23148,7 +25200,7 @@ var ByteStream = ( ); var ByteStream_default = ByteStream; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/syntax/Keywords.js +// ../../../node_modules/pdf-lib/es/core/syntax/Keywords.js var Space = CharCodes_default.Space; var CarriageReturn2 = CharCodes_default.CarriageReturn; var Newline2 = CharCodes_default.Newline; @@ -23230,7 +25282,7 @@ var Keywords = { EOF3endstream: __spreadArrays([Newline2], endstream) }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/parser/PDFObjectParser.js +// ../../../node_modules/pdf-lib/es/core/parser/PDFObjectParser.js var PDFObjectParser = ( /** @class */ (function(_super) { @@ -23421,7 +25473,7 @@ var PDFObjectParser = ( ); var PDFObjectParser_default = PDFObjectParser; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/parser/PDFObjectStreamParser.js +// ../../../node_modules/pdf-lib/es/core/parser/PDFObjectStreamParser.js var PDFObjectStreamParser = ( /** @class */ (function(_super) { @@ -23493,7 +25545,7 @@ var PDFObjectStreamParser = ( ); var PDFObjectStreamParser_default = PDFObjectStreamParser; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/parser/PDFXRefStreamParser.js +// ../../../node_modules/pdf-lib/es/core/parser/PDFXRefStreamParser.js var PDFXRefStreamParser = ( /** @class */ (function() { @@ -23574,7 +25626,7 @@ var PDFXRefStreamParser = ( ); var PDFXRefStreamParser_default = PDFXRefStreamParser; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/parser/PDFParser.js +// ../../../node_modules/pdf-lib/es/core/parser/PDFParser.js var PDFParser = ( /** @class */ (function(_super) { @@ -23890,7 +25942,7 @@ var PDFParser = ( ); var PDFParser_default = PDFParser; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/annotation/flags.js +// ../../../node_modules/pdf-lib/es/core/annotation/flags.js var flag2 = function(bitIndex) { return 1 << bitIndex; }; @@ -23908,7 +25960,7 @@ var AnnotationFlags; AnnotationFlags2[AnnotationFlags2["LockedContents"] = flag2(10 - 1)] = "LockedContents"; })(AnnotationFlags || (AnnotationFlags = {})); -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/objects.js +// ../../../node_modules/pdf-lib/es/api/objects.js var asPDFName = function(name) { return name instanceof PDFName_default ? name : PDFName_default.of(name); }; @@ -23919,7 +25971,7 @@ var asNumber = function(num) { return num instanceof PDFNumber_default ? num.asNumber() : num; }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/rotations.js +// ../../../node_modules/pdf-lib/es/api/rotations.js var RotationTypes; (function(RotationTypes2) { RotationTypes2["Degrees"] = "degrees"; @@ -23987,7 +26039,7 @@ var rotateRectangle = function(rectangle, borderWidth, degreeAngle) { return { x: x - b, y: y - b, width: w, height: h }; }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/operators.js +// ../../../node_modules/pdf-lib/es/api/operators.js var clip = function() { return PDFOperator_default.of(PDFOperatorNames_default.ClipNonZero); }; @@ -24179,7 +26231,7 @@ var endMarkedContent = function() { return PDFOperator_default.of(PDFOperatorNames_default.EndMarkedContent); }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/colors.js +// ../../../node_modules/pdf-lib/es/api/colors.js var ColorTypes; (function(ColorTypes2) { ColorTypes2["Grayscale"] = "Grayscale"; @@ -24222,7 +26274,7 @@ var colorToComponents = function(color) { return color.type === Grayscale ? [color.gray] : color.type === RGB ? [color.red, color.green, color.blue] : color.type === CMYK ? [color.cyan, color.magenta, color.yellow, color.key] : error("Invalid color: " + JSON.stringify(color)); }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/svgPath.js +// ../../../node_modules/pdf-lib/es/api/svgPath.js var cx = 0; var cy = 0; var px = 0; @@ -24576,7 +26628,7 @@ var svgPathToOperators = function(path) { return apply(parse(path)); }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/operations.js +// ../../../node_modules/pdf-lib/es/api/operations.js var drawLinesOfText = function(lines, options) { var operators = [ pushGraphicsState(), @@ -25002,7 +27054,7 @@ var drawOptionList = function(options) { ]); }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/errors.js +// ../../../node_modules/pdf-lib/es/api/errors.js var EncryptedPDFError = ( /** @class */ (function(_super) { @@ -25189,7 +27241,7 @@ var InvalidMaxLengthError = ( })(Error) ); -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/text/alignment.js +// ../../../node_modules/pdf-lib/es/api/text/alignment.js var TextAlignment; (function(TextAlignment2) { TextAlignment2[TextAlignment2["Left"] = 0] = "Left"; @@ -25197,7 +27249,7 @@ var TextAlignment; TextAlignment2[TextAlignment2["Right"] = 2] = "Right"; })(TextAlignment || (TextAlignment = {})); -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/text/layout.js +// ../../../node_modules/pdf-lib/es/api/text/layout.js var MIN_FONT_SIZE = 4; var MAX_FONT_SIZE = 500; var computeFontSize = function(lines, font, bounds, multiline) { @@ -25390,7 +27442,7 @@ var layoutSinglelineText = function(text2, _a) { }; }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/form/appearances.js +// ../../../node_modules/pdf-lib/es/api/form/appearances.js var normalizeAppearance = function(appearance) { if ("normal" in appearance) return appearance; @@ -25775,7 +27827,7 @@ var defaultOptionListAppearanceProvider = function(optionList, widget, font) { })); }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/PDFEmbeddedPage.js +// ../../../node_modules/pdf-lib/es/api/PDFEmbeddedPage.js var PDFEmbeddedPage = ( /** @class */ (function() { @@ -25825,7 +27877,7 @@ var PDFEmbeddedPage = ( ); var PDFEmbeddedPage_default = PDFEmbeddedPage; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/PDFFont.js +// ../../../node_modules/pdf-lib/es/api/PDFFont.js var PDFFont = ( /** @class */ (function() { @@ -25899,7 +27951,7 @@ var PDFFont = ( ); var PDFFont_default = PDFFont; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/PDFImage.js +// ../../../node_modules/pdf-lib/es/api/PDFImage.js var PDFImage = ( /** @class */ (function() { @@ -25966,7 +28018,7 @@ var PDFImage = ( ); var PDFImage_default = PDFImage; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/image/alignment.js +// ../../../node_modules/pdf-lib/es/api/image/alignment.js var ImageAlignment; (function(ImageAlignment2) { ImageAlignment2[ImageAlignment2["Left"] = 0] = "Left"; @@ -25974,7 +28026,7 @@ var ImageAlignment; ImageAlignment2[ImageAlignment2["Right"] = 2] = "Right"; })(ImageAlignment || (ImageAlignment = {})); -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/form/PDFField.js +// ../../../node_modules/pdf-lib/es/api/form/PDFField.js var assertFieldAppearanceOptions = function(options) { assertOrUndefined(options === null || options === void 0 ? void 0 : options.x, "options.x", ["number"]); assertOrUndefined(options === null || options === void 0 ? void 0 : options.y, "options.y", ["number"]); @@ -26187,7 +28239,7 @@ var PDFField = ( ); var PDFField_default = PDFField; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/form/PDFCheckBox.js +// ../../../node_modules/pdf-lib/es/api/form/PDFCheckBox.js var PDFCheckBox = ( /** @class */ (function(_super) { @@ -26290,7 +28342,7 @@ var PDFCheckBox = ( ); var PDFCheckBox_default = PDFCheckBox; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/form/PDFDropdown.js +// ../../../node_modules/pdf-lib/es/api/form/PDFDropdown.js var PDFDropdown = ( /** @class */ (function(_super) { @@ -26493,7 +28545,7 @@ var PDFDropdown = ( ); var PDFDropdown_default = PDFDropdown; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/form/PDFOptionList.js +// ../../../node_modules/pdf-lib/es/api/form/PDFOptionList.js var PDFOptionList = ( /** @class */ (function(_super) { @@ -26674,7 +28726,7 @@ var PDFOptionList = ( ); var PDFOptionList_default = PDFOptionList; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/form/PDFRadioGroup.js +// ../../../node_modules/pdf-lib/es/api/form/PDFRadioGroup.js var PDFRadioGroup = ( /** @class */ (function(_super) { @@ -26825,7 +28877,7 @@ var PDFRadioGroup = ( ); var PDFRadioGroup_default = PDFRadioGroup; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/form/PDFSignature.js +// ../../../node_modules/pdf-lib/es/api/form/PDFSignature.js var PDFSignature = ( /** @class */ (function(_super) { @@ -26849,7 +28901,7 @@ var PDFSignature = ( ); var PDFSignature_default = PDFSignature; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/form/PDFTextField.js +// ../../../node_modules/pdf-lib/es/api/form/PDFTextField.js var PDFTextField = ( /** @class */ (function(_super) { @@ -27073,7 +29125,7 @@ var PDFTextField = ( ); var PDFTextField_default = PDFTextField; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/StandardFonts.js +// ../../../node_modules/pdf-lib/es/api/StandardFonts.js var StandardFonts; (function(StandardFonts2) { StandardFonts2["Courier"] = "Courier"; @@ -27092,7 +29144,7 @@ var StandardFonts; StandardFonts2["ZapfDingbats"] = "ZapfDingbats"; })(StandardFonts || (StandardFonts = {})); -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/form/PDFForm.js +// ../../../node_modules/pdf-lib/es/api/form/PDFForm.js var PDFForm = ( /** @class */ (function() { @@ -27449,7 +29501,7 @@ var addFieldToParent = function(_a, _b, partialName) { field.setParent(parentRef); }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/sizes.js +// ../../../node_modules/pdf-lib/es/api/sizes.js var PageSizes = { "4A0": [4767.87, 6740.79], "2A0": [3370.39, 4767.87], @@ -27503,7 +29555,7 @@ var PageSizes = { Tabloid: [792, 1224] }; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/PDFDocumentOptions.js +// ../../../node_modules/pdf-lib/es/api/PDFDocumentOptions.js var ParseSpeeds; (function(ParseSpeeds2) { ParseSpeeds2[ParseSpeeds2["Fastest"] = Infinity] = "Fastest"; @@ -27512,7 +29564,7 @@ var ParseSpeeds; ParseSpeeds2[ParseSpeeds2["Slow"] = 100] = "Slow"; })(ParseSpeeds || (ParseSpeeds = {})); -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/PDFEmbeddedFile.js +// ../../../node_modules/pdf-lib/es/api/PDFEmbeddedFile.js var PDFEmbeddedFile = ( /** @class */ (function() { @@ -27570,7 +29622,7 @@ var PDFEmbeddedFile = ( ); var PDFEmbeddedFile_default = PDFEmbeddedFile; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/PDFJavaScript.js +// ../../../node_modules/pdf-lib/es/api/PDFJavaScript.js var PDFJavaScript = ( /** @class */ (function() { @@ -27624,7 +29676,7 @@ var PDFJavaScript = ( ); var PDFJavaScript_default = PDFJavaScript; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/core/embedders/JavaScriptEmbedder.js +// ../../../node_modules/pdf-lib/es/core/embedders/JavaScriptEmbedder.js var JavaScriptEmbedder = ( /** @class */ (function() { @@ -27662,7 +29714,7 @@ var JavaScriptEmbedder = ( ); var JavaScriptEmbedder_default = JavaScriptEmbedder; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/PDFDocument.js +// ../../../node_modules/pdf-lib/es/api/PDFDocument.js var PDFDocument = ( /** @class */ (function() { @@ -28348,7 +30400,7 @@ function assertIsLiteralOrHexString(pdfObject) { } } -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/PDFPageOptions.js +// ../../../node_modules/pdf-lib/es/api/PDFPageOptions.js var BlendMode; (function(BlendMode2) { BlendMode2["Normal"] = "Normal"; @@ -28365,7 +30417,7 @@ var BlendMode; BlendMode2["Exclusion"] = "Exclusion"; })(BlendMode || (BlendMode = {})); -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/PDFPage.js +// ../../../node_modules/pdf-lib/es/api/PDFPage.js var PDFPage = ( /** @class */ (function() { @@ -29017,7 +31069,7 @@ var PDFPage = ( ); var PDFPage_default = PDFPage; -// ../../../../../../../../../../../../node_modules/pdf-lib/es/api/form/PDFButton.js +// ../../../node_modules/pdf-lib/es/api/form/PDFButton.js var PDFButton = ( /** @class */ (function(_super) { @@ -29111,10 +31163,10 @@ var PDFButton = ( ); var PDFButton_default = PDFButton; -// src/export-deck-browser.js +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-deck-browser.js var import_jszip2 = __toESM(require_jszip_min(), 1); -// ../../../../../../../../../node_modules/.pnpm/pptxgenjs@4.0.1/node_modules/pptxgenjs/dist/pptxgen.es.js +// node_modules/.pnpm/pptxgenjs@4.0.1/node_modules/pptxgenjs/dist/pptxgen.es.js var import_jszip = __toESM(require_jszip_min2()); function __awaiter2(thisArg, _arguments, P, generator) { function adopt(value2) { @@ -34434,11 +36486,24 @@ var PptxGenJS = class { } }; -// src/pptx-html-build.js +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/pptx-html-build.js var PX_PER_IN = 96; var EMU_PER_IN = 914400; var SLIDE_W_IN = 13.333; var SLIDE_H_IN = 7.5; +var EDITABLE_TEXT_TYPES2 = /* @__PURE__ */ new Set([ + "p", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "text", + "svg-text", + "list", + "merged-text" +]); var WIDTH_SAFETY_IN = 0.15; function capTextBoxWidth(x, w) { return Math.min(w, Math.max(0.15, SLIDE_W_IN - x - 0.02)); @@ -34516,7 +36581,62 @@ async function addBackground(slideData, targetSlide) { } } function addElements(slideData, targetSlide, pres) { - for (const el of slideData.elements) { + if (slideData.fullPageFallback) { + const payload = toImagePayload( + slideData.fullPageFallback.data || slideData.fullPageFallback.src + ); + if (!payload) throw new Error("Full-page fallback has no image payload"); + targetSlide.addImage({ + ...payload, + x: 0, + y: 0, + w: SLIDE_W_IN, + h: SLIDE_H_IN + }); + return; + } + const suppressedNativeVisualIds = /* @__PURE__ */ new Set([ + ...slideData.suppressedNativeVisualIds || [], + ...(slideData.fallbackLayers || []).flatMap((layer) => layer.suppressedNativeVisualIds || []) + ]); + const paintItems = [ + ...(slideData.elements || []).map((element2, order) => ({ + type: "element", + item: element2, + zIndex: element2.zIndex ?? 0, + order: element2.paintOrder ?? order, + subOrder: element2.subOrder ?? 0, + stableOrder: order + })), + ...(slideData.fallbackLayers || []).map((layer, order) => ({ + type: "fallback", + item: layer, + zIndex: layer.zIndex ?? 0, + order: layer.paintOrder ?? (slideData.elements || []).length + order, + subOrder: layer.subOrder ?? 0, + stableOrder: (slideData.elements || []).length + order + })) + ].sort((a, b) => a.zIndex - b.zIndex || a.order - b.order || a.subOrder - b.subOrder || a.stableOrder - b.stableOrder); + for (const paintItem of paintItems) { + if (paintItem.type === "fallback") { + const layer = paintItem.item; + const payload = toImagePayload(layer.data || layer.src); + const bbox = layer.bbox || {}; + if (!payload) continue; + const fullPageCanvas = layer.canvas === "full-page"; + targetSlide.addImage({ + ...payload, + x: fullPageCanvas ? 0 : bbox.x ?? 0, + y: fullPageCanvas ? 0 : bbox.y ?? 0, + w: fullPageCanvas ? SLIDE_W_IN : bbox.w ?? SLIDE_W_IN, + h: fullPageCanvas ? SLIDE_H_IN : bbox.h ?? SLIDE_H_IN + }); + continue; + } + const el = paintItem.item; + if (suppressedNativeVisualIds.has(el.sourceId) && !EDITABLE_TEXT_TYPES2.has(el.type)) { + continue; + } if (el.type === "image") { const payload = toImagePayload(el.src); if (!payload) continue; @@ -34535,14 +36655,21 @@ function addElements(slideData, targetSlide, pres) { h: el.y2 - el.y1, line: { color: el.color, width: el.width } }); - } else if (el.type === "shape") { + } else if (el.type === "shape" || el.type === "svg-shape") { const shapeOptions = { x: el.position.x, y: el.position.y, w: el.position.w, - h: el.position.h, - shape: el.shape.rectRadius > 0 ? pres.ShapeType.roundRect : pres.ShapeType.rect + h: el.position.h }; + const nativeShapeType = { + circle: pres.ShapeType.ellipse, + ellipse: pres.ShapeType.ellipse, + triangle: pres.ShapeType.triangle, + diamond: pres.ShapeType.diamond, + rect: pres.ShapeType.rect + }[el.svgType]; + shapeOptions.shape = nativeShapeType || (el.shape.rectRadius > 0 ? pres.ShapeType.roundRect : pres.ShapeType.rect); if (el.shape.fill) { shapeOptions.fill = { color: el.shape.fill }; if (el.shape.transparency != null) shapeOptions.fill.transparency = el.shape.transparency; @@ -34550,7 +36677,12 @@ function addElements(slideData, targetSlide, pres) { if (el.shape.line) shapeOptions.line = el.shape.line; if (el.shape.rectRadius > 0) shapeOptions.rectRadius = el.shape.rectRadius; if (el.shape.shadow) shapeOptions.shadow = el.shape.shadow; - targetSlide.addText(el.text || "", shapeOptions); + if (el.shape.rotate != null) shapeOptions.rotate = el.shape.rotate; + if (el.type === "svg-shape") { + targetSlide.addShape(shapeOptions.shape, shapeOptions); + } else { + targetSlide.addText(el.text || "", shapeOptions); + } } else if (el.type === "list" || el.type === "merged-text") { const { x: boxX, w: boxW } = safeTextBoxGeometry(el.position.x, el.position.w, el.style.align, false); const listOptions = { @@ -34616,10 +36748,38 @@ async function buildSlideFromExtracted(slideData, bodyDimensions, pres, options if (validationWarnings.length) { console.warn("[ppt-live-export] slide validation warnings (export continues):", validationWarnings.join("; ")); } + const diagnostics = [ + ...slideData?.diagnostics || [], + ...validationWarnings.map((message) => ({ + severity: "fallback", + code: "pptx_layout_warning", + message, + sourceId: null, + tag: null + })) + ]; const targetSlide = options.slide || pres.addSlide(); - await addBackground(slideData, targetSlide); - addElements(slideData, targetSlide, pres); - return { slide: targetSlide, placeholders: slideData.placeholders || [] }; + try { + await addBackground(slideData, targetSlide); + addElements(slideData, targetSlide, pres); + } catch (error2) { + const diagnostic = { + severity: "blocking", + kind: "blocking", + code: "pptx_serialization", + message: String(error2?.message || error2 || "PPTX serialization failed."), + sourceId: null, + tag: null + }; + error2.diagnostic = diagnostic; + error2.diagnostics = [...diagnostics, diagnostic]; + throw error2; + } + return { + slide: targetSlide, + placeholders: slideData.placeholders || [], + diagnostics + }; } function createPptxDeck(deck = {}) { const pptx = new PptxGenJS(); @@ -34646,7 +36806,7 @@ function buildSpeakerNotes(sourceSlide = {}) { ].filter(Boolean).join("\n\n"); } -// src/pptx-element-export.js +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/pptx-element-export.js var SLIDE_W = 13.333; var SLIDE_H = 7.5; function drawSlideBackdrop(pptx, slide, theme, index) { @@ -34739,7 +36899,7 @@ function drawElement(pptx, slide, element2, theme) { h: box.h, margin: 0.08, fit: "shrink", - color: hex(resolveColor2(style.color, theme)), + color: hex(resolveColor(style.color, theme)), fontFace: "Aptos", fontSize: pxToPt(style.fontSize || 22), bold: Number(style.fontWeight || 500) >= 700, @@ -34751,8 +36911,8 @@ function drawElement(pptx, slide, element2, theme) { slide.addShape(pptx.ShapeType.roundRect, { ...box, rectRadius: 0.08, - fill: { color: hex(resolveColor2(style.background, theme)), transparency: transparency(style.opacity) }, - line: { color: hex(resolveColor2(style.background, theme)), transparency: 100 } + fill: { color: hex(resolveColor(style.background, theme)), transparency: transparency(style.opacity) }, + line: { color: hex(resolveColor(style.background, theme)), transparency: 100 } }); if (element2.text) slide.addText(element2.text, common); return; @@ -34773,7 +36933,7 @@ function drawElement(pptx, slide, element2, theme) { ...common, y: box.y + 0.08, h: box.h * 0.48, - color: hex(resolveColor2(style.color || "primary", theme)), + color: hex(resolveColor(style.color || "primary", theme)), fontSize: pxToPt(style.fontSize || 42), bold: true }); @@ -34803,7 +36963,7 @@ function drawElement(pptx, slide, element2, theme) { if (element2.type === "media") { slide.addShape(pptx.ShapeType.roundRect, { ...box, - fill: { color: hex(resolveColor2(style.background || "soft", theme)), transparency: 10 }, + fill: { color: hex(resolveColor(style.background || "soft", theme)), transparency: 10 }, line: { color: hex(theme.primary), transparency: 55, dash: "dash" } }); slide.addText(String(element2.text || "Image placeholder"), { @@ -34820,7 +36980,7 @@ function drawElement(pptx, slide, element2, theme) { function drawPanel(pptx, slide, box, style, theme) { slide.addShape(pptx.ShapeType.roundRect, { ...box, - fill: { color: hex(resolveColor2(style.background || "panel", theme)), transparency: transparency(style.opacity) }, + fill: { color: hex(resolveColor(style.background || "panel", theme)), transparency: transparency(style.opacity) }, line: { color: hex(theme.primary), transparency: 82 }, shadow: { type: "outer", color: "111827", opacity: 0.12, blur: 1, angle: 45, distance: 1 } }); @@ -34830,8 +36990,8 @@ function drawTextBackground(pptx, slide, box, style, theme) { if (bg === "transparent") return; slide.addShape(pptx.ShapeType.roundRect, { ...box, - fill: { color: hex(resolveColor2(bg, theme)), transparency: transparency(style.opacity) }, - line: { color: hex(resolveColor2(bg, theme)), transparency: 100 } + fill: { color: hex(resolveColor(bg, theme)), transparency: transparency(style.opacity) }, + line: { color: hex(resolveColor(bg, theme)), transparency: 100 } }); } function drawBars(pptx, slide, element2, box, theme) { @@ -34893,7 +37053,7 @@ function pct(value2) { function pxToPt(value2) { return Math.max(6, Math.min(66, Math.round((Number(value2) || 22) * 0.58))); } -function resolveColor2(value2, theme) { +function resolveColor(value2, theme) { if (!value2 || value2 === "transparent") return theme.background; if (value2 === "ink") return theme.ink; if (value2 === "muted") return theme.muted; @@ -34932,7 +37092,7 @@ async function exportElementDeckToPptx(deck) { return pptx; } -// src/export-deck-browser.js +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-deck-browser.js var MIME_PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation"; var RASTER_TEXT_TYPES2 = /* @__PURE__ */ new Set(["p", "h1", "h2", "h3", "h4", "h5", "h6", "text", "list", "merged-text"]); function filterSlideDataForRasterBackdrop(slideData) { @@ -35039,7 +37199,7 @@ async function exportPngZipFromPages(deck, pages) { }; } -// src/export-html.js +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-html.js function buildHtmlDeck(state2) { if ((state2.slides || []).some((slide) => slide.html)) { return buildSourceHtmlDeck(state2); @@ -35062,7 +37222,7 @@ ${deckCss()} } function buildSourceHtmlDeck(state2) { const slides = (state2.slides || []).map((slide, index) => `
      - +
      `).join("\n"); return ` @@ -35128,7 +37288,7 @@ body{margin:0;background:#111827;font-family:-apple-system,BlinkMacSystemFont,"S `; } -// src/export-format-icons.js +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-format-icons.js var SVG_ATTRS = 'xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" aria-hidden="true" focusable="false"'; var ICONS = { pptx: ``, @@ -35149,17 +37309,8 @@ function exportFormatTone(formatId) { return tones[formatId] || "#475569"; } -// src/bitfun-backend-adapter.js -var EVENT_LISTENERS = /* @__PURE__ */ new Set(); +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/agent-prompt.js var PPT_DESIGN_SKILL_KEY = "user::bitfun-system::ppt-design"; -function emitEvent(event) { - EVENT_LISTENERS.forEach((listener) => { - try { - listener(event); - } catch { - } - }); -} function serializeInput(input) { try { return JSON.stringify(input ?? {}, null, 2); @@ -35183,23 +37334,37 @@ function describeStyle(style = {}) { if (style.stylePreset) parts.push(`\u98CE\u683C\u9884\u8BBE: ${style.stylePreset}`); return parts.length ? parts.join("\u3001") : ""; } +function formatContractDiagnostic(diagnostic) { + if (!diagnostic) return ""; + if (typeof diagnostic === "string") return diagnostic.trim(); + const code = String(diagnostic.code || "unknown_contract_error"); + const continuation = String(diagnostic.continuationPrompt || "").trim(); + return [`\u8BCA\u65AD\u4EE3\u7801\uFF1A${code}`, continuation].filter(Boolean).join("\n"); +} function buildAgentPrompt(input) { const hasDeck = hasCurrentDeck(input); const styleLine = describeStyle(input?.style); const instruction = input?.instruction || input?.userInput || ""; - let prompt = hasDeck ? `\u4F7F\u7528 PPT-Design skill \u7F16\u8F91\u73B0\u6709 PPT\u3002\u7F16\u8F91\u6307\u4EE4\uFF1A${instruction || "\uFF08\u89C1 currentDeck \u4E0A\u4E0B\u6587\uFF09"}\u3002` : `\u4F7F\u7528 PPT-Design skill \u751F\u6210 PPT\u3002\u7528\u6237\u9700\u6C42\uFF1A${instruction || "\uFF08\u89C1 input JSON\uFF09"}\u3002`; - if (styleLine) { - prompt += ` + let prompt = hasDeck ? `\u7F16\u8F91\u73B0\u6709 PPT\u3002\u7F16\u8F91\u6307\u4EE4\uFF1A${instruction || "\uFF08\u89C1 currentDeck \u4E0A\u4E0B\u6587\uFF09"}\u3002` : `\u751F\u6210 PPT\u3002\u7528\u6237\u9700\u6C42\uFF1A${instruction || "\uFF08\u89C1 input JSON\uFF09"}\u3002`; + prompt = `\u5148\u8C03\u7528 Skill\uFF0C\u5E76\u4E14 skill key \u5FC5\u987B\u7CBE\u786E\u4E3A \`${PPT_DESIGN_SKILL_KEY}\`\u3002 +${prompt}`; + if (styleLine) prompt += ` \u6837\u5F0F\u504F\u597D\uFF1A${styleLine}\u3002`; - } prompt += ` +## \u751F\u6210\u6587\u4EF6\u534F\u8BAE + +- \u5F53\u524D agent \u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\u5C31\u662F deck \u6839\u76EE\u5F55\uFF1B\u6240\u6709\u8DEF\u5F84\u5747\u76F8\u5BF9\u8BE5\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\u3002 +- \u5148\u5199\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\u4E0B\u7684 \`project.json\`\uFF0C\u518D\u5199\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\u4E0B\u7684 \`slides/slide-NN.html\`\u3002 +- \u53EA\u6709\u5728 \`slide_order\` \u5F15\u7528\u7684\u6BCF\u4E00\u9875\u90FD\u5DF2\u6709\u5B8C\u6574 HTML \u540E\uFF0C\u624D\u5C06 \`project.json\` \u7684 \`status\` \u8BBE\u4E3A \`"complete"\`\u3002 +- \u5B8C\u6210\u524D\u505A\u4E00\u6B21\u6709\u754C\u68C0\u67E5\uFF1A\u6838\u5BF9 \`outline[].slide_id\`\u3001\`slide_order\` \u548C\u5BF9\u5E94\u9875\u9762\u6587\u4EF6\uFF1B\u7F3A\u4EC0\u4E48\u53EA\u8865\u4EC0\u4E48\uFF0C\u68C0\u67E5\u540E\u7ACB\u5373\u7ED3\u675F\u3002 + ## \u7EA6\u675F - \u7528\u6237\u53EA\u80FD\u770B\u5230 PPT Live UI\uFF0C\u65E0\u6CD5\u56DE\u7B54\u63D0\u95EE\u3002\u5982\u6709\u6B67\u4E49\u81EA\u884C\u5224\u65AD\u6700\u4F18\u65B9\u6848\u5E76\u8BB0\u5F55\u5047\u8BBE\u3002 - \u4E0D\u8981\u8C03\u7528 AskUserQuestion\u3001ControlHub\u3001GenerativeUI\u3001ComputerUse \u7B49\u4EA4\u4E92\u5DE5\u5177\u3002 - \u7814\u7A76\u7528 WebSearch / WebFetch \u5373\u53EF\u3002 -- **\u4E00\u6B21\u5199\u5BF9\uFF0C\u7981\u6B62\u4E8B\u540E\u5BA1\u8BA1**\uFF1A\u6BCF\u9875 HTML \u5728\u5199\u5165\u65F6\u5C31\u8981\u6EE1\u8DB3\u6240\u6709\u7EA6\u675F\uFF08\u753B\u5E03\u5C3A\u5BF8\u3001\u56DB\u6761 OOXML \u786C\u7EA6\u675F\u3001\u9632\u6EA2\u51FA\u9884\u7B97\uFF09\u3002\u6240\u6709\u9875\u9762\u5199\u5B8C\u540E\u4E0D\u5F97\u518D\u9010\u9875 Read\u2192Edit \u8FD4\u5DE5\u6216 Grep \u6279\u91CF\u68C0\u67E5\u3002\u5199\u5B8C\u5373\u7ED3\u675F\u3002 +- **\u4E00\u6B21\u5199\u5BF9\uFF0C\u7981\u6B62\u4E8B\u540E\u5BA1\u8BA1**\uFF1A\u6BCF\u9875 HTML \u5728\u5199\u5165\u65F6\u5C31\u8981\u6EE1\u8DB3\u6240\u6709\u7EA6\u675F\uFF08\u753B\u5E03\u5C3A\u5BF8\u3001\u56DB\u6761 OOXML \u786C\u7EA6\u675F\u3001\u9632\u6EA2\u51FA\u9884\u7B97\uFF09\u3002\u5B8C\u6210\u68C0\u67E5\u53EA\u6838\u5BF9\u751F\u6210\u6587\u4EF6\u534F\u8BAE\uFF0C\u4E0D\u9010\u9875 Read\u2192Edit \u8FD4\u5DE5\u6216 Grep \u6279\u91CF\u5BA1\u8BA1\u9875\u9762\u5185\u5BB9\u3002 `; if (hasDeck) { prompt += ` @@ -35214,14 +37379,30 @@ function buildAgentPrompt(input) { Input JSON: \`\`\`json ${serializeInput(input)} -\`\``; +\`\`\``; if (input?.continueAfterInterruption) { - prompt = `\u4E0A\u4E00\u6B21\u751F\u6210\u88AB\u4E2D\u65AD\u4E86\u3002\u8BF7\u7EE7\u7EED\u5B8C\u6210\u4EFB\u52A1\uFF1A\u68C0\u67E5 project.json \u548C\u5DF2\u5199\u7684 slides/ \u6587\u4EF6\uFF0C\u53EA\u8865\u5199\u8FD8\u6CA1\u5B8C\u6210\u7684\u9875\u9762\uFF0C\u4E0D\u8981\u91CD\u5199\u5DF2\u6709\u7684\u9875\u9762\u3002 + const diagnostic = formatContractDiagnostic(input.projectContractDiagnostic); + prompt = `\u4E0A\u4E00\u6B21\u751F\u6210\u88AB\u4E2D\u65AD\u6216\u672A\u901A\u8FC7\u6587\u4EF6\u5951\u7EA6\u3002\u8BF7\u5728\u540C\u4E00\u4F1A\u8BDD\u4E2D\u5B9A\u5411\u7EED\u8DD1\uFF0C\u4E0D\u8981\u91CD\u5199\u5DF2\u5B8C\u6210\u9875\u9762\u3002 +${diagnostic ? ` +${diagnostic} +` : ""} +\u68C0\u67E5 \`project.json\` \u548C\u5DF2\u5199\u7684 \`slides/\` \u6587\u4EF6\uFF0C\u53EA\u4FEE\u590D\u8BCA\u65AD\u6307\u51FA\u7684\u5185\u5BB9\uFF1B\u5B8C\u6210\u540E\u6267\u884C\u4E00\u6B21\u6709\u754C\u68C0\u67E5\u3002 ${prompt}`; } return prompt; } + +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/bitfun-backend-adapter.js +var EVENT_LISTENERS = /* @__PURE__ */ new Set(); +function emitEvent(event) { + EVENT_LISTENERS.forEach((listener) => { + try { + listener(event); + } catch { + } + }); +} function installAgentBackend(app) { let agentEventsHooked = false; const ensureAgentEvents = () => { @@ -35233,23 +37414,16 @@ function installAgentBackend(app) { }); }; app.backend = { - // The agent delivers through project files written using the ppt-design - // skill's native workflow; 'files' tells ui.js to read them back. protocol: "files", async call(action, input, options = {}) { if (action !== "ppt.generate") { throw new Error(`Unsupported PPT Live action: ${action}`); } ensureAgentEvents(); - const prompt = buildAgentPrompt(input); - const result = await app.agent.run(prompt, { + const result = await app.agent.run(buildAgentPrompt(input), { runId: options.idempotencyKey, sessionName: "PPT Live", - // Reuse the session when the caller carries one so follow-up edits - // resume with the loaded skill/preset/research context. sessionId: options.sessionId, - // The agent works inside a dedicated deck project directory under - // the app's own appdata storage (never the user's workspace). appDataWorkspace: options.appDataWorkspace }); if (!result?.sessionId || !result?.turnId) { @@ -35281,12 +37455,440 @@ function installAgentBackend(app) { } function installBitFunBackendAdapter(app = window.app) { if (!app || app.backend?.call) return; - if (app.agent?.run) { - installAgentBackend(app); + if (app.agent?.run) installAgentBackend(app); +} + +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/deck-project-contract.js +var DeckProjectContractError = class extends Error { + constructor(diagnostic) { + super(`[${diagnostic.code}] ${diagnostic.summary}`); + this.name = "DeckProjectContractError"; + this.diagnostic = diagnostic; + } +}; +function contractError(code, summary, continuationPrompt, details = {}) { + return new DeckProjectContractError({ + code, + summary, + continuationPrompt, + ...details + }); +} +function missingSlideFilesDiagnostic(missingPaths) { + return { + code: "missing_slide_files", + summary: `Missing or incomplete slide files: ${missingPaths.join(", ")}`, + continuationPrompt: `\u53EA\u8865\u5199\u8FD9\u4E9B\u7F3A\u5931\u6216\u4E0D\u5B8C\u6574\u9875\u9762\uFF1A${missingPaths.join("\u3001")}\u3002\u4FDD\u7559\u5176\u4ED6\u9875\u9762\u4E0D\u53D8\uFF1B\u8865\u9F50\u540E\u518D\u628A\u72B6\u6001\u786E\u8BA4\u4E3A complete \u5E76\u6267\u884C\u4E00\u6B21\u6709\u754C\u68C0\u67E5\u3002`, + missingPaths + }; +} +var defaultSleep = (delayMs) => new Promise((resolve) => setTimeout(resolve, delayMs)); +async function readVisibleFileWithRetry(readFile, relPath, { + maxAttempts = 6, + delayMs = 120, + sleep = defaultSleep, + accept +} = {}) { + let lastValue = ""; + let lastError = null; + for (let attempt = 1; attempt <= maxAttempts; attempt += 1) { + try { + lastValue = String(await readFile(relPath) || ""); + if (accept(lastValue)) return lastValue; + } catch (error2) { + lastError = error2; + } + if (attempt < maxAttempts) await sleep(delayMs); + } + return { lastValue, lastError }; +} +function createDeckProjectSkeleton({ + title = "", + language = "", + style = {} +} = {}) { + return { + status: "planning", + title, + language, + outline: [], + slide_order: [], + style, + assumptions: [] + }; +} +function createDeckProjectSeed({ + hasExistingDeck = false, + title = "", + language = "", + style = {}, + slides = [], + serializeElementSlide = null +} = {}) { + if (!hasExistingDeck) { + return { + plan: createDeckProjectSkeleton({ title, language, style }), + slideFiles: [] + }; + } + const outline = slides.map((slide, index) => { + const slideId = `slide-${String(index + 1).padStart(2, "0")}`; + return { + id: slideId, + title: String(slide?.title || ""), + bullets: [], + slide_id: slideId + }; + }); + const slideFiles = []; + const missingPaths = []; + slides.forEach((slide, index) => { + const relPath = `slides/slide-${String(index + 1).padStart(2, "0")}.html`; + let html = String(slide?.html || ""); + if (!isCompleteSlideHtml(html) && Array.isArray(slide?.elements) && serializeElementSlide) { + try { + html = String(serializeElementSlide(slide) || ""); + } catch { + html = ""; + } + } + if (isCompleteSlideHtml(html)) slideFiles.push({ relPath, html: html.trim() }); + else missingPaths.push(relPath); + }); + const diagnostic = missingPaths.length ? missingSlideFilesDiagnostic(missingPaths) : null; + return { + plan: { + status: diagnostic ? "planning" : "complete", + title, + language, + outline, + slide_order: outline.map((item) => item.slide_id), + style, + assumptions: [] + }, + slideFiles, + diagnostic + }; +} +function seedPersistenceError(code, phase, missingPaths) { + return new DeckProjectContractError({ + code, + phase, + summary: "Deck project seed persistence failed.", + continuationPrompt: `\u8BF7\u5728\u540C\u4E00\u4F1A\u8BDD\u4E2D\u8865\u5199\u8FD9\u4E9B deck \u9879\u76EE\u8DEF\u5F84\uFF1A${missingPaths.join("\u3001")}\uFF0C\u4FDD\u7559\u5DF2\u6210\u529F\u5199\u5165\u7684\u6587\u4EF6\u5E76\u7EE7\u7EED\u751F\u6210\u3002`, + missingPaths + }); +} +async function persistDeckProjectSeed(fs, projectDir, seed) { + try { + await fs.mkdir(`${projectDir}/slides`, { recursive: true }); + } catch { + throw seedPersistenceError("seed_fs_mkdir_failed", "mkdir", ["slides"]); + } + try { + await fs.writeFile(`${projectDir}/project.json`, `${JSON.stringify(seed.plan, null, 2)} +`); + } catch { + throw seedPersistenceError("seed_fs_write_failed", "project-write", ["project.json"]); + } + for (const slideFile of seed.slideFiles || []) { + try { + await fs.writeFile(`${projectDir}/${slideFile.relPath}`, slideFile.html); + } catch { + throw seedPersistenceError("seed_fs_write_failed", "slide-write", [slideFile.relPath]); + } + } +} +function buildDeckRunRequestInput(baseInput, { + sessionId = "", + projectContractDiagnostic = null +} = {}) { + return { + ...baseInput, + ...sessionId ? { continueAfterInterruption: true } : {}, + ...projectContractDiagnostic ? { projectContractDiagnostic } : {} + }; +} +function parseProjectJson(raw) { + try { + const plan = JSON.parse(raw); + if (!plan || Array.isArray(plan) || typeof plan !== "object") throw new Error("root must be an object"); + return plan; + } catch (error2) { + throw contractError( + "invalid_project_json", + "`project.json` is not valid JSON.", + "\u4FEE\u590D `project.json` JSON\uFF0C\u4F7F\u6839\u503C\u4E3A\u5BF9\u8C61\uFF1B\u4E0D\u8981\u91CD\u5199\u5DF2\u6709\u9875\u9762\u3002\u4FEE\u590D\u540E\u7EE7\u7EED\u5B8C\u6210\u5951\u7EA6\u3002", + { cause: String(error2?.message || error2) } + ); } } +async function readProjectPlanWithRetry(readFile, options = {}) { + const { requireComplete = false } = options; + const result = await readVisibleFileWithRetry(readFile, "project.json", { + ...options, + accept: (raw) => { + if (!raw.trim()) return false; + try { + const parsed = JSON.parse(raw); + return Boolean(parsed) && !Array.isArray(parsed) && typeof parsed === "object" && (!requireComplete || parsed.status === "complete"); + } catch { + return false; + } + } + }); + if (typeof result === "string") return parseProjectJson(result); + if (!result.lastValue.trim()) { + throw contractError( + "missing_project_json", + "`project.json` is missing or empty.", + "\u5728\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\u521B\u5EFA `project.json`\uFF0C\u5148\u5199 status\u3001outline \u548C slide_order\uFF0C\u518D\u7EE7\u7EED\u8865\u5199\u9875\u9762\uFF1B\u4E0D\u8981\u91CD\u5199\u5DF2\u6709\u9875\u9762\u3002", + { cause: String(result.lastError?.message || result.lastError || "") } + ); + } + return parseProjectJson(result.lastValue); +} +function validateCompletedPlan(plan) { + if (plan.status !== "complete") { + throw contractError( + "project_incomplete", + "`project.json` has not declared a complete deck.", + '\u7EE7\u7EED\u5F53\u524D\u8BA1\u5212\uFF1A\u5148\u5B8C\u6210 outline \u548C\u9875\u9762\u6587\u4EF6\uFF0C\u786E\u8BA4\u6240\u6709\u5F15\u7528\u9875\u9762\u5B58\u5728\u540E\uFF0C\u518D\u628A `project.json.status` \u8BBE\u4E3A `"complete"`\u3002' + ); + } + if (!Array.isArray(plan.outline) || !plan.outline.length) { + throw contractError( + "invalid_project_contract", + "`outline` must be a non-empty array.", + "\u4FEE\u590D `project.json`\uFF1A\u5148\u5199\u975E\u7A7A `outline`\uFF0C\u6BCF\u9879\u63D0\u4F9B\u552F\u4E00 `slide_id`\uFF0C\u5E76\u8BA9 `slide_order` \u7CBE\u786E\u5BF9\u5E94\u8FD9\u4E9B ID\u3002" + ); + } + if (!Array.isArray(plan.slide_order) || !plan.slide_order.length) { + throw contractError( + "invalid_project_contract", + "`slide_order` must be a non-empty array.", + "\u4FEE\u590D `project.json`\uFF1A\u8BA9 `slide_order` \u6309\u5C55\u793A\u987A\u5E8F\u5217\u51FA\u5168\u90E8 `outline[].slide_id`\u3002" + ); + } + const outlineIds = []; + const outlineItemIds = /* @__PURE__ */ new Set(); + for (const item of plan.outline) { + const requiredFields = [ + ["id", typeof item?.id === "string" && Boolean(item.id.trim())], + ["title", typeof item?.title === "string" && Boolean(item.title.trim())], + ["bullets", Array.isArray(item?.bullets) && item.bullets.every((bullet) => typeof bullet === "string")] + ]; + const invalidField = requiredFields.find(([, valid]) => !valid)?.[0]; + if (invalidField) { + throw contractError( + "invalid_project_contract", + `Every outline item must have valid id, title, and bullets fields; invalid ${invalidField}.`, + `\u4FEE\u590D \`project.json\` \u7684 \`outline[].${invalidField}\`\uFF0C\u786E\u4FDD id/title \u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32\u4E14 bullets \u4E3A\u5B57\u7B26\u4E32\u6570\u7EC4\uFF1B\u4E0D\u8981\u6539\u65E0\u5173\u9875\u9762\u3002`, + { invalidOutlineField: invalidField } + ); + } + const itemId = item.id.trim(); + if (outlineItemIds.has(itemId)) { + throw contractError( + "invalid_project_contract", + `Every outline item id must be unique; duplicate ${itemId}.`, + "\u4FEE\u590D `project.json` \u7684 `outline[].id`\uFF0C\u786E\u4FDD\u6BCF\u9879 id \u662F\u552F\u4E00\u975E\u7A7A\u5B57\u7B26\u4E32\uFF1B\u4E0D\u8981\u6539\u65E0\u5173\u9875\u9762\u3002", + { invalidOutlineField: "id" } + ); + } + outlineItemIds.add(itemId); + const slideId = String(item.slide_id || ""); + if (!/^slide-\d{2}$/.test(slideId)) { + throw contractError( + "invalid_project_contract", + "Every outline item must have a `slide-NN` slide_id.", + "\u4FEE\u590D `project.json` \u7684 `outline[].slide_id`\uFF0C\u7EDF\u4E00\u4F7F\u7528\u4E24\u4F4D\u6570 `slide-NN`\uFF0C\u5E76\u540C\u6B65 `slide_order`\uFF1B\u4E0D\u8981\u6539\u65E0\u5173\u9875\u9762\u3002" + ); + } + outlineIds.push(slideId); + } + const orderedIds = plan.slide_order.map((value2) => String(value2 || "")); + const uniqueOutlineIds = new Set(outlineIds); + const uniqueOrderedIds = new Set(orderedIds); + const sameIds = outlineIds.length === orderedIds.length && uniqueOutlineIds.size === outlineIds.length && uniqueOrderedIds.size === orderedIds.length && outlineIds.every((id) => uniqueOrderedIds.has(id)); + if (!sameIds) { + throw contractError( + "invalid_project_contract", + "`slide_order` and `outline[].slide_id` disagree.", + "\u4FEE\u590D `project.json`\uFF1A\u8BA9 `slide_order` \u4E0E `outline[].slide_id` \u4E00\u4E00\u5BF9\u5E94\u4E14\u65E0\u91CD\u590D\uFF1B\u53EA\u4FEE\u590D\u8BA1\u5212\u6216\u7F3A\u5931\u9875\u9762\uFF0C\u4E0D\u91CD\u5199\u5DF2\u6709\u9875\u9762\u3002", + { outlineSlideIds: outlineIds, slideOrder: orderedIds } + ); + } + return orderedIds; +} +function isCompleteSlideHtml(raw) { + const match = String(raw || "").match( + /^\uFEFF?\s*(?:]*>\s*)?]*)?>[\s\S]*?]*)?>([\s\S]*?)<\/body>[\s\S]*?<\/html>\s*$/i + ); + if (!match) return false; + return Boolean(match[1].replace(//g, "").trim()); +} +async function readCompleteSlideWithRetry(readFile, relPath, options) { + const result = await readVisibleFileWithRetry(readFile, relPath, { + ...options, + accept: isCompleteSlideHtml + }); + return typeof result === "string" ? result.trim() : null; +} +async function readDeckProjectContract(readFile, options = {}) { + const plan = await readProjectPlanWithRetry(readFile, { ...options, requireComplete: true }); + const slideOrder = validateCompletedPlan(plan); + const outlineById = new Map(plan.outline.map((item) => [String(item.slide_id), item])); + const slides = []; + const missingPaths = []; + for (let index = 0; index < slideOrder.length; index += 1) { + const slideId = slideOrder[index]; + const relPath = `slides/${slideId}.html`; + const html = await readCompleteSlideWithRetry(readFile, relPath, options); + if (!html) { + missingPaths.push(relPath); + continue; + } + slides.push({ + slideId, + slideNumber: index + 1, + relPath, + outlineEntry: outlineById.get(slideId), + html + }); + } + if (missingPaths.length) { + throw new DeckProjectContractError(missingSlideFilesDiagnostic(missingPaths)); + } + return { plan, slides }; +} -// ui.js +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-diagnostics.js +var DIAGNOSTIC_REASONS = { + "en-US": { + active_content_removed: "Unsafe active content was removed.", + canvas_overflow: "Slide content exceeded the canvas; visual fallback was used.", + canvas_size: "Slide dimensions could not preserve native fidelity; visual fallback was used.", + text_out_of_bounds: "Text exceeded the slide boundary; visual fallback was used.", + bottom_safety_margin: "Text entered the bottom safety margin; visual fallback was used.", + css_gradient: "A CSS gradient required visual fallback.", + css_filter: "A CSS filter required visual fallback.", + generated_content: "Generated CSS content required visual fallback.", + page_visual_fallback: "A page visual fallback preserved the slide appearance.", + full_page_fallback: "A full-page visual fallback preserved the slide appearance.", + unreadable_document: "The slide document could not be read.", + unmeasurable_canvas: "The slide canvas could not be measured.", + pptx_serialization: "The slide could not be serialized to PPTX.", + full_page_raster_failed: "The final visual fallback could not be rendered." + }, + "zh-CN": { + active_content_removed: "\u5DF2\u79FB\u9664\u4E0D\u5B89\u5168\u7684\u6D3B\u52A8\u5185\u5BB9\u3002", + canvas_overflow: "\u9875\u9762\u5185\u5BB9\u8D85\u51FA\u5E7B\u706F\u7247\u8FB9\u754C\uFF0C\u5DF2\u5207\u6362\u89C6\u89C9\u515C\u5E95\u3002", + canvas_size: "\u9875\u9762\u5C3A\u5BF8\u65E0\u6CD5\u4FDD\u8BC1\u539F\u751F\u4FDD\u771F\uFF0C\u5DF2\u5207\u6362\u89C6\u89C9\u515C\u5E95\u3002", + text_out_of_bounds: "\u6587\u5B57\u8D85\u51FA\u5E7B\u706F\u7247\u8FB9\u754C\uFF0C\u5DF2\u5207\u6362\u89C6\u89C9\u515C\u5E95\u3002", + bottom_safety_margin: "\u6587\u5B57\u8FDB\u5165\u5E95\u90E8\u5B89\u5168\u8FB9\u8DDD\uFF0C\u5DF2\u5207\u6362\u89C6\u89C9\u515C\u5E95\u3002", + css_gradient: "CSS \u6E10\u53D8\u5DF2\u4F7F\u7528\u89C6\u89C9\u515C\u5E95\u3002", + css_filter: "CSS \u6EE4\u955C\u5DF2\u4F7F\u7528\u89C6\u89C9\u515C\u5E95\u3002", + generated_content: "CSS \u751F\u6210\u5185\u5BB9\u5DF2\u4F7F\u7528\u89C6\u89C9\u515C\u5E95\u3002", + page_visual_fallback: "\u5DF2\u4F7F\u7528\u9875\u9762\u89C6\u89C9\u515C\u5E95\u4FDD\u7559\u5916\u89C2\u3002", + full_page_fallback: "\u5DF2\u4F7F\u7528\u6574\u9875\u89C6\u89C9\u515C\u5E95\u4FDD\u7559\u5916\u89C2\u3002", + unreadable_document: "\u65E0\u6CD5\u8BFB\u53D6\u5E7B\u706F\u7247\u6587\u6863\u3002", + unmeasurable_canvas: "\u65E0\u6CD5\u6D4B\u91CF\u5E7B\u706F\u7247\u753B\u5E03\u3002", + pptx_serialization: "\u65E0\u6CD5\u5C06\u5E7B\u706F\u7247\u5E8F\u5217\u5316\u4E3A PPTX\u3002", + full_page_raster_failed: "\u6700\u7EC8\u89C6\u89C9\u515C\u5E95\u6E32\u67D3\u5931\u8D25\u3002" + } +}; +var UNKNOWN_REASON = { + "en-US": "Export encountered a protected internal error.", + "zh-CN": "\u5BFC\u51FA\u9047\u5230\u5DF2\u4FDD\u62A4\u7684\u5185\u90E8\u9519\u8BEF\u3002" +}; +function sanitizeDiagnosticSourceId(value2) { + const safe = String(value2 || "").replace(/[^a-zA-Z0-9_-]/g, "").slice(0, 48); + return safe || null; +} +function formatLocalizedExportDiagnostic(diagnostic = {}, locale = "en-US") { + const resolvedLocale = locale === "zh-CN" ? locale : "en-US"; + const reason = DIAGNOSTIC_REASONS[resolvedLocale][diagnostic.code] || UNKNOWN_REASON[resolvedLocale]; + return { + slideNumber: Number.isFinite(diagnostic.slideNumber) ? diagnostic.slideNumber : diagnostic.slideNumber, + sourceId: sanitizeDiagnosticSourceId(diagnostic.sourceId), + phase: String(diagnostic.phase || "").replace(/[^a-z-]/g, "").slice(0, 32) || null, + severity: diagnostic.severity === "blocking" ? "blocking" : diagnostic.severity, + code: String(diagnostic.code || "unknown").replace(/[^a-z0-9_-]/gi, "").slice(0, 64), + reason: reason.slice(0, 120) + }; +} +function localizeExportDiagnosticLocations(locations = [], locale = "en-US") { + return locations.map((location) => formatLocalizedExportDiagnostic(location, locale)); +} +function summarizePptxExportDiagnostics(preparedSlides = []) { + const counts = { + repaired: 0, + svgImage: 0, + localPng: 0, + pageVisual: 0, + fullPage: 0, + blocking: 0 + }; + const locations = []; + const seen = /* @__PURE__ */ new Set(); + const addLocation = (slideNumber, item, defaults = {}) => { + const location = { + slideNumber, + sourceId: item?.sourceId || defaults.sourceId || null, + phase: item?.phase || defaults.phase || null, + severity: item?.severity || defaults.severity || "fallback", + code: item?.code || defaults.code || null, + reason: item?.reason || item?.message || defaults.reason || null + }; + const key = [ + location.slideNumber, + location.sourceId, + location.phase, + location.severity, + location.code + ].join(":"); + if (seen.has(key)) return; + seen.add(key); + locations.push(location); + }; + preparedSlides.forEach((prepared, arrayIndex) => { + const slideNumber = (prepared?.index ?? arrayIndex) + 1; + const slideData = prepared?.slideData || {}; + (slideData.diagnostics || []).forEach((diagnostic) => { + if (diagnostic.severity === "repaired") counts.repaired += 1; + if (diagnostic.severity === "blocking") counts.blocking += 1; + if (diagnostic.severity === "repaired" || diagnostic.severity === "blocking" || diagnostic.phase || diagnostic.sourceId) { + addLocation(slideNumber, diagnostic); + } + }); + (slideData.fallbackLayers || []).forEach((layer) => { + if (layer.kind === "svg-image") counts.svgImage += 1; + if (layer.kind === "raster" && layer.phase === "local-visual") counts.localPng += 1; + if (layer.kind === "raster" && layer.phase === "page-visual") counts.pageVisual += 1; + addLocation(slideNumber, layer, { + severity: "fallback", + code: layer.kind === "svg-image" ? "svg_image_fallback" : "png_visual_fallback" + }); + }); + if (slideData.fullPageFallback) { + counts.fullPage += 1; + addLocation(slideNumber, slideData.fullPageFallback, { + severity: "fallback", + code: "full_page_fallback", + phase: "full-page" + }); + } + }); + return { + counts, + locations, + hasWarnings: counts.repaired + counts.svgImage + counts.localPng + counts.pageVisual + counts.fullPage > 0, + hasBlocking: counts.blocking > 0 + }; +} + +// src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/ui.js var state = createInitialState(); var busy = false; var dragState = null; @@ -35922,18 +38524,15 @@ async function readDeckProjectFile(project, relPath) { if (!fs?.readFile) throw new Error("PPT Live fs API is unavailable"); return await fs.readFile(`${project.dir}/${relPath}`); } -async function tryReadDeckJsonFile(project, relPath) { +async function tryReadDeckPlanFile(project) { try { - const raw = String(await readDeckProjectFile(project, relPath) || ""); - if (!raw.trim()) return null; - return extractBackendJson(raw); + return await readProjectPlanWithRetry( + (relPath) => readDeckProjectFile(project, relPath) + ); } catch { return null; } } -async function tryReadDeckPlanFile(project) { - return await tryReadDeckJsonFile(project, "project.json"); -} async function tryReadDeckSlideFile(project, slideNumber) { try { const raw = String(await readDeckProjectFile(project, deckSlideFileName(slideNumber)) || "").trim(); @@ -35954,26 +38553,16 @@ async function tryReadDeckSlideFileWithRetry(project, slideNumber, maxAttempts = return null; } async function readDeckFromProjectFiles(project) { - const plan = await tryReadDeckPlanFile(project); - if (!plan) throw new Error("PPT Live agent finished without a valid project.json"); - const slideOrder = Array.isArray(plan.slide_order) && plan.slide_order.length ? plan.slide_order : Array.isArray(plan.outline) ? plan.outline.map((_, index) => `slide-${String(index + 1).padStart(2, "0")}`) : []; - const slides = []; - for (let index = 0; index < slideOrder.length; index += 1) { - const slideId = String(slideOrder[index] || `slide-${String(index + 1).padStart(2, "0")}`); - const slideNumber = index + 1; - const html = await tryReadDeckSlideFile(project, slideNumber); - const outlineEntry = plan.outline?.[index]; - const title = typeof outlineEntry === "string" ? outlineEntry : outlineEntry?.title || `${translate("newSlideTitle")} ${slideNumber}`; - if (html) { - slides.push({ - id: `ppt-live-slide-${slideNumber}`, - slideNumber, - title, - html - }); - } - } - if (!slides.length) throw new Error("PPT Live agent did not produce any slide files"); + const result = await readDeckProjectContract( + (relPath) => readDeckProjectFile(project, relPath) + ); + const { plan } = result; + const slides = result.slides.map((slide) => ({ + id: `ppt-live-slide-${slide.slideNumber}`, + slideNumber: slide.slideNumber, + title: slide.outlineEntry?.title || `${translate("newSlideTitle")} ${slide.slideNumber}`, + html: slide.html + })); return { title: resolveDeckTitle({ plan, slides }), language: plan.language || "", @@ -35985,32 +38574,35 @@ async function readDeckFromProjectFiles(project) { } async function seedDeckProjectFromState(project) { const fs = runtime().fs; - if (!project || !fs?.writeFile || !state.slides?.length) return; + if (!project || !fs?.writeFile || !fs?.mkdir) { + throw new DeckProjectContractError({ + code: "seed_fs_unavailable", + summary: "Deck project filesystem is unavailable.", + continuationPrompt: "\u8BF7\u5728\u540C\u4E00\u4F1A\u8BDD\u4E2D\u91CD\u65B0\u521B\u5EFA deck \u9879\u76EE\u76EE\u5F55\u548C slides \u5B50\u76EE\u5F55\uFF0C\u7136\u540E\u7EE7\u7EED\u751F\u6210\u3002", + missingPaths: [`${project?.dir || "deck-project"}/slides`] + }); + } const hasExistingProject = await tryReadDeckPlanFile(project); if (hasExistingProject) return; try { - const outline = state.slides.map((slide, index) => ({ - id: `slide-${String(index + 1).padStart(2, "0")}`, - title: String(slide.title || ""), - bullets: [], - slide_id: `slide-${String(index + 1).padStart(2, "0")}` - })); - const projectJson = { - title: state.title || "", + const seed = createDeckProjectSeed({ + hasExistingDeck: hasUsableDeckForRevision(), + title: isEphemeralDeckTitle(state.title) ? "" : state.title, language: getLocale(), - outline, - slide_order: outline.map((item) => item.slide_id), - style: buildGenerationStyle() - }; - await fs.writeFile(`${project.dir}/project.json`, `${JSON.stringify(projectJson, null, 2)} -`); - for (let index = 0; index < state.slides.length; index += 1) { - const slide = state.slides[index]; - if (slide.html) { - await fs.writeFile(`${project.dir}/${deckSlideFileName(index + 1)}`, slide.html); - } - } - } catch { + style: buildGenerationStyle(), + slides: state.slides, + serializeElementSlide: buildElementSlideHtml + }); + await persistDeckProjectSeed(fs, project.dir, seed); + } catch (error2) { + if (error2 instanceof DeckProjectContractError) throw error2; + throw new DeckProjectContractError({ + code: "seed_fs_write_failed", + summary: "Deck project seed files could not be written.", + continuationPrompt: "\u8BF7\u5728\u540C\u4E00\u4F1A\u8BDD\u4E2D\u521B\u5EFA\u7F3A\u5931\u7684 slides \u76EE\u5F55\u5E76\u91CD\u5199\u5931\u8D25\u7684 seed \u6587\u4EF6\uFF0C\u7136\u540E\u7EE7\u7EED\u751F\u6210\u3002", + missingPaths: [`${project.dir}/slides`], + cause: String(error2?.message || error2) + }); } } async function pruneOldDeckProjects(currentRunId) { @@ -36303,9 +38895,20 @@ async function runCoworkDeckGeneration(operation, instruction) { prepareAgentGenerationSurface(operation, instruction); let completed = false; const project = backendUsesFileProtocol() ? currentDeckProject() || newDeckProject() : null; + let projectContractDiagnostic = null; if (project && !state.agentSession?.workspaceSubdir) { await pruneOldDeckProjects(project.runId); - await seedDeckProjectFromState(project); + try { + await seedDeckProjectFromState(project); + } catch (error2) { + if (!(error2 instanceof DeckProjectContractError)) throw error2; + projectContractDiagnostic = error2.diagnostic; + addGenerationEvent({ + title: translate("generationStageAudit"), + detail: error2.diagnostic.continuationPrompt, + kind: "start" + }); + } } const retrySession = { id: state.agentSession?.id || null, @@ -36330,10 +38933,13 @@ async function runCoworkDeckGeneration(operation, instruction) { setStatus(translate("generationRetrying", { attempt, max: PPT_BACKEND_MAX_ATTEMPTS })); await new Promise((resolve) => setTimeout(resolve, retryDelayMs(lastError, attempt))); } - const requestInput = { - ...buildBackendRequestBase(operation, instruction), - ...retrySession?.id ? { continueAfterInterruption: true } : {} - }; + const requestInput = buildDeckRunRequestInput( + buildBackendRequestBase(operation, instruction), + { + sessionId: retrySession?.id, + projectContractDiagnostic + } + ); const hasExistingDeck = hasUsableDeckForRevision(); if (hasExistingDeck) { requestInput.currentSlideIndex = getActiveIndex(state); @@ -36440,6 +39046,7 @@ async function runCoworkDeckGeneration(operation, instruction) { break; } catch (error2) { lastError = error2; + if (error2?.diagnostic) projectContractDiagnostic = error2.diagnostic; if (isUnknownSessionBackendError(error2)) retrySession.id = null; else if (error2?.pptLiveSessionId) retrySession.id = error2.pptLiveSessionId; if (!isRetryableBackendError(error2) || attempt >= PPT_BACKEND_MAX_ATTEMPTS) throw error2; @@ -37188,6 +39795,58 @@ function getExportLabels(format) { }; return labels[format] || null; } +function formatExportDiagnostics(summary) { + if (!summary?.hasWarnings && !summary?.hasBlocking) return ""; + const countLabels = [ + ["repaired", "exportDiagnosticsRepaired"], + ["svgImage", "exportDiagnosticsSvg"], + ["localPng", "exportDiagnosticsLocalPng"], + ["pageVisual", "exportDiagnosticsPageVisual"], + ["fullPage", "exportDiagnosticsFullPage"], + ["blocking", "exportDiagnosticsBlocking"] + ].filter(([countKey]) => summary.counts?.[countKey] > 0).map(([countKey, labelKey]) => translate(labelKey, { count: summary.counts[countKey] })); + const phaseKeys = { + "local-svg": "exportDiagnosticsPhaseSvg", + "local-visual": "exportDiagnosticsPhaseLocalPng", + "page-visual": "exportDiagnosticsPhasePageVisual", + "full-page": "exportDiagnosticsPhaseFullPage" + }; + const locations = localizeExportDiagnosticLocations(summary.locations || [], getLocale()).filter((location) => location.sourceId).slice(0, 3).map((location) => translate("exportDiagnosticsLocation", { + slide: location.slideNumber, + source: location.sourceId, + phase: translate( + phaseKeys[location.phase] || (location.severity === "blocking" ? "exportDiagnosticsPhaseBlocking" : "exportDiagnosticsPhaseRepair") + ), + reason: location.reason + })); + return translate("exportDiagnosticsSummary", { + counts: countLabels.join(", "), + locations: locations.join("; ") + }); +} +function formatBlockingExportDiagnostics(diagnostics) { + const blocking = Array.isArray(diagnostics) ? diagnostics.filter((diagnostic) => diagnostic?.severity === "blocking") : []; + if (!blocking.length) return ""; + return formatExportDiagnostics({ + counts: { + repaired: 0, + svgImage: 0, + localPng: 0, + pageVisual: 0, + fullPage: 0, + blocking: blocking.length + }, + locations: blocking.map((diagnostic) => ({ + slideNumber: diagnostic.slideNumber || "?", + sourceId: diagnostic.sourceId || "?", + phase: diagnostic.phase || null, + severity: "blocking", + code: diagnostic.code + })), + hasWarnings: false, + hasBlocking: true + }); +} function setExportRenderProgress(index, total, format) { const labels = getExportLabels(format === "pptx" ? "pptx" : format); if (!labels || total <= 0) return; @@ -37250,6 +39909,7 @@ async function executeExport(format) { onRasterProgress: (index) => setExportRenderProgress(index, slides.length, "pptx") }); result = await exportPptxPrepared(deckPayload, preparedSlides); + result.exportSummary = summarizePptxExportDiagnostics(preparedSlides); } else { result = await exportPptxFromDeck(deckPayload); } @@ -37270,7 +39930,7 @@ async function executeExport(format) { filename, result.mimeType || "application/octet-stream" ); - return { filename }; + return { filename, exportSummary: result?.exportSummary || null }; } var exportInFlight = false; var handlers = { @@ -37886,16 +40546,19 @@ async function confirmExportFromModal() { const previewFrame = $("exportPreviewFrame"); const previewSnapshot = previewFrame?.innerHTML || ""; try { - const { filename } = await executeExport(format); + const { filename, exportSummary } = await executeExport(format); const savedMessage = translate("exportSavedTo", { path: filename }); + const diagnosticMessage = formatExportDiagnostics(exportSummary); + const completedMessage = diagnosticMessage ? `${savedMessage} ${diagnosticMessage}` : savedMessage; $("exportOverlay")?.classList.remove("is-exporting"); - setExportModalFeedback("success", savedMessage); - setExportStatus(savedMessage); + setExportModalFeedback("success", completedMessage); + setExportStatus(completedMessage); revealDownloadFolder(); await new Promise((resolve) => setTimeout(resolve, 1600)); closeExportModal(); } catch (error2) { - const message = error2 instanceof Error ? error2.message : String(error2); + const localizedDiagnostics = formatBlockingExportDiagnostics(error2?.diagnostics); + const message = localizedDiagnostics || (error2 instanceof Error ? error2.message : String(error2)); runtime().log?.error?.(`PPT Live ${format} export failed`, { error: message }); $("exportOverlay")?.classList.remove("is-exporting"); setExportModalFeedback("error", `${labels.failed} ${message}`); diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/meta.json b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/meta.json index 76719d7e84..3865589f77 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/meta.json +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/meta.json @@ -10,7 +10,7 @@ "ppt", "ai" ], - "version": 203, + "version": 216, "created_at": 0, "updated_at": 0, "permissions": { diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/agent-prompt.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/agent-prompt.js new file mode 100644 index 0000000000..b95ebb753a --- /dev/null +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/agent-prompt.js @@ -0,0 +1,91 @@ +export const PPT_DESIGN_SKILL_KEY = 'user::bitfun-system::ppt-design'; + +function serializeInput(input) { + try { + return JSON.stringify(input ?? {}, null, 2); + } catch { + return '{}'; + } +} + +function hasCurrentDeck(input) { + return Array.isArray(input?.currentDeck?.slides) && input.currentDeck.slides.length > 0; +} + +function describeStyle(style = {}) { + const parts = []; + const font = style.fontFamily; + if (font === 'serif') parts.push('衬线字体'); + else if (font === 'sans') parts.push('非衬线字体'); + + const density = style.density === 'loose' ? 'spacious' : style.density; + if (density === 'compact') parts.push('紧凑信息密度'); + else if (density === 'spacious') parts.push('宽松留白'); + + const colorMode = style.colorMode || style.theme; + if (colorMode === 'dark') parts.push('深色主题'); + if (style.stylePreset) parts.push(`风格预设: ${style.stylePreset}`); + return parts.length ? parts.join('、') : ''; +} + +function formatContractDiagnostic(diagnostic) { + if (!diagnostic) return ''; + if (typeof diagnostic === 'string') return diagnostic.trim(); + const code = String(diagnostic.code || 'unknown_contract_error'); + const continuation = String(diagnostic.continuationPrompt || '').trim(); + return [`诊断代码:${code}`, continuation].filter(Boolean).join('\n'); +} + +export function buildAgentPrompt(input) { + const hasDeck = hasCurrentDeck(input); + const styleLine = describeStyle(input?.style); + const instruction = input?.instruction || input?.userInput || ''; + let prompt = hasDeck + ? `编辑现有 PPT。编辑指令:${instruction || '(见 currentDeck 上下文)'}。` + : `生成 PPT。用户需求:${instruction || '(见 input JSON)'}。`; + + prompt = `先调用 Skill,并且 skill key 必须精确为 \`${PPT_DESIGN_SKILL_KEY}\`。\n${prompt}`; + if (styleLine) prompt += `\n样式偏好:${styleLine}。`; + + prompt += ` + +## 生成文件协议 + +- 当前 agent 工作区根目录就是 deck 根目录;所有路径均相对该工作区根目录。 +- 先写工作区根目录下的 \`project.json\`,再写工作区根目录下的 \`slides/slide-NN.html\`。 +- 只有在 \`slide_order\` 引用的每一页都已有完整 HTML 后,才将 \`project.json\` 的 \`status\` 设为 \`"complete"\`。 +- 完成前做一次有界检查:核对 \`outline[].slide_id\`、\`slide_order\` 和对应页面文件;缺什么只补什么,检查后立即结束。 + +## 约束 + +- 用户只能看到 PPT Live UI,无法回答提问。如有歧义自行判断最优方案并记录假设。 +- 不要调用 AskUserQuestion、ControlHub、GenerativeUI、ComputerUse 等交互工具。 +- 研究用 WebSearch / WebFetch 即可。 +- **一次写对,禁止事后审计**:每页 HTML 在写入时就要满足所有约束(画布尺寸、四条 OOXML 硬约束、防溢出预算)。完成检查只核对生成文件协议,不逐页 Read→Edit 返工或 Grep 批量审计页面内容。 +`; + + if (hasDeck) { + prompt += ` +## 编辑上下文 + +- \`currentDeck\` 已提供。将用户指令视为对现有 deck 的增量编辑,除非指令明确要求全新生成。 +- \`currentDeck.slides[].slideNumber\` 是从 1 开始的页码,与用户口语一致。 +- 编辑时只重写变更的 \`slides/slide-NN.html\` 文件,不动其他页。 +`; + } + + prompt += ` +Input JSON: +\`\`\`json +${serializeInput(input)} +\`\`\``; + + if (input?.continueAfterInterruption) { + const diagnostic = formatContractDiagnostic(input.projectContractDiagnostic); + prompt = `上一次生成被中断或未通过文件契约。请在同一会话中定向续跑,不要重写已完成页面。 +${diagnostic ? `\n${diagnostic}\n` : ''} +检查 \`project.json\` 和已写的 \`slides/\` 文件,只修复诊断指出的内容;完成后执行一次有界检查。\n\n${prompt}`; + } + + return prompt; +} diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/bitfun-backend-adapter.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/bitfun-backend-adapter.js index fd7901f0d9..7d521d7a0f 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/bitfun-backend-adapter.js +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/bitfun-backend-adapter.js @@ -2,17 +2,15 @@ // // The MiniApp agent bridge (`app.agent.*`) is the only generation path. A // single cowork agent turn loads BitFun's pinned built-in `ppt-design` skill -// and produces the entire deck end to end — research, outline, design system, -// and every slide HTML — following the skill's native project.json + -// slides/slide-NN.html file protocol. -// -// Design principle: the prompt stays minimal. The ppt-design skill owns all -// design rules, schemas, templates, and quality bars via progressive disclosure -// (SKILL.md → references/*.md). The prompt only carries user intent + style -// preferences + MiniApp headless constraints. +// and produces the entire deck through its project.json + slides/ file protocol. + +import { + PPT_DESIGN_SKILL_KEY, + buildAgentPrompt, +} from './agent-prompt.js'; const EVENT_LISTENERS = new Set(); -export const PPT_DESIGN_SKILL_KEY = 'user::bitfun-system::ppt-design'; +export { PPT_DESIGN_SKILL_KEY }; function emitEvent(event) { EVENT_LISTENERS.forEach((listener) => { @@ -24,111 +22,11 @@ function emitEvent(event) { }); } -// ─── Agent prompt builder (minimal — delegates to skill) ───────────────────── - -function serializeInput(input) { - try { - return JSON.stringify(input ?? {}, null, 2); - } catch { - return '{}'; - } -} - -function hasCurrentDeck(input) { - return Array.isArray(input?.currentDeck?.slides) && input.currentDeck.slides.length > 0; -} - -/** - * Describe the user's style preferences in one concise line, so the skill can - * apply them without the prompt restating design rules the skill already owns. - */ -function describeStyle(style = {}) { - const parts = []; - const font = style.fontFamily; - if (font === 'serif') parts.push('衬线字体'); - else if (font === 'sans') parts.push('非衬线字体'); - - const density = style.density === 'loose' ? 'spacious' : style.density; - if (density === 'compact') parts.push('紧凑信息密度'); - else if (density === 'spacious') parts.push('宽松留白'); - - const colorMode = style.colorMode || style.theme; - if (colorMode === 'dark') parts.push('深色主题'); - - if (style.stylePreset) parts.push(`风格预设: ${style.stylePreset}`); - - return parts.length ? parts.join('、') : ''; -} - -/** - * Build the full agent user prompt for a `ppt.generate` run. - * - * Intentionally minimal: user intent + style line + "use ppt-design skill". - * All design rules, file schemas, layout templates, quality bars, and - * progressive-disclosure reference routing live inside the skill itself. - * Restating them here creates prompt/skill duplication that confuses the model. - */ -function buildAgentPrompt(input) { - const hasDeck = hasCurrentDeck(input); - const styleLine = describeStyle(input?.style); - const instruction = input?.instruction || input?.userInput || ''; - - // --- Core task (one sentence) --- - let prompt = hasDeck - ? `使用 PPT-Design skill 编辑现有 PPT。编辑指令:${instruction || '(见 currentDeck 上下文)'}。` - : `使用 PPT-Design skill 生成 PPT。用户需求:${instruction || '(见 input JSON)'}。`; - - // --- Style preferences (one line) --- - if (styleLine) { - prompt += `\n样式偏好:${styleLine}。`; - } - - // --- MiniApp headless constraints (only what the skill doesn't know) --- - prompt += ` - -## 约束 - -- 用户只能看到 PPT Live UI,无法回答提问。如有歧义自行判断最优方案并记录假设。 -- 不要调用 AskUserQuestion、ControlHub、GenerativeUI、ComputerUse 等交互工具。 -- 研究用 WebSearch / WebFetch 即可。 -- **一次写对,禁止事后审计**:每页 HTML 在写入时就要满足所有约束(画布尺寸、四条 OOXML 硬约束、防溢出预算)。所有页面写完后不得再逐页 Read→Edit 返工或 Grep 批量检查。写完即结束。 -`; - - // --- Context for edit operations --- - if (hasDeck) { - prompt += ` -## 编辑上下文 - -- \`currentDeck\` 已提供。将用户指令视为对现有 deck 的增量编辑,除非指令明确要求全新生成。 -- \`currentDeck.slides[].slideNumber\` 是从 1 开始的页码,与用户口语一致。 -- 编辑时只重写变更的 \`slides/slide-NN.html\` 文件,不动其他页。 -`; - } - - // --- Full input JSON (for research context, outline hints, etc.) --- - prompt += ` -Input JSON: -\`\`\`json -${serializeInput(input)} -\`\``; - - // --- Interruption continuation prefix --- - if (input?.continueAfterInterruption) { - prompt = `上一次生成被中断了。请继续完成任务:检查 project.json 和已写的 slides/ 文件,只补写还没完成的页面,不要重写已有的页面。\n\n${prompt}`; - } - - return prompt; -} - -// ─── Agent-backed backend (primary path) ───────────────────────────────────── - function installAgentBackend(app) { let agentEventsHooked = false; const ensureAgentEvents = () => { if (agentEventsHooked) return; agentEventsHooked = true; - // Host events already carry sessionId/turnId/sourceEvent/text/contentType/ - // toolEvent/error in the shape ui.js consumes; re-emit them as-is. app.agent.onEvent((event) => { if (!event || typeof event !== 'object') return; emitEvent(event); @@ -136,23 +34,16 @@ function installAgentBackend(app) { }; app.backend = { - // The agent delivers through project files written using the ppt-design - // skill's native workflow; 'files' tells ui.js to read them back. protocol: 'files', async call(action, input, options = {}) { if (action !== 'ppt.generate') { throw new Error(`Unsupported PPT Live action: ${action}`); } ensureAgentEvents(); - const prompt = buildAgentPrompt(input); - const result = await app.agent.run(prompt, { + const result = await app.agent.run(buildAgentPrompt(input), { runId: options.idempotencyKey, sessionName: 'PPT Live', - // Reuse the session when the caller carries one so follow-up edits - // resume with the loaded skill/preset/research context. sessionId: options.sessionId, - // The agent works inside a dedicated deck project directory under - // the app's own appdata storage (never the user's workspace). appDataWorkspace: options.appDataWorkspace, }); if (!result?.sessionId || !result?.turnId) { @@ -183,11 +74,7 @@ function installAgentBackend(app) { }; } -// ─── Install ───────────────────────────────────────────────────────────────── - export function installBitFunBackendAdapter(app = window.app) { if (!app || app.backend?.call) return; - if (app.agent?.run) { - installAgentBackend(app); - } + if (app.agent?.run) installAgentBackend(app); } diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/deck-project-contract.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/deck-project-contract.js new file mode 100644 index 0000000000..158d562753 --- /dev/null +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/deck-project-contract.js @@ -0,0 +1,327 @@ +export class DeckProjectContractError extends Error { + constructor(diagnostic) { + super(`[${diagnostic.code}] ${diagnostic.summary}`); + this.name = 'DeckProjectContractError'; + this.diagnostic = diagnostic; + } +} + +function contractError(code, summary, continuationPrompt, details = {}) { + return new DeckProjectContractError({ + code, + summary, + continuationPrompt, + ...details, + }); +} + +function missingSlideFilesDiagnostic(missingPaths) { + return { + code: 'missing_slide_files', + summary: `Missing or incomplete slide files: ${missingPaths.join(', ')}`, + continuationPrompt: `只补写这些缺失或不完整页面:${missingPaths.join('、')}。保留其他页面不变;补齐后再把状态确认为 complete 并执行一次有界检查。`, + missingPaths, + }; +} + +const defaultSleep = (delayMs) => new Promise((resolve) => setTimeout(resolve, delayMs)); + +async function readVisibleFileWithRetry(readFile, relPath, { + maxAttempts = 6, + delayMs = 120, + sleep = defaultSleep, + accept, +} = {}) { + let lastValue = ''; + let lastError = null; + for (let attempt = 1; attempt <= maxAttempts; attempt += 1) { + try { + lastValue = String(await readFile(relPath) || ''); + if (accept(lastValue)) return lastValue; + } catch (error) { + lastError = error; + } + if (attempt < maxAttempts) await sleep(delayMs); + } + return { lastValue, lastError }; +} + +export function createDeckProjectSkeleton({ + title = '', + language = '', + style = {}, +} = {}) { + return { + status: 'planning', + title, + language, + outline: [], + slide_order: [], + style, + assumptions: [], + }; +} + +export function createDeckProjectSeed({ + hasExistingDeck = false, + title = '', + language = '', + style = {}, + slides = [], + serializeElementSlide = null, +} = {}) { + if (!hasExistingDeck) { + return { + plan: createDeckProjectSkeleton({ title, language, style }), + slideFiles: [], + }; + } + const outline = slides.map((slide, index) => { + const slideId = `slide-${String(index + 1).padStart(2, '0')}`; + return { + id: slideId, + title: String(slide?.title || ''), + bullets: [], + slide_id: slideId, + }; + }); + const slideFiles = []; + const missingPaths = []; + slides.forEach((slide, index) => { + const relPath = `slides/slide-${String(index + 1).padStart(2, '0')}.html`; + let html = String(slide?.html || ''); + if (!isCompleteSlideHtml(html) && Array.isArray(slide?.elements) && serializeElementSlide) { + try { + html = String(serializeElementSlide(slide) || ''); + } catch { + html = ''; + } + } + if (isCompleteSlideHtml(html)) slideFiles.push({ relPath, html: html.trim() }); + else missingPaths.push(relPath); + }); + const diagnostic = missingPaths.length ? missingSlideFilesDiagnostic(missingPaths) : null; + return { + plan: { + status: diagnostic ? 'planning' : 'complete', + title, + language, + outline, + slide_order: outline.map((item) => item.slide_id), + style, + assumptions: [], + }, + slideFiles, + diagnostic, + }; +} + +function seedPersistenceError(code, phase, missingPaths) { + return new DeckProjectContractError({ + code, + phase, + summary: 'Deck project seed persistence failed.', + continuationPrompt: `请在同一会话中补写这些 deck 项目路径:${missingPaths.join('、')},保留已成功写入的文件并继续生成。`, + missingPaths, + }); +} + +export async function persistDeckProjectSeed(fs, projectDir, seed) { + try { + await fs.mkdir(`${projectDir}/slides`, { recursive: true }); + } catch { + throw seedPersistenceError('seed_fs_mkdir_failed', 'mkdir', ['slides']); + } + try { + await fs.writeFile(`${projectDir}/project.json`, `${JSON.stringify(seed.plan, null, 2)}\n`); + } catch { + throw seedPersistenceError('seed_fs_write_failed', 'project-write', ['project.json']); + } + for (const slideFile of seed.slideFiles || []) { + try { + await fs.writeFile(`${projectDir}/${slideFile.relPath}`, slideFile.html); + } catch { + throw seedPersistenceError('seed_fs_write_failed', 'slide-write', [slideFile.relPath]); + } + } +} + +export function buildDeckRunRequestInput(baseInput, { + sessionId = '', + projectContractDiagnostic = null, +} = {}) { + return { + ...baseInput, + ...(sessionId ? { continueAfterInterruption: true } : {}), + ...(projectContractDiagnostic ? { projectContractDiagnostic } : {}), + }; +} + +function parseProjectJson(raw) { + try { + const plan = JSON.parse(raw); + if (!plan || Array.isArray(plan) || typeof plan !== 'object') throw new Error('root must be an object'); + return plan; + } catch (error) { + throw contractError( + 'invalid_project_json', + '`project.json` is not valid JSON.', + '修复 `project.json` JSON,使根值为对象;不要重写已有页面。修复后继续完成契约。', + { cause: String(error?.message || error) }, + ); + } +} + +export async function readProjectPlanWithRetry(readFile, options = {}) { + const { requireComplete = false } = options; + const result = await readVisibleFileWithRetry(readFile, 'project.json', { + ...options, + accept: (raw) => { + if (!raw.trim()) return false; + try { + const parsed = JSON.parse(raw); + return Boolean(parsed) + && !Array.isArray(parsed) + && typeof parsed === 'object' + && (!requireComplete || parsed.status === 'complete'); + } catch { + return false; + } + }, + }); + if (typeof result === 'string') return parseProjectJson(result); + if (!result.lastValue.trim()) { + throw contractError( + 'missing_project_json', + '`project.json` is missing or empty.', + '在工作区根目录创建 `project.json`,先写 status、outline 和 slide_order,再继续补写页面;不要重写已有页面。', + { cause: String(result.lastError?.message || result.lastError || '') }, + ); + } + return parseProjectJson(result.lastValue); +} + +function validateCompletedPlan(plan) { + if (plan.status !== 'complete') { + throw contractError( + 'project_incomplete', + '`project.json` has not declared a complete deck.', + '继续当前计划:先完成 outline 和页面文件,确认所有引用页面存在后,再把 `project.json.status` 设为 `"complete"`。', + ); + } + if (!Array.isArray(plan.outline) || !plan.outline.length) { + throw contractError( + 'invalid_project_contract', + '`outline` must be a non-empty array.', + '修复 `project.json`:先写非空 `outline`,每项提供唯一 `slide_id`,并让 `slide_order` 精确对应这些 ID。', + ); + } + if (!Array.isArray(plan.slide_order) || !plan.slide_order.length) { + throw contractError( + 'invalid_project_contract', + '`slide_order` must be a non-empty array.', + '修复 `project.json`:让 `slide_order` 按展示顺序列出全部 `outline[].slide_id`。', + ); + } + + const outlineIds = []; + const outlineItemIds = new Set(); + for (const item of plan.outline) { + const requiredFields = [ + ['id', typeof item?.id === 'string' && Boolean(item.id.trim())], + ['title', typeof item?.title === 'string' && Boolean(item.title.trim())], + ['bullets', Array.isArray(item?.bullets) && item.bullets.every((bullet) => typeof bullet === 'string')], + ]; + const invalidField = requiredFields.find(([, valid]) => !valid)?.[0]; + if (invalidField) { + throw contractError( + 'invalid_project_contract', + `Every outline item must have valid id, title, and bullets fields; invalid ${invalidField}.`, + `修复 \`project.json\` 的 \`outline[].${invalidField}\`,确保 id/title 为非空字符串且 bullets 为字符串数组;不要改无关页面。`, + { invalidOutlineField: invalidField }, + ); + } + const itemId = item.id.trim(); + if (outlineItemIds.has(itemId)) { + throw contractError( + 'invalid_project_contract', + `Every outline item id must be unique; duplicate ${itemId}.`, + '修复 `project.json` 的 `outline[].id`,确保每项 id 是唯一非空字符串;不要改无关页面。', + { invalidOutlineField: 'id' }, + ); + } + outlineItemIds.add(itemId); + const slideId = String(item.slide_id || ''); + if (!/^slide-\d{2}$/.test(slideId)) { + throw contractError( + 'invalid_project_contract', + 'Every outline item must have a `slide-NN` slide_id.', + '修复 `project.json` 的 `outline[].slide_id`,统一使用两位数 `slide-NN`,并同步 `slide_order`;不要改无关页面。', + ); + } + outlineIds.push(slideId); + } + + const orderedIds = plan.slide_order.map((value) => String(value || '')); + const uniqueOutlineIds = new Set(outlineIds); + const uniqueOrderedIds = new Set(orderedIds); + const sameIds = outlineIds.length === orderedIds.length + && uniqueOutlineIds.size === outlineIds.length + && uniqueOrderedIds.size === orderedIds.length + && outlineIds.every((id) => uniqueOrderedIds.has(id)); + if (!sameIds) { + throw contractError( + 'invalid_project_contract', + '`slide_order` and `outline[].slide_id` disagree.', + '修复 `project.json`:让 `slide_order` 与 `outline[].slide_id` 一一对应且无重复;只修复计划或缺失页面,不重写已有页面。', + { outlineSlideIds: outlineIds, slideOrder: orderedIds }, + ); + } + return orderedIds; +} + +function isCompleteSlideHtml(raw) { + const match = String(raw || '').match( + /^\uFEFF?\s*(?:]*>\s*)?]*)?>[\s\S]*?]*)?>([\s\S]*?)<\/body>[\s\S]*?<\/html>\s*$/i, + ); + if (!match) return false; + return Boolean(match[1].replace(//g, '').trim()); +} + +async function readCompleteSlideWithRetry(readFile, relPath, options) { + const result = await readVisibleFileWithRetry(readFile, relPath, { + ...options, + accept: isCompleteSlideHtml, + }); + return typeof result === 'string' ? result.trim() : null; +} + +export async function readDeckProjectContract(readFile, options = {}) { + const plan = await readProjectPlanWithRetry(readFile, { ...options, requireComplete: true }); + const slideOrder = validateCompletedPlan(plan); + const outlineById = new Map(plan.outline.map((item) => [String(item.slide_id), item])); + const slides = []; + const missingPaths = []; + + for (let index = 0; index < slideOrder.length; index += 1) { + const slideId = slideOrder[index]; + const relPath = `slides/${slideId}.html`; + const html = await readCompleteSlideWithRetry(readFile, relPath, options); + if (!html) { + missingPaths.push(relPath); + continue; + } + slides.push({ + slideId, + slideNumber: index + 1, + relPath, + outlineEntry: outlineById.get(slideId), + html, + }); + } + + if (missingPaths.length) { + throw new DeckProjectContractError(missingSlideFilesDiagnostic(missingPaths)); + } + return { plan, slides }; +} diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/element-model-html.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/element-model-html.js new file mode 100644 index 0000000000..87ac64e9f4 --- /dev/null +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/element-model-html.js @@ -0,0 +1,163 @@ +const escapeHtml = (value) => String(value ?? '') + .replaceAll('&', '&') + .replaceAll('<', '<') + .replaceAll('>', '>') + .replaceAll('"', '"') + .replaceAll("'", '''); + +const DEFAULT_THEME = { + background: '#ffffff', + ink: '#111111', + muted: '#666666', + primary: '#0f766e', + accent: '#f97316', + panel: '#ffffff', +}; + +function colorMix(hex, alpha) { + const raw = String(hex || DEFAULT_THEME.primary).replace('#', ''); + const normalized = raw.length === 3 ? raw.split('').map((value) => value + value).join('') : raw; + const parsed = Number.parseInt(normalized, 16); + if (!Number.isFinite(parsed)) return `rgba(15, 118, 110, ${alpha})`; + return `rgba(${(parsed >> 16) & 255}, ${(parsed >> 8) & 255}, ${parsed & 255}, ${alpha})`; +} + +export function resolveElementColor(value, theme = {}) { + const palette = { ...DEFAULT_THEME, ...theme }; + if (!value || value === 'transparent') return 'transparent'; + if (value === 'soft') return colorMix(palette.primary, 0.1); + if (Object.hasOwn(palette, value)) return palette[value]; + return String(value); +} + +function editorFontSize(value) { + const size = Math.max(8, Number(value) || 24); + const cqw = Math.round((size / 10.2) * 1000) / 1000; + return `clamp(8px, ${cqw}cqw, ${size}px)`; +} + +function elementStyle(element, theme, mode) { + const style = element?.style || {}; + const fontSize = Math.max(8, Number(style.fontSize) || 24); + return [ + `left:${Number(element?.x) || 0}%`, + `top:${Number(element?.y) || 0}%`, + `width:${Number(element?.w) || 0}%`, + `height:${Number(element?.h) || 0}%`, + `font-size:${mode === 'editor' ? editorFontSize(fontSize) : `${fontSize}px`}`, + `font-weight:${Number(style.fontWeight) || 600}`, + `color:${resolveElementColor(style.color || 'ink', theme)}`, + `text-align:${style.align || 'left'}`, + `background:${resolveElementColor(style.background || 'transparent', theme)}`, + `opacity:${Number.isFinite(Number(style.opacity)) ? Number(style.opacity) : 1}`, + `border-radius:${Math.max(0, Number(style.borderRadius) || 0)}px`, + ].join(';'); +} + +function semanticElementContent(element, mediaPlaceholder) { + const type = String(element?.type || 'text'); + if (type === 'list') { + return `
        ${(element.items || []).map((item) => `
      • ${escapeHtml(item)}

      • `).join('')}
      `; + } + if (type === 'metric') { + return `

      ${escapeHtml(element.text || '')}

      ${escapeHtml(element.label || '')}

      `; + } + if (type === 'chart') { + const points = Array.isArray(element.data) ? element.data : []; + const max = Math.max(1, ...points.map((point) => Math.abs(Number(point?.value) || 0))); + return `

      ${escapeHtml(element.text || '')}

      ${points.map((point) => { + const value = Number(point?.value) || 0; + const height = Math.max(8, Math.abs(value) / max * 100); + return `

      ${escapeHtml(point?.label || '')}

      ${escapeHtml(value)}

      `; + }).join('')}
      `; + } + if (type === 'media') { + const source = element.src || element.url || element.dataUrl || element.imageUrl || ''; + const caption = element.text || element.label || mediaPlaceholder; + return `
      ${source ? `${escapeHtml(caption)}` : ''}

      ${escapeHtml(caption)}

      `; + } + const text = element.text || ''; + return text ? `

      ${escapeHtml(text)}

      ` : ''; +} + +function editorElementContent(element, mediaPlaceholder, editable) { + const type = String(element?.type || 'text'); + if (type === 'list') { + return `
        ${(element.items || []).map((item, index) => editable + ? `
      • ${escapeHtml(item)}
      • ` + : `
      • ${escapeHtml(item)}
      • `).join('')}
      `; + } + if (type === 'metric') { + return `${escapeHtml(element.text)}${escapeHtml(element.label)}`; + } + if (type === 'chart') { + const points = Array.isArray(element.data) ? element.data : []; + const max = Math.max(1, ...points.map((point) => Number(point?.value) || 0)); + return `${escapeHtml(element.text)}
      ${points.map((point) => `${escapeHtml(point?.label)}`).join('')}
      `; + } + if (type === 'media') return `${escapeHtml(element.text || mediaPlaceholder)}`; + return editable + ? `${escapeHtml(element.text || '')}` + : escapeHtml(element.text || ''); +} + +export function elementModelElementHtml(element = {}, theme = {}, { + mode = 'semantic', + editable = false, + selectedId = '', + mediaPlaceholder = 'Media placeholder', +} = {}) { + const type = String(element.type || 'text'); + const selected = mode === 'editor' && editable && selectedId === element.id; + const content = mode === 'editor' + ? editorElementContent(element, mediaPlaceholder, editable) + : semanticElementContent(element, mediaPlaceholder); + return `
      ${content}${selected ? '' : ''}
      `; +} + +export function buildElementSlideHtml(slide = {}) { + const theme = { ...DEFAULT_THEME, ...(slide.theme || {}) }; + const elements = Array.isArray(slide.elements) ? slide.elements : []; + const fallback = elements.length + ? '' + : `

      ${escapeHtml(slide.title || 'Slide')}

      ${slide.subtitle || slide.claim ? `

      ${escapeHtml(slide.subtitle || slide.claim)}

      ` : ''}
      `; + return ` + + + + +${escapeHtml(slide.title || 'Slide')} + + + + ${elements.map((element) => elementModelElementHtml(element, theme)).join('\n ')} + ${fallback} + +`; +} diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-diagnostics.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-diagnostics.js new file mode 100644 index 0000000000..95c71005af --- /dev/null +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-diagnostics.js @@ -0,0 +1,133 @@ +const DIAGNOSTIC_REASONS = { + 'en-US': { + active_content_removed: 'Unsafe active content was removed.', + canvas_overflow: 'Slide content exceeded the canvas; visual fallback was used.', + canvas_size: 'Slide dimensions could not preserve native fidelity; visual fallback was used.', + text_out_of_bounds: 'Text exceeded the slide boundary; visual fallback was used.', + bottom_safety_margin: 'Text entered the bottom safety margin; visual fallback was used.', + css_gradient: 'A CSS gradient required visual fallback.', + css_filter: 'A CSS filter required visual fallback.', + generated_content: 'Generated CSS content required visual fallback.', + page_visual_fallback: 'A page visual fallback preserved the slide appearance.', + full_page_fallback: 'A full-page visual fallback preserved the slide appearance.', + unreadable_document: 'The slide document could not be read.', + unmeasurable_canvas: 'The slide canvas could not be measured.', + pptx_serialization: 'The slide could not be serialized to PPTX.', + full_page_raster_failed: 'The final visual fallback could not be rendered.', + }, + 'zh-CN': { + active_content_removed: '已移除不安全的活动内容。', + canvas_overflow: '页面内容超出幻灯片边界,已切换视觉兜底。', + canvas_size: '页面尺寸无法保证原生保真,已切换视觉兜底。', + text_out_of_bounds: '文字超出幻灯片边界,已切换视觉兜底。', + bottom_safety_margin: '文字进入底部安全边距,已切换视觉兜底。', + css_gradient: 'CSS 渐变已使用视觉兜底。', + css_filter: 'CSS 滤镜已使用视觉兜底。', + generated_content: 'CSS 生成内容已使用视觉兜底。', + page_visual_fallback: '已使用页面视觉兜底保留外观。', + full_page_fallback: '已使用整页视觉兜底保留外观。', + unreadable_document: '无法读取幻灯片文档。', + unmeasurable_canvas: '无法测量幻灯片画布。', + pptx_serialization: '无法将幻灯片序列化为 PPTX。', + full_page_raster_failed: '最终视觉兜底渲染失败。', + }, +}; + +const UNKNOWN_REASON = { + 'en-US': 'Export encountered a protected internal error.', + 'zh-CN': '导出遇到已保护的内部错误。', +}; + +export function sanitizeDiagnosticSourceId(value) { + const safe = String(value || '').replace(/[^a-zA-Z0-9_-]/g, '').slice(0, 48); + return safe || null; +} + +export function formatLocalizedExportDiagnostic(diagnostic = {}, locale = 'en-US') { + const resolvedLocale = locale === 'zh-CN' ? locale : 'en-US'; + const reason = DIAGNOSTIC_REASONS[resolvedLocale][diagnostic.code] + || UNKNOWN_REASON[resolvedLocale]; + return { + slideNumber: Number.isFinite(diagnostic.slideNumber) ? diagnostic.slideNumber : diagnostic.slideNumber, + sourceId: sanitizeDiagnosticSourceId(diagnostic.sourceId), + phase: String(diagnostic.phase || '').replace(/[^a-z-]/g, '').slice(0, 32) || null, + severity: diagnostic.severity === 'blocking' ? 'blocking' : diagnostic.severity, + code: String(diagnostic.code || 'unknown').replace(/[^a-z0-9_-]/gi, '').slice(0, 64), + reason: reason.slice(0, 120), + }; +} + +export function localizeExportDiagnosticLocations(locations = [], locale = 'en-US') { + return locations.map((location) => formatLocalizedExportDiagnostic(location, locale)); +} + +export function summarizePptxExportDiagnostics(preparedSlides = []) { + const counts = { + repaired: 0, + svgImage: 0, + localPng: 0, + pageVisual: 0, + fullPage: 0, + blocking: 0, + }; + const locations = []; + const seen = new Set(); + const addLocation = (slideNumber, item, defaults = {}) => { + const location = { + slideNumber, + sourceId: item?.sourceId || defaults.sourceId || null, + phase: item?.phase || defaults.phase || null, + severity: item?.severity || defaults.severity || 'fallback', + code: item?.code || defaults.code || null, + reason: item?.reason || item?.message || defaults.reason || null, + }; + const key = [ + location.slideNumber, + location.sourceId, + location.phase, + location.severity, + location.code, + ].join(':'); + if (seen.has(key)) return; + seen.add(key); + locations.push(location); + }; + + preparedSlides.forEach((prepared, arrayIndex) => { + const slideNumber = (prepared?.index ?? arrayIndex) + 1; + const slideData = prepared?.slideData || {}; + (slideData.diagnostics || []).forEach((diagnostic) => { + if (diagnostic.severity === 'repaired') counts.repaired += 1; + if (diagnostic.severity === 'blocking') counts.blocking += 1; + if (diagnostic.severity === 'repaired' || diagnostic.severity === 'blocking' + || diagnostic.phase || diagnostic.sourceId) { + addLocation(slideNumber, diagnostic); + } + }); + (slideData.fallbackLayers || []).forEach((layer) => { + if (layer.kind === 'svg-image') counts.svgImage += 1; + if (layer.kind === 'raster' && layer.phase === 'local-visual') counts.localPng += 1; + if (layer.kind === 'raster' && layer.phase === 'page-visual') counts.pageVisual += 1; + addLocation(slideNumber, layer, { + severity: 'fallback', + code: layer.kind === 'svg-image' ? 'svg_image_fallback' : 'png_visual_fallback', + }); + }); + if (slideData.fullPageFallback) { + counts.fullPage += 1; + addLocation(slideNumber, slideData.fullPageFallback, { + severity: 'fallback', + code: 'full_page_fallback', + phase: 'full-page', + }); + } + }); + + return { + counts, + locations, + hasWarnings: counts.repaired + counts.svgImage + counts.localPng + + counts.pageVisual + counts.fullPage > 0, + hasBlocking: counts.blocking > 0, + }; +} diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-html.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-html.js index dec8af5c4b..deba9cfcba 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-html.js +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-html.js @@ -1,6 +1,7 @@ import { escapeHtml } from './state.js'; import { getLocale } from './i18n.js'; import { normalizeSlideDocument, slideHtml } from './render.js'; +import { sanitizeSlideMarkup } from './sanitize-slide-markup.js'; export function buildHtmlDeck(state) { if ((state.slides || []).some((slide) => slide.html)) { @@ -28,7 +29,7 @@ ${deckCss()} function buildSourceHtmlDeck(state) { const slides = (state.slides || []) .map((slide, index) => `
      - +
      `) .join('\n'); return ` diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-slide-browser.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-slide-browser.js index e992c30545..fc6b5679e0 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-slide-browser.js +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/export-slide-browser.js @@ -5,18 +5,30 @@ // 1. Mount slide HTML in an off-screen shadow-DOM div (1280×720) // 2. sanitizeSlideDocumentRoot() — normalize/repair the HTML for export // 3. extractSlideDataFromDocument() — walk DOM → structured slideData -// 4. Optionally rasterize a background layer (text hidden) for visual fidelity +// 4. Rasterize isolated local visual layers when native/SVG mapping is unsafe +// 5. Escalate failed local captures to page-visual, then full-page fallback // // The prepared slideData is then passed to export-deck-browser.js → // pptx-html-build.js for the actual PPTX generation. // ───────────────────────────────────────────────────────────────────────────── import { normalizeSlideDocument, scopeSlideAuthorStyles } from './render.js'; +import { sanitizeSlideDocument, sanitizeSlideMarkup } from './sanitize-slide-markup.js'; import { sanitizeSlideDocumentRoot } from './sanitize-slide-html.js'; import { extractSlideDataFromDocument, measureBodyDimensions } from './html2pptx-dom-core.js'; +import { buildElementSlideHtml } from './element-model-html.js'; +import { + buildPageVisualFallbackRequest, + buildRasterFallbackRequests, + buildWholePageVisualFallbackRequest, + renderRasterFallbackPlan, +} from './fallback-layer-render.js'; + +export { buildElementSlideHtml }; export const EXPORT_VIEWPORT = { width: 1280, height: 720 }; const RASTER_TEXT_TYPES = new Set(['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'text', 'list', 'merged-text']); +const EDITABLE_TEXT_TYPES = new Set([...RASTER_TEXT_TYPES, 'svg-text']); export function countVectorTextElements(slideData) { return (slideData?.elements || []).filter((el) => RASTER_TEXT_TYPES.has(el.type)).length; @@ -94,11 +106,14 @@ function wrapExportDocument(root, body) { body, documentElement: root, defaultView: window, + querySelector: (sel) => root.querySelector(sel), querySelectorAll: (sel) => root.querySelectorAll(sel), createElement: (tag) => document.createElement(tag), + createTreeWalker: (...args) => document.createTreeWalker(...args), getElementById: (id) => root.querySelector(`#${id}`), head: root.querySelector('style')?.parentElement || root, _exportRoot: root, + _pptxSecurityDiagnostics: body._pptxSecurityDiagnostics || [], }; } @@ -141,7 +156,7 @@ async function waitForExportPaint() { } function mountMarkupOnRoot(root, markup) { - const parsed = new DOMParser().parseFromString(markup, 'text/html'); + const parsed = sanitizeSlideDocument(new DOMParser().parseFromString(markup, 'text/html')); root.replaceChildren(); parsed.querySelectorAll('style').forEach((node) => { @@ -151,6 +166,7 @@ function mountMarkupOnRoot(root, markup) { }); const body = document.createElement('div'); + body._pptxSecurityDiagnostics = parsed._pptxSecurityDiagnostics || []; body.className = 'ppt-export-body'; if (parsed.body) { for (const attr of parsed.body.attributes) { @@ -206,16 +222,106 @@ function elementLabel(element) { * these findings as repair requirements rather than silently rasterizing or * flattening unsupported HTML. */ +export function analyzeMountedSlideForPptx(doc, source = '') { + if (!doc?.body) { + return { + valid: false, + issues: [{ + severity: 'blocking', + kind: 'blocking', + code: 'unreadable_document', + message: 'The slide document could not be read.', + sourceId: 'slide-document', + }], + }; + } + const issues = [...(doc._pptxSecurityDiagnostics || [])]; + const seen = new Set(issues.map((item) => `${item.code}:${item.sourceId || ''}`)); + const add = (code, message, element = null, severity = 'fallback') => { + const sourceId = element?.dataset?.pptxSourceId || element?.id || null; + const key = `${code}:${sourceId || ''}`; + if (seen.has(key)) return; + seen.add(key); + issues.push({ + severity, + kind: severity === 'blocking' ? 'blocking' : undefined, + code, + message, + sourceId, + tag: element?.tagName?.toLowerCase?.() || null, + }); + }; + const body = doc.body; + if (body.querySelector('script,iframe,object,embed,base,meta[http-equiv="refresh" i],foreignObject,maction')) { + add('active_content_residual', 'Active content remained after sanitization.', body, 'blocking'); + } + if (!String(source || '').trim() || !/<\/html>\s*$/i.test(String(source || '').trim())) { + add('incomplete_html', 'The slide document is incomplete.', body, 'blocking'); + } + let bodyRect; + try { + bodyRect = body.getBoundingClientRect(); + if (!(bodyRect.width > 0) || !(bodyRect.height > 0)) { + add('unmeasurable_canvas', 'The slide canvas could not be measured.', body, 'blocking'); + } + } catch { + add('unmeasurable_canvas', 'The slide canvas could not be measured.', body, 'blocking'); + } + if (bodyRect) { + if (Math.abs(bodyRect.width - EXPORT_VIEWPORT.width) > 2 + || Math.abs(bodyRect.height - EXPORT_VIEWPORT.height) > 2) { + add('canvas_size', 'The slide canvas size requires page visual fallback.', body); + } + const dimensions = measureBodyDimensions(doc); + if (dimensions.errors?.length) { + add('canvas_overflow', 'Slide content exceeds the canvas.', body); + } + const view = doc.defaultView || window; + body.querySelectorAll('p,h1,h2,h3,h4,h5,h6,li').forEach((element) => { + const rect = element.getBoundingClientRect(); + if (rect.width <= 0 || rect.height <= 0) return; + if (rect.left < bodyRect.left - 1 || rect.top < bodyRect.top - 1 + || rect.right > bodyRect.right + 1 || rect.bottom > bodyRect.bottom + 1) { + add('text_out_of_bounds', 'Text extends outside the slide canvas.', element); + } + const computed = view.getComputedStyle(element); + if (parseFloat(computed.fontSize || 0) > 12 && rect.bottom > bodyRect.bottom - 48) { + add('bottom_safety_margin', 'Text enters the bottom safety margin.', element); + } + }); + } + return { valid: issues.length === 0, issues: issues.slice(0, 32) }; +} + export async function validateSlideForPptxGeneration(html) { + let exportRoot = null; + try { + const doc = await loadHtmlInExportRoot(html); + exportRoot = doc._exportRoot; + sanitizeSlideDocumentRoot(doc); + await waitForExportPaint(); + return analyzeMountedSlideForPptx(doc, html); + } finally { + if (exportRoot) removeExportRoot(exportRoot); + } +} + +async function validateSlideForPptxGenerationLegacy(html) { const source = String(html || '').trim(); const issues = []; const seen = new Set(); - const add = (code, message, element = null) => { + const add = (code, message, element = null, severity = 'fallback') => { const suffix = element ? ` (${elementLabel(element)})` : ''; const key = `${code}:${message}${suffix}`; if (seen.has(key)) return; seen.add(key); - issues.push({ code, message: `${message}${suffix}` }); + issues.push({ + severity, + code, + message: `${message}${suffix}`, + sourceId: element?.dataset?.pptxSourceId || element?.id || null, + tag: element?.tagName?.toLowerCase?.() || null, + }); }; if (!source || !/<\/html>\s*$/i.test(source)) { @@ -237,6 +343,19 @@ export async function validateSlideForPptxGeneration(html) { exportRoot = doc._exportRoot; const view = doc.defaultView || window; const body = doc.body; + const sourceElements = [body, ...body.querySelectorAll('*')]; + const usedSourceIds = new Set( + sourceElements.map((element) => element.dataset.pptxSourceId).filter(Boolean), + ); + let sourceSequence = 1; + sourceElements.forEach((element) => { + if (element.dataset.pptxSourceId) return; + while (usedSourceIds.has(`pptx-source-${sourceSequence}`)) sourceSequence += 1; + const sourceId = `pptx-source-${sourceSequence}`; + element.dataset.pptxSourceId = sourceId; + usedSourceIds.add(sourceId); + sourceSequence += 1; + }); const bodyRect = body.getBoundingClientRect(); const bodyDimensions = measureBodyDimensions(doc); bodyDimensions.errors.forEach((message) => add('canvas_overflow', message)); @@ -318,9 +437,19 @@ export async function validateSlideForPptxGeneration(html) { try { const slideData = extractSlideDataFromDocument(doc); - (slideData.errors || []).forEach((message) => add('pptx_conversion', message)); + (slideData.diagnostics || []).forEach((diagnostic) => { + const key = `${diagnostic.code}:${diagnostic.message}:${diagnostic.sourceId || ''}`; + if (seen.has(key)) return; + seen.add(key); + issues.push(diagnostic); + }); } catch (error) { - add('pptx_conversion', String(error?.message || error || 'PPTX conversion validation failed.')); + add( + 'pptx_serialization', + String(error?.message || error || 'PPTX conversion validation failed.'), + null, + 'blocking', + ); } } finally { if (exportRoot) removeExportRoot(exportRoot); @@ -337,23 +466,60 @@ async function prepareSlideOnce(html, aggressive, options = {}) { try { const doc = await loadHtmlInExportRoot(html); exportRoot = doc._exportRoot; - sanitizeSlideDocumentRoot(doc, aggressive); + const repairResult = sanitizeSlideDocumentRoot(doc, aggressive); await waitForExportPaint(); const bodyDimensions = measureBodyDimensions(doc); const slideData = extractSlideDataFromDocument(doc); - // Content overflow must never block the export: clip/off-slide content is - // preferable to a failed run. Demote overflow findings to warnings. + const analysis = analyzeMountedSlideForPptx(doc, html); + const mergedDiagnostics = [ + ...(analysis.issues || []), + ...(repairResult?.diagnostics || []), + ...(slideData.diagnostics || []), + ]; + const diagnosticKeys = new Set(); + const diagnostics = mergedDiagnostics.filter((diagnostic) => { + const key = `${diagnostic.severity}:${diagnostic.code}:${diagnostic.sourceId || ''}`; + if (diagnosticKeys.has(key)) return false; + diagnosticKeys.add(key); + return true; + }); + slideData.diagnostics = diagnostics; + const rasterRequests = buildRasterFallbackRequests(doc, diagnostics); + const pageFallbackCodes = new Set([ + 'canvas_size', 'canvas_overflow', 'text_out_of_bounds', 'bottom_safety_margin', + ]); + const pageFallbackDiagnostics = diagnostics.filter((item) => pageFallbackCodes.has(item.code)); + const nativeVisualSourceIds = [...new Set( + (slideData.elements || []) + .filter((element) => !EDITABLE_TEXT_TYPES.has(element.type)) + .map((element) => element.sourceId) + .filter(Boolean), + )]; + const pageVisualRequest = pageFallbackDiagnostics.length + ? buildWholePageVisualFallbackRequest( + doc, + pageFallbackDiagnostics, + nativeVisualSourceIds, + ) + : buildPageVisualFallbackRequest(doc, rasterRequests); const overflowWarnings = bodyDimensions.errors || []; - if (overflowWarnings.length) { - console.warn('[ppt-live-export] slide overflows canvas; exporting anyway:', overflowWarnings.join('; ')); - } const safeBodyDimensions = { ...bodyDimensions, errors: [] }; - const errors = slideData.errors || []; - if (!errors.length || options.allowValidationErrors) { - return { slideData, bodyDimensions: safeBodyDimensions, aggressive, warnings: overflowWarnings }; + const blocking = diagnostics.filter((diagnostic) => diagnostic.severity === 'blocking'); + if (!blocking.length || options.allowValidationErrors) { + return { + slideData, + bodyDimensions: safeBodyDimensions, + diagnostics, + rasterRequests, + pageVisualRequest, + aggressive, + warnings: overflowWarnings, + }; } - return { error: new Error(errors.join('\n')) }; + const error = new Error(blocking.map((diagnostic) => diagnostic.message).join('\n')); + error.diagnostics = blocking; + return { error }; } finally { if (exportRoot) removeExportRoot(exportRoot); } @@ -374,34 +540,46 @@ export async function prepareSlidesForPptxExport(slides, options = {}) { for (const [index, slide] of slides.entries()) { if (!slide?.html) continue; const item = await prepareSlideForPptxExport(slide.html, options); - let rasterBase64 = null; - const vectorTextCount = countVectorTextElements(item.slideData); - const rasterOnly = vectorTextCount === 0; - // Always render a raster background when the host WebView is available. - // For slides with vector text, slideHtmlForRasterBackdrop hides ALL text - // via universal CSS — the raster contains only visual elements (backgrounds, - // borders, images) and the vector layer overlays editable text. This - // avoids text-overlap from tag-based selective hiding. - if (typeof options.renderRaster === 'function') { - try { - if (typeof options.onRasterProgress === 'function') { - options.onRasterProgress(index, slide); - } - const rasterHtml = rasterOnly - ? slideExportHtml(slide) - : slideHtmlForRasterBackdrop(slide.html); - rasterBase64 = await options.renderRaster(rasterHtml, index); - } catch { - rasterBase64 = null; - } + if (item.rasterRequests?.length && typeof options.onRasterProgress === 'function') { + options.onRasterProgress(index, slide); + } + const rasterResult = await renderRasterFallbackPlan({ + localRequests: item.rasterRequests || [], + pageVisualRequest: item.pageVisualRequest, + fullPageRequest: { + sourceId: `slide-${index + 1}`, + zIndex: 0, + paintOrder: 0, + kind: 'raster', + phase: 'full-page', + bbox: { x: 0, y: 0, w: 13.333, h: 7.5 }, + buildHtml: () => slideExportHtml(slide), + diagnostics: [], + }, + }, options.renderRaster, index); + if (rasterResult.blocking) { + const error = new Error( + rasterResult.diagnostics.map((diagnostic) => diagnostic.message).join('\n') + || `Slide ${index + 1} fallback rendering failed`, + ); + error.diagnostics = rasterResult.diagnostics; + throw error; } + item.slideData.fallbackLayers = [ + ...(item.slideData.fallbackLayers || []), + ...rasterResult.layers, + ]; + item.slideData.fullPageFallback = rasterResult.fullPageFallback; + item.slideData.diagnostics = [ + ...(item.slideData.diagnostics || []), + ...rasterResult.diagnostics, + ]; prepared.push({ index, slideId: slide.id, notes: slide, ...item, - rasterBase64, - rasterOnly: Boolean(rasterBase64 && rasterOnly), + fallbackDiagnostics: rasterResult.diagnostics, }); } return prepared; @@ -410,45 +588,7 @@ export async function prepareSlidesForPptxExport(slides, options = {}) { } } -export function buildElementSlideHtml(slide = {}) { - const theme = slide.theme || {}; - const title = String(slide.title || 'Slide').replace(/[<>&]/g, (ch) => ({ - '<': '<', '>': '>', '&': '&', - })[ch] || ch); - const subtitle = String(slide.subtitle || slide.claim || '').replace(/[<>&]/g, (ch) => ({ - '<': '<', '>': '>', '&': '&', - })[ch] || ch); - const background = theme.background || '#ffffff'; - const ink = theme.ink || '#111111'; - const muted = theme.muted || '#666666'; - return ` - - - - - - -

      ${title}

      - ${subtitle ? `

      ${subtitle}

      ` : ''} - -`; -} - export function slideExportHtml(slide) { - if (slide?.html) return normalizeSlideDocument(slide.html); - return buildElementSlideHtml(slide); + if (slide?.html) return sanitizeSlideMarkup(normalizeSlideDocument(slide.html)); + return sanitizeSlideMarkup(buildElementSlideHtml(slide)); } diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/fallback-layer-render.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/fallback-layer-render.js new file mode 100644 index 0000000000..a1697bf577 --- /dev/null +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/fallback-layer-render.js @@ -0,0 +1,516 @@ +import { buildDomPaintOrderMap } from './paint-order.js'; + +const EXPORT_WIDTH = 1280; +const EXPORT_HEIGHT = 720; +const LOCAL_RASTER_CODES = new Set([ + 'css_gradient', + 'css_filter', + 'computed_gradient', + 'generated_content', + 'container_background_image', + 'merge_background_image', + 'complex_svg_raster', +]); + +function rasterLayerZIndex(element, view) { + let current = element; + while (current) { + const raw = view.getComputedStyle(current).zIndex; + if (raw && raw !== 'auto') { + const parsed = parseInt(raw, 10); + if (Number.isFinite(parsed)) return parsed; + } + current = current.parentElement; + } + return 0; +} + +function escapedAttributeValue(value) { + return String(value).replace(/["\\]/g, '\\$&'); +} + +function serializeRasterTargetDocument(doc, targetSpecs) { + const targets = (Array.isArray(targetSpecs) ? targetSpecs : [targetSpecs]).map((target) => ( + typeof target === 'string' + ? { sourceId: target, captureStrategy: 'visual-subtree' } + : target + )); + const sourceRoot = doc._exportRoot || doc.documentElement; + const sourceBody = doc.body; + const bodyClone = sourceBody.cloneNode(true); + let targetCount = 0; + targets.forEach(({ sourceId, captureStrategy }) => { + const target = bodyClone.querySelector( + `[data-pptx-source-id="${escapedAttributeValue(sourceId)}"]`, + ) || (bodyClone.dataset?.pptxSourceId === sourceId ? bodyClone : null); + if (!target) return; + target.setAttribute('data-pptx-raster-target', '1'); + target.setAttribute('data-pptx-capture-strategy', captureStrategy); + targetCount += 1; + }); + if (!targetCount) return null; + + const authorStyles = [...sourceRoot.querySelectorAll('style')] + .map((style) => style.textContent || '') + .join('\n'); + const bodyAttributes = [...bodyClone.attributes] + .filter((attribute) => !['class', 'style'].includes(attribute.name)) + .map((attribute) => ` ${attribute.name}="${String(attribute.value).replace(/"/g, '"')}"`) + .join(''); + const isolationCss = ` +html, body, .ppt-export-root, .ppt-export-body { + margin: 0 !important; + padding: 0 !important; + width: ${EXPORT_WIDTH}px !important; + height: ${EXPORT_HEIGHT}px !important; + overflow: hidden !important; + background: transparent !important; + background-color: transparent !important; +} +.ppt-export-body [data-pptx-source-id] { + visibility: hidden !important; +} +.ppt-export-body [data-pptx-raster-target="1"], +.ppt-export-body [data-pptx-capture-strategy="visual-subtree"] * { + visibility: visible !important; +} +.ppt-export-body [data-pptx-capture-strategy="self-decoration"] > *, +.ppt-export-body [data-pptx-capture-strategy="pseudo-only"] > * { + visibility: hidden !important; +} +.ppt-export-body [data-pptx-capture-strategy="pseudo-only"] { + background: none !important; + background-image: none !important; + border-color: transparent !important; + box-shadow: none !important; + filter: none !important; +} +.ppt-export-body [data-pptx-raster-target="1"] :is(p,h1,h2,h3,h4,h5,h6,li,span,a,small,label,code,b,strong,i,em,u,mark,sub,sup), +.ppt-export-body [data-pptx-raster-target="1"]:is(p,h1,h2,h3,h4,h5,h6,li,span,a,small,label,code,b,strong,i,em,u,mark,sub,sup) { + color: transparent !important; + -webkit-text-fill-color: transparent !important; + text-shadow: none !important; +} +.ppt-export-body [data-pptx-raster-target="1"] ::marker { + color: transparent !important; + -webkit-text-fill-color: transparent !important; +} +.ppt-export-body [data-pptx-raster-target="1"] svg text, +.ppt-export-body svg[data-pptx-raster-target="1"] text { + visibility: hidden !important; +} +`; + return `
      ${bodyClone.innerHTML}
      `; +} + +export function buildRasterFallbackRequests(doc, diagnostics = []) { + const bodyRect = doc.body.getBoundingClientRect(); + const view = doc.defaultView || globalThis.window; + const sourceOrder = buildDomPaintOrderMap(doc); + const grouped = new Map(); + diagnostics.forEach((diagnostic) => { + if (!LOCAL_RASTER_CODES.has(diagnostic.code) || !diagnostic.sourceId) return; + const captureStrategy = diagnostic.code === 'generated_content' + ? 'pseudo-only' + : (['css_filter', 'complex_svg_raster'].includes(diagnostic.code) + ? 'visual-subtree' + : 'self-decoration'); + const key = `${diagnostic.sourceId}:${captureStrategy}`; + if (!grouped.has(key)) { + grouped.set(key, { + sourceId: diagnostic.sourceId, + captureStrategy, + diagnostics: [], + }); + } + grouped.get(key).diagnostics.push(diagnostic); + }); + const requests = []; + grouped.forEach(({ sourceId, captureStrategy, diagnostics: sourceDiagnostics }) => { + const element = doc.body.dataset?.pptxSourceId === sourceId + ? doc.body + : doc.body.querySelector( + `[data-pptx-source-id="${escapedAttributeValue(sourceId)}"]`, + ); + const failureRequest = (code, reason, details = {}) => ({ + sourceId, + zIndex: details.zIndex ?? 0, + paintOrder: sourceOrder.get(sourceId) ?? requests.length, + subOrder: 0, + kind: 'raster', + phase: 'local-visual', + canvas: 'full-page', + captureStrategy, + suppressedNativeVisualIds: [], + bbox: details.bbox || { x: 0, y: 0, w: 0, h: 0 }, + diagnostics: sourceDiagnostics, + buildFailure: { + code, + stage: 'request-build', + reason, + }, + }); + if (!element) { + requests.push(failureRequest( + 'local_raster_target_missing', + `Raster fallback source "${sourceId}" is not present in the export document.`, + )); + return; + } + let rect; + try { + rect = element.getBoundingClientRect(); + } catch (error) { + requests.push(failureRequest( + 'local_raster_serialize_failed', + `Raster fallback source "${sourceId}" could not be measured: ${String(error?.message || error)}`, + { zIndex: rasterLayerZIndex(element, view) }, + )); + return; + } + const bbox = { + x: (rect.left - bodyRect.left) / 96, + y: (rect.top - bodyRect.top) / 96, + w: rect.width / 96, + h: rect.height / 96, + }; + if (!(rect.width > 0) || !(rect.height > 0)) { + requests.push(failureRequest( + 'local_raster_unmeasurable', + `Raster fallback source "${sourceId}" has no measurable width or height.`, + { zIndex: rasterLayerZIndex(element, view), bbox }, + )); + return; + } + try { + if (!serializeRasterTargetDocument(doc, { sourceId, captureStrategy })) { + throw new Error('Raster target was not retained in the export document.'); + } + } catch (error) { + requests.push(failureRequest( + 'local_raster_serialize_failed', + `Raster fallback source "${sourceId}" could not be serialized: ${String(error?.message || error)}`, + { zIndex: rasterLayerZIndex(element, view), bbox }, + )); + return; + } + const suppressedNativeVisualIds = captureStrategy === 'pseudo-only' + ? [] + : (captureStrategy === 'self-decoration' + ? [sourceId] + : [element, ...element.querySelectorAll('[data-pptx-source-id]')] + .map((item) => item.dataset?.pptxSourceId) + .filter(Boolean)); + requests.push({ + sourceId, + zIndex: rasterLayerZIndex(element, view), + paintOrder: sourceOrder.get(sourceId) ?? requests.length, + subOrder: 0, + kind: 'raster', + phase: 'local-visual', + canvas: 'full-page', + captureStrategy, + suppressedNativeVisualIds: [...new Set(suppressedNativeVisualIds)], + bbox, + buildHtml: () => serializeRasterTargetDocument(doc, { sourceId, captureStrategy }), + diagnostics: sourceDiagnostics, + }); + }); + return requests.sort((a, b) => a.zIndex - b.zIndex || a.paintOrder - b.paintOrder); +} + +export function buildPageVisualFallbackRequest(doc, localRequests = []) { + const sourceIds = [...new Set(localRequests.map((request) => request.sourceId).filter(Boolean))]; + if (!sourceIds.length) return null; + const targetSpecs = localRequests.map((request) => ({ + sourceId: request.sourceId, + captureStrategy: request.captureStrategy, + })); + const request = { + sourceId: 'slide-visuals', + sourceIds, + captureStrategy: 'page-visual', + suppressedNativeVisualIds: [...new Set( + localRequests.flatMap((request) => request.suppressedNativeVisualIds || []), + )], + zIndex: Math.min(...localRequests.map((request) => request.zIndex ?? 0)), + paintOrder: Math.min(...localRequests.map((request) => request.paintOrder ?? 0)), + subOrder: Math.min(...localRequests.map((request) => request.subOrder ?? 0)), + kind: 'raster', + phase: 'page-visual', + canvas: 'full-page', + bbox: { x: 0, y: 0, w: 13.333, h: 7.5 }, + diagnostics: localRequests.flatMap((request) => request.diagnostics || []), + }; + const missingSourceIds = localRequests + .filter((localRequest) => localRequest.buildFailure?.code === 'local_raster_target_missing') + .map((localRequest) => localRequest.sourceId); + if (missingSourceIds.length) { + return { + ...request, + buildFailure: { + code: 'page_visual_target_missing', + stage: 'request-build', + reason: `Page-visual fallback cannot cover missing sources: ${missingSourceIds.join(', ')}.`, + }, + }; + } + try { + if (!serializeRasterTargetDocument(doc, targetSpecs)) { + return { + ...request, + buildFailure: { + code: 'page_visual_target_missing', + stage: 'request-build', + reason: `Page-visual fallback could not locate any requested sources: ${sourceIds.join(', ')}.`, + }, + }; + } + return { + ...request, + buildHtml: () => serializeRasterTargetDocument(doc, targetSpecs), + }; + } catch (error) { + return { + ...request, + buildFailure: { + code: 'page_visual_serialize_failed', + stage: 'request-build', + reason: `Page-visual fallback could not be serialized: ${String(error?.message || error)}`, + }, + }; + } +} + +export function buildWholePageVisualFallbackRequest( + doc, + diagnostics = [], + suppressedNativeVisualIds = [], +) { + const bodySourceId = doc?.body?.dataset?.pptxSourceId; + if (!bodySourceId) { + return { + sourceId: 'slide-visuals', + phase: 'page-visual', + kind: 'raster', + bbox: { x: 0, y: 0, w: 13.333, h: 7.5 }, + diagnostics, + suppressedNativeVisualIds: [...new Set(suppressedNativeVisualIds)], + buildFailure: { + code: 'page_visual_target_missing', + stage: 'request-build', + reason: 'Whole-page visual source is unavailable.', + }, + }; + } + const request = buildPageVisualFallbackRequest(doc, [{ + sourceId: bodySourceId, + captureStrategy: 'visual-subtree', + suppressedNativeVisualIds: [...new Set(suppressedNativeVisualIds)], + zIndex: 0, + paintOrder: 0, + subOrder: 0, + diagnostics, + }]); + return { + ...request, + sourceId: 'slide-visuals', + sourceIds: [bodySourceId], + captureStrategy: 'whole-page-visual', + }; +} + +export async function renderRasterFallbackLayers(requests, renderRaster, slideIndex) { + const layers = []; + const failures = []; + if (typeof renderRaster !== 'function') { + return { layers, failures: [...requests] }; + } + for (const request of requests) { + if (request.buildFailure) { + failures.push({ + ...request, + error: request.buildFailure.reason, + }); + continue; + } + try { + const html = typeof request.buildHtml === 'function' ? request.buildHtml() : request.html; + if (!html) throw new Error('Raster fallback HTML could not be generated'); + const rendered = await renderRaster(html, slideIndex, { + sourceId: request.sourceId, + bbox: request.bbox, + zIndex: request.zIndex, + paintOrder: request.paintOrder, + subOrder: request.subOrder, + phase: request.phase, + captureStrategy: request.captureStrategy, + suppressedNativeVisualIds: request.suppressedNativeVisualIds || [], + }); + const raw = String(rendered || '').replace(/^data:.*;base64,/, ''); + if (!raw) throw new Error('Raster renderer returned no PNG data'); + layers.push({ + ...request, + buildHtml: undefined, + html: undefined, + data: `data:image/png;base64,${raw}`, + }); + } catch (error) { + failures.push({ ...request, error: String(error?.message || error) }); + } + } + return { layers, failures }; +} + +function failureDiagnostic(code, failure, slideIndex, severity = 'fallback') { + const reason = failure.buildFailure?.reason || failure.error; + return { + severity, + kind: severity === 'blocking' ? 'blocking' : undefined, + code: failure.buildFailure?.code || code, + message: `${failure.phase || 'raster'} fallback failed for ${failure.sourceId || 'slide visual'}: ${reason}`, + sourceId: failure.sourceId || null, + slideNumber: slideIndex + 1, + phase: failure.phase || null, + stage: failure.buildFailure?.stage || 'render', + reason, + }; +} + +export async function renderRasterFallbackPlan(plan, renderRaster, slideIndex) { + const diagnostics = []; + if (plan.pageVisualRequest?.captureStrategy === 'whole-page-visual') { + const pageResult = await renderRasterFallbackLayers( + [plan.pageVisualRequest], + renderRaster, + slideIndex, + ); + if (pageResult.layers.length) { + return { + layers: pageResult.layers, + fullPageFallback: null, + diagnostics: [{ + severity: 'fallback', + code: 'page_visual_fallback', + message: `Slide ${slideIndex + 1} used a page visual fallback.`, + sourceId: 'slide-visuals', + slideNumber: slideIndex + 1, + phase: 'page-visual', + }], + blocking: false, + }; + } + diagnostics.push(...pageResult.failures.map((failure) => ( + failureDiagnostic('page_visual_raster_failed', failure, slideIndex) + ))); + const fullResult = await renderRasterFallbackLayers( + plan.fullPageRequest ? [plan.fullPageRequest] : [], + renderRaster, + slideIndex, + ); + if (fullResult.layers.length) { + return { + layers: [], + fullPageFallback: fullResult.layers[0], + diagnostics: [ + ...diagnostics, + { + severity: 'fallback', + code: 'full_page_fallback', + message: `Slide ${slideIndex + 1} used a full-page fallback.`, + sourceId: fullResult.layers[0].sourceId, + slideNumber: slideIndex + 1, + phase: 'full-page', + }, + ], + blocking: false, + }; + } + diagnostics.push(...fullResult.failures.map((failure) => ( + failureDiagnostic('full_page_raster_failed', failure, slideIndex, 'blocking') + ))); + return { layers: [], fullPageFallback: null, diagnostics, blocking: true }; + } + const localResult = await renderRasterFallbackLayers( + plan.localRequests || [], + renderRaster, + slideIndex, + ); + if (!localResult.failures.length) { + return { + layers: localResult.layers, + fullPageFallback: null, + diagnostics, + blocking: false, + }; + } + + diagnostics.push(...localResult.failures.map((failure) => ( + failureDiagnostic('local_raster_failed', failure, slideIndex) + ))); + + if (plan.pageVisualRequest) { + const pageResult = await renderRasterFallbackLayers( + [plan.pageVisualRequest], + renderRaster, + slideIndex, + ); + if (pageResult.layers.length) { + const layer = pageResult.layers[0]; + diagnostics.push({ + severity: 'fallback', + code: 'page_visual_fallback', + message: `Slide ${slideIndex + 1} used a transparent page visual fallback.`, + sourceId: layer.sourceId, + slideNumber: slideIndex + 1, + phase: 'page-visual', + reason: 'One or more local visual layers could not be rendered.', + }); + return { + layers: [layer], + fullPageFallback: null, + diagnostics, + blocking: false, + }; + } + diagnostics.push(...pageResult.failures.map((failure) => ( + failureDiagnostic('page_visual_raster_failed', failure, slideIndex) + ))); + } + + if (plan.fullPageRequest) { + const fullResult = await renderRasterFallbackLayers( + [plan.fullPageRequest], + renderRaster, + slideIndex, + ); + if (fullResult.layers.length) { + const fullPageFallback = fullResult.layers[0]; + diagnostics.push({ + severity: 'fallback', + code: 'full_page_fallback', + message: `Slide ${slideIndex + 1} was exported as a full-page PNG fallback.`, + sourceId: fullPageFallback.sourceId, + slideNumber: slideIndex + 1, + phase: 'full-page', + reason: 'Local and transparent page visual fallback rendering failed.', + }); + return { + layers: [], + fullPageFallback, + diagnostics, + blocking: false, + }; + } + diagnostics.push(...fullResult.failures.map((failure) => ( + failureDiagnostic('full_page_raster_failed', failure, slideIndex, 'blocking') + ))); + } + + return { + layers: [], + fullPageFallback: null, + diagnostics, + blocking: true, + }; +} diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/html2pptx-dom-core.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/html2pptx-dom-core.js index 9eb0b9d976..369e58251e 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/html2pptx-dom-core.js +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/html2pptx-dom-core.js @@ -13,6 +13,8 @@ // Unit conversions: 96 px = 1 inch, 1 px = 0.75 pt, PPTX uses inches/EMU. // Slide canvas: 1280×720 px = 13.333"×7.5" (LAYOUT_WIDE). // ───────────────────────────────────────────────────────────────────────────── +import { buildDomPaintOrderMap } from './paint-order.js'; + export const PT_PER_PX = 0.75; export const PX_PER_IN = 96; @@ -43,7 +45,57 @@ export function measureBodyDimensions(doc = document) { export function extractSlideDataFromDocument(doc = document) { const document = doc; - const view = document.defaultView || window; + const view = document?.defaultView || globalThis.window; + const diagnostics = []; + const diagnosticKeys = new Set(); + + const addDiagnostic = (severity, code, message, element = null) => { + const sourceId = element?.dataset?.pptxSourceId || element?.id || null; + const key = `${severity}:${code}:${sourceId || ''}`; + if (diagnosticKeys.has(key)) return; + diagnosticKeys.add(key); + const diagnostic = { + severity, + kind: severity === 'blocking' ? 'blocking' : undefined, + code, + message, + sourceId, + tag: element?.tagName?.toLowerCase?.() || null, + }; + try { + const rect = element?.getBoundingClientRect?.(); + if (rect && rect.width > 0 && rect.height > 0) { + diagnostic.bbox = { + x: rect.left, + y: rect.top, + width: rect.width, + height: rect.height, + }; + } + } catch { + // bbox is optional. + } + diagnostics.push(diagnostic); + }; + + if (!document?.body || !view?.getComputedStyle) { + addDiagnostic( + 'blocking', + 'unreadable_document', + 'Slide document has no readable body or computed-style view.', + document?.documentElement || null, + ); + const unreadableDiagnostic = diagnostics[diagnostics.length - 1]; + unreadableDiagnostic.sourceId = unreadableDiagnostic.sourceId || 'slide-document'; + unreadableDiagnostic.tag = 'document'; + return { + background: { type: 'color', value: 'FFFFFF' }, + elements: [], + placeholders: [], + diagnostics, + errors: diagnostics.map((item) => item.message), + }; + } const PT_PER_PX = 0.75; const PX_PER_IN = 96; @@ -252,7 +304,7 @@ export function extractSlideDataFromDocument(doc = document) { element.childNodes.forEach((node) => { let textTransform = baseTextTransform; - const isText = node.nodeType === Node.TEXT_NODE || node.tagName === 'BR'; + const isText = node.nodeType === view.Node.TEXT_NODE || node.tagName === 'BR'; if (isText) { const text = node.tagName === 'BR' ? '\n' : textTransform(node.textContent.replace(/\s+/g, ' ')); const prevRun = runs[runs.length - 1]; @@ -262,7 +314,7 @@ export function extractSlideDataFromDocument(doc = document) { runs.push({ text, options: { ...baseOptions } }); } - } else if (node.nodeType === Node.ELEMENT_NODE && node.textContent.trim()) { + } else if (node.nodeType === view.Node.ELEMENT_NODE && node.textContent.trim()) { const options = { ...baseOptions }; const computed = view.getComputedStyle(node); @@ -287,16 +339,16 @@ export function extractSlideDataFromDocument(doc = document) { // Validate: Check for margins on inline elements if (computed.marginLeft && parseFloat(computed.marginLeft) > 0) { - errors.push(`Inline element <${node.tagName.toLowerCase()}> has margin-left which is not supported in PowerPoint. Remove margin from inline elements.`); + addDiagnostic('fallback', 'inline_margin', `Inline element <${node.tagName.toLowerCase()}> has margin-left; fallback layout may be needed.`, node); } if (computed.marginRight && parseFloat(computed.marginRight) > 0) { - errors.push(`Inline element <${node.tagName.toLowerCase()}> has margin-right which is not supported in PowerPoint. Remove margin from inline elements.`); + addDiagnostic('fallback', 'inline_margin', `Inline element <${node.tagName.toLowerCase()}> has margin-right; fallback layout may be needed.`, node); } if (computed.marginTop && parseFloat(computed.marginTop) > 0) { - errors.push(`Inline element <${node.tagName.toLowerCase()}> has margin-top which is not supported in PowerPoint. Remove margin from inline elements.`); + addDiagnostic('fallback', 'inline_margin', `Inline element <${node.tagName.toLowerCase()}> has margin-top; fallback layout may be needed.`, node); } if (computed.marginBottom && parseFloat(computed.marginBottom) > 0) { - errors.push(`Inline element <${node.tagName.toLowerCase()}> has margin-bottom which is not supported in PowerPoint. Remove margin from inline elements.`); + addDiagnostic('fallback', 'inline_margin', `Inline element <${node.tagName.toLowerCase()}> has margin-bottom; fallback layout may be needed.`, node); } // Recursively process the child node. This will flatten nested spans into multiple runs. @@ -328,7 +380,7 @@ export function extractSlideDataFromDocument(doc = document) { const style = view.getComputedStyle(el); const bgImage = style.backgroundImage || ''; if (bgImage.includes('linear-gradient') || bgImage.includes('radial-gradient')) { - return { gradient: true }; + return { gradient: true, element: el }; } if (bgImage && bgImage !== 'none') { const urlMatch = bgImage.match(/url\(["']?([^"')]+)["']?\)/); @@ -345,6 +397,14 @@ export function extractSlideDataFromDocument(doc = document) { // Extract background from body / slide root wrapper const body = document.body; const bodyRect = body.getBoundingClientRect(); + if (!(bodyRect.width > 0) || !(bodyRect.height > 0)) { + addDiagnostic( + 'blocking', + 'unmeasurable_canvas', + 'Slide canvas has no measurable width or height.', + body, + ); + } const boxFor = (rect) => ({ left: rect.left - bodyRect.left, top: rect.top - bodyRect.top, @@ -390,14 +450,52 @@ export function extractSlideDataFromDocument(doc = document) { }; const readZIndex = (el) => { - const raw = view.getComputedStyle(el).zIndex; - if (!raw || raw === 'auto') return 0; - const parsed = parseInt(raw, 10); - return Number.isFinite(parsed) ? parsed : 0; + let current = el; + while (current && current !== body) { + const raw = view.getComputedStyle(current).zIndex; + if (raw && raw !== 'auto') { + const parsed = parseInt(raw, 10); + if (Number.isFinite(parsed)) return parsed; + } + current = current.parentElement; + } + return 0; }; + const domPaintOrder = buildDomPaintOrderMap(document); + const sourceSubOrders = new Map(); + let unmappedPaintOrder = Math.max(-1, ...domPaintOrder.values()) + 1; + const nextPaintMetadata = (el) => { + const sourceId = el?.dataset?.pptxSourceId || el?.id || null; + const subOrder = sourceSubOrders.get(sourceId) || 0; + sourceSubOrders.set(sourceId, subOrder + 1); + return { + sourceId, + paintOrder: domPaintOrder.get(sourceId) ?? unmappedPaintOrder++, + subOrder, + }; + }; const pushElement = (entry, el) => { - if (el) entry.zIndex = readZIndex(el); + const paintMetadata = nextPaintMetadata(el); + entry.kind = entry.kind || 'native'; + entry.paintOrder = entry.paintOrder ?? paintMetadata.paintOrder; + entry.subOrder = entry.subOrder ?? paintMetadata.subOrder; + if (!entry.bbox) { + if (entry.position) { + entry.bbox = { ...entry.position }; + } else if (entry.type === 'line') { + entry.bbox = { + x: Math.min(entry.x1, entry.x2), + y: Math.min(entry.y1, entry.y2), + w: Math.abs(entry.x2 - entry.x1), + h: Math.abs(entry.y2 - entry.y1), + }; + } + } + if (el) { + entry.zIndex = readZIndex(el); + entry.sourceId = paintMetadata.sourceId; + } elements.push(entry); }; @@ -422,14 +520,13 @@ export function extractSlideDataFromDocument(doc = document) { return null; }; - // Collect validation errors - const errors = []; - const bgResolved = resolveSlideBackground(body); if (bgResolved.gradient) { - errors.push( - 'CSS gradients are not supported. Use Sharp to rasterize gradients as PNG images first, ' + - 'then reference with background-image: url(\'gradient.png\')', + addDiagnostic( + 'fallback', + 'css_gradient', + 'CSS gradient requires fallback rendering; native gradient mapping is not available.', + bgResolved.element || body, ); } @@ -440,6 +537,7 @@ export function extractSlideDataFromDocument(doc = document) { // Process all elements const elements = []; + const slideDataFallbackLayers = []; const placeholders = []; const textTags = ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'UL', 'OL', 'LI']; const genericInlineTextTags = new Set([ @@ -459,7 +557,7 @@ export function extractSlideDataFromDocument(doc = document) { }; const hasDirectText = (el) => Array.from(el.childNodes).some( - (node) => node.nodeType === Node.TEXT_NODE && node.textContent.replace(/\s+/g, ' ').trim(), + (node) => node.nodeType === view.Node.TEXT_NODE && node.textContent.replace(/\s+/g, ' ').trim(), ); const isGenericTextElement = (el) => { @@ -519,12 +617,13 @@ export function extractSlideDataFromDocument(doc = document) { const text = el.textContent.replace(/\s+/g, ' ').trim(); if (rect.width === 0 || rect.height === 0 || !text) return false; - if (type !== 'text' && el.tagName !== 'LI' && /^[•\-\*▪▸○●◆◇■□]\s/.test(text.trimStart())) { - errors.push( - `Text element <${el.tagName.toLowerCase()}> starts with bullet symbol "${text.substring(0, 20)}...". ` + - 'Use
        or
          lists instead of manual bullet symbols.' + if (type !== 'text' && el.tagName !== 'LI' && /^[•●○▪‣·▸◆◇■□]\s/u.test(text.trimStart())) { + addDiagnostic( + 'fallback', + 'manual_bullet_unrepaired', + `Text element <${el.tagName.toLowerCase()}> still starts with a manual bullet; exporting as editable text.`, + el, ); - return false; } const computed = view.getComputedStyle(el); @@ -629,9 +728,495 @@ export function extractSlideDataFromDocument(doc = document) { return true; }; + const svgColor = (value, fallback = null) => { + if (!value || value === 'none' || value === 'transparent') return fallback; + return rgbToHex(value); + }; + const svgNumber = (value, fallback = 0) => { + const parsed = parseFloat(String(value || '')); + return Number.isFinite(parsed) ? parsed : fallback; + }; + const identityMatrix = () => [1, 0, 0, 1, 0, 0]; + const multiplyMatrix = (left, right) => [ + left[0] * right[0] + left[2] * right[1], + left[1] * right[0] + left[3] * right[1], + left[0] * right[2] + left[2] * right[3], + left[1] * right[2] + left[3] * right[3], + left[0] * right[4] + left[2] * right[5] + left[4], + left[1] * right[4] + left[3] * right[5] + left[5], + ]; + const parseSvgTransform = (value = '') => { + const raw = String(value || '').trim(); + let matrix = identityMatrix(); + let layoutMatrix = identityMatrix(); + let rotation = 0; + if (!raw || raw === 'none') { + return { matrix, layoutMatrix, rotation, reliable: true }; + } + if (/(?:skew|perspective|matrix3d)\s*\(/i.test(raw)) { + return { matrix, layoutMatrix, rotation, reliable: false }; + } + const functions = raw.matchAll(/(matrix|translate|scale|rotate)\s*\(([^)]*)\)/gi); + let matched = false; + for (const match of functions) { + matched = true; + const name = match[1].toLowerCase(); + const values = match[2].trim().split(/[\s,]+/).filter(Boolean).map((item) => parseFloat(item)); + let next = identityMatrix(); + let nextLayout = identityMatrix(); + if (name === 'matrix' && values.length >= 6) { + if (Math.abs(values[1]) > 1e-6 || Math.abs(values[2]) > 1e-6) { + return { matrix, layoutMatrix, rotation, reliable: false }; + } + next = values.slice(0, 6); + nextLayout = next; + } else if (name === 'translate') { + next = [1, 0, 0, 1, values[0] || 0, values[1] || 0]; + nextLayout = next; + } else if (name === 'scale') { + const x = Number.isFinite(values[0]) ? values[0] : 1; + const y = Number.isFinite(values[1]) ? values[1] : x; + next = [x, 0, 0, y, 0, 0]; + nextLayout = next; + } else if (name === 'rotate') { + const angle = values[0] || 0; + rotation += angle; + const radians = angle * Math.PI / 180; + const cos = Math.cos(radians); + const sin = Math.sin(radians); + const rotationMatrix = [cos, sin, -sin, cos, 0, 0]; + if (Number.isFinite(values[1]) && Number.isFinite(values[2])) { + next = multiplyMatrix( + multiplyMatrix([1, 0, 0, 1, values[1], values[2]], rotationMatrix), + [1, 0, 0, 1, -values[1], -values[2]], + ); + } else { + next = rotationMatrix; + } + } + matrix = multiplyMatrix(matrix, next); + layoutMatrix = multiplyMatrix(layoutMatrix, nextLayout); + } + return { matrix, layoutMatrix, rotation, reliable: matched }; + }; + const transformForSvgNode = (node, svg) => { + if (typeof node.getCTM === 'function') { + try { + const ctm = node.getCTM(); + const matrix = ctm + ? [ctm.a, ctm.b, ctm.c, ctm.d, ctm.e, ctm.f].map(Number) + : null; + if (matrix?.every(Number.isFinite)) { + const scaleX = Math.hypot(matrix[0], matrix[1]); + const scaleY = Math.hypot(matrix[2], matrix[3]); + const orthogonality = scaleX > 0 && scaleY > 0 + ? Math.abs((matrix[0] * matrix[2] + matrix[1] * matrix[3]) / (scaleX * scaleY)) + : Infinity; + if (orthogonality > 1e-5 || matrix[0] * matrix[3] - matrix[1] * matrix[2] <= 0) { + return { + matrix, + layoutMatrix: identityMatrix(), + rotation: 0, + reliable: false, + coordinateSpace: 'viewport', + }; + } + return { + matrix, + layoutMatrix: [scaleX, 0, 0, scaleY, matrix[4], matrix[5]], + rotation: Math.atan2(matrix[1], matrix[0]) * 180 / Math.PI, + reliable: true, + coordinateSpace: 'viewport', + }; + } + } catch { + // Fall through to deterministic attribute/computed-style parsing. + } + } + const chain = []; + let current = node; + while (current && current !== svg) { + chain.unshift(current); + current = current.parentElement; + } + let matrix = identityMatrix(); + let layoutMatrix = identityMatrix(); + let rotation = 0; + for (const item of chain) { + const attributeTransform = parseSvgTransform(item.getAttribute('transform')); + if (!attributeTransform.reliable) { + return { matrix, layoutMatrix, rotation, reliable: false }; + } + matrix = multiplyMatrix(matrix, attributeTransform.matrix); + layoutMatrix = multiplyMatrix(layoutMatrix, attributeTransform.layoutMatrix); + rotation += attributeTransform.rotation; + + const computedTransformValue = view.getComputedStyle(item).transform; + if (computedTransformValue && computedTransformValue !== 'none' + && computedTransformValue !== item.getAttribute('transform')) { + const computedTransform = parseSvgTransform(computedTransformValue); + if (!computedTransform.reliable) { + return { matrix, layoutMatrix, rotation, reliable: false }; + } + let computedMatrix = computedTransform.matrix; + const originValues = String(view.getComputedStyle(item).transformOrigin || '') + .split(/\s+/).map((value) => parseFloat(value)); + if (Number.isFinite(originValues[0]) && Number.isFinite(originValues[1]) + && computedTransform.rotation) { + computedMatrix = multiplyMatrix( + multiplyMatrix( + [1, 0, 0, 1, originValues[0], originValues[1]], + computedMatrix, + ), + [1, 0, 0, 1, -originValues[0], -originValues[1]], + ); + } + matrix = multiplyMatrix(matrix, computedMatrix); + layoutMatrix = multiplyMatrix(layoutMatrix, computedTransform.layoutMatrix); + rotation += computedTransform.rotation; + } + } + return { + matrix, + layoutMatrix, + rotation, + reliable: true, + coordinateSpace: 'viewBox', + }; + }; + const transformPoint = (point, matrix) => ({ + x: matrix[0] * point.x + matrix[2] * point.y + matrix[4], + y: matrix[1] * point.x + matrix[3] * point.y + matrix[5], + }); + const parseSvgPoints = (value) => { + const numbers = String(value || '').trim().split(/[\s,]+/).filter(Boolean).map(Number); + const points = []; + for (let index = 0; index + 1 < numbers.length; index += 2) { + if (Number.isFinite(numbers[index]) && Number.isFinite(numbers[index + 1])) { + points.push({ x: numbers[index], y: numbers[index + 1] }); + } + } + return points; + }; + const svgStyleProperties = [ + 'fill', 'fill-opacity', 'fill-rule', + 'stroke', 'stroke-width', 'stroke-opacity', 'stroke-linecap', 'stroke-linejoin', + 'stroke-dasharray', 'stroke-dashoffset', + 'opacity', 'color', 'vector-effect', + ]; + const resolvedSvgStyle = (element, property) => { + let current = element; + while (current) { + const value = String( + view.getComputedStyle(current).getPropertyValue(property) || '', + ).trim(); + if (value && !['inherit', 'unset', 'initial'].includes(value)) return value; + if (['opacity', 'vector-effect'].includes(property)) break; + current = current.parentElement; + } + return ''; + }; + const inlineComputedSvgStyles = (original, clone) => { + svgStyleProperties.forEach((property) => { + const value = resolvedSvgStyle(original, property); + if (value) clone.style.setProperty(property, value); + }); + const originalChildren = [...original.children]; + const cloneChildren = [...clone.children]; + originalChildren.forEach((child, index) => { + if (cloneChildren[index]) inlineComputedSvgStyles(child, cloneChildren[index]); + }); + }; + const serializeSvgVisual = (svg, node) => { + const rootClone = svg.cloneNode(false); + rootClone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + if (!rootClone.getAttribute('width')) rootClone.setAttribute('width', '100%'); + if (!rootClone.getAttribute('height')) rootClone.setAttribute('height', '100%'); + inlineComputedSvgStyles(svg, rootClone); + + [...svg.querySelectorAll('defs')].forEach((defs) => { + const defsClone = defs.cloneNode(true); + inlineComputedSvgStyles(defs, defsClone); + rootClone.appendChild(defsClone); + }); + + const ancestors = []; + let current = node.parentElement; + while (current && current !== svg) { + ancestors.unshift(current); + current = current.parentElement; + } + let targetParent = rootClone; + ancestors.forEach((ancestor) => { + const ancestorClone = ancestor.cloneNode(false); + inlineComputedSvgStyles(ancestor, ancestorClone); + targetParent.appendChild(ancestorClone); + targetParent = ancestorClone; + }); + const targetClone = node.cloneNode(true); + inlineComputedSvgStyles(node, targetClone); + targetClone.querySelectorAll?.('text').forEach((text) => text.remove()); + targetParent.appendChild(targetClone); + return `data:image/svg+xml,${encodeURIComponent(rootClone.outerHTML)}`; + }; + const boundsOfPoints = (points) => { + const xs = points.map((point) => point.x); + const ys = points.map((point) => point.y); + return { + left: Math.min(...xs), + top: Math.min(...ys), + width: Math.max(...xs) - Math.min(...xs), + height: Math.max(...ys) - Math.min(...ys), + }; + }; + const isDiamondPoints = (points) => { + if (points.length !== 4) return false; + const bounds = boundsOfPoints(points); + const cx = bounds.left + bounds.width / 2; + const cy = bounds.top + bounds.height / 2; + const tolerance = Math.max(bounds.width, bounds.height) * 0.08 + 0.01; + return points.every((point) => ( + Math.abs(point.x - cx) <= tolerance || Math.abs(point.y - cy) <= tolerance + )); + }; + const emitNativeSvg = (svg) => { + const svgRect = rectFor(svg); + if (svgRect.width <= 0 || svgRect.height <= 0) return; + const viewBox = String(svg.getAttribute('viewBox') || `0 0 ${svgRect.width} ${svgRect.height}`) + .trim().split(/[\s,]+/).map(Number); + const [vbX = 0, vbY = 0, vbW = svgRect.width, vbH = svgRect.height] = viewBox; + const xScale = svgRect.width / (vbW || svgRect.width); + const yScale = svgRect.height / (vbH || svgRect.height); + const fallbackLayers = slideDataFallbackLayers; + const toSlidePoint = (point) => ({ + x: svgRect.left + ((point.x - vbX) * xScale), + y: svgRect.top + ((point.y - vbY) * yScale), + }); + const pushLine = (start, end, node, stroke, width, coordinateSpace = 'viewBox') => { + const toLinePoint = (point) => ( + coordinateSpace === 'viewport' + ? { x: svgRect.left + point.x, y: svgRect.top + point.y } + : toSlidePoint(point) + ); + const first = toLinePoint(start); + const second = toLinePoint(end); + pushElement({ + type: 'line', + kind: 'native', + x1: pxToInch(first.x), + y1: pxToInch(first.y), + x2: pxToInch(second.x), + y2: pxToInch(second.y), + color: stroke || '000000', + width, + }, node); + }; + const hasBrowserOnlySvg = Boolean( + svg.querySelector('filter,mask,foreignObject,use,pattern,textPath,clipPath,image'), + ); + const canSerializeSvgVisual = (node) => ( + !svg.querySelector('script') + && !/(?:href|src)\s*=\s*["']\s*(?:https?:)?\/\//i.test(node.outerHTML || '') + ); + const pushSvgImageLayer = (node, code, message) => { + if (!canSerializeSvgVisual(node)) { + addDiagnostic( + 'fallback', + 'complex_svg_raster', + 'Complex SVG cannot be safely serialized and requires local browser raster rendering.', + svg, + ); + return; + } + const paintMetadata = nextPaintMetadata(node); + fallbackLayers.push({ + sourceId: paintMetadata.sourceId, + zIndex: readZIndex(node), + paintOrder: paintMetadata.paintOrder, + subOrder: paintMetadata.subOrder, + kind: 'svg-image', + captureStrategy: 'local-svg', + bbox: { + x: pxToInch(svgRect.left), + y: pxToInch(svgRect.top), + w: pxToInch(svgRect.width), + h: pxToInch(svgRect.height), + }, + data: serializeSvgVisual(svg, node), + diagnostics: [{ + severity: 'fallback', + code, + message, + sourceId: node.dataset?.pptxSourceId || node.id || null, + }], + }); + }; + svg.querySelectorAll('rect,circle,ellipse,line,polyline,polygon,text,path').forEach((node) => { + const tag = node.tagName.toLowerCase(); + if (tag === 'path') { + if (!hasBrowserOnlySvg) { + pushSvgImageLayer( + node, + 'complex_svg_vector', + 'Complex SVG geometry is preserved as a local movable vector image.', + ); + } + return; + } + const transform = transformForSvgNode(node, svg); + if (!transform.reliable) { + pushSvgImageLayer( + node, + 'svg_transform_vector', + 'SVG transform cannot be represented reliably as a native shape; preserving it as SVG.', + ); + return; + } + const transformedToSlidePoint = (transformed) => ( + transform.coordinateSpace === 'viewport' + ? { x: svgRect.left + transformed.x, y: svgRect.top + transformed.y } + : toSlidePoint(transformed) + ); + const transformToSlidePoint = (point, matrix) => ( + transformedToSlidePoint(transformPoint(point, matrix)) + ); + const mapPoint = (x, y) => transformToSlidePoint( + { x: svgNumber(x), y: svgNumber(y) }, + transform.matrix, + ); + const mapLayoutPoint = (x, y) => transformToSlidePoint( + { x: svgNumber(x), y: svgNumber(y) }, + transform.layoutMatrix, + ); + const fill = svgColor(node.getAttribute('fill') || view.getComputedStyle(node).fill); + const stroke = svgColor(node.getAttribute('stroke') || view.getComputedStyle(node).stroke); + const opacity = svgNumber(node.getAttribute('opacity') || view.getComputedStyle(node).opacity, 1); + const lineWidth = svgNumber(node.getAttribute('stroke-width'), 1) * 0.75; + const common = { + type: tag === 'text' ? 'svg-text' : 'svg-shape', + kind: 'native', + svgType: tag, + position: null, + shape: { fill, line: stroke ? { color: stroke, width: lineWidth } : null, transparency: Math.round((1 - opacity) * 100), rectRadius: 0 }, + }; + if (tag === 'rect') { + const x = svgNumber(node.getAttribute('x')); + const y = svgNumber(node.getAttribute('y')); + const width = svgNumber(node.getAttribute('width')); + const height = svgNumber(node.getAttribute('height')); + const points = [ + mapPoint(x, y), mapPoint(x + width, y), mapPoint(x + width, y + height), mapPoint(x, y + height), + ]; + const bounds = boundsOfPoints(points); + const layoutBounds = boundsOfPoints([ + mapLayoutPoint(x, y), + mapLayoutPoint(x + width, y), + mapLayoutPoint(x + width, y + height), + mapLayoutPoint(x, y + height), + ]); + common.position = { x: pxToInch(layoutBounds.left), y: pxToInch(layoutBounds.top), w: pxToInch(layoutBounds.width), h: pxToInch(layoutBounds.height) }; + common.bbox = { x: pxToInch(bounds.left), y: pxToInch(bounds.top), w: pxToInch(bounds.width), h: pxToInch(bounds.height) }; + if (transform.rotation) common.shape.rotate = transform.rotation; + } else if (tag === 'circle' || tag === 'ellipse') { + const rx = tag === 'circle' ? svgNumber(node.getAttribute('r')) : svgNumber(node.getAttribute('rx')); + const ry = tag === 'circle' ? rx : svgNumber(node.getAttribute('ry')); + const cx = svgNumber(node.getAttribute('cx')); + const cy = svgNumber(node.getAttribute('cy')); + const points = [ + mapPoint(cx - rx, cy), mapPoint(cx + rx, cy), mapPoint(cx, cy - ry), mapPoint(cx, cy + ry), + ]; + const bounds = boundsOfPoints(points); + const layoutBounds = boundsOfPoints([ + mapLayoutPoint(cx - rx, cy), mapLayoutPoint(cx + rx, cy), + mapLayoutPoint(cx, cy - ry), mapLayoutPoint(cx, cy + ry), + ]); + common.position = { x: pxToInch(layoutBounds.left), y: pxToInch(layoutBounds.top), w: pxToInch(layoutBounds.width), h: pxToInch(layoutBounds.height) }; + common.bbox = { x: pxToInch(bounds.left), y: pxToInch(bounds.top), w: pxToInch(bounds.width), h: pxToInch(bounds.height) }; + if (transform.rotation) common.shape.rotate = transform.rotation; + } else if (tag === 'line') { + pushLine( + transformPoint({ x: svgNumber(node.getAttribute('x1')), y: svgNumber(node.getAttribute('y1')) }, transform.matrix), + transformPoint({ x: svgNumber(node.getAttribute('x2')), y: svgNumber(node.getAttribute('y2')) }, transform.matrix), + node, + stroke, + lineWidth, + transform.coordinateSpace, + ); + return; + } else if (tag === 'text') { + common.text = node.textContent || ''; + const fontSize = svgNumber(node.getAttribute('font-size'), 16); + const origin = mapPoint(node.getAttribute('x'), svgNumber(node.getAttribute('y')) - fontSize); + common.position = { x: pxToInch(origin.x), y: pxToInch(origin.y), w: pxToInch(Math.max(1, svgRect.width)), h: pxToInch(Math.max(1, fontSize * yScale * 1.3)) }; + common.style = { fontSize: svgNumber(node.getAttribute('font-size'), 16) * 0.75, fontFace: 'Arial', color: fill || '000000', align: 'left' }; + if (transform.rotation) common.style.rotate = transform.rotation; + } else { + const points = parseSvgPoints(node.getAttribute('points')) + .map((point) => transformPoint(point, transform.matrix)); + if (tag === 'polygon' && (points.length === 3 || isDiamondPoints(points))) { + const slidePoints = points.map(transformedToSlidePoint); + const bounds = boundsOfPoints(slidePoints); + common.svgType = points.length === 3 ? 'triangle' : 'diamond'; + common.position = { + x: pxToInch(bounds.left), + y: pxToInch(bounds.top), + w: pxToInch(bounds.width), + h: pxToInch(bounds.height), + }; + common.bbox = { ...common.position }; + if (transform.rotation) common.shape.rotate = transform.rotation; + } else { + const closed = tag === 'polygon' && points.length > 2 ? [...points, points[0]] : points; + for (let index = 0; index + 1 < closed.length; index += 1) { + pushLine( + closed[index], + closed[index + 1], + node, + stroke || fill, + lineWidth, + transform.coordinateSpace, + ); + } + if (tag === 'polygon' && fill && points.length > 2) { + const sourceId = node.dataset?.pptxSourceId || node.id || null; + fallbackLayers.push({ + sourceId, + zIndex: readZIndex(node), + paintOrder: domPaintOrder.get(sourceId) ?? unmappedPaintOrder++, + subOrder: -1, + kind: 'svg-image', + bbox: { + x: pxToInch(svgRect.left), + y: pxToInch(svgRect.top), + w: pxToInch(svgRect.width), + h: pxToInch(svgRect.height), + }, + data: serializeSvgVisual(svg, node), + diagnostics: [{ + severity: 'fallback', + code: 'svg_polygon_fill', + message: 'Polygon fill is preserved as a local SVG layer over an editable outline.', + sourceId: node.dataset?.pptxSourceId || node.id || null, + }], + }); + } + return; + } + } + if (common.position || common.type === 'line') pushElement(common, node); + }); + processed.add(svg); + svg.querySelectorAll('*').forEach((node) => processed.add(node)); + }; + document.querySelectorAll('*').forEach((el) => { if (processed.has(el)) return; + if (el.tagName === 'svg') { + emitNativeSvg(el); + return; + } + // [data-pptx-merge="true"] — opt-in: merge all

          /

          -

          descendants // into ONE PowerPoint text frame (single editable text box). // Each child paragraph becomes a run with breakLine:true at the end; @@ -646,9 +1231,11 @@ export function extractSlideDataFromDocument(doc = document) { // Reject nested merge containers — undefined behavior. if (el.querySelector('[data-pptx-merge="true"]')) { - errors.push( - `data-pptx-merge container cannot contain another data-pptx-merge container. ` + - 'Nested merge is not supported.' + addDiagnostic( + 'fallback', + 'nested_merge_container', + 'Nested data-pptx-merge containers require fallback handling.', + el, ); processed.add(el); return; @@ -658,11 +1245,12 @@ export function extractSlideDataFromDocument(doc = document) { // Container background image — same restriction as regular divs. if (mergeComputed.backgroundImage && mergeComputed.backgroundImage !== 'none') { - errors.push( - 'Background images on data-pptx-merge container are not supported. ' + - 'Use solid colors or borders, or layer images via slide.addImage().' + addDiagnostic( + 'fallback', + 'merge_background_image', + 'Background image on data-pptx-merge requires fallback rendering.', + el, ); - return; } // Emit a shape for the container's bg/uniform-border (mirrors the regular div branch). @@ -677,7 +1265,7 @@ export function extractSlideDataFromDocument(doc = document) { const mHasUniformBorder = mHasBorder && mBorders.every(b => b === mBorders[0]); if (mHasBg || mHasUniformBorder) { - elements.push({ + pushElement({ type: 'shape', text: '', position: { @@ -707,15 +1295,17 @@ export function extractSlideDataFromDocument(doc = document) { })(), shadow: parseBoxShadow(mergeComputed.boxShadow) } - }); + }, el); } // Collect

          / descendants in document order. const textDescendants = Array.from(el.querySelectorAll('p, h1, h2, h3, h4, h5, h6')); if (textDescendants.length === 0) { - errors.push( - `data-pptx-merge container has no

          / children to merge. ` + - 'Remove the data-pptx-merge attribute or add text elements.' + addDiagnostic( + 'fallback', + 'empty_merge_container', + 'data-pptx-merge container has no semantic text children.', + el, ); processed.add(el); return; @@ -794,7 +1384,7 @@ export function extractSlideDataFromDocument(doc = document) { return; } - elements.push({ + pushElement({ type: 'merged-text', items: mergedRuns, position: { @@ -804,7 +1394,7 @@ export function extractSlideDataFromDocument(doc = document) { h: pxToInch(containerRect.height) }, style: baseStyle - }); + }, el); processed.add(el); return; @@ -881,8 +1471,11 @@ export function extractSlideDataFromDocument(doc = document) { if (el.classList && el.classList.contains('placeholder')) { const rect = rectFor(el); if (rect.width === 0 || rect.height === 0) { - errors.push( - `Placeholder "${el.id || 'unnamed'}" has ${rect.width === 0 ? 'width: 0' : 'height: 0'}. Check the layout CSS.` + addDiagnostic( + 'fallback', + 'unmeasurable_placeholder', + `Placeholder "${el.id || 'unnamed'}" has ${rect.width === 0 ? 'width: 0' : 'height: 0'}.`, + el, ); } else { placeholders.push({ @@ -901,7 +1494,7 @@ export function extractSlideDataFromDocument(doc = document) { if (el.tagName === 'IMG') { const rect = rectFor(el); if (rect.width > 0 && rect.height > 0) { - elements.push({ + pushElement({ type: 'image', src: el.src, position: { @@ -910,7 +1503,52 @@ export function extractSlideDataFromDocument(doc = document) { w: pxToInch(rect.width), h: pxToInch(rect.height) } - }); + }, el); + processed.add(el); + return; + } + } + + // Common CSS arrow: a zero-sized box with one opaque border and + // transparent side borders maps cleanly to an editable PPT triangle. + if (el.tagName === 'DIV') { + const computed = view.getComputedStyle(el); + const isZeroBox = svgNumber(computed.width) === 0 && svgNumber(computed.height) === 0; + const sides = ['Top', 'Right', 'Bottom', 'Left'].map((side) => ({ + side, + width: svgNumber(computed[`border${side}Width`]), + color: computed[`border${side}Color`], + })); + const opaqueSides = sides.filter((side) => ( + side.width > 0 && !isTransparentBg(side.color) + )); + if (isZeroBox && opaqueSides.length === 1 && sides.filter((side) => side.width > 0).length >= 3) { + const active = opaqueSides[0]; + const rect = rectFor(el); + const horizontal = sides.find((side) => side.side === 'Left').width + + sides.find((side) => side.side === 'Right').width; + const vertical = sides.find((side) => side.side === 'Top').width + + sides.find((side) => side.side === 'Bottom').width; + const rotations = { Bottom: 0, Left: 90, Top: 180, Right: 270 }; + pushElement({ + type: 'svg-shape', + svgType: 'triangle', + kind: 'native', + text: '', + position: { + x: pxToInch(rect.left - sides.find((side) => side.side === 'Left').width), + y: pxToInch(rect.top - sides.find((side) => side.side === 'Top').width), + w: pxToInch(Math.max(1, horizontal)), + h: pxToInch(Math.max(1, vertical)), + }, + shape: { + fill: rgbToHex(active.color), + line: null, + transparency: extractAlpha(active.color), + rectRadius: 0, + rotate: rotations[active.side], + }, + }, el); processed.add(el); return; } @@ -925,11 +1563,12 @@ export function extractSlideDataFromDocument(doc = document) { // Check for background images on shapes const bgImage = computed.backgroundImage; if (bgImage && bgImage !== 'none') { - errors.push( - 'Background images on DIV elements are not supported. ' + - 'Use solid colors or borders for shapes, or use slide.addImage() in PptxGenJS to layer images.' + addDiagnostic( + 'fallback', + 'container_background_image', + 'Container background image requires fallback rendering.', + el, ); - return; } // Check for borders - both uniform and partial @@ -1154,18 +1793,60 @@ export function extractSlideDataFromDocument(doc = document) { emitTextElement(el); }); - const paintRank = (type) => { - if (type === 'shape') return 0; - if (type === 'line') return 1; - if (type === 'image') return 2; - return 3; - }; elements.sort((a, b) => { const z = (a.zIndex ?? 0) - (b.zIndex ?? 0); if (z !== 0) return z; - return paintRank(a.type) - paintRank(b.type); + const paint = (a.paintOrder ?? 0) - (b.paintOrder ?? 0); + if (paint !== 0) return paint; + const sub = (a.subOrder ?? 0) - (b.subOrder ?? 0); + if (sub !== 0) return sub; + return (a.stableOrder ?? 0) - (b.stableOrder ?? 0); }); - return { background, elements, placeholders, errors }; + document.querySelectorAll('*').forEach((element) => { + const computed = view.getComputedStyle(element); + const filter = String(computed.filter || element.style?.filter || ''); + if (filter && filter !== 'none') { + addDiagnostic('fallback', 'css_filter', 'CSS filter requires fallback rendering.', element); + } + if (String(element.tagName).toUpperCase() === 'SVG') { + if (element.querySelector('filter,mask,foreignObject,use,pattern,textPath,clipPath,image')) { + addDiagnostic( + 'fallback', + 'complex_svg_raster', + 'SVG filter, mask, or foreignObject requires local browser raster rendering.', + element, + ); + } else if (element.querySelector('path')) { + addDiagnostic( + 'fallback', + 'complex_svg_vector', + 'Complex SVG geometry is preserved as a local SVG image.', + element, + ); + } + } + }); + + const blockingErrors = diagnostics + .filter((diagnostic) => diagnostic.severity === 'blocking') + .map((diagnostic) => diagnostic.message); + slideDataFallbackLayers.sort((a, b) => { + const z = (a.zIndex ?? 0) - (b.zIndex ?? 0); + if (z !== 0) return z; + const order = (a.paintOrder ?? 0) - (b.paintOrder ?? 0); + if (order !== 0) return order; + const sub = (a.subOrder ?? 0) - (b.subOrder ?? 0); + if (sub !== 0) return sub; + return (a.stableOrder ?? 0) - (b.stableOrder ?? 0); + }); + return { + background, + elements, + fallbackLayers: slideDataFallbackLayers, + placeholders, + diagnostics, + errors: blockingErrors, + }; } diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/i18n.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/i18n.js index 5054aeea7c..9037409775 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/i18n.js +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/i18n.js @@ -258,6 +258,20 @@ export const STRINGS = { exportPptxWorking: 'Rendering editable PPTX...', exportPptxDone: 'Editable PPTX downloaded.', exportPptxFailed: 'PPTX export failed:', + exportDiagnosticsSummary: 'Exported with visual adjustments: {{counts}}. {{locations}}', + exportDiagnosticsRepaired: '{{count}} automatic repairs', + exportDiagnosticsSvg: '{{count}} local SVG layers', + exportDiagnosticsLocalPng: '{{count}} local PNG layers', + exportDiagnosticsPageVisual: '{{count}} page visual layers', + exportDiagnosticsFullPage: '{{count}} full-page fallbacks', + exportDiagnosticsBlocking: '{{count}} blocking failures', + exportDiagnosticsLocation: 'Slide {{slide}}, element {{source}} ({{phase}}): {{reason}}', + exportDiagnosticsPhaseRepair: 'automatic repair', + exportDiagnosticsPhaseSvg: 'local SVG', + exportDiagnosticsPhaseLocalPng: 'local PNG', + exportDiagnosticsPhasePageVisual: 'page visual fallback', + exportDiagnosticsPhaseFullPage: 'full-page fallback', + exportDiagnosticsPhaseBlocking: 'blocking failure', exportPdfWorking: 'Rendering PDF...', exportPdfDone: 'PDF downloaded.', exportPdfFailed: 'PDF export failed:', @@ -634,6 +648,20 @@ export const STRINGS = { exportPptxWorking: '正在渲染可编辑 PPTX...', exportPptxDone: '可编辑 PPTX 已下载。', exportPptxFailed: 'PPTX 导出失败:', + exportDiagnosticsSummary: '已完成导出,并进行了视觉调整:{{counts}}。{{locations}}', + exportDiagnosticsRepaired: '自动修复 {{count}} 处', + exportDiagnosticsSvg: '局部 SVG 层 {{count}} 个', + exportDiagnosticsLocalPng: '局部 PNG 层 {{count}} 个', + exportDiagnosticsPageVisual: '页面视觉层 {{count}} 个', + exportDiagnosticsFullPage: '整页兜底 {{count}} 页', + exportDiagnosticsBlocking: '阻断失败 {{count}} 处', + exportDiagnosticsLocation: '第 {{slide}} 页,元素 {{source}}({{phase}}):{{reason}}', + exportDiagnosticsPhaseRepair: '自动修复', + exportDiagnosticsPhaseSvg: '局部 SVG', + exportDiagnosticsPhaseLocalPng: '局部 PNG', + exportDiagnosticsPhasePageVisual: '页面视觉兜底', + exportDiagnosticsPhaseFullPage: '整页兜底', + exportDiagnosticsPhaseBlocking: '阻断失败', exportPdfWorking: '正在渲染 PDF...', exportPdfDone: 'PDF 已下载。', exportPdfFailed: 'PDF 导出失败:', diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/paint-order.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/paint-order.js new file mode 100644 index 0000000000..040a5a361b --- /dev/null +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/paint-order.js @@ -0,0 +1,9 @@ +export function buildDomPaintOrderMap(doc) { + const map = new Map(); + if (!doc?.body) return map; + [doc.body, ...doc.body.querySelectorAll('*')].forEach((element, index) => { + const sourceId = element.dataset?.pptxSourceId || element.id || null; + if (sourceId && !map.has(sourceId)) map.set(sourceId, index); + }); + return map; +} diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/pptx-html-build.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/pptx-html-build.js index d171d9013e..6f55d7b20f 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/pptx-html-build.js +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/pptx-html-build.js @@ -19,6 +19,9 @@ const PX_PER_IN = 96; const EMU_PER_IN = 914400; const SLIDE_W_IN = 13.333; const SLIDE_H_IN = 7.5; +const EDITABLE_TEXT_TYPES = new Set([ + 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'text', 'svg-text', 'list', 'merged-text', +]); // PowerPoint and browsers render the same font at the same point size with // measurably different glyph widths (different font metric tables / hinting). @@ -129,7 +132,68 @@ async function addBackground(slideData, targetSlide) { } function addElements(slideData, targetSlide, pres) { - for (const el of slideData.elements) { + if (slideData.fullPageFallback) { + const payload = toImagePayload( + slideData.fullPageFallback.data || slideData.fullPageFallback.src, + ); + if (!payload) throw new Error('Full-page fallback has no image payload'); + targetSlide.addImage({ + ...payload, + x: 0, + y: 0, + w: SLIDE_W_IN, + h: SLIDE_H_IN, + }); + return; + } + const suppressedNativeVisualIds = new Set([ + ...(slideData.suppressedNativeVisualIds || []), + ...(slideData.fallbackLayers || []) + .flatMap((layer) => layer.suppressedNativeVisualIds || []), + ]); + const paintItems = [ + ...(slideData.elements || []).map((element, order) => ({ + type: 'element', + item: element, + zIndex: element.zIndex ?? 0, + order: element.paintOrder ?? order, + subOrder: element.subOrder ?? 0, + stableOrder: order, + })), + ...(slideData.fallbackLayers || []).map((layer, order) => ({ + type: 'fallback', + item: layer, + zIndex: layer.zIndex ?? 0, + order: layer.paintOrder ?? ((slideData.elements || []).length + order), + subOrder: layer.subOrder ?? 0, + stableOrder: (slideData.elements || []).length + order, + })), + ].sort((a, b) => ( + a.zIndex - b.zIndex + || a.order - b.order + || a.subOrder - b.subOrder + || a.stableOrder - b.stableOrder + )); + for (const paintItem of paintItems) { + if (paintItem.type === 'fallback') { + const layer = paintItem.item; + const payload = toImagePayload(layer.data || layer.src); + const bbox = layer.bbox || {}; + if (!payload) continue; + const fullPageCanvas = layer.canvas === 'full-page'; + targetSlide.addImage({ + ...payload, + x: fullPageCanvas ? 0 : (bbox.x ?? 0), + y: fullPageCanvas ? 0 : (bbox.y ?? 0), + w: fullPageCanvas ? SLIDE_W_IN : (bbox.w ?? SLIDE_W_IN), + h: fullPageCanvas ? SLIDE_H_IN : (bbox.h ?? SLIDE_H_IN), + }); + continue; + } + const el = paintItem.item; + if (suppressedNativeVisualIds.has(el.sourceId) && !EDITABLE_TEXT_TYPES.has(el.type)) { + continue; + } if (el.type === 'image') { const payload = toImagePayload(el.src); if (!payload) continue; @@ -148,14 +212,22 @@ function addElements(slideData, targetSlide, pres) { h: el.y2 - el.y1, line: { color: el.color, width: el.width }, }); - } else if (el.type === 'shape') { + } else if (el.type === 'shape' || el.type === 'svg-shape') { const shapeOptions = { x: el.position.x, y: el.position.y, w: el.position.w, h: el.position.h, - shape: el.shape.rectRadius > 0 ? pres.ShapeType.roundRect : pres.ShapeType.rect, }; + const nativeShapeType = { + circle: pres.ShapeType.ellipse, + ellipse: pres.ShapeType.ellipse, + triangle: pres.ShapeType.triangle, + diamond: pres.ShapeType.diamond, + rect: pres.ShapeType.rect, + }[el.svgType]; + shapeOptions.shape = nativeShapeType + || (el.shape.rectRadius > 0 ? pres.ShapeType.roundRect : pres.ShapeType.rect); if (el.shape.fill) { shapeOptions.fill = { color: el.shape.fill }; if (el.shape.transparency != null) shapeOptions.fill.transparency = el.shape.transparency; @@ -163,7 +235,12 @@ function addElements(slideData, targetSlide, pres) { if (el.shape.line) shapeOptions.line = el.shape.line; if (el.shape.rectRadius > 0) shapeOptions.rectRadius = el.shape.rectRadius; if (el.shape.shadow) shapeOptions.shadow = el.shape.shadow; - targetSlide.addText(el.text || '', shapeOptions); + if (el.shape.rotate != null) shapeOptions.rotate = el.shape.rotate; + if (el.type === 'svg-shape') { + targetSlide.addShape(shapeOptions.shape, shapeOptions); + } else { + targetSlide.addText(el.text || '', shapeOptions); + } } else if (el.type === 'list' || el.type === 'merged-text') { const { x: boxX, w: boxW } = safeTextBoxGeometry(el.position.x, el.position.w, el.style.align, false); const listOptions = { @@ -233,10 +310,38 @@ export async function buildSlideFromExtracted(slideData, bodyDimensions, pres, o if (validationWarnings.length) { console.warn('[ppt-live-export] slide validation warnings (export continues):', validationWarnings.join('; ')); } + const diagnostics = [ + ...(slideData?.diagnostics || []), + ...validationWarnings.map((message) => ({ + severity: 'fallback', + code: 'pptx_layout_warning', + message, + sourceId: null, + tag: null, + })), + ]; const targetSlide = options.slide || pres.addSlide(); - await addBackground(slideData, targetSlide); - addElements(slideData, targetSlide, pres); - return { slide: targetSlide, placeholders: slideData.placeholders || [] }; + try { + await addBackground(slideData, targetSlide); + addElements(slideData, targetSlide, pres); + } catch (error) { + const diagnostic = { + severity: 'blocking', + kind: 'blocking', + code: 'pptx_serialization', + message: String(error?.message || error || 'PPTX serialization failed.'), + sourceId: null, + tag: null, + }; + error.diagnostic = diagnostic; + error.diagnostics = [...diagnostics, diagnostic]; + throw error; + } + return { + slide: targetSlide, + placeholders: slideData.placeholders || [], + diagnostics, + }; } export function createPptxDeck(deck = {}) { diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/render.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/render.js index 942a40f9d6..d58244f936 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/render.js +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/render.js @@ -2,6 +2,13 @@ import { escapeHtml, extractHtmlSlideBackground, getActiveIndex, getActiveSlide, import { translate as t, getLocale } from './i18n.js'; import { refreshFlatSelect } from './flat-select.js'; import { DEFAULT_STYLE_PRESET } from './style-presets.js'; +import { + elementModelElementHtml, + resolveElementColor, +} from './element-model-html.js'; +import { sanitizeSlideMarkup } from './sanitize-slide-markup.js'; + +export { resolveElementColor as resolveColor }; export function applyI18n() { document.documentElement.lang = getLocale(); @@ -174,21 +181,23 @@ const HTML_SLIDE_PREVIEW_HOST_CLASS = 'html-slide-preview-host'; const HTML_SLIDE_PREVIEW_SCALER_CLASS = 'html-slide-preview-scaler'; const DEFAULT_SLIDE_DESIGN = { width: 1280, height: 720 }; -function writeSandboxIframeDocument(frame, html) { +function writeSandboxIframeDocument(frame, sanitizedHtml) { const doc = frame.contentDocument; if (!doc) return false; doc.open(); - doc.write(normalizeSlideDocument(html)); + doc.write(sanitizedHtml); doc.close(); return true; } function mountSandboxIframeHtml(frame, html, onMounted) { + const sanitizedHtml = sanitizeSlideMarkup(normalizeSlideDocument(html)); frame.setAttribute('sandbox', 'allow-same-origin'); + frame.srcdoc = sanitizedHtml; frame.src = 'about:blank'; const mount = () => { - if (!writeSandboxIframeDocument(frame, html)) return false; + if (!writeSandboxIframeDocument(frame, sanitizedHtml)) return false; onMounted?.(); return true; }; @@ -368,22 +377,6 @@ export function fitHtmlSlidePreviewSurface(host) { const SLIDE_SHADOW_ROOT_CLASS = 'ppt-slide-shadow-root'; const SLIDE_SHADOW_BODY_CLASS = 'ppt-slide-shadow-body'; -/** Strip active content (scripts, inline handlers, javascript: URLs) from a parsed slide document. */ -function sanitizeParsedSlideDocument(parsed) { - parsed.querySelectorAll('script, iframe, object, embed, meta[http-equiv="refresh" i]').forEach((node) => node.remove()); - parsed.querySelectorAll('*').forEach((node) => { - for (const attr of [...node.attributes]) { - const name = attr.name.toLowerCase(); - if (name.startsWith('on')) { - node.removeAttribute(attr.name); - } else if ((name === 'href' || name === 'src' || name === 'xlink:href') && /^\s*javascript:/i.test(attr.value)) { - node.removeAttribute(attr.name); - } - } - }); - return parsed; -} - /** * Build the in-document editable slide stage. The PPT Live app document * itself lives in a sandboxed host iframe without `allow-same-origin` @@ -401,9 +394,8 @@ function createEditableSlideStage(html, frameClass) { const designW = Number(stage.dataset.designW); const designH = Number(stage.dataset.designH); - const parsed = sanitizeParsedSlideDocument( - new DOMParser().parseFromString(normalizeSlideDocument(html), 'text/html'), - ); + const sanitizedMarkup = sanitizeSlideMarkup(normalizeSlideDocument(html)); + const parsed = new DOMParser().parseFromString(sanitizedMarkup, 'text/html'); const shadow = stage.attachShadow({ mode: 'open' }); const rootEl = document.createElement('div'); @@ -459,7 +451,7 @@ function createEditableSlideStage(html, frameClass) { rootEl.appendChild(bodyEl); shadow.appendChild(rootEl); - stage._pptLiveSourceHtml = String(html || ''); + stage._pptLiveSourceHtml = sanitizedMarkup; return stage; } @@ -1271,7 +1263,7 @@ export function hydrateHtmlSlideIframes(root = document) { export function slideHtml(slide, options = {}) { if (slide?.html) { const mountId = `slide-${++pendingSlideHtmlMountSeq}`; - pendingSlideHtmlMounts.set(mountId, normalizeSlideDocument(slide.html)); + pendingSlideHtmlMounts.set(mountId, sanitizeSlideMarkup(normalizeSlideDocument(slide.html))); return ``; } const editable = Boolean(options.editable); @@ -1288,7 +1280,12 @@ export function slideHtml(slide, options = {}) { ${slide.kicker ? `

          ${escapeHtml(slide.kicker)}
          ` : ''} ${slide.proofObject ? `
          ${escapeHtml(slide.proofObject)}
          ` : ''} ${slideQualityBadge(slide)} - ${(slide.elements || []).map((element) => elementHtml(element, slide.theme, editable, selectedId)).join('')} + ${(slide.elements || []).map((element) => elementModelElementHtml(element, slide.theme, { + mode: 'editor', + editable, + selectedId, + mediaPlaceholder: t('mediaPlaceholder'), + })).join('')} ${slide.sourceNote ? `
          ${escapeHtml(slide.sourceNote)}
          ` : ''} `; } @@ -1398,68 +1395,6 @@ export function normalizeSlideDocument(html) { return `${source}`; } -function elementHtml(element, theme, editable, selectedId) { - const selected = editable && selectedId === element.id; - const style = [ - `left:${element.x}%`, - `top:${element.y}%`, - `width:${element.w}%`, - `height:${element.h}%`, - `font-size:${fontSizeCss(element.style.fontSize)}`, - `font-weight:${element.style.fontWeight}`, - `color:${resolveColor(element.style.color, theme)}`, - `text-align:${element.style.align || 'left'}`, - `background:${resolveColor(element.style.background, theme)}`, - `opacity:${element.style.opacity}`, - `border-radius:${element.style.borderRadius}px`, - ].join(';'); - let content = ''; - if (element.type === 'list') { - content = `
            ${(element.items || []).map((item, index) => editable - ? `
          • ${escapeHtml(item)}
          • ` - : `
          • ${escapeHtml(item)}
          • `).join('')}
          `; - } else if (element.type === 'metric') { - content = `${escapeHtml(element.text)}${escapeHtml(element.label)}`; - } else if (element.type === 'chart') { - const max = Math.max(1, ...(element.data || []).map((point) => Number(point.value) || 0)); - content = `${escapeHtml(element.text)}
          ${(element.data || []).map((point) => `${escapeHtml(point.label)}`).join('')}
          `; - } else if (element.type === 'media') { - content = `${escapeHtml(element.text || t('mediaPlaceholder'))}`; - } else { - content = editable - ? `${escapeHtml(element.text || '')}` - : escapeHtml(element.text || ''); - } - return `
          ${content}${selected ? '' : ''}
          `; -} - -export function resolveColor(value, theme) { - if (!value || value === 'transparent') return 'transparent'; - if (value === 'ink') return theme.ink; - if (value === 'muted') return theme.muted; - if (value === 'primary') return theme.primary; - if (value === 'accent') return theme.accent; - if (value === 'panel') return theme.panel || '#ffffff'; - if (value === 'soft') return colorMix(theme.primary, 0.1); - if (value === 'background') return theme.background; - return value; -} - -function colorMix(hex, alpha) { - const raw = String(hex || '#0f766e').replace('#', ''); - const int = parseInt(raw.length === 3 ? raw.split('').map((x) => x + x).join('') : raw, 16); - const r = (int >> 16) & 255; - const g = (int >> 8) & 255; - const b = int & 255; - return `rgba(${r}, ${g}, ${b}, ${alpha})`; -} - -function fontSizeCss(value) { - const size = Math.max(8, Number(value) || 24); - const cqw = Math.round((size / 10.2) * 1000) / 1000; - return `clamp(8px, ${cqw}cqw, ${size}px)`; -} - function byId(id) { return document.getElementById(id); } diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/sanitize-slide-html.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/sanitize-slide-html.js index 04f634b854..c67e743b42 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/sanitize-slide-html.js +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/sanitize-slide-html.js @@ -1,10 +1,104 @@ export function sanitizeSlideDocumentRoot(doc = document, aggressive = false) { const document = doc; const view = document.defaultView || window; + const diagnostics = []; + const seenDiagnostics = new Set(); const skipTags = new Set(['SCRIPT', 'STYLE', 'PRE', 'CODE', 'SVG', 'TEXTAREA']); const inlineSelector = 'strong,b,em,i,u,span,a,small,mark,sub,sup,code'; const textSelector = 'p,h1,h2,h3,h4,h5,h6,li'; + const textContainerSelector = 'p,h1,h2,h3,h4,h5,h6,li'; + const manualBulletPattern = /^(\s*)([•●○▪‣·▸◆◇■□–—*-])\s+/u; + const ambiguousBulletSymbols = new Set(['-', '*', '–', '—']); + + function sourceIdOf(element) { + return element?.dataset?.pptxSourceId || element?.id || null; + } + + function assignSourceIds() { + const body = document.body; + if (!body) return; + const elements = [body, ...body.querySelectorAll('*')]; + const reserved = new Set( + elements.map((element) => element.dataset.pptxSourceId?.trim()).filter(Boolean), + ); + const used = new Set(); + elements.forEach((element) => { + const sourceId = element.dataset.pptxSourceId?.trim(); + if (!sourceId) return; + if (!used.has(sourceId)) { + element.dataset.pptxSourceId = sourceId; + used.add(sourceId); + return; + } + let suffix = 2; + let candidate = `${sourceId}-${suffix}`; + while (used.has(candidate) || reserved.has(candidate)) { + suffix += 1; + candidate = `${sourceId}-${suffix}`; + } + element.dataset.pptxSourceId = candidate; + used.add(candidate); + reserved.add(candidate); + addDiagnostic( + 'repaired', + 'duplicate_source_id_repaired', + `Duplicate source element id "${sourceId}" was reassigned to "${candidate}".`, + element, + ); + }); + let sequence = 1; + elements.forEach((element) => { + if (element.dataset?.pptxSourceId) return; + while (used.has(`pptx-source-${sequence}`) || reserved.has(`pptx-source-${sequence}`)) { + sequence += 1; + } + const sourceId = `pptx-source-${sequence}`; + sequence += 1; + element.dataset.pptxSourceId = sourceId; + used.add(sourceId); + }); + } + + function derivedSourceId(element, suffix) { + const base = sourceIdOf(element) || 'pptx-source'; + let candidate = `${base}-${suffix}`; + let sequence = 2; + while (document.querySelector(`[data-pptx-source-id="${candidate}"]`)) { + candidate = `${base}-${suffix}-${sequence}`; + sequence += 1; + } + return candidate; + } + + function addDiagnostic(severity, code, message, element = null) { + const sourceId = sourceIdOf(element); + const key = `${severity}:${code}:${sourceId || ''}`; + if (seenDiagnostics.has(key)) return; + seenDiagnostics.add(key); + const diagnostic = { + severity, + kind: severity === 'blocking' ? 'blocking' : undefined, + code, + message, + sourceId, + tag: element?.tagName?.toLowerCase?.() || null, + }; + try { + const rect = element?.getBoundingClientRect?.(); + if (rect && rect.width > 0 && rect.height > 0) { + diagnostic.bbox = { + x: rect.left, + y: rect.top, + width: rect.width, + height: rect.height, + }; + } + } catch { + // Diagnostics remain useful without optional geometry. + } + diagnostics.push(diagnostic); + } function inferBlockTag(node) { const cls = String(node.className || '').toLowerCase(); @@ -43,19 +137,89 @@ export function sanitizeSlideDocumentRoot(doc = document, aggressive = false) { } } + function repairNestedParagraphs(root) { + root.querySelectorAll(textContainerSelector).forEach((outer) => { + const nested = [...outer.children].filter((child) => child.matches(textContainerSelector)); + if (!nested.length || !outer.parentNode) return; + const fragments = []; + let current = document.createElement(outer.tagName.toLowerCase()); + const copyOuterAttributes = (target) => { + [...outer.attributes].forEach((attribute) => { + if (attribute.name !== 'data-pptx-source-id') target.setAttribute(attribute.name, attribute.value); + }); + }; + copyOuterAttributes(current); + current.dataset.pptxSourceId = sourceIdOf(outer); + [...outer.childNodes].forEach((node) => { + if (node.nodeType === view.Node.ELEMENT_NODE && node.matches(textContainerSelector)) { + if (current.textContent.trim() || current.children.length) fragments.push(current); + fragments.push(node); + current = document.createElement(outer.tagName.toLowerCase()); + copyOuterAttributes(current); + current.dataset.pptxSourceId = derivedSourceId(outer, `split-${fragments.length + 1}`); + } else { + current.appendChild(node); + } + }); + if (current.textContent.trim() || current.children.length) fragments.push(current); + outer.replaceWith(...fragments); + addDiagnostic( + 'repaired', + 'nested_paragraph_repaired', + 'Nested paragraph structure was split into ordered sibling paragraphs.', + fragments[0] || nested[0], + ); + }); + } + function wrapDirectTextNodes(root) { root.querySelectorAll('div').forEach((div) => { if (skipTags.has(div.tagName)) return; - [...div.childNodes].forEach((node) => { - if (node.nodeType !== Node.TEXT_NODE) return; - const text = node.textContent.replace(/\s+/g, ' ').trim(); - if (!text) { - node.remove(); - return; + let sequence = 1; + let nodes = [...div.childNodes]; + while (nodes.length) { + const firstDirectText = nodes.findIndex( + (node) => node.nodeType === view.Node.TEXT_NODE && node.textContent.trim(), + ); + if (firstDirectText < 0) break; + let start = firstDirectText; + while (start > 0) { + const previous = nodes[start - 1]; + if (previous.nodeType === view.Node.ELEMENT_NODE + && !previous.matches(inlineSelector) + && previous.tagName !== 'BR') break; + start -= 1; + } + let end = firstDirectText; + while (end + 1 < nodes.length) { + const next = nodes[end + 1]; + if (next.nodeType === view.Node.ELEMENT_NODE + && !next.matches(inlineSelector) + && next.tagName !== 'BR') break; + end += 1; } + const group = nodes.slice(start, end + 1); const block = document.createElement(inferBlockTag(div)); - block.textContent = text; - div.replaceChild(block, node); + block.dataset.pptxSourceId = derivedSourceId(div, `text-${sequence}`); + sequence += 1; + group[0].before(block); + group.forEach((node) => { + if (node.nodeType === view.Node.TEXT_NODE) { + node.textContent = node.textContent.replace(/\s+/g, ' '); + } + block.appendChild(node); + }); + block.normalize(); + addDiagnostic( + 'repaired', + 'direct_text_wrapped', + 'Direct container text was wrapped in a semantic text block.', + block, + ); + nodes = [...div.childNodes]; + } + [...div.childNodes].forEach((node) => { + if (node.nodeType === view.Node.TEXT_NODE && !node.textContent.trim()) node.remove(); }); }); } @@ -66,11 +230,96 @@ export function sanitizeSlideDocumentRoot(doc = document, aggressive = false) { const hasBg = computed.backgroundColor && computed.backgroundColor !== 'rgba(0, 0, 0, 0)'; const hasBorder = hasVisibleBorder(computed); if (!hasBg && !hasBorder) return; + if (span.closest(textContainerSelector)) return; const block = document.createElement('p'); if (span.className) block.className = span.className; if (span.getAttribute('style')) block.setAttribute('style', span.getAttribute('style')); - block.textContent = span.textContent; + block.dataset.pptxSourceId = sourceIdOf(span); + while (span.firstChild) block.appendChild(span.firstChild); span.replaceWith(block); + addDiagnostic( + 'repaired', + 'decorated_inline_promoted', + 'Decorated inline text was promoted to a block that can be exported as shape plus text.', + block, + ); + }); + } + + function removeManualBullet(element) { + const symbol = element.textContent.match(manualBulletPattern)?.[2]; + if (!symbol) return; + const walker = document.createTreeWalker(element, view.NodeFilter.SHOW_TEXT); + let textNode = walker.nextNode(); + let removed = false; + while (textNode) { + if (!removed) { + const symbolIndex = textNode.textContent.search(/\S/u); + if (symbolIndex >= 0) { + if (textNode.textContent.slice(symbolIndex).startsWith(symbol)) { + textNode.textContent = textNode.textContent.slice(symbolIndex + symbol.length).replace(/^\s+/u, ''); + removed = true; + if (textNode.textContent) return; + } else { + return; + } + } + } else if (textNode.textContent) { + textNode.textContent = textNode.textContent.replace(/^\s+/u, ''); + return; + } + textNode = walker.nextNode(); + } + } + + function normalizeManualBulletBlocks(root) { + root.querySelectorAll('body, div, section, article, aside, main, td, th').forEach((parent) => { + let group = []; + const flush = () => { + if (!group.length) return; + const first = group[0]; + const firstSymbol = first.textContent.match(manualBulletPattern)?.[2]; + if (group.length === 1 && ambiguousBulletSymbols.has(firstSymbol)) { + group = []; + return; + } + const list = document.createElement('ul'); + list.dataset.pptxSourceId = derivedSourceId(first, 'list'); + const firstComputed = view.getComputedStyle(first); + const authoredIndent = parseFloat(firstComputed.marginLeft || first.style.marginLeft || '0') || 0; + list.style.margin = '0'; + list.style.paddingLeft = `${Math.max(24, authoredIndent + 24)}px`; + first.parentNode.insertBefore(list, first); + group.forEach((block) => { + const item = document.createElement('li'); + [...block.attributes].forEach((attribute) => { + if (!['id', 'data-pptx-source-id'].includes(attribute.name)) { + item.setAttribute(attribute.name, attribute.value); + } + }); + item.dataset.pptxSourceId = sourceIdOf(block); + while (block.firstChild) item.appendChild(block.firstChild); + removeManualBullet(item); + list.appendChild(item); + block.remove(); + }); + addDiagnostic( + 'repaired', + 'manual_bullet_list', + `${group.length} consecutive manual bullet paragraph(s) were converted to a semantic list.`, + list, + ); + group = []; + }; + [...parent.children].forEach((child) => { + const isTextBlock = /^(P|H[1-6])$/.test(child.tagName); + if (isTextBlock && manualBulletPattern.test(child.textContent || '')) { + group.push(child); + } else { + flush(); + } + }); + flush(); }); } @@ -93,6 +342,75 @@ export function sanitizeSlideDocumentRoot(doc = document, aggressive = false) { }); } + function collectFallbackDiagnostics(root) { + root.querySelectorAll('*').forEach((element) => { + const computed = view.getComputedStyle(element); + const backgroundImage = String(computed.backgroundImage || element.style?.backgroundImage || ''); + if (backgroundImage.includes('gradient')) { + addDiagnostic( + 'fallback', + 'css_gradient', + 'CSS gradient requires fallback rendering; native gradient mapping is not available.', + element, + ); + } + const filter = String(computed.filter || element.style?.filter || ''); + if (filter && filter !== 'none') { + addDiagnostic( + 'fallback', + 'css_filter', + 'CSS filter requires fallback rendering.', + element, + ); + } + }); + root.querySelectorAll('svg').forEach((svg) => { + if (svg.querySelector('filter,mask,foreignObject,use,pattern,textPath,clipPath,image')) { + addDiagnostic( + 'fallback', + 'complex_svg_raster', + 'SVG filter, mask, or foreignObject requires local browser raster rendering.', + svg, + ); + } else if (svg.querySelector('path')) { + addDiagnostic( + 'fallback', + 'complex_svg_vector', + 'Complex SVG geometry will be preserved as a local SVG image.', + svg, + ); + } + }); + root.querySelectorAll('style').forEach((style) => { + let rules = []; + try { + rules = [...(style.sheet?.cssRules || [])]; + } catch { + return; + } + rules.forEach((rule) => { + const selector = rule.selectorText || ''; + const content = rule.style?.content; + if (!/::(before|after)/.test(selector) + || !content + || ['none', 'normal', '""', "''"].includes(content)) return; + const baseSelector = selector.replace(/::(before|after)/g, '').trim(); + let matches = []; + try { + matches = [...root.querySelectorAll(baseSelector)]; + } catch { + return; + } + matches.forEach((element) => addDiagnostic( + 'fallback', + 'generated_content', + 'Pseudo-element generated content requires fallback rendering.', + element, + )); + }); + }); + } + function hasVisibleBorder(computed) { return ['Top', 'Right', 'Bottom', 'Left'].some((side) => parseFloat(computed[`border${side}Width`] || 0) > 0); } @@ -273,14 +591,18 @@ export function sanitizeSlideDocumentRoot(doc = document, aggressive = false) { (root.head || root.documentElement).appendChild(style); } + assignSourceIds(); + collectFallbackDiagnostics(document); ensureExportCanvas(); - wrapDirectTextNodes(document); + repairNestedParagraphs(document); promoteDecoratedSpans(document); + wrapDirectTextNodes(document); + normalizeManualBulletBlocks(document); normalizeInlineLists(document); - flattenGradients(document); - stripUnsupportedDivBackgrounds(document); if (aggressive) { + flattenGradients(document); + stripUnsupportedDivBackgrounds(document); hoistTextDecorations(document); resetInlineBoxModel(document); enforceInlineElementsSafe(document); @@ -297,4 +619,5 @@ export function sanitizeSlideDocumentRoot(doc = document, aggressive = false) { // Preserve author layout/CSS; snapshot computed styles for a stable second paint. inlineSnapshotLayoutStyles(document); } + return { diagnostics }; } diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/sanitize-slide-markup.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/sanitize-slide-markup.js new file mode 100644 index 0000000000..5b6a19c023 --- /dev/null +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/sanitize-slide-markup.js @@ -0,0 +1,260 @@ +const SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; +const DELETE_WITH_CONTENT_TAGS = new Set([ + 'script', 'iframe', 'object', 'embed', 'base', 'meta', 'link', 'template', + 'frame', 'frameset', 'portal', +]); + +export const HTML_ALLOWED_TAGS = new Set([ + 'html', 'head', 'body', 'title', 'style', + 'div', 'section', 'article', 'main', 'header', 'footer', 'nav', 'aside', + 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'span', 'strong', 'b', 'em', 'i', + 'u', 's', 'small', 'mark', 'sub', 'sup', 'code', 'pre', 'blockquote', + 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'br', 'hr', 'a', + 'table', 'caption', 'colgroup', 'col', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td', + 'figure', 'figcaption', 'img', 'label', 'time', +]); + +export const SVG_ALLOWED_TAGS = new Set([ + 'svg', 'g', 'defs', 'desc', 'title', + 'rect', 'circle', 'ellipse', 'line', 'polyline', 'polygon', 'path', + 'text', 'tspan', 'textpath', 'use', 'foreignobject', 'symbol', 'marker', + 'lineargradient', 'radialgradient', 'stop', 'pattern', 'clippath', 'mask', 'filter', + 'feblend', 'fecolormatrix', 'fecomponenttransfer', 'fecomposite', 'feconvolvematrix', + 'fediffuselighting', 'fedisplacementmap', 'fedistantlight', 'fedropshadow', + 'feflood', 'fefunca', 'fefuncb', 'fefuncg', 'fefuncr', 'fegaussianblur', + 'feimage', 'femerge', 'femergenode', 'femorphology', 'feoffset', + 'fepointlight', 'fespecularlighting', 'fespotlight', 'fetile', 'feturbulence', +]); + +export const GLOBAL_ALLOWED_ATTRIBUTES = new Set([ + 'id', 'class', 'style', 'title', 'role', 'lang', 'dir', 'hidden', + 'tabindex', 'draggable', 'spellcheck', 'contenteditable', +]); + +export const TAG_ALLOWED_ATTRIBUTES = Object.freeze({ + img: new Set(['src', 'alt', 'width', 'height', 'loading', 'decoding']), + ol: new Set(['start', 'reversed', 'type']), + li: new Set(['value']), + col: new Set(['span']), + th: new Set(['colspan', 'rowspan', 'scope', 'headers', 'abbr']), + td: new Set(['colspan', 'rowspan', 'headers']), + label: new Set(['for']), + time: new Set(['datetime']), +}); + +export const SVG_GLOBAL_ALLOWED_ATTRIBUTES = new Set([ + 'id', 'class', 'style', 'transform', 'fill', 'fill-opacity', 'fill-rule', + 'stroke', 'stroke-width', 'stroke-opacity', 'stroke-linecap', 'stroke-linejoin', + 'stroke-dasharray', 'stroke-dashoffset', 'opacity', 'filter', 'clip-path', + 'clip-rule', 'mask', 'color', 'color-interpolation', 'color-interpolation-filters', + 'visibility', 'display', 'font-family', 'font-size', 'font-style', 'font-weight', + 'text-anchor', 'dominant-baseline', 'pointer-events', 'vector-effect', + 'paint-order', 'shape-rendering', 'text-rendering', 'stop-color', 'stop-opacity', + 'flood-color', 'flood-opacity', 'lighting-color', + 'marker-start', 'marker-mid', 'marker-end', +]); +const SVG_RESOURCE_PRESENTATION_ATTRIBUTES = new Set([ + 'fill', 'stroke', 'filter', 'clip-path', 'mask', + 'marker-start', 'marker-mid', 'marker-end', +]); + +const SVG_GEOMETRY_ATTRIBUTES = new Set([ + 'x', 'y', 'x1', 'y1', 'x2', 'y2', 'cx', 'cy', 'r', 'rx', 'ry', + 'width', 'height', 'd', 'points', 'pathlength', +]); +const SVG_FILTER_ATTRIBUTES = new Set([ + 'in', 'in2', 'result', 'operator', 'k1', 'k2', 'k3', 'k4', 'mode', 'type', + 'values', 'tablevalues', 'slope', 'intercept', 'amplitude', 'exponent', 'offset', + 'stddeviation', 'edgemode', 'kernelmatrix', 'kernelunitlength', 'targetx', 'targety', + 'order', 'preservealpha', 'surfacescale', 'diffuseconstant', 'specularconstant', + 'specularexponent', 'limitingconeangle', 'azimuth', 'elevation', + 'pointsatx', 'pointsaty', 'pointsatz', 'basefrequency', 'numoctaves', 'seed', + 'stitchtiles', 'scale', 'xchannelselector', 'ychannelselector', 'radius', 'dx', 'dy', +]); +export const SVG_TAG_ALLOWED_ATTRIBUTES = Object.freeze({ + svg: new Set(['viewbox', 'width', 'height', 'x', 'y', 'preserveaspectratio', 'xmlns', 'xmlns:xlink']), + symbol: new Set(['viewbox', 'x', 'y', 'width', 'height', 'preserveaspectratio']), + marker: new Set(['viewbox', 'markerwidth', 'markerheight', 'markerunits', 'orient', 'preserveaspectratio', 'refx', 'refy']), + rect: new Set([...SVG_GEOMETRY_ATTRIBUTES]), + circle: new Set([...SVG_GEOMETRY_ATTRIBUTES]), + ellipse: new Set([...SVG_GEOMETRY_ATTRIBUTES]), + line: new Set([...SVG_GEOMETRY_ATTRIBUTES]), + polyline: new Set([...SVG_GEOMETRY_ATTRIBUTES]), + polygon: new Set([...SVG_GEOMETRY_ATTRIBUTES]), + path: new Set([...SVG_GEOMETRY_ATTRIBUTES]), + text: new Set(['x', 'y', 'dx', 'dy', 'rotate', 'textlength', 'lengthadjust']), + tspan: new Set(['x', 'y', 'dx', 'dy', 'rotate', 'textlength', 'lengthadjust']), + textpath: new Set(['href', 'xlink:href', 'startoffset', 'method', 'spacing', 'side', 'textlength', 'lengthadjust']), + use: new Set(['x', 'y', 'width', 'height', 'href', 'xlink:href']), + foreignobject: new Set(['x', 'y', 'width', 'height']), + lineargradient: new Set(['x1', 'y1', 'x2', 'y2', 'gradientunits', 'gradienttransform', 'spreadmethod', 'href', 'xlink:href']), + radialgradient: new Set(['cx', 'cy', 'r', 'fx', 'fy', 'fr', 'gradientunits', 'gradienttransform', 'spreadmethod', 'href', 'xlink:href']), + stop: new Set(['offset']), + pattern: new Set(['x', 'y', 'width', 'height', 'patternunits', 'patterncontentunits', 'patterntransform', 'viewbox', 'preserveaspectratio', 'href', 'xlink:href']), + clippath: new Set(['clippathunits']), + mask: new Set(['x', 'y', 'width', 'height', 'maskunits', 'maskcontentunits']), + filter: new Set(['x', 'y', 'width', 'height', 'filterunits', 'primitiveunits']), +}); + +function canonicalizeCssEscapes(value) { + let current = String(value || ''); + for (let pass = 0; pass < 4; pass += 1) { + const decoded = current + .replace(/\\([0-9a-f]{1,6})(?:\r\n|[ \n\r\t\f])?/gi, (_match, hex) => ( + String.fromCodePoint(Number.parseInt(hex, 16) || 0) + )) + .replace(/\\([^\n\r\f0-9a-f])/gi, '$1'); + if (decoded === current) break; + current = decoded; + } + return current; +} + +function hasUnsafeCss(value) { + // Agent-authored CSS is untrusted. Decode CSS escapes first, then remove the + // complete declaration container instead of attempting a partial CSS parser. + const css = canonicalizeCssEscapes(value).toLowerCase(); + return /url\s*\(|@import\b|@font-face\b|expression\s*\(|behavior\s*:|-moz-binding\b|(?:-webkit-)?image-set\s*\(|(?:image|cross-fade|element|src)\s*\(/.test(css); +} + +function isSafeRasterDataImage(value) { + const candidate = String(value || '').trim(); + const match = candidate.match(/^data:image\/(png|jpeg|gif|webp)((?:;[a-z0-9._-]+=[a-z0-9._-]+)*)(;base64)?,([\s\S]*)$/i); + if (!match) return false; + const payload = match[4]; + if (!payload) return false; + return match[3] + ? /^[a-z0-9+/=\s]+$/i.test(payload) + : !/[<>"'`]/.test(payload) && /^(?:%[0-9a-f]{2}|[a-z0-9!$&()*+,\-./:;=?@_~\s])+$/i.test(payload); +} + +function isAllowedResource(node, name, value) { + const localName = String(node.localName || '').toLowerCase(); + const isSvg = node.namespaceURI === SVG_NAMESPACE || node.closest?.('svg'); + if ((name === 'href' || name === 'xlink:href') && isSvg) { + return /^#[a-z_][\w:.-]*$/i.test(canonicalizeCssEscapes(value).trim()); + } + if (name === 'src') return localName === 'img' && isSafeRasterDataImage(value); + return false; +} + +function normalizedLocalPaintServer(value) { + const canonical = canonicalizeCssEscapes(value).trim(); + const match = canonical.match(/^url\(\s*(#[a-z_][\w:.-]*)\s*\)$/i); + return match ? `url(${match[1]})` : null; +} + +function normalizedSvgResourceAttribute(name, value) { + const canonical = canonicalizeCssEscapes(value).trim(); + const lower = canonical.toLowerCase(); + if (name === 'href' || name === 'xlink:href') { + return /^#[a-z_][\w:.-]*$/i.test(canonical) ? canonical : null; + } + if (!SVG_RESOURCE_PRESENTATION_ATTRIBUTES.has(name)) return canonical; + if (/\burl\s*\(/i.test(canonical)) return normalizedLocalPaintServer(canonical); + if (name === 'fill' || name === 'stroke') { + if (/(?:javascript|vbscript|file|data|blob|https?):|(?:^|[\s"'(])\/\//i.test(lower)) return null; + if (/(?:-webkit-)?image-set\s*\(|(?:image|cross-fade|element|src)\s*\(/i.test(lower)) return null; + return canonical || null; + } + return /^(?:none|inherit|initial|unset)$/i.test(canonical) ? canonical : null; +} + +function hasSafeCustomAttributeValue(value) { + const canonical = canonicalizeCssEscapes(value).trim().toLowerCase(); + return !/(?:javascript|vbscript|file|data|blob|https?):|(?:^|[\s"'(])\/\//.test(canonical) + && !hasUnsafeCss(canonical); +} + +function isSvgElement(node) { + return node.namespaceURI === SVG_NAMESPACE; +} + +function allowedAttributeName(node, name) { + const tag = String(node.localName || '').toLowerCase(); + if (name.startsWith('data-') || name.startsWith('aria-')) return true; + if (isSvgElement(node)) { + if (GLOBAL_ALLOWED_ATTRIBUTES.has(name) || SVG_GLOBAL_ALLOWED_ATTRIBUTES.has(name)) return true; + if (SVG_TAG_ALLOWED_ATTRIBUTES[tag]?.has(name)) return true; + return tag.startsWith('fe') && ( + SVG_GEOMETRY_ATTRIBUTES.has(name) || SVG_FILTER_ATTRIBUTES.has(name) + ); + } + return GLOBAL_ALLOWED_ATTRIBUTES.has(name) || Boolean(TAG_ALLOWED_ATTRIBUTES[tag]?.has(name)); +} + +export function isAllowedSanitizedAttribute(node, rawName, value) { + const name = String(rawName || '').toLowerCase(); + if (!name || name.startsWith('on') || !allowedAttributeName(node, name)) return false; + if (name.startsWith('data-') || name.startsWith('aria-')) { + return hasSafeCustomAttributeValue(value); + } + if (name === 'style') return !hasUnsafeCss(value); + if (name === 'src' || name === 'href' || name === 'xlink:href') { + return isAllowedResource(node, name, value); + } + if (isSvgElement(node) && SVG_RESOURCE_PRESENTATION_ATTRIBUTES.has(name)) { + return normalizedSvgResourceAttribute(name, value) !== null; + } + if (name === 'xmlns') return value === SVG_NAMESPACE; + if (name === 'xmlns:xlink') return value === 'http://www.w3.org/1999/xlink'; + return true; +} + +function unwrapNode(node) { + node.replaceWith(...node.childNodes); +} + +export function sanitizeSlideDocument(parsed) { + let repaired = false; + [...parsed.querySelectorAll('*')].forEach((node) => { + const tag = String(node.localName || node.tagName || '').toLowerCase(); + const allowedTags = isSvgElement(node) ? SVG_ALLOWED_TAGS : HTML_ALLOWED_TAGS; + if (DELETE_WITH_CONTENT_TAGS.has(tag)) { + repaired = true; + node.remove(); + } else if (!allowedTags.has(tag)) { + repaired = true; + unwrapNode(node); + } + }); + parsed.querySelectorAll('style').forEach((style) => { + if (hasUnsafeCss(style.textContent)) { + repaired = true; + style.remove(); + } + }); + parsed.querySelectorAll('*').forEach((node) => { + for (const attribute of [...node.attributes]) { + if (!isAllowedSanitizedAttribute(node, attribute.name, attribute.value)) { + repaired = true; + node.removeAttribute(attribute.name); + } else if (isSvgElement(node)) { + const name = attribute.name.toLowerCase(); + if (SVG_RESOURCE_PRESENTATION_ATTRIBUTES.has(name) + || name === 'href' + || name === 'xlink:href') { + const normalized = normalizedSvgResourceAttribute(name, attribute.value); + if (normalized !== attribute.value) { + repaired = true; + node.setAttribute(attribute.name, normalized); + } + } + } + } + }); + parsed._pptxSecurityDiagnostics = repaired ? [{ + severity: 'repaired', + code: 'active_content_removed', + message: 'Unsafe active content and resource references were removed.', + sourceId: 'slide-document', + phase: 'security-repair', + }] : []; + return parsed; +} + +export function sanitizeSlideMarkup(markup) { + const parsed = new DOMParser().parseFromString(String(markup || ''), 'text/html'); + sanitizeSlideDocument(parsed); + return `${parsed.documentElement.outerHTML}`; +} diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test/dom-repair-diagnostics.test.mjs b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test/dom-repair-diagnostics.test.mjs new file mode 100644 index 0000000000..4eedb24bef --- /dev/null +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test/dom-repair-diagnostics.test.mjs @@ -0,0 +1,1777 @@ +import assert from 'node:assert/strict'; +import { createRequire } from 'node:module'; +import test from 'node:test'; + +import { extractSlideDataFromDocument } from '../src/html2pptx-dom-core.js'; +import { buildSlideFromExtracted } from '../src/pptx-html-build.js'; +import { sanitizeSlideDocumentRoot } from '../src/sanitize-slide-html.js'; +import { + HTML_ALLOWED_TAGS, + SVG_ALLOWED_TAGS, + isAllowedSanitizedAttribute, + sanitizeSlideDocument, +} from '../src/sanitize-slide-markup.js'; +import { + buildPageVisualFallbackRequest, + buildRasterFallbackRequests, + buildWholePageVisualFallbackRequest, + renderRasterFallbackPlan, + renderRasterFallbackLayers, +} from '../src/fallback-layer-render.js'; +import { + formatLocalizedExportDiagnostic, + sanitizeDiagnosticSourceId, + summarizePptxExportDiagnostics, +} from '../src/export-diagnostics.js'; +import { STRINGS } from '../src/i18n.js'; + +const requireFromWebUi = createRequire( + new URL('../../../../../../../../../web-ui/package.json', import.meta.url), +); +const { JSDOM, VirtualConsole } = requireFromWebUi('jsdom'); + +function createSilentDom(markup, options = {}) { + return new JSDOM(markup, { + ...options, + virtualConsole: new VirtualConsole(), + }); +} + +function createDocument(bodyHtml, css = '') { + const dom = createSilentDom(`${bodyHtml}`, { + pretendToBeVisual: true, + }); + installMeasurableLayout(dom.window.document); + return dom.window.document; +} + +function installMeasurableLayout(doc) { + const rect = (left, top, width, height) => ({ + x: left, + y: top, + left, + top, + width, + height, + right: left + width, + bottom: top + height, + toJSON() { + return { left, top, width, height }; + }, + }); + Object.defineProperties(doc.body, { + scrollWidth: { configurable: true, value: 1280 }, + scrollHeight: { configurable: true, value: 720 }, + }); + doc.body.getBoundingClientRect = () => rect(0, 0, 1280, 720); + [...doc.body.querySelectorAll('*')].forEach((element, index) => { + element.getBoundingClientRect = () => rect(40, 30 + index * 36, 640, 30); + Object.defineProperties(element, { + offsetWidth: { configurable: true, value: 640 }, + offsetHeight: { configurable: true, value: 30 }, + scrollHeight: { configurable: true, value: 30 }, + }); + }); + doc.createRange = () => ({ + selectNodeContents(element) { + this.element = element; + }, + getBoundingClientRect() { + return this.element?.getBoundingClientRect() || rect(0, 0, 0, 0); + }, + detach() {}, + }); +} + +test('shared markup sanitizer removes active content and unsafe resource URLs for every export surface', () => { + const dom = createSilentDom(` + + + + link + + bad + bad + `); + const sanitized = sanitizeSlideDocument(dom.window.document).documentElement.outerHTML; + + for (const unsafe of ['link<\/a>/); + assert.match(sanitized, /id="local"/); + assert.doesNotMatch(sanitized, /assets\/image\.png/); +}); + +test('sanitizer fail-closes escaped CSS and applies element-specific resource rules', () => { + const dom = createSilentDom(` + + + +
          + Text remains + + + +
          +
          + + `); + + const sanitized = sanitizeSlideDocument(dom.window.document); + + assert.equal(sanitized.querySelector('form'), null); + assert.equal(sanitized.querySelector('#anchor').hasAttribute('href'), false); + assert.equal(sanitized.querySelector('#anchor').textContent, 'Text remains'); + assert.equal(sanitized.querySelector('#safe-png').getAttribute('src'), 'data:image/png;base64,AA=='); + assert.equal(sanitized.querySelector('#safe-png').hasAttribute('srcset'), false); + assert.equal(sanitized.querySelector('#bad-svg').hasAttribute('src'), false); + assert.equal(sanitized.querySelector('#poster'), null); + assert.equal(sanitized.querySelector('#escaped-url').hasAttribute('style'), false); + assert.equal(sanitized.querySelector('#escaped-expression').hasAttribute('style'), false); + assert.equal(sanitized.querySelector('#escaped-import'), null); + assert.match(sanitized.querySelector('#safe-style').textContent, /linear-gradient/); + assert.equal(sanitized.querySelector('#svg-local').getAttribute('xlink:href'), '#shape'); + assert.equal(sanitized.querySelector('#svg-remote').hasAttribute('href'), false); +}); + +test('sanitizer enforces tag and attribute allowlists plus embedded-resource CSS denial', () => { + const dom = createSilentDom(` + + + + + + Visible child +
          + + + + + + + + + Path text + SVG text + + `); + + const sanitized = sanitizeSlideDocument(dom.window.document); + const body = sanitized.body; + + assert.equal(sanitized.querySelector('link,#image-set,#escaped-image-set'), null); + assert.match(sanitized.querySelector('#safe-css').textContent, /linear-gradient/); + assert.equal(body.hasAttribute('mystery'), false); + assert.equal(body.getAttribute('data-safe'), 'ok'); + assert.equal(body.hasAttribute('data-url'), false); + assert.equal(sanitized.querySelector('marquee,custom-tag,unknown-svg-tag'), null); + assert.match(body.textContent, /Visible child/); + assert.equal(sanitized.querySelector('#layout').hasAttribute('unknown-attr'), false); + assert.match(sanitized.querySelector('#layout').getAttribute('style'), /display:\s*flex/); + assert.equal(sanitized.querySelector('svg').hasAttribute('unknown-svg'), false); + assert.equal(sanitized.querySelector('use').getAttribute('href'), '#paint'); + assert.equal(sanitized.querySelector('use').hasAttribute('externalResourcesRequired'), false); + assert.ok(sanitized.querySelector('symbol,marker,textPath')); + assert.equal(sanitized.querySelector('textPath').getAttribute('href'), '#route'); + assert.match(sanitized.querySelector('svg').textContent, /SVG text/); + + sanitized.querySelectorAll('*').forEach((node) => { + const tag = node.localName.toLowerCase(); + const allowedTags = node.namespaceURI === 'http://www.w3.org/2000/svg' + ? SVG_ALLOWED_TAGS + : HTML_ALLOWED_TAGS; + assert.ok(allowedTags.has(tag), `unexpected sanitized tag: ${tag}`); + [...node.attributes].forEach((attribute) => { + assert.equal( + isAllowedSanitizedAttribute(node, attribute.name, attribute.value), + true, + `unexpected sanitized attribute: ${tag}.${attribute.name}`, + ); + }); + }); +}); + +test('whole-page visual request owns native visual suppression at construction', () => { + const doc = createDocument('

          Text

          '); + sanitizeSlideDocumentRoot(doc); + const request = buildWholePageVisualFallbackRequest( + doc, + [{ code: 'canvas_overflow', severity: 'fallback' }], + ['panel', 'image', 'panel'], + ); + assert.deepEqual(request.suppressedNativeVisualIds, ['panel', 'image']); +}); + +test('all SVG paint-server and resource presentation attributes canonicalize to local fragments', () => { + const dom = createSilentDom(''); + const doc = dom.window.document; + const svg = doc.querySelector('svg'); + const resourceAttributes = [ + 'fill', 'stroke', 'filter', 'clip-path', 'mask', + 'marker-start', 'marker-mid', 'marker-end', + ]; + const appendPath = (id, attribute, value) => { + const path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); + path.setAttribute('id', id); + path.setAttribute('d', 'M0 0L1 1'); + path.setAttribute(attribute, value); + svg.append(path); + return path; + }; + + resourceAttributes.forEach((attribute, index) => { + appendPath(`local-${index}`, attribute, 'url(#safe-paint)'); + appendPath(`external-${index}`, attribute, 'url(https://evil.invalid/paint.svg#x)'); + appendPath(`escaped-${index}`, attribute, '\\75\\72\\6c (https://evil.invalid/paint.svg#x)'); + }); + appendPath('fill-color', 'fill', '#123456'); + appendPath('stroke-color', 'stroke', 'currentColor'); + [ + ['protocol-relative', 'fill', 'url(//evil.invalid/x)'], + ['data-resource', 'stroke', 'url(data:image/svg+xml,bad)'], + ['blob-resource', 'filter', 'url(blob:secret)'], + ['file-resource', 'mask', 'url(file:///tmp/secret.svg)'], + ].forEach(([id, attribute, value]) => appendPath(id, attribute, value)); + const useLocal = doc.createElementNS('http://www.w3.org/2000/svg', 'use'); + useLocal.id = 'href-local'; + useLocal.setAttribute('href', '\\23 safe-paint'); + svg.append(useLocal); + const useExternal = doc.createElementNS('http://www.w3.org/2000/svg', 'use'); + useExternal.id = 'href-external'; + useExternal.setAttribute('href', '\\68 ttps://evil.invalid/x.svg'); + svg.append(useExternal); + + const sanitized = sanitizeSlideDocument(doc); + + resourceAttributes.forEach((attribute, index) => { + assert.equal(sanitized.querySelector(`#local-${index}`).getAttribute(attribute), 'url(#safe-paint)'); + assert.equal(sanitized.querySelector(`#external-${index}`).hasAttribute(attribute), false); + assert.equal(sanitized.querySelector(`#escaped-${index}`).hasAttribute(attribute), false); + }); + assert.equal(sanitized.querySelector('#fill-color').getAttribute('fill'), '#123456'); + assert.equal(sanitized.querySelector('#stroke-color').getAttribute('stroke'), 'currentColor'); + for (const id of ['protocol-relative', 'data-resource', 'blob-resource', 'file-resource']) { + const element = sanitized.querySelector(`#${id}`); + assert.equal( + [...element.attributes].some((attribute) => resourceAttributes.includes(attribute.name)), + false, + id, + ); + } + assert.equal(sanitized.querySelector('#href-local').getAttribute('href'), '#safe-paint'); + assert.equal(sanitized.querySelector('#href-external').hasAttribute('href'), false); + sanitized.querySelectorAll('svg *').forEach((node) => { + [...node.attributes].forEach((attribute) => { + assert.equal(isAllowedSanitizedAttribute(node, attribute.name, attribute.value), true); + }); + }); +}); + +test('repairs consecutive manual bullets into one semantic list with preserved styles', () => { + const doc = createDocument(` +
          +

          • First item

          +

          ● Second item

          +

          Ordinary paragraph

          +
          + `); + + const { diagnostics } = sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + const slideData = extractSlideDataFromDocument(doc); + + const list = doc.querySelector('section > ul'); + assert.ok(list); + assert.equal(list.children.length, 2); + assert.deepEqual([...list.children].map((item) => item.textContent.trim()), ['First item', 'Second item']); + assert.equal(list.children[0].style.marginLeft, '24px'); + assert.equal(doc.querySelector('section > p').textContent, 'Ordinary paragraph'); + assert.equal(slideData.elements.filter((element) => element.type === 'list').length, 1); + assert.ok(!slideData.errors.some((message) => message.includes('starts with bullet symbol'))); + assert.ok(diagnostics.some((item) => item.code === 'manual_bullet_list' && item.severity === 'repaired')); +}); + +test('removes a manual bullet split from its text by inline formatting', () => { + const doc = createDocument(` +
          +

          Item one

          +

          Item two

          +
          + `); + + sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + const slideData = extractSlideDataFromDocument(doc); + const list = slideData.elements.find((element) => element.type === 'list'); + + assert.deepEqual([...doc.querySelectorAll('li')].map((item) => item.textContent.trim()), ['Item one', 'Item two']); + assert.ok(list); + assert.doesNotMatch(list.items.map((run) => run.text).join(''), /[•●]/u); +}); + +test('does not classify a dash without following whitespace as a manual bullet', () => { + const doc = createDocument('

          –40°C remains a normal sentence

          '); + + sanitizeSlideDocumentRoot(doc); + + assert.equal(doc.querySelectorAll('ul, ol').length, 0); + assert.equal(doc.querySelector('p').textContent, '–40°C remains a normal sentence'); +}); + +test('keeps standalone en/em dash asides but repairs consecutive dash lists', () => { + const doc = createDocument(` +
          +

          – This is an aside

          +

          Ordinary separator

          +

          — This is another aside

          +
          +
          +

          – First dash item

          +

          — Second dash item

          +
          + `); + + sanitizeSlideDocumentRoot(doc); + + assert.equal(doc.querySelectorAll('#asides ul').length, 0); + assert.deepEqual( + [...doc.querySelectorAll('#asides > p')].map((item) => item.textContent), + ['– This is an aside', 'Ordinary separator', '— This is another aside'], + ); + assert.deepEqual( + [...doc.querySelectorAll('#dash-list li')].map((item) => item.textContent), + ['First dash item', 'Second dash item'], + ); +}); + +test('repairs consecutive ambiguous dash bullets but leaves a single dash sentence alone', () => { + const doc = createDocument(` +

          - First

          - Second

          +

          - This standalone sentence is intentionally unchanged.

          + `); + + sanitizeSlideDocumentRoot(doc); + + assert.deepEqual( + [...doc.querySelectorAll('#list li')].map((item) => item.textContent), + ['First', 'Second'], + ); + assert.equal(doc.querySelector('#sentence > p').textContent, '- This standalone sentence is intentionally unchanged.'); +}); + +test('repairs direct text, decorated spans, nested paragraphs, and merge text without reordering', () => { + const doc = createDocument(` +
          Alpha middle Omega
          +
          Badge
          +
          Lead

          Second

          Tail
          + `); + const outer = doc.createElement('p'); + outer.append('Before '); + const inner = doc.createElement('p'); + inner.textContent = 'Nested'; + outer.append(inner, ' After'); + doc.body.appendChild(outer); + installMeasurableLayout(doc); + const beforeText = doc.body.textContent.replace(/\s+/g, ' ').trim(); + + const { diagnostics } = sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + const slideData = extractSlideDataFromDocument(doc); + + assert.equal(doc.body.textContent.replace(/\s+/g, ' ').trim(), beforeText); + assert.equal(doc.querySelector('#direct > p')?.textContent.replace(/\s+/g, ' ').trim(), 'Alpha middle Omega'); + assert.equal(doc.querySelector('#direct > p > em')?.textContent, 'middle'); + assert.equal(doc.querySelector('#decorated > p')?.textContent, 'Badge'); + assert.equal(doc.querySelector('p p'), null); + assert.deepEqual( + [...doc.querySelector('[data-pptx-merge="true"]').children].map((node) => node.textContent.trim()), + ['Lead', 'Second', 'Tail'], + ); + const merged = slideData.elements.find((element) => element.type === 'merged-text'); + assert.ok(merged); + assert.deepEqual(merged.items.map((run) => run.text.trim()), ['Lead', 'Second', 'Tail']); + assert.equal(merged.items[0].options.breakLine, true); + assert.equal(merged.items[1].options.breakLine, true); + for (const code of ['direct_text_wrapped', 'decorated_inline_promoted', 'nested_paragraph_repaired']) { + assert.ok(diagnostics.some((item) => item.code === code && item.severity === 'repaired'), code); + } +}); + +test('preserves explicit source ids and assigns stable generated ids', () => { + const doc = createDocument(` +

          Title

          +

          • Generated item

          + `); + + sanitizeSlideDocumentRoot(doc); + const firstIds = [...doc.querySelectorAll('[data-pptx-source-id]')] + .map((element) => element.dataset.pptxSourceId); + sanitizeSlideDocumentRoot(doc); + const secondIds = [...doc.querySelectorAll('[data-pptx-source-id]')] + .map((element) => element.dataset.pptxSourceId); + installMeasurableLayout(doc); + const slideData = extractSlideDataFromDocument(doc); + + assert.ok(firstIds.includes('author-title')); + assert.deepEqual(secondIds, firstIds); + assert.equal(new Set(firstIds).size, firstIds.length); + assert.ok(slideData.elements.some((element) => element.sourceId === 'author-title')); + assert.ok(slideData.elements + .filter((element) => ['p', 'list'].includes(element.type)) + .every((element) => element.sourceId)); +}); + +test('repairs duplicate authored source ids uniquely and remains stable on rerun', () => { + const doc = createDocument(` +

          First

          +

          Second

          +

          Third

          +

          Fourth

          + `); + + sanitizeSlideDocumentRoot(doc); + const firstIds = [...doc.body.querySelectorAll('p')].map((element) => element.dataset.pptxSourceId); + sanitizeSlideDocumentRoot(doc); + const secondIds = [...doc.body.querySelectorAll('p')].map((element) => element.dataset.pptxSourceId); + + assert.equal(firstIds[0], 'duplicate'); + assert.equal(new Set(firstIds).size, firstIds.length); + assert.deepEqual(secondIds, firstIds); +}); + +test('classifies unsupported visual capabilities as fallback diagnostics', () => { + const doc = createDocument(` +
          Gradient
          +
          Filtered
          + +
          Pseudo
          + `, '.with-pseudo::before { content: "prefix"; }'); + + const { diagnostics } = sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + const extracted = extractSlideDataFromDocument(doc); + + for (const code of ['css_gradient', 'css_filter', 'complex_svg_raster', 'generated_content']) { + const diagnostic = diagnostics.find((item) => item.code === code); + assert.equal(diagnostic?.severity, 'fallback', code); + assert.ok(diagnostic.sourceId, code); + assert.ok(diagnostic.tag, code); + } + assert.ok(!diagnostics.some((item) => item.severity === 'blocking')); + for (const code of ['css_filter', 'complex_svg_raster']) { + assert.equal( + extracted.diagnostics.find((item) => item.code === code)?.severity, + 'fallback', + code, + ); + } +}); + +test('comprehensive DOM fixture preserves editable text and every native or fallback visual', async () => { + const doc = createDocument(` +
          +
          +

          • Manual one

          +

          • Manual two

          +

          Plain bold italic

          +
          +

          Merged first

          Merged second

          +
          + + + +
          Header text
          Cell text
          + Photo +
          +
          + + + + Basic SVG text + + + + + Complex SVG label + +
          +

          Gradient label

          +
          +
          +

          Filtered label

          +
          +

          Pseudo label

          +
          +

          Foreground copy

          + `, '.fixture-pseudo::before { content: "Generated star"; color: red; }'); + const beforeText = doc.body.textContent.replace(/\s+/g, ' ').trim(); + + const repair = sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + const extracted = extractSlideDataFromDocument(doc); + const allDiagnostics = [...repair.diagnostics, ...extracted.diagnostics]; + const localRequests = buildRasterFallbackRequests(doc, allDiagnostics); + const rendered = await renderRasterFallbackLayers( + localRequests, + async (_html, _slideIndex, metadata) => Buffer.from(`png:${metadata.sourceId}`).toString('base64'), + 0, + ); + const preparedModel = { + ...extracted, + fallbackLayers: [...(extracted.fallbackLayers || []), ...rendered.layers], + diagnostics: allDiagnostics, + }; + + const repairedDomText = doc.body.textContent.replace(/\s+/g, ' ').trim(); + for (const phrase of ['Manual one', 'Manual two', 'Plain bold italic', 'Merged first', 'Merged second']) { + assert.ok(beforeText.includes(phrase) && repairedDomText.includes(phrase), phrase); + } + const editableText = preparedModel.elements.flatMap((element) => { + if (typeof element.text === 'string') return [element.text]; + const runs = element.items || element.text || []; + return Array.isArray(runs) ? [runs.map((run) => run.text).join('')] : []; + }).join(' | '); + for (const text of [ + 'Manual one', 'Manual two', 'Plain bold italic', 'Merged first', 'Merged second', + 'Header text', 'Cell text', 'Basic SVG text', 'Complex SVG label', + 'Gradient label', 'Filtered label', 'Pseudo label', 'Foreground copy', + ]) { + assert.match(editableText, new RegExp(text), text); + } + + const diagnosticCodes = new Set(preparedModel.diagnostics.map((item) => item.code)); + for (const code of ['manual_bullet_list', 'css_gradient', 'css_filter', 'complex_svg_raster', 'generated_content']) { + assert.ok(diagnosticCodes.has(code), code); + } + assert.ok(preparedModel.diagnostics.some((item) => item.severity === 'repaired')); + assert.ok(preparedModel.diagnostics.some((item) => item.severity === 'fallback')); + assert.ok(!preparedModel.diagnostics.some((item) => item.severity === 'blocking')); + + const nativeBySource = new Map(preparedModel.elements.map((item) => [item.sourceId, item])); + assert.equal(nativeBySource.get('photo')?.type, 'image'); + assert.equal(nativeBySource.get('css-shape')?.type, 'shape'); + assert.equal(nativeBySource.get('css-triangle')?.svgType, 'triangle'); + assert.equal(nativeBySource.get('svg-rect')?.type, 'svg-shape'); + assert.equal(nativeBySource.get('svg-line')?.type, 'line'); + const fallbackSources = new Set(preparedModel.fallbackLayers.map((item) => item.sourceId)); + for (const sourceId of ['complex-svg', 'gradient', 'filtered', 'pseudo']) { + assert.ok(fallbackSources.has(sourceId), sourceId); + } + assert.equal(preparedModel.background.value, '0a141e'); + const background = nativeBySource.get('css-shape'); + const foreground = nativeBySource.get('foreground-copy'); + assert.ok(background.paintOrder < foreground.paintOrder); + assert.ok(background.zIndex < foreground.zIndex); +}); + +test('returns blocking diagnostics for an unmeasurable slide canvas', () => { + const doc = createDocument('

          Unreadable geometry

          '); + doc.body.getBoundingClientRect = () => ({ + left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0, + }); + + const slideData = extractSlideDataFromDocument(doc); + const diagnostic = slideData.diagnostics.find((item) => item.code === 'unmeasurable_canvas'); + + assert.equal(diagnostic?.severity, 'blocking'); + assert.equal(diagnostic?.kind, 'blocking'); + assert.equal(diagnostic?.tag, 'body'); +}); + +test('returns a located unreadable_document blocking diagnostic', () => { + const slideData = extractSlideDataFromDocument(null); + const diagnostic = slideData.diagnostics.find((item) => item.code === 'unreadable_document'); + + assert.equal(diagnostic?.severity, 'blocking'); + assert.equal(diagnostic?.kind, 'blocking'); + assert.equal(diagnostic?.sourceId, 'slide-document'); + assert.equal(diagnostic?.tag, 'document'); + assert.deepEqual(slideData.errors, [diagnostic.message]); +}); + +test('emits a structured pptx_serialization blocking diagnostic from the production builder', async () => { + const serializationFailure = new Error('addText serialization failed'); + const targetSlide = { + addText() { + throw serializationFailure; + }, + }; + const slideData = { + background: { type: 'color', value: 'FFFFFF' }, + elements: [{ + type: 'p', + text: 'Serializable text', + position: { x: 1, y: 1, w: 4, h: 1 }, + style: { fontSize: 20, fontFace: 'Arial', color: '111111', align: 'left' }, + sourceId: 'source-text', + }], + placeholders: [], + diagnostics: [], + errors: [], + }; + + await assert.rejects( + buildSlideFromExtracted( + slideData, + { width: 1280, height: 720, errors: [] }, + { addSlide: () => targetSlide, ShapeType: {} }, + ), + (error) => { + assert.equal(error, serializationFailure); + assert.equal(error.diagnostic?.severity, 'blocking'); + assert.equal(error.diagnostic?.code, 'pptx_serialization'); + assert.match(error.diagnostic?.message || '', /addText serialization failed/); + assert.ok(error.diagnostics.includes(error.diagnostic)); + return true; + }, + ); +}); + +test('keeps editable HTML objects and emits native basic SVG primitives with source paint metadata', () => { + const doc = createDocument(` +
          +

          Editable title

          + +
          + + + + + SVG label + + `); + sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + + const extracted = extractSlideDataFromDocument(doc); + const svgElements = extracted.elements.filter((element) => ( + element.type === 'svg-shape' || element.type === 'svg-text' || element.type === 'line' + )); + + assert.ok(extracted.elements.some((element) => element.type === 'p' && element.text === 'Editable title'), + 'editable HTML text must remain when SVG exists'); + assert.ok(extracted.elements.some((element) => element.type === 'image'), + 'editable HTML image must remain when SVG exists'); + assert.ok(extracted.elements.some((element) => element.type === 'shape')); + assert.equal(svgElements.length, 4); + assert.deepEqual(svgElements.map((element) => element.kind), ['native', 'native', 'native', 'native']); + assert.ok(svgElements.every((element) => element.sourceId && Number.isFinite(element.zIndex))); + assert.equal(svgElements.find((element) => element.text === 'SVG label')?.type, 'svg-text'); +}); + +test('serializes fallback layers in paint order without removing editable objects', async () => { + const calls = []; + const slide = { + addText(value, options) { calls.push({ op: 'text', value, options }); }, + addImage(options) { calls.push({ op: 'image', options }); }, + addShape(type, options) { calls.push({ op: 'shape', type, options }); }, + }; + await buildSlideFromExtracted({ + background: { type: 'color', value: 'FFFFFF' }, + elements: [ + { + type: 'p', + text: 'Editable', + sourceId: 'text', + zIndex: 20, + kind: 'native', + position: { x: 1, y: 1, w: 4, h: 1 }, + style: { fontSize: 20, fontFace: 'Arial', color: '111111', align: 'left' }, + }, + ], + fallbackLayers: [{ + sourceId: 'complex-visual', + kind: 'raster', + zIndex: 10, + bbox: { x: 0, y: 0, w: 2, h: 2 }, + data: 'data:image/png;base64,AA==', + diagnostics: [{ severity: 'fallback', code: 'css_gradient', message: 'gradient' }], + }], + placeholders: [], + diagnostics: [], + errors: [], + }, { width: 1280, height: 720, errors: [] }, { + addSlide: () => slide, + ShapeType: { line: 'line', rect: 'rect', roundRect: 'roundRect' }, + }); + + assert.deepEqual(calls.map((call) => call.op), ['image', 'text']); + assert.equal(calls[0].options.x, 0); + assert.equal(calls[1].value, 'Editable'); +}); + +test('maps SVG polyline and recognized polygons to editable geometry with local fill fidelity', () => { + const doc = createDocument(` +

          Editable stays

          + + + + + + + `); + sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + + const slideData = extractSlideDataFromDocument(doc); + const route = slideData.elements.filter((element) => element.sourceId === 'route'); + const triangle = slideData.elements.find((element) => element.sourceId === 'triangle'); + const diamond = slideData.elements.find((element) => element.sourceId === 'diamond'); + const freeform = slideData.elements.filter((element) => element.sourceId === 'freeform'); + const fidelity = slideData.fallbackLayers?.find((layer) => layer.sourceId === 'freeform'); + + assert.equal(route.length, 2); + assert.ok(route.every((element) => element.type === 'line' && element.kind === 'native')); + assert.equal(triangle?.svgType, 'triangle'); + assert.equal(triangle?.kind, 'native'); + assert.equal(diamond?.svgType, 'diamond'); + assert.equal(freeform.length, 5); + assert.ok(freeform.every((element) => element.type === 'line' && element.kind === 'native')); + assert.equal(fidelity?.kind, 'svg-image'); + assert.equal(fidelity?.zIndex, 7); + assert.match(fidelity?.data || '', /^data:image\/svg\+xml/); + assert.ok(slideData.elements.some((element) => element.text === 'Editable stays')); +}); + +test('applies viewBox plus translate scale and rotate transforms to SVG coordinates', () => { + const doc = createDocument(` + + + + + + `); + sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + const svg = doc.querySelector('svg'); + svg.getBoundingClientRect = () => ({ + x: 100, y: 50, left: 100, top: 50, right: 300, bottom: 150, width: 200, height: 100, + }); + + const slideData = extractSlideDataFromDocument(doc); + const translated = slideData.elements.find((element) => element.sourceId === 'translated'); + const scaled = slideData.elements.find((element) => element.sourceId === 'scaled'); + const rotated = slideData.elements.find((element) => element.sourceId === 'rotated'); + + assert.deepEqual( + [translated.x1, translated.y1, translated.x2, translated.y2].map((value) => Number(value.toFixed(4))), + [1.1458, 0.7292, 1.3542, 0.7292], + ); + assert.deepEqual( + [scaled.x1, scaled.y1, scaled.x2, scaled.y2].map((value) => Number(value.toFixed(4))), + [1.25, 0.9375, 1.6667, 0.9375], + ); + assert.deepEqual( + [rotated.x1, rotated.y1, rotated.x2, rotated.y2].map((value) => Number(value.toFixed(4))), + [1.0417, 0.5208, 1.0417, 0.7292], + ); +}); + +test('serializes path-only complex SVG as a local movable vector layer without duplicating SVG text', () => { + const doc = createDocument(` +

          HTML text remains editable

          + + `); + sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + + const slideData = extractSlideDataFromDocument(doc); + const layer = slideData.fallbackLayers?.find((item) => item.sourceId === 'curve'); + const decoded = decodeURIComponent(String(layer?.data || '').split(',').slice(1).join(',')); + + assert.equal(layer?.kind, 'svg-image'); + assert.equal(layer?.zIndex, 4); + assert.match(decoded, / element.type === 'svg-text' && element.text === 'Editable SVG text')); + assert.ok(slideData.elements.some((element) => element.text === 'HTML text remains editable')); +}); + +test('maps a common CSS border triangle to a native editable triangle', () => { + const doc = createDocument(` +
          + `); + sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + + const triangle = extractSlideDataFromDocument(doc).elements + .find((element) => element.sourceId === 'arrow' && element.svgType === 'triangle'); + + assert.equal(triangle?.kind, 'native'); + assert.equal(triangle?.zIndex, 9); + assert.equal(triangle?.shape.fill, 'ff0000'); +}); + +test('fake PPTX receives native shapes text lines and local SVG images while preserving metadata', async () => { + const calls = []; + const slide = { + addText(value, options) { calls.push({ op: 'text', value, options }); }, + addImage(options) { calls.push({ op: 'image', options }); }, + addShape(type, options) { calls.push({ op: 'shape', type, options }); }, + }; + const elements = [ + { + type: 'svg-shape', svgType: 'triangle', kind: 'native', sourceId: 'triangle', zIndex: 1, paintOrder: 1, + text: '', position: { x: 1, y: 1, w: 1, h: 1 }, + shape: { fill: 'FF0000', line: null, rectRadius: 0 }, + }, + { + type: 'line', kind: 'native', sourceId: 'route', zIndex: 3, paintOrder: 3, + x1: 1, y1: 1, x2: 2, y2: 2, color: '000000', width: 1, + }, + { + type: 'svg-text', kind: 'native', sourceId: 'label', zIndex: 4, paintOrder: 4, + text: 'Vector text', position: { x: 1, y: 1, w: 2, h: 1 }, + style: { fontSize: 16, fontFace: 'Arial', color: '111111', align: 'left' }, + }, + ]; + const fallbackLayers = [{ + sourceId: 'curve', zIndex: 2, paintOrder: 2, kind: 'svg-image', + bbox: { x: 0, y: 0, w: 3, h: 2 }, + data: 'data:image/svg+xml,%3Csvg%3E%3Cpath%20d%3D%22M0%200L1%201%22%2F%3E%3C%2Fsvg%3E', + diagnostics: [], + }]; + + await buildSlideFromExtracted({ + background: { type: 'color', value: 'FFFFFF' }, + elements, + fallbackLayers, + placeholders: [], + diagnostics: [], + errors: [], + }, { width: 1280, height: 720, errors: [] }, { + addSlide: () => slide, + ShapeType: { + line: 'line', rect: 'rect', roundRect: 'roundRect', ellipse: 'ellipse', + triangle: 'triangle', diamond: 'diamond', + }, + }); + + assert.deepEqual(calls.map((call) => call.op), ['shape', 'image', 'shape', 'text']); + assert.equal(calls[0].options.shape, 'triangle'); + assert.equal(calls[1].options.data.startsWith('data:image/svg+xml'), true); + assert.equal(calls[2].type, 'line'); + assert.equal(calls[3].value, 'Vector text'); + assert.deepEqual( + elements.map(({ sourceId, zIndex, kind }) => ({ sourceId, zIndex, kind })), + [ + { sourceId: 'triangle', zIndex: 1, kind: 'native' }, + { sourceId: 'route', zIndex: 3, kind: 'native' }, + { sourceId: 'label', zIndex: 4, kind: 'native' }, + ], + ); +}); + +test('builds one transparent text-hidden raster HTML request per unsupported source visual', () => { + const doc = createDocument(` +
          +

          Editable gradient label

          +
          +
          +

          Editable filter label

          +
          +
          Unrelated visual
          + `); + const repair = sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + const slideData = extractSlideDataFromDocument(doc); + const diagnostics = [...repair.diagnostics, ...slideData.diagnostics]; + + const requests = buildRasterFallbackRequests(doc, diagnostics); + + assert.deepEqual(requests.map((request) => request.sourceId).sort(), ['filtered', 'gradient']); + assert.ok(requests.every((request) => request.kind === 'raster' && Number.isFinite(request.zIndex))); + assert.ok(requests.every((request) => request.bbox.w > 0 && request.bbox.h > 0)); + assert.ok(requests.every((request) => request.html === undefined && typeof request.buildHtml === 'function')); + assert.ok(requests.every((request) => /background:\s*transparent\s*!important/i.test(request.buildHtml()))); + assert.ok(requests.every((request) => /pptx-raster-hide-editable-text/.test(request.buildHtml()))); + assert.ok(requests.every((request) => /data-pptx-raster-target="1"/.test(request.buildHtml()))); + assert.ok(requests.every((request) => /visibility:\s*hidden\s*!important/.test(request.buildHtml()))); + assert.ok(slideData.elements.some((element) => element.text === 'Editable gradient label')); + assert.ok(slideData.elements.some((element) => element.text === 'Editable filter label')); +}); + +test('request-build failures escalate without silently dropping unsupported visuals', async (t) => { + const fullPageRequest = { + sourceId: 'slide-1', + zIndex: 0, + paintOrder: 0, + kind: 'raster', + phase: 'full-page', + bbox: { x: 0, y: 0, w: 13.333, h: 7.5 }, + html: 'full page', + diagnostics: [], + }; + const runPlan = async (doc, diagnostics, renderRaster) => { + const localRequests = buildRasterFallbackRequests(doc, diagnostics); + return { + localRequests, + pageVisualRequest: buildPageVisualFallbackRequest(doc, localRequests), + result: await renderRasterFallbackPlan({ + localRequests, + pageVisualRequest: buildPageVisualFallbackRequest(doc, localRequests), + fullPageRequest, + }, renderRaster, 0), + }; + }; + + await t.test('missing source element records local and page build failures before full-page fallback', async () => { + const doc = createDocument(` +
          +

          Editable text survives in source HTML

          + `); + const phases = []; + const { localRequests, pageVisualRequest, result } = await runPlan(doc, [ + { severity: 'fallback', code: 'css_gradient', sourceId: 'missing-gradient' }, + { severity: 'fallback', code: 'css_gradient', sourceId: 'valid-gradient' }, + ], async (_html, _index, metadata) => { + phases.push(metadata.phase); + return metadata.phase === 'full-page' ? 'full-page-png' : 'local-png'; + }); + + assert.equal(localRequests.length, 2); + const missingRequest = localRequests.find((request) => request.sourceId === 'missing-gradient'); + assert.equal(missingRequest.buildFailure?.code, 'local_raster_target_missing'); + assert.equal(missingRequest.buildFailure?.stage, 'request-build'); + assert.match(missingRequest.buildFailure?.reason || '', /missing-gradient/); + assert.equal(pageVisualRequest.buildFailure?.code, 'page_visual_target_missing'); + assert.deepEqual(phases, ['local-visual', 'full-page']); + assert.equal(result.blocking, false); + assert.equal(result.fullPageFallback?.data, 'data:image/png;base64,full-page-png'); + assert.ok(result.diagnostics.some((item) => ( + item.code === 'local_raster_target_missing' + && item.sourceId === 'missing-gradient' + && item.stage === 'request-build' + && item.reason + ))); + assert.ok(result.diagnostics.some((item) => ( + item.code === 'page_visual_target_missing' + && item.sourceId === 'slide-visuals' + && item.stage === 'request-build' + && item.reason + ))); + assert.ok(result.diagnostics.some((item) => item.code === 'full_page_fallback')); + + const blocked = await runPlan(doc, [ + { severity: 'fallback', code: 'css_gradient', sourceId: 'missing-gradient' }, + { severity: 'fallback', code: 'css_gradient', sourceId: 'valid-gradient' }, + ], async () => { + throw new Error('full-page host failed'); + }); + assert.equal(blocked.result.blocking, true); + assert.equal(blocked.result.fullPageFallback, null); + assert.ok(blocked.result.diagnostics.some((item) => ( + item.code === 'full_page_raster_failed' + && item.severity === 'blocking' + && item.stage === 'render' + && /full-page host failed/.test(item.reason) + ))); + }); + + await t.test('zero-size source skips local renderer but invokes page-visual renderer with source coverage', async () => { + const doc = createDocument(` +
          +

          Editable zero-size label

          +
          + `); + doc.querySelector('[data-pptx-source-id="zero-gradient"]').getBoundingClientRect = () => ({ + x: 40, y: 40, left: 40, top: 40, right: 40, bottom: 40, width: 0, height: 0, + }); + const phases = []; + const { localRequests, result } = await runPlan(doc, [ + { severity: 'fallback', code: 'css_gradient', sourceId: 'zero-gradient' }, + ], async (_html, _index, metadata) => { + phases.push(metadata.phase); + return 'page-visual-png'; + }); + + assert.equal(localRequests[0].buildFailure?.code, 'local_raster_unmeasurable'); + assert.deepEqual(phases, ['page-visual']); + assert.equal(result.fullPageFallback, null); + assert.equal(result.layers[0].data, 'data:image/png;base64,page-visual-png'); + assert.deepEqual(result.layers[0].sourceIds, ['zero-gradient']); + assert.ok(result.diagnostics.some((item) => ( + item.code === 'local_raster_unmeasurable' + && item.sourceId === 'zero-gradient' + && item.stage === 'request-build' + ))); + assert.ok(result.diagnostics.some((item) => item.code === 'page_visual_fallback')); + }); + + await t.test('serialization failure records both build stages and reaches full-page renderer', async () => { + const doc = createDocument(` +
          +

          Editable filtered label

          +
          + `); + doc.body.cloneNode = () => { + throw new Error('DOM clone failed'); + }; + const phases = []; + const { localRequests, pageVisualRequest, result } = await runPlan(doc, [ + { severity: 'fallback', code: 'css_filter', sourceId: 'broken-filter' }, + ], async (_html, _index, metadata) => { + phases.push(metadata.phase); + return 'full-page-after-clone-error'; + }); + + assert.equal(localRequests[0].buildFailure?.code, 'local_raster_serialize_failed'); + assert.equal(pageVisualRequest.buildFailure?.code, 'page_visual_serialize_failed'); + assert.deepEqual(phases, ['full-page']); + assert.equal(result.fullPageFallback?.data, 'data:image/png;base64,full-page-after-clone-error'); + for (const code of ['local_raster_serialize_failed', 'page_visual_serialize_failed']) { + assert.ok(result.diagnostics.some((item) => ( + item.code === code + && item.stage === 'request-build' + && /DOM clone failed/.test(item.reason) + )), code); + } + }); +}); + +test('renders local PNG fallback requests independently and preserves layer metadata', async () => { + const calls = []; + const requests = [ + { + sourceId: 'gradient', zIndex: 2, paintOrder: 3, kind: 'raster', + bbox: { x: 1, y: 1, w: 2, h: 1 }, html: 'gradient', diagnostics: [], + }, + { + sourceId: 'filter', zIndex: 5, paintOrder: 8, kind: 'raster', + bbox: { x: 4, y: 2, w: 3, h: 2 }, html: 'filter', diagnostics: [], + }, + ]; + + const result = await renderRasterFallbackLayers( + requests, + async (html, slideIndex, metadata) => { + calls.push({ html, slideIndex, metadata }); + return `png-${metadata.sourceId}`; + }, + 6, + ); + + assert.equal(result.failures.length, 0); + assert.deepEqual(result.layers.map((layer) => layer.sourceId), ['gradient', 'filter']); + assert.deepEqual(result.layers.map((layer) => layer.data), [ + 'data:image/png;base64,png-gradient', + 'data:image/png;base64,png-filter', + ]); + assert.deepEqual(result.layers.map(({ bbox, zIndex, paintOrder, kind }) => ({ + bbox, zIndex, paintOrder, kind, + })), requests.map(({ bbox, zIndex, paintOrder, kind }) => ({ + bbox, zIndex, paintOrder, kind, + }))); + assert.deepEqual(calls.map((call) => call.metadata.sourceId), ['gradient', 'filter']); + assert.ok(calls.every((call) => call.slideIndex === 6)); +}); + +test('escalates local raster failure to page visuals and then full-page fallback with located diagnostics', async () => { + const calls = []; + const localRequests = [{ + sourceId: 'gradient-card', zIndex: 3, paintOrder: 4, kind: 'raster', phase: 'local-visual', + bbox: { x: 1, y: 1, w: 2, h: 2 }, html: 'local', diagnostics: [], + }]; + const pageVisualRequest = { + sourceId: 'slide-visuals', zIndex: 3, paintOrder: 4, kind: 'raster', phase: 'page-visual', + bbox: { x: 0, y: 0, w: 13.333, h: 7.5 }, html: 'visuals', diagnostics: [], + }; + const fullPageRequest = { + sourceId: 'slide-7', zIndex: 0, paintOrder: 0, kind: 'raster', phase: 'full-page', + bbox: { x: 0, y: 0, w: 13.333, h: 7.5 }, html: 'full', diagnostics: [], + }; + + const result = await renderRasterFallbackPlan({ + localRequests, + pageVisualRequest, + fullPageRequest, + }, async (_html, _index, metadata) => { + calls.push(metadata); + if (metadata.phase !== 'full-page') throw new Error(`${metadata.phase} failed`); + return 'full-page-png'; + }, 6); + + assert.deepEqual(calls.map((call) => call.phase), ['local-visual', 'page-visual', 'full-page']); + assert.equal(result.layers.length, 0); + assert.equal(result.fullPageFallback?.data, 'data:image/png;base64,full-page-png'); + assert.equal(result.fullPageFallback?.sourceId, 'slide-7'); + assert.equal(result.blocking, false); + assert.ok(result.diagnostics.some((diagnostic) => ( + diagnostic.code === 'full_page_fallback' + && diagnostic.slideNumber === 7 + && diagnostic.sourceId === 'slide-7' + && diagnostic.phase === 'full-page' + ))); + assert.ok(result.diagnostics.some((diagnostic) => ( + diagnostic.code === 'local_raster_failed' + && diagnostic.sourceId === 'gradient-card' + && /local-visual failed/.test(diagnostic.reason) + ))); +}); + +test('uses one page-visual layer after a local failure and does not render full page', async () => { + const phases = []; + const result = await renderRasterFallbackPlan({ + localRequests: [{ + sourceId: 'pseudo', zIndex: 2, paintOrder: 5, kind: 'raster', phase: 'local-visual', + bbox: { x: 1, y: 1, w: 1, h: 1 }, html: 'local', diagnostics: [], + }], + pageVisualRequest: { + sourceId: 'slide-visuals', zIndex: 2, paintOrder: 5, kind: 'raster', phase: 'page-visual', + bbox: { x: 0, y: 0, w: 13.333, h: 7.5 }, html: 'visual', diagnostics: [], + }, + fullPageRequest: { + sourceId: 'slide-1', kind: 'raster', phase: 'full-page', + bbox: { x: 0, y: 0, w: 13.333, h: 7.5 }, html: 'full', diagnostics: [], + }, + }, async (_html, _index, metadata) => { + phases.push(metadata.phase); + if (metadata.phase === 'local-visual') throw new Error('local failed'); + return 'visual-png'; + }, 0); + + assert.deepEqual(phases, ['local-visual', 'page-visual']); + assert.equal(result.fullPageFallback, null); + assert.equal(result.layers.length, 1); + assert.equal(result.layers[0].phase, 'page-visual'); + assert.equal(result.layers[0].data, 'data:image/png;base64,visual-png'); + assert.ok(result.diagnostics.some((diagnostic) => diagnostic.code === 'page_visual_fallback')); +}); + +test('records every fallback level and keeps all source coverage when local rendering partially fails', async (t) => { + const localRequests = [ + { + sourceId: 'gradient', zIndex: 1, paintOrder: 1, kind: 'raster', phase: 'local-visual', + bbox: { x: 1, y: 1, w: 2, h: 1 }, html: 'gradient', + suppressedNativeVisualIds: ['gradient'], diagnostics: [], + }, + { + sourceId: 'filtered', zIndex: 2, paintOrder: 2, kind: 'raster', phase: 'local-visual', + bbox: { x: 4, y: 1, w: 2, h: 1 }, html: 'filtered', + suppressedNativeVisualIds: ['filtered', 'filtered-image'], diagnostics: [], + }, + ]; + const pageVisualRequest = { + sourceId: 'slide-visuals', + sourceIds: ['gradient', 'filtered'], + suppressedNativeVisualIds: ['gradient', 'filtered', 'filtered-image'], + zIndex: 1, + paintOrder: 1, + kind: 'raster', + phase: 'page-visual', + bbox: { x: 0, y: 0, w: 13.333, h: 7.5 }, + html: 'all unsupported visuals', + diagnostics: [], + }; + const fullPageRequest = { + sourceId: 'slide-4', + zIndex: 0, + paintOrder: 0, + kind: 'raster', + phase: 'full-page', + bbox: { x: 0, y: 0, w: 13.333, h: 7.5 }, + html: 'full page', + diagnostics: [], + }; + + await t.test('page visual replaces the complete unsupported source set after one local failure', async () => { + const attempts = []; + const result = await renderRasterFallbackPlan({ + localRequests, + pageVisualRequest, + fullPageRequest, + }, async (_html, _slideIndex, metadata) => { + attempts.push(`${metadata.phase}:${metadata.sourceId}`); + if (metadata.sourceId === 'filtered') throw new Error('filtered local failed'); + return Buffer.from(metadata.sourceId).toString('base64'); + }, 3); + + assert.deepEqual(attempts, [ + 'local-visual:gradient', + 'local-visual:filtered', + 'page-visual:slide-visuals', + ]); + assert.equal(result.blocking, false); + assert.equal(result.fullPageFallback, null); + assert.equal(result.layers.length, 1); + assert.deepEqual(result.layers[0].sourceIds, ['gradient', 'filtered']); + assert.deepEqual( + result.layers[0].suppressedNativeVisualIds, + ['gradient', 'filtered', 'filtered-image'], + ); + assert.ok(result.diagnostics.some((item) => ( + item.code === 'local_raster_failed' + && item.sourceId === 'filtered' + && item.slideNumber === 4 + ))); + assert.ok(result.diagnostics.some((item) => ( + item.code === 'page_visual_fallback' + && item.sourceId === 'slide-visuals' + && item.slideNumber === 4 + ))); + }); + + await t.test('all failed levels produce located blocking evidence instead of an empty success', async () => { + const result = await renderRasterFallbackPlan({ + localRequests, + pageVisualRequest, + fullPageRequest, + }, async (_html, _slideIndex, metadata) => { + throw new Error(`${metadata.phase}:${metadata.sourceId} unavailable`); + }, 3); + + assert.equal(result.blocking, true); + assert.deepEqual(result.layers, []); + assert.equal(result.fullPageFallback, null); + const byCode = new Map(result.diagnostics.map((item) => [item.code, item])); + assert.equal(byCode.get('local_raster_failed')?.sourceId, 'filtered'); + assert.equal(byCode.get('page_visual_raster_failed')?.sourceId, 'slide-visuals'); + assert.equal(byCode.get('full_page_raster_failed')?.sourceId, 'slide-4'); + assert.equal(byCode.get('full_page_raster_failed')?.severity, 'blocking'); + assert.equal(byCode.get('full_page_raster_failed')?.slideNumber, 4); + for (const diagnostic of result.diagnostics) { + assert.ok(diagnostic.reason, `${diagnostic.code} must retain its renderer failure`); + assert.ok(diagnostic.sourceId, `${diagnostic.code} must retain its source location`); + assert.ok(diagnostic.phase, `${diagnostic.code} must retain its fallback phase`); + } + }); +}); + +test('builds a transparent page-visual request containing only all unsupported targets', () => { + const doc = createDocument(` +

          One

          +

          Two

          +

          Native

          + `); + const repair = sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + const localRequests = buildRasterFallbackRequests(doc, repair.diagnostics); + + const request = buildPageVisualFallbackRequest(doc, localRequests); + + assert.equal(request.phase, 'page-visual'); + assert.equal(request.kind, 'raster'); + assert.deepEqual(request.sourceIds.sort(), ['one', 'two']); + assert.equal(request.html, undefined); + assert.equal((request.buildHtml().match(/<[^>]+data-pptx-raster-target="1"/g) || []).length, 2); + assert.match(request.buildHtml(), /background:\s*transparent\s*!important/i); + assert.match(request.buildHtml(), /pptx-raster-hide-editable-text/); +}); + +test('full-page fallback serializes as the only slide object', async () => { + const calls = []; + const slide = { + addText(value, options) { calls.push({ op: 'text', value, options }); }, + addImage(options) { calls.push({ op: 'image', options }); }, + addShape(type, options) { calls.push({ op: 'shape', type, options }); }, + }; + + await buildSlideFromExtracted({ + background: { type: 'color', value: 'FFFFFF' }, + elements: [{ + type: 'p', + text: 'Must not duplicate', + sourceId: 'text', + kind: 'native', + zIndex: 1, + position: { x: 1, y: 1, w: 2, h: 1 }, + style: { fontSize: 18, fontFace: 'Arial', color: '111111', align: 'left' }, + }], + fallbackLayers: [], + fullPageFallback: { + sourceId: 'slide-3', + kind: 'raster', + phase: 'full-page', + data: 'data:image/png;base64,full-page', + }, + placeholders: [], + diagnostics: [], + errors: [], + }, { width: 1280, height: 720, errors: [] }, { + addSlide: () => slide, + ShapeType: { line: 'line', rect: 'rect', roundRect: 'roundRect' }, + }); + + assert.deepEqual(calls.map((call) => call.op), ['image']); + assert.deepEqual( + (({ x, y, w, h }) => ({ x, y, w, h }))(calls[0].options), + { x: 0, y: 0, w: 13.333, h: 7.5 }, + ); +}); + +test('places an uncropped transparent local fallback canvas at full-slide geometry while retaining source bbox', async () => { + const calls = []; + const slide = { + addImage(options) { calls.push(options); }, + addText() {}, + addShape() {}, + }; + const layer = { + sourceId: 'filtered-card', + kind: 'raster', + phase: 'local-visual', + canvas: 'full-page', + zIndex: 2, + paintOrder: 2, + bbox: { x: 4, y: 2, w: 2, h: 1 }, + data: 'data:image/png;base64,transparent-page-canvas', + }; + + await buildSlideFromExtracted({ + background: { type: 'color', value: 'FFFFFF' }, + elements: [], + fallbackLayers: [layer], + placeholders: [], + diagnostics: [], + errors: [], + }, { width: 1280, height: 720, errors: [] }, { + addSlide: () => slide, + ShapeType: {}, + }); + + assert.deepEqual( + (({ x, y, w, h }) => ({ x, y, w, h }))(calls[0]), + { x: 0, y: 0, w: 13.333, h: 7.5 }, + ); + assert.deepEqual(layer.bbox, { x: 4, y: 2, w: 2, h: 1 }); +}); + +test('summarizes repairs local SVG PNG full-page fallback and blocking diagnostics by slide and source', () => { + const summary = summarizePptxExportDiagnostics([ + { + index: 0, + slideData: { + diagnostics: [ + { severity: 'repaired', code: 'manual_bullet_list', sourceId: 'list' }, + { severity: 'fallback', code: 'page_visual_fallback', sourceId: 'slide-visuals', phase: 'page-visual' }, + ], + fallbackLayers: [ + { kind: 'svg-image', sourceId: 'curve', phase: 'local-svg' }, + { kind: 'raster', sourceId: 'gradient', phase: 'local-visual' }, + { kind: 'raster', sourceId: 'slide-visuals', phase: 'page-visual' }, + ], + }, + }, + { + index: 2, + slideData: { + diagnostics: [ + { + severity: 'fallback', code: 'full_page_fallback', sourceId: 'slide-3', + phase: 'full-page', reason: 'local and page visual failed', + }, + { + severity: 'blocking', code: 'pptx_serialization', sourceId: 'bad-shape', + reason: 'serialization failed', + }, + ], + fallbackLayers: [], + fullPageFallback: { kind: 'raster', sourceId: 'slide-3', phase: 'full-page' }, + }, + }, + ]); + + assert.deepEqual(summary.counts, { + repaired: 1, + svgImage: 1, + localPng: 1, + pageVisual: 1, + fullPage: 1, + blocking: 1, + }); + assert.ok(summary.locations.some((item) => ( + item.slideNumber === 1 && item.sourceId === 'curve' && item.phase === 'local-svg' + ))); + assert.ok(summary.locations.some((item) => ( + item.slideNumber === 3 && item.sourceId === 'slide-3' && item.phase === 'full-page' + ))); + assert.ok(summary.locations.some((item) => ( + item.slideNumber === 3 && item.sourceId === 'bad-shape' && item.severity === 'blocking' + ))); + assert.equal(summary.hasWarnings, true); + assert.equal(summary.hasBlocking, true); +}); + +test('localized export diagnostic labels cover every summarized count and location', () => { + const requiredKeys = [ + 'exportDiagnosticsSummary', + 'exportDiagnosticsRepaired', + 'exportDiagnosticsSvg', + 'exportDiagnosticsLocalPng', + 'exportDiagnosticsPageVisual', + 'exportDiagnosticsFullPage', + 'exportDiagnosticsBlocking', + 'exportDiagnosticsLocation', + ]; + for (const locale of ['en-US', 'zh-CN']) { + requiredKeys.forEach((key) => assert.ok(STRINGS[locale][key], `${locale}:${key}`)); + } +}); + +test('localizes known diagnostics and safely redacts unknown low-level reasons', () => { + assert.equal( + formatLocalizedExportDiagnostic({ code: 'canvas_overflow' }, 'zh-CN').reason, + '页面内容超出幻灯片边界,已切换视觉兜底。', + ); + assert.equal( + formatLocalizedExportDiagnostic({ code: 'canvas_overflow' }, 'en-US').reason, + 'Slide content exceeded the canvas; visual fallback was used.', + ); + const unknown = formatLocalizedExportDiagnostic({ + code: 'vendor_failure', + reason: 'Failed at /Users/alice/private/file.html\nhttps://secret.invalid ', + sourceId: '../../secret/', + }, 'en-US'); + assert.equal(unknown.reason, 'Export encountered a protected internal error.'); + assert.doesNotMatch(JSON.stringify(unknown), /Users|https?:|script|[<>/]|\.\./i); + assert.equal(unknown.sourceId, sanitizeDiagnosticSourceId('../../secret/')); + assert.ok(unknown.reason.length <= 120); +}); + +test('routes filter mask and foreignObject SVG visuals to local PNG without dropping editable text', () => { + const doc = createDocument(` + + + + +
          Foreign visual
          + Editable label +
          + + + + `); + const repair = sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + const slideData = extractSlideDataFromDocument(doc); + const diagnostics = [...repair.diagnostics, ...slideData.diagnostics]; + const request = buildRasterFallbackRequests(doc, diagnostics) + .find((item) => item.sourceId === 'unsafe-svg'); + const unsafeReferenceRequest = buildRasterFallbackRequests(doc, diagnostics) + .find((item) => item.sourceId === 'unsafe-reference'); + + assert.ok(diagnostics.some((item) => item.code === 'complex_svg_raster')); + assert.equal(request?.captureStrategy, 'visual-subtree'); + assert.ok(request?.suppressedNativeVisualIds.includes('unsafe-svg')); + assert.ok(request?.suppressedNativeVisualIds.includes('filtered-path')); + assert.equal(unsafeReferenceRequest?.captureStrategy, 'visual-subtree'); + assert.ok(slideData.elements.some((element) => ( + element.type === 'svg-text' && element.text === 'Editable label' + ))); +}); + +test('assigns decoration subtree and pseudo capture strategies with exact native suppression scopes', () => { + const doc = createDocument(` +
          + +

          Gradient text

          +
          +
          + +

          Filtered text

          +
          +

          Pseudo owner

          + `); + sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + const requests = buildRasterFallbackRequests(doc, [ + { severity: 'fallback', code: 'css_gradient', sourceId: 'gradient' }, + { severity: 'fallback', code: 'css_filter', sourceId: 'filtered' }, + { severity: 'fallback', code: 'generated_content', sourceId: 'pseudo' }, + ]); + const bySource = new Map(requests.map((request) => [request.sourceId, request])); + + assert.equal(bySource.get('gradient').captureStrategy, 'self-decoration'); + assert.deepEqual(bySource.get('gradient').suppressedNativeVisualIds, ['gradient']); + assert.equal(bySource.get('gradient').html, undefined); + assert.match(bySource.get('gradient').buildHtml(), /data-pptx-capture-strategy="self-decoration"/); + assert.match(bySource.get('gradient').buildHtml(), /self-decoration[^}]*>\s*\*/s); + + assert.equal(bySource.get('filtered').captureStrategy, 'visual-subtree'); + assert.ok(bySource.get('filtered').suppressedNativeVisualIds.includes('filtered-child')); + assert.ok(bySource.get('filtered').suppressedNativeVisualIds.includes('filtered')); + assert.match(bySource.get('filtered').buildHtml(), /data-pptx-capture-strategy="visual-subtree"/); + + assert.equal(bySource.get('pseudo').captureStrategy, 'pseudo-only'); + assert.deepEqual(bySource.get('pseudo').suppressedNativeVisualIds, []); + assert.match(bySource.get('pseudo').buildHtml(), /data-pptx-capture-strategy="pseudo-only"/); + assert.match(bySource.get('pseudo').buildHtml(), /background:\s*none\s*!important/); +}); + +test('suppresses duplicated native visuals for raster captures while retaining editable text and unrelated children', async () => { + const calls = []; + const slide = { + addText(value) { calls.push({ op: 'text', value }); }, + addImage(options) { calls.push({ op: 'image', data: options.data, path: options.path }); }, + addShape(type) { calls.push({ op: 'shape', type }); }, + }; + await buildSlideFromExtracted({ + background: { type: 'color', value: 'FFFFFF' }, + elements: [ + { + type: 'shape', sourceId: 'gradient', kind: 'native', zIndex: 1, paintOrder: 1, + text: '', position: { x: 1, y: 1, w: 3, h: 2 }, + shape: { fill: 'FF0000', line: null, rectRadius: 0 }, + }, + { + type: 'image', sourceId: 'gradient-child', kind: 'native', zIndex: 1, paintOrder: 2, + src: 'data:image/png;base64,native-child', position: { x: 1, y: 1, w: 1, h: 1 }, + }, + { + type: 'image', sourceId: 'filtered-child', kind: 'native', zIndex: 2, paintOrder: 4, + src: 'data:image/png;base64,duplicate-filtered-child', position: { x: 4, y: 1, w: 1, h: 1 }, + }, + { + type: 'p', sourceId: 'filtered-text', kind: 'native', zIndex: 2, paintOrder: 5, + text: 'Editable filtered text', position: { x: 4, y: 1, w: 2, h: 1 }, + style: { fontSize: 16, fontFace: 'Arial', color: '111111', align: 'left' }, + }, + ], + fallbackLayers: [ + { + sourceId: 'gradient', kind: 'raster', phase: 'local-visual', zIndex: 1, paintOrder: 0, + captureStrategy: 'self-decoration', suppressedNativeVisualIds: ['gradient'], + canvas: 'full-page', bbox: { x: 1, y: 1, w: 3, h: 2 }, + data: 'data:image/png;base64,gradient-layer', + }, + { + sourceId: 'filtered', kind: 'raster', phase: 'local-visual', zIndex: 2, paintOrder: 3, + captureStrategy: 'visual-subtree', + suppressedNativeVisualIds: ['filtered', 'filtered-child', 'filtered-text'], + canvas: 'full-page', bbox: { x: 4, y: 1, w: 3, h: 2 }, + data: 'data:image/png;base64,filter-layer', + }, + ], + placeholders: [], + diagnostics: [], + errors: [], + }, { width: 1280, height: 720, errors: [] }, { + addSlide: () => slide, + ShapeType: { rect: 'rect', roundRect: 'roundRect', line: 'line' }, + }); + + assert.deepEqual(calls.map((call) => call.op), ['image', 'image', 'image', 'text']); + assert.ok(calls.some((call) => call.data?.includes('gradient-layer'))); + assert.ok(calls.some((call) => call.data?.includes('native-child'))); + assert.ok(calls.some((call) => call.data?.includes('filter-layer'))); + assert.ok(!calls.some((call) => call.data?.includes('duplicate-filtered-child'))); + assert.equal(calls.filter((call) => call.value === 'Editable filtered text').length, 1); +}); + +test('preserves actual SVG DOM paint order between paths and native primitives', () => { + const extractOrder = (markup) => { + const doc = createDocument(markup); + sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + const slideData = extractSlideDataFromDocument(doc); + return [...slideData.elements, ...(slideData.fallbackLayers || [])] + .filter((item) => ['ordered-path', 'ordered-rect'].includes(item.sourceId)) + .sort((left, right) => left.paintOrder - right.paintOrder) + .map((item) => item.sourceId); + }; + + assert.deepEqual(extractOrder(` + + + + + `), ['ordered-path', 'ordered-rect']); + assert.deepEqual(extractOrder(` + + + + + `), ['ordered-rect', 'ordered-path']); +}); + +test('uses attribute and computed CSS SVG transforms and falls back when transform cannot be represented', () => { + const doc = createDocument(` + + + + + + + `); + sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + doc.querySelector('[data-pptx-source-id="ctm-transform"]').getCTM = () => ({ + a: 1, b: 0, c: 0, d: 1, e: 30, f: 10, + }); + const slideData = extractSlideDataFromDocument(doc); + const attr = slideData.elements.find((item) => item.sourceId === 'attr-transform'); + const css = slideData.elements.find((item) => item.sourceId === 'css-transform'); + const unsafeNative = slideData.elements.find((item) => item.sourceId === 'unsafe-transform'); + const unsafeFallback = slideData.fallbackLayers?.find((item) => item.sourceId === 'unsafe-transform'); + const ctm = slideData.elements.find((item) => item.sourceId === 'ctm-transform'); + + assert.equal(attr?.kind, 'native'); + assert.ok(attr.bbox.w > 0 && attr.bbox.h > 0); + assert.equal(css?.kind, 'native'); + assert.equal(Number(css?.shape?.rotate?.toFixed(1)), 30); + assert.ok(css.bbox.w > css.position.w); + assert.equal(unsafeNative, undefined); + assert.equal(unsafeFallback?.kind, 'svg-image'); + const svgRect = doc.querySelector('svg').getBoundingClientRect(); + assert.equal(Number(ctm?.bbox?.x.toFixed(4)), Number(((svgRect.left + 40) / 96).toFixed(4))); + assert.equal(Number(ctm?.bbox?.y.toFixed(4)), Number(((svgRect.top + 20) / 96).toFixed(4))); +}); + +test('attaches bbox sourceId zIndex and native kind metadata to every native object', () => { + const doc = createDocument(` +
          +

          Editable copy

          + +
          + + `); + sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + const native = extractSlideDataFromDocument(doc).elements; + + assert.ok(native.length >= 3); + native.forEach((element) => { + assert.equal(element.kind, 'native'); + assert.ok(element.sourceId); + assert.ok(Number.isFinite(element.zIndex)); + assert.ok(element.bbox); + assert.ok(Number.isFinite(element.bbox.x)); + assert.ok(Number.isFinite(element.bbox.y)); + assert.ok(Number.isFinite(element.bbox.w)); + assert.ok(Number.isFinite(element.bbox.h)); + }); +}); + +test('does not apply viewBox scaling twice to getCTM polygon coordinates', () => { + const doc = createDocument(` + + + + + `); + sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + for (const id of ['ctm-triangle', 'ctm-diamond']) { + doc.querySelector(`[data-pptx-source-id="${id}"]`).getCTM = () => ({ + a: 2, b: 0, c: 0, d: 3, e: 30, f: 15, + }); + } + const svgRect = doc.querySelector('svg').getBoundingClientRect(); + const slideData = extractSlideDataFromDocument(doc); + const triangle = slideData.elements.find((item) => item.sourceId === 'ctm-triangle'); + const diamond = slideData.elements.find((item) => item.sourceId === 'ctm-diamond'); + + assert.equal(Number(triangle.position.x.toFixed(4)), Number(((svgRect.left + 30) / 96).toFixed(4))); + assert.equal(Number(triangle.position.w.toFixed(4)), Number((40 / 96).toFixed(4))); + assert.equal(Number(diamond.position.y.toFixed(4)), Number(((svgRect.top + 15) / 96).toFixed(4))); + assert.equal(Number(diamond.position.h.toFixed(4)), Number((60 / 96).toFixed(4))); +}); + +test('shares one full-DOM paint order domain across HTML native and raster fallback siblings', () => { + const wrappers = Array.from({ length: 30 }, (_, index) => ( + `
          ` + )).join(''); + const doc = createDocument(` +
          + ${wrappers} +
          +
          + `); + const repair = sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + const slideData = extractSlideDataFromDocument(doc); + const raster = buildRasterFallbackRequests(doc, repair.diagnostics) + .find((item) => item.sourceId === 'gradient-middle'); + const before = slideData.elements.find((item) => item.sourceId === 'native-before'); + const after = slideData.elements.find((item) => item.sourceId === 'native-after'); + + assert.ok(before.paintOrder < raster.paintOrder); + assert.ok(raster.paintOrder < after.paintOrder); + assert.equal(before.subOrder, 0); + assert.equal(raster.subOrder, 0); + assert.equal(after.subOrder, 0); +}); + +test('orders decomposed objects by shared paintOrder and explicit subOrder in Stage 2', async () => { + const calls = []; + const slide = { + addText() {}, + addImage(options) { calls.push(options.data); }, + addShape(_type, options) { calls.push(options.line?.color); }, + }; + await buildSlideFromExtracted({ + background: { type: 'color', value: 'FFFFFF' }, + elements: [ + { + type: 'line', sourceId: 'poly', kind: 'native', zIndex: 0, paintOrder: 8, subOrder: 2, + x1: 0, y1: 0, x2: 1, y2: 1, color: '222222', width: 1, + }, + { + type: 'line', sourceId: 'poly', kind: 'native', zIndex: 0, paintOrder: 8, subOrder: 1, + x1: 0, y1: 0, x2: 1, y2: 1, color: '111111', width: 1, + }, + ], + fallbackLayers: [{ + sourceId: 'middle', kind: 'svg-image', zIndex: 0, paintOrder: 8, subOrder: 1.5, + bbox: { x: 0, y: 0, w: 1, h: 1 }, data: 'data:image/svg+xml,mid', + }], + placeholders: [], + diagnostics: [], + errors: [], + }, { width: 1280, height: 720, errors: [] }, { + addSlide: () => slide, + ShapeType: { line: 'line', rect: 'rect', roundRect: 'roundRect' }, + }); + + assert.deepEqual(calls, ['111111', 'data:image/svg+xml,mid', '222222']); +}); + +test('local SVG image preserves class and inherited styles plus ancestor transforms', () => { + const doc = createDocument(` + + + + + + + `, '.accent { fill: inherit; stroke-width: 5; }'); + sanitizeSlideDocumentRoot(doc); + installMeasurableLayout(doc); + const slideData = extractSlideDataFromDocument(doc); + const layer = slideData.fallbackLayers.find((item) => item.sourceId === 'styled-path'); + const markup = decodeURIComponent(layer.data.replace('data:image/svg+xml,', '')); + + assert.match(markup, /viewBox="0 0 300 150"/); + assert.match(markup, /transform="translate\(40 20\)"/); + assert.match(markup, /fill:\s*rgb\(10,\s*20,\s*30\)/); + assert.match(markup, /stroke:\s*rgb\(40,\s*50,\s*60\)/); + assert.match(markup, /stroke-width:\s*5(?:px)?/); + assert.match(markup, /opacity:\s*0\.6/); + assert.equal(layer.bbox.w, 640 / 96); + assert.equal(layer.bbox.h, 30 / 96); +}); diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test/generated-file-protocol.test.mjs b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test/generated-file-protocol.test.mjs new file mode 100644 index 0000000000..ffff744bfd --- /dev/null +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test/generated-file-protocol.test.mjs @@ -0,0 +1,706 @@ +import assert from 'node:assert/strict'; +import { readFile } from 'node:fs/promises'; +import test from 'node:test'; + +import { + PPT_DESIGN_SKILL_KEY, + buildAgentPrompt, +} from '../src/agent-prompt.js'; +import { + DeckProjectContractError, + createDeckProjectSkeleton, + persistDeckProjectSeed, + readDeckProjectContract, + readProjectPlanWithRetry, +} from '../src/deck-project-contract.js'; +import * as deckProjectContract from '../src/deck-project-contract.js'; +import { + buildElementSlideHtml as buildPureElementSlideHtml, + elementModelElementHtml, +} from '../src/element-model-html.js'; + +const validPlan = { + status: 'complete', + title: '可靠生成协议', + language: 'zh-CN', + outline: [ + { id: 'intro', title: '协议先于页面', bullets: [], slide_id: 'slide-01' }, + { id: 'finish', title: '完成必须可验证', bullets: [], slide_id: 'slide-02' }, + ], + slide_order: ['slide-01', 'slide-02'], + style: {}, + assumptions: [], +}; + +const completeSlide = (title) => `

          ${title}

          `; + +test('shared pure element-model serializer module is available', async () => { + const serializer = await import('../src/element-model-html.js').catch(() => null); + + assert.ok(serializer, 'element-model serializer module should exist'); + assert.equal(typeof serializer.buildElementSlideHtml, 'function'); + assert.equal(typeof serializer.elementModelElementHtml, 'function'); +}); + +test('element-model serializer preserves six element types, semantics, geometry, and theme', async () => { + const baseStyle = { + fontSize: 24, + fontWeight: 600, + color: 'ink', + background: 'panel', + opacity: 0.9, + borderRadius: 8, + align: 'left', + }; + const slide = { + title: 'Element deck', + theme: { + background: '#fefefe', + ink: '#101010', + muted: '#606060', + primary: '#0055aa', + accent: '#ee5500', + panel: '#ffffff', + }, + elements: [ + { id: 'text-1', type: 'text', x: 1, y: 2, w: 30, h: 10, text: '正文不可丢', style: { ...baseStyle, fontSize: 30 } }, + { id: 'list-1', type: 'list', x: 3, y: 14, w: 35, h: 25, items: ['第一项', '第二项'], style: baseStyle }, + { id: 'metric-1', type: 'metric', x: 40, y: 5, w: 20, h: 18, text: '42%', label: '转化率', style: { ...baseStyle, color: 'primary' } }, + { + id: 'chart-1', + type: 'chart', + x: 42, + y: 28, + w: 40, + h: 35, + text: '季度趋势', + data: [{ label: 'Q1', value: 10 }, { label: 'Q2', value: 24 }], + style: baseStyle, + }, + { + id: 'media-1', + type: 'media', + x: 5, + y: 52, + w: 28, + h: 38, + text: '产品截图', + src: 'https://example.com/product.png', + style: baseStyle, + }, + { id: 'shape-1', type: 'shape', x: 70, y: 68, w: 20, h: 20, text: '形状标签', style: { ...baseStyle, background: 'accent' } }, + ], + }; + + const html = buildPureElementSlideHtml(slide); + + assert.match(html, /width:\s*1280px/); + assert.match(html, /height:\s*720px/); + assert.match(html, /background:\s*#fefefe/); + assert.match(html, /data-element-type="text"[^>]*style="[^"]*left:1%;top:2%;width:30%;height:10%/); + assert.match(html, /font-size:30px/); + assert.match(html, /color:#101010/); + assert.match(html, /]*>正文不可丢<\/p>/); + assert.match(html, /
        1. 第一项<\/p><\/li>/); + assert.match(html, /

        2. 第二项<\/p><\/li>/); + assert.match(html, /]*>42%<\/p>/); + assert.match(html, /]*>转化率<\/p>/); + assert.match(html, /季度趋势/); + assert.match(html, /Q1/); + assert.match(html, />1024]*src="https:\/\/example\.com\/product\.png"/); + assert.match(html, /产品截图/); + assert.match(html, /data-element-type="shape"/); + assert.match(html, /background:#ee5500/); + assert.match(html, /形状标签/); + + const seed = deckProjectContract.createDeckProjectSeed({ + hasExistingDeck: true, + title: 'Element deck', + slides: [{ ...slide, html: '' }], + serializeElementSlide: buildPureElementSlideHtml, + }); + const files = new Map([ + ['project.json', JSON.stringify(seed.plan)], + ...seed.slideFiles.map((file) => [file.relPath, file.html]), + ]); + const deck = await readDeckProjectContract(async (relPath) => files.get(relPath), { maxAttempts: 1 }); + assert.equal(seed.plan.status, 'complete'); + assert.equal(deck.slides[0].html, html); +}); + +test('shared element helper preserves editor interaction markup', () => { + const theme = { ink: '#111111', primary: '#0055aa', muted: '#666666', panel: '#ffffff' }; + const style = { + fontSize: 24, + fontWeight: 600, + color: 'ink', + background: 'transparent', + opacity: 1, + borderRadius: 0, + align: 'left', + }; + const text = elementModelElementHtml( + { id: 'text-1', type: 'text', x: 1, y: 2, w: 30, h: 10, text: '可编辑正文', style }, + theme, + { mode: 'editor', editable: true, selectedId: 'text-1' }, + ); + const list = elementModelElementHtml( + { id: 'list-1', type: 'list', x: 1, y: 2, w: 30, h: 10, items: ['A'], style }, + theme, + { mode: 'editor', editable: true }, + ); + + assert.match(text, /class="slide-element element-text is-selected"/); + assert.match(text, /data-edit-text="text-1"/); + assert.match(text, /contenteditable="true"/); + assert.match(text, /class="resize-handle"/); + assert.match(text, /font-size:clamp\(8px,/); + assert.match(list, /data-edit-list="list-1"/); + assert.match(list, /data-item-index="0"/); +}); + +test('prompt pins the stable skill key and workspace-relative delivery contract', () => { + const prompt = buildAgentPrompt({ instruction: '生成两页协议说明' }); + + assert.equal(PPT_DESIGN_SKILL_KEY, 'user::bitfun-system::ppt-design'); + assert.match(prompt, /user::bitfun-system::ppt-design/); + assert.match(prompt, /工作区根目录下的 `project\.json`/); + assert.match(prompt, /工作区根目录下的 `slides\/slide-NN\.html`/); + assert.match(prompt, /`project\.json` 的 `status` 设为 `"complete"`/); + assert.match(prompt, /`slide_order`.*每一页.*完整 HTML/s); +}); + +test('prompt carries a targeted contract diagnostic into same-session continuation', () => { + const prompt = buildAgentPrompt({ + instruction: '继续生成', + continueAfterInterruption: true, + projectContractDiagnostic: { + code: 'missing_slide_files', + continuationPrompt: '只补写 slides/slide-02.html,然后重新完成有界检查。', + }, + }); + + assert.match(prompt, /同一会话/); + assert.match(prompt, /missing_slide_files/); + assert.match(prompt, /只补写 slides\/slide-02\.html/); +}); + +test('project.json read retries transient visibility like slide reads', async () => { + let attempts = 0; + const sleeps = []; + const plan = await readProjectPlanWithRetry(async (relPath) => { + assert.equal(relPath, 'project.json'); + attempts += 1; + if (attempts === 1) throw new Error('not visible yet'); + if (attempts === 2) return '{"status":"complete"'; + return JSON.stringify(validPlan); + }, { + maxAttempts: 3, + delayMs: 7, + sleep: async (delay) => sleeps.push(delay), + }); + + assert.deepEqual(plan, validPlan); + assert.equal(attempts, 3); + assert.deepEqual(sleeps, [7, 7]); +}); + +test('project contract waits for a planning skeleton to become complete in the same run', async () => { + const skeleton = createDeckProjectSkeleton({ title: '逐步写入' }); + let projectReads = 0; + const sleeps = []; + + const deck = await readDeckProjectContract(async (relPath) => { + if (relPath === 'project.json') { + projectReads += 1; + return JSON.stringify(projectReads === 1 ? skeleton : { + ...validPlan, + outline: [validPlan.outline[0]], + slide_order: ['slide-01'], + }); + } + return completeSlide('恢复后的第一页'); + }, { + maxAttempts: 2, + delayMs: 5, + sleep: async (delay) => sleeps.push(delay), + }); + + assert.equal(projectReads, 2); + assert.deepEqual(sleeps, [5]); + assert.equal(deck.plan.status, 'complete'); + assert.equal(deck.slides[0].outlineEntry.title, '协议先于页面'); + assert.match(deck.slides[0].html, /恢复后的第一页/); +}); + +test('project contract rejects slide_order and outline disagreement', async () => { + const plan = { + ...validPlan, + slide_order: ['slide-01', 'slide-03'], + }; + + await assert.rejects( + readDeckProjectContract(async (relPath) => ( + relPath === 'project.json' ? JSON.stringify(plan) : completeSlide(relPath) + ), { maxAttempts: 1 }), + (error) => { + assert.ok(error instanceof DeckProjectContractError); + assert.equal(error.diagnostic.code, 'invalid_project_contract'); + assert.match(error.diagnostic.continuationPrompt, /slide_order/); + assert.match(error.diagnostic.continuationPrompt, /outline/); + return true; + }, + ); +}); + +test('project contract follows slide_order when it intentionally differs from outline order', async () => { + const reversed = { + ...validPlan, + slide_order: ['slide-02', 'slide-01'], + }; + + const deck = await readDeckProjectContract(async (relPath) => ( + relPath === 'project.json' + ? JSON.stringify(reversed) + : completeSlide(relPath.endsWith('slide-01.html') ? 'First file' : 'Second file') + ), { maxAttempts: 1 }); + + assert.deepEqual(deck.slides.map((slide) => slide.slideId), ['slide-02', 'slide-01']); + assert.deepEqual(deck.slides.map((slide) => slide.slideNumber), [1, 2]); + assert.deepEqual(deck.slides.map((slide) => slide.outlineEntry.id), ['finish', 'intro']); + assert.match(deck.slides[0].html, /Second file/); +}); + +test('project contract requires id, title, and bullets on every outline item', async (t) => { + const invalidItems = [ + ['id', { title: '标题', bullets: [], slide_id: 'slide-01' }], + ['title', { id: 'intro', bullets: [], slide_id: 'slide-01' }], + ['bullets', { id: 'intro', title: '标题', slide_id: 'slide-01' }], + ]; + + for (const [field, outlineItem] of invalidItems) { + await t.test(`rejects missing ${field}`, async () => { + const plan = { + ...validPlan, + outline: [outlineItem], + slide_order: ['slide-01'], + }; + await assert.rejects( + readDeckProjectContract(async (relPath) => ( + relPath === 'project.json' ? JSON.stringify(plan) : completeSlide('第一页') + ), { maxAttempts: 1 }), + (error) => { + assert.equal(error.diagnostic.code, 'invalid_project_contract'); + assert.equal(error.diagnostic.invalidOutlineField, field); + assert.match(error.diagnostic.continuationPrompt, new RegExp(field)); + return true; + }, + ); + }); + } +}); + +test('project contract requires string bullets and unique outline ids', async (t) => { + await t.test('rejects non-string bullet entries', async () => { + const plan = { + ...validPlan, + outline: [{ ...validPlan.outline[0], bullets: ['valid', 42] }], + slide_order: ['slide-01'], + }; + await assert.rejects( + readDeckProjectContract(async (relPath) => ( + relPath === 'project.json' ? JSON.stringify(plan) : completeSlide('第一页') + ), { maxAttempts: 1 }), + (error) => error.diagnostic.invalidOutlineField === 'bullets', + ); + }); + + await t.test('rejects duplicate outline ids', async () => { + const plan = { + ...validPlan, + outline: [ + validPlan.outline[0], + { ...validPlan.outline[1], id: validPlan.outline[0].id }, + ], + }; + await assert.rejects( + readDeckProjectContract(async (relPath) => ( + relPath === 'project.json' ? JSON.stringify(plan) : completeSlide(relPath) + ), { maxAttempts: 1 }), + (error) => error.diagnostic.invalidOutlineField === 'id', + ); + }); +}); + +test('project contract reports every missing page for targeted continuation', async () => { + await assert.rejects( + readDeckProjectContract(async (relPath) => { + if (relPath === 'project.json') return JSON.stringify(validPlan); + if (relPath === 'slides/slide-01.html') return completeSlide('第一页'); + throw new Error('not found'); + }, { maxAttempts: 2, delayMs: 0 }), + (error) => { + assert.equal(error.diagnostic.code, 'missing_slide_files'); + assert.deepEqual(error.diagnostic.missingPaths, ['slides/slide-02.html']); + assert.match(error.diagnostic.continuationPrompt, /只补写.*slides\/slide-02\.html/s); + assert.match(error.message, /missing_slide_files/); + return true; + }, + ); +}); + +test('slide completeness requires html and body opening and closing structure', async (t) => { + const malformedSlides = [ + ['garbage with closing html only', 'garbage'], + ['html without body', '

          content
          '], + ['body without closing body', 'content'], + ['truncated closing html tag', 'content \n '], + ]; + + for (const [name, malformedHtml] of malformedSlides) { + await t.test(name, async () => { + const oneSlidePlan = { + ...validPlan, + outline: [validPlan.outline[0]], + slide_order: ['slide-01'], + }; + await assert.rejects( + readDeckProjectContract(async (relPath) => ( + relPath === 'project.json' ? JSON.stringify(oneSlidePlan) : malformedHtml + ), { maxAttempts: 1 }), + (error) => { + assert.equal(error.diagnostic.code, 'missing_slide_files'); + assert.deepEqual(error.diagnostic.missingPaths, ['slides/slide-01.html']); + return true; + }, + ); + }); + } +}); + +test('bad project JSON returns a repairable same-session diagnostic', async () => { + await assert.rejects( + readProjectPlanWithRetry(async () => '{"status":"complete"', { maxAttempts: 2, delayMs: 0 }), + (error) => { + assert.equal(error.diagnostic.code, 'invalid_project_json'); + assert.match(error.diagnostic.continuationPrompt, /修复 `project\.json` JSON/); + return true; + }, + ); +}); + +test('missing project.json has a distinct targeted diagnostic', async () => { + await assert.rejects( + readProjectPlanWithRetry(async () => { + const error = new Error('not found'); + error.code = 'ENOENT'; + throw error; + }, { maxAttempts: 2, delayMs: 0 }), + (error) => { + assert.equal(error.diagnostic.code, 'missing_project_json'); + assert.match(error.diagnostic.continuationPrompt, /创建 `project\.json`/); + return true; + }, + ); +}); + +test('empty project.json retries and remains a targeted missing-project continuation', async () => { + let attempts = 0; + await assert.rejects( + readProjectPlanWithRetry(async () => { + attempts += 1; + return attempts === 1 ? '' : ' \n'; + }, { maxAttempts: 2, delayMs: 0 }), + (error) => { + assert.equal(error.diagnostic.code, 'missing_project_json'); + assert.match(error.diagnostic.summary, /missing or empty/); + assert.match(error.diagnostic.continuationPrompt, /创建 `project\.json`/); + return true; + }, + ); + assert.equal(attempts, 2); +}); + +test('new-deck skeleton is valid JSON but cannot satisfy completion contract', async () => { + const skeleton = createDeckProjectSkeleton({ + title: '待规划 deck', + language: 'zh-CN', + style: { theme: 'light' }, + }); + const serialized = `${JSON.stringify(skeleton, null, 2)}\n`; + + assert.deepEqual(JSON.parse(serialized), skeleton); + assert.equal(skeleton.status, 'planning'); + assert.deepEqual(skeleton.outline, []); + assert.deepEqual(skeleton.slide_order, []); + await assert.rejects( + readDeckProjectContract(async (relPath) => { + if (relPath === 'project.json') return serialized; + throw new Error(`unexpected read: ${relPath}`); + }, { maxAttempts: 1 }), + (error) => error.diagnostic.code === 'project_incomplete', + ); +}); + +test('existing-deck seed serializes element-only slides and passes the strict contract', async () => { + assert.equal(typeof deckProjectContract.createDeckProjectSeed, 'function'); + const seed = deckProjectContract.createDeckProjectSeed({ + hasExistingDeck: true, + title: '旧 deck', + language: 'zh-CN', + style: { theme: 'light' }, + slides: [ + { title: '旧第一页', html: completeSlide('旧第一页') }, + { + title: '旧第二页', + html: '', + elements: [{ type: 'text', text: '来自 element model' }], + }, + ], + serializeElementSlide: buildPureElementSlideHtml, + }); + + assert.equal(seed.plan.status, 'complete'); + assert.deepEqual(seed.plan.slide_order, ['slide-01', 'slide-02']); + assert.deepEqual(seed.plan.outline[1], { + id: 'slide-02', + title: '旧第二页', + bullets: [], + slide_id: 'slide-02', + }); + assert.equal(seed.slideFiles.length, 2); + assert.match(seed.slideFiles[1].html, /]/i); + assert.match(seed.slideFiles[1].html, /]/i); + + const files = new Map([ + ['project.json', JSON.stringify(seed.plan)], + ...seed.slideFiles.map((file) => [file.relPath, file.html]), + ]); + const deck = await readDeckProjectContract(async (relPath) => { + if (!files.has(relPath)) throw new Error('not found'); + return files.get(relPath); + }, { maxAttempts: 1 }); + assert.equal(deck.slides.length, 2); +}); + +test('legacy element-model seed round-trips every serialized element without losing content', async () => { + const legacySlide = { + title: '旧元素模型', + theme: { + background: '#fefefe', + ink: '#101010', + muted: '#606060', + primary: '#0055aa', + accent: '#ee5500', + panel: '#ffffff', + }, + elements: [ + { id: 'text-old', type: 'text', x: 2, y: 4, w: 30, h: 10, text: '旧正文', style: {} }, + { id: 'list-old', type: 'list', x: 2, y: 16, w: 30, h: 20, items: ['旧列表一', '旧列表二'], style: {} }, + { id: 'metric-old', type: 'metric', x: 36, y: 4, w: 20, h: 16, text: '98%', label: '旧指标', style: {} }, + { + id: 'chart-old', type: 'chart', x: 36, y: 24, w: 40, h: 30, text: '旧图表', + data: [{ label: '旧类别', value: 7 }], style: {}, + }, + { + id: 'media-old', type: 'media', x: 2, y: 50, w: 24, h: 30, + text: '旧媒体', src: 'data:image/png;base64,AA==', style: {}, + }, + { id: 'shape-old', type: 'shape', x: 78, y: 58, w: 18, h: 20, text: '旧形状', style: {} }, + ], + }; + const seed = deckProjectContract.createDeckProjectSeed({ + hasExistingDeck: true, + title: '旧 deck', + slides: [legacySlide], + serializeElementSlide: buildPureElementSlideHtml, + }); + const files = new Map([ + ['project.json', JSON.stringify(seed.plan)], + ...seed.slideFiles.map((file) => [file.relPath, file.html]), + ]); + + const deck = await readDeckProjectContract(async (relPath) => files.get(relPath), { maxAttempts: 1 }); + const html = deck.slides[0].html; + + for (const id of legacySlide.elements.map((element) => element.id)) { + assert.match(html, new RegExp(`data-element-id="${id}"`), id); + } + for (const text of ['旧正文', '旧列表一', '旧列表二', '98%', '旧指标', '旧图表', '旧类别', '7', '旧媒体', '旧形状']) { + assert.match(html, new RegExp(text), text); + } + assert.match(html, /src="data:image\/png;base64,AA=="/); + assert.equal(seed.plan.status, 'complete'); + assert.equal(deck.slides[0].slideId, 'slide-01'); +}); + +test('existing-deck seed stays planning with an exact diagnostic when a slide cannot serialize', () => { + const seed = deckProjectContract.createDeckProjectSeed({ + hasExistingDeck: true, + title: '旧 deck', + language: 'zh-CN', + slides: [ + { title: '旧第一页', html: completeSlide('旧第一页') }, + { title: '损坏页面' }, + ], + serializeElementSlide: () => { + throw new Error('unsupported slide model'); + }, + }); + + assert.equal(seed.plan.status, 'planning'); + assert.equal(seed.diagnostic.code, 'missing_slide_files'); + assert.deepEqual(seed.diagnostic.missingPaths, ['slides/slide-02.html']); + assert.match(seed.diagnostic.continuationPrompt, /slides\/slide-02\.html/); +}); + +test('persistDeckProjectSeed creates slides directory before ordered writes', async () => { + const calls = []; + let directoryReady = false; + const fs = { + async mkdir(path, options) { + calls.push(['mkdir', path, options]); + directoryReady = true; + }, + async writeFile(path, content) { + assert.equal(directoryReady, true); + calls.push(['write', path, content]); + }, + }; + const seed = { + plan: { status: 'complete' }, + slideFiles: [ + { relPath: 'slides/slide-01.html', html: completeSlide('one') }, + { relPath: 'slides/slide-02.html', html: completeSlide('two') }, + ], + }; + + await persistDeckProjectSeed(fs, '/deck', seed); + + assert.deepEqual(calls.map(([operation, path]) => [operation, path]), [ + ['mkdir', '/deck/slides'], + ['write', '/deck/project.json'], + ['write', '/deck/slides/slide-01.html'], + ['write', '/deck/slides/slide-02.html'], + ]); + assert.deepEqual(calls[0][2], { recursive: true }); +}); + +test('persistDeckProjectSeed reports mkdir and slide write failures for same-session continuation', async (t) => { + await t.test('mkdir failure', async () => { + await assert.rejects( + persistDeckProjectSeed({ + async mkdir() { throw new Error('/private/deck denied'); }, + async writeFile() { assert.fail('write must not run'); }, + }, '/deck', { plan: {}, slideFiles: [] }), + (error) => { + assert.ok(error instanceof DeckProjectContractError); + assert.equal(error.diagnostic.code, 'seed_fs_mkdir_failed'); + assert.equal(error.diagnostic.phase, 'mkdir'); + assert.deepEqual(error.diagnostic.missingPaths, ['slides']); + assert.match(error.diagnostic.continuationPrompt, /slides/); + return true; + }, + ); + }); + await t.test('slide write failure', async () => { + await assert.rejects( + persistDeckProjectSeed({ + async mkdir() {}, + async writeFile(path) { + if (path.endsWith('slide-02.html')) throw new Error(' /Users/alice/deck'); + }, + }, '/deck', { + plan: {}, + slideFiles: [ + { relPath: 'slides/slide-01.html', html: completeSlide('one') }, + { relPath: 'slides/slide-02.html', html: completeSlide('two') }, + ], + }), + (error) => { + assert.equal(error.diagnostic.code, 'seed_fs_write_failed'); + assert.equal(error.diagnostic.phase, 'slide-write'); + assert.deepEqual(error.diagnostic.missingPaths, ['slides/slide-02.html']); + return true; + }, + ); + }); +}); + +test('request always carries seed diagnostics while continuation depends on an existing session', () => { + assert.equal(typeof deckProjectContract.buildDeckRunRequestInput, 'function'); + const diagnostic = { + code: 'missing_slide_files', + continuationPrompt: '只补写 slides/slide-02.html。', + }; + const request = deckProjectContract.buildDeckRunRequestInput( + { operation: 'generate', instruction: '继续' }, + { sessionId: 'session-1', projectContractDiagnostic: diagnostic }, + ); + + assert.equal(request.continueAfterInterruption, true); + assert.equal(request.projectContractDiagnostic, diagnostic); + assert.equal(request.operation, 'generate'); + assert.deepEqual( + deckProjectContract.buildDeckRunRequestInput( + { operation: 'generate' }, + { sessionId: '', projectContractDiagnostic: diagnostic }, + ), + { operation: 'generate', projectContractDiagnostic: diagnostic }, + ); +}); + +test('first-turn prompt receives seed filesystem continuation diagnostics', () => { + const diagnostic = { + code: 'seed_fs_mkdir_failed', + continuationPrompt: '创建 slides 目录后继续。', + missingPaths: ['slides'], + }; + const request = deckProjectContract.buildDeckRunRequestInput( + { operation: 'generate', instruction: '生成演示稿' }, + { sessionId: '', projectContractDiagnostic: diagnostic }, + ); + const prompt = buildAgentPrompt(request); + + assert.equal(request.continueAfterInterruption, undefined); + assert.equal(request.projectContractDiagnostic, diagnostic); + assert.match(prompt, /seed_fs_mkdir_failed/); + assert.match(prompt, /创建 slides 目录后继续/); +}); + +test('skill defines the workspace root unambiguously and bounded plan-first completion', async () => { + const skillUrl = new URL('../../../../../../../../assembly/core/builtin_skills/ppt-design/SKILL.md', import.meta.url); + const skill = await readFile(skillUrl, 'utf8'); + + assert.doesNotMatch(skill, /\{\{ppt_project_dir\}\}/); + assert.match(skill, /当前工作区根目录就是当前 deck 根目录/); + assert.match(skill, /先.*project\.json.*再.*slides\/slide-NN\.html/s); + assert.match(skill, /有界完成检查/); + assert.match(skill, /仅检查一次/); +}); + +test('repository exposes and runs the focused PPT Live contract test in CI', async () => { + const repoRoot = new URL('../../../../../../../../../../', import.meta.url); + const packageJson = JSON.parse(await readFile(new URL('package.json', repoRoot), 'utf8')); + const ci = await readFile(new URL('.github/workflows/ci.yml', repoRoot), 'utf8'); + + assert.equal( + packageJson.scripts['test:ppt-live'], + 'node --test src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test/*.test.mjs', + ); + assert.match(ci, /name: Validate PPT Live generated-file contract[\s\S]*run: pnpm run test:ppt-live/); + assert.ok( + ci.indexOf('- name: Install dependencies') < ci.indexOf('- name: Validate PPT Live generated-file contract'), + 'PPT Live tests must run after pnpm install on a clean runner', + ); +}); + +test('UI seeds deck projects through the production persistence helper', async () => { + const ui = await readFile(new URL('../ui.js', import.meta.url), 'utf8'); + assert.match(ui, /import\s*\{[\s\S]*persistDeckProjectSeed[\s\S]*\}\s*from\s*['"]\.\/src\/deck-project-contract\.js['"]/); + assert.match(ui, /await persistDeckProjectSeed\(fs,\s*project\.dir,\s*seed\)/); +}); diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test/pptx-ooxml-artifact.test.mjs b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test/pptx-ooxml-artifact.test.mjs new file mode 100644 index 0000000000..b0f63f24da --- /dev/null +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test/pptx-ooxml-artifact.test.mjs @@ -0,0 +1,623 @@ +import assert from 'node:assert/strict'; +import { createRequire } from 'node:module'; +import test from 'node:test'; + +import { + buildSlideFromExtracted, + createPptxDeck, +} from '../src/pptx-html-build.js'; + +const requireFromPptxGen = createRequire(import.meta.resolve('pptxgenjs')); +const JSZip = requireFromPptxGen('jszip'); +const requireFromWebUi = createRequire( + new URL('../../../../../../../../../web-ui/package.json', import.meta.url), +); +const { JSDOM, VirtualConsole } = requireFromWebUi('jsdom'); + +const PNG_1X1 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII='; +const BODY_DIMENSIONS = { width: 1280, height: 720, errors: [] }; + +function textElement({ + text, + sourceId, + zIndex, + paintOrder, + x = 1, + y = 1, + w = 4, + h = 0.6, +}) { + return { + type: 'p', + text, + sourceId, + kind: 'native', + zIndex, + paintOrder, + position: { x, y, w, h }, + style: { + fontSize: 20, + fontFace: 'Arial', + color: '111111', + align: 'left', + lineSpacing: 24, + margin: 0, + }, + }; +} + +async function writeAndOpen(pptx) { + const output = await pptx.write({ outputType: 'nodebuffer' }); + assert.ok(Buffer.isBuffer(output), 'PptxGenJS 4.0.1 must return a Node Buffer'); + assert.ok(output.length > 0, 'PPTX buffer must not be empty'); + return JSZip.loadAsync(output); +} + +async function zipText(zip, path) { + const entry = zip.file(path); + assert.ok(entry, `${path} must exist in the PPTX`); + return entry.async('string'); +} + +function topLevelSlideObjects(slideXml) { + return [...slideXml.matchAll(/[\s\S]*?<\/p:\1>/g)] + .map((match) => ({ type: match[1], xml: match[0] })); +} + +function pictureExtents(objectXml) { + const match = objectXml.match( + /[\s\S]*?\s*/, + ); + assert.ok(match, 'picture transform must contain offset and extent'); + return { + x: Number(match[1]), + y: Number(match[2]), + cx: Number(match[3]), + cy: Number(match[4]), + }; +} + +function relatedMediaPaths(relsXml) { + return [...relsXml.matchAll(/Type="[^"]*\/image" Target="\.\.\/media\/([^"]+)"/g)] + .map((match) => `ppt/media/${match[1]}`); +} + +async function withControllableExportDom(run) { + const dom = new JSDOM('', { + pretendToBeVisual: true, + virtualConsole: new VirtualConsole(), + }); + const { window } = dom; + const { document } = window; + const savedGlobals = new Map(); + const globals = { + window, + document, + DOMParser: window.DOMParser, + Node: window.Node, + NodeFilter: window.NodeFilter, + getComputedStyle: window.getComputedStyle.bind(window), + requestAnimationFrame: window.requestAnimationFrame.bind(window), + cancelAnimationFrame: window.cancelAnimationFrame.bind(window), + }; + Object.entries(globals).forEach(([key, value]) => { + savedGlobals.set(key, Object.getOwnPropertyDescriptor(globalThis, key)); + Object.defineProperty(globalThis, key, { + configurable: true, + writable: true, + value, + }); + }); + + const rect = (left, top, width, height) => ({ + x: left, + y: top, + left, + top, + width, + height, + right: left + width, + bottom: top + height, + toJSON() { + return { left, top, width, height }; + }, + }); + const measuredRect = (element) => { + if (element.classList?.contains('ppt-export-root') + || element.classList?.contains('ppt-export-body')) { + return rect(0, 0, 1280, 720); + } + const style = element.style || {}; + const order = Number(element.dataset?.layoutOrder || 0); + return rect( + parseFloat(style.left) || 40, + parseFloat(style.top) || (40 + order * 70), + parseFloat(style.width) || 480, + parseFloat(style.height) || 48, + ); + }; + const elementPrototype = window.HTMLElement.prototype; + const svgPrototype = window.SVGElement.prototype; + const originalHtmlRect = elementPrototype.getBoundingClientRect; + const originalSvgRect = svgPrototype.getBoundingClientRect; + elementPrototype.getBoundingClientRect = function getBoundingClientRect() { + return measuredRect(this); + }; + svgPrototype.getBoundingClientRect = function getBoundingClientRect() { + return measuredRect(this); + }; + const prototypeDescriptors = { + offsetWidth: Object.getOwnPropertyDescriptor(elementPrototype, 'offsetWidth'), + offsetHeight: Object.getOwnPropertyDescriptor(elementPrototype, 'offsetHeight'), + scrollWidth: Object.getOwnPropertyDescriptor(elementPrototype, 'scrollWidth'), + scrollHeight: Object.getOwnPropertyDescriptor(elementPrototype, 'scrollHeight'), + }; + Object.defineProperties(elementPrototype, { + offsetWidth: { configurable: true, get() { return measuredRect(this).width; } }, + offsetHeight: { configurable: true, get() { return measuredRect(this).height; } }, + scrollWidth: { configurable: true, get() { return measuredRect(this).width; } }, + scrollHeight: { configurable: true, get() { return measuredRect(this).height; } }, + }); + const originalCreateRange = document.createRange.bind(document); + document.createRange = () => ({ + element: null, + selectNodeContents(element) { + this.element = element; + }, + getBoundingClientRect() { + return this.element ? measuredRect(this.element) : rect(0, 0, 0, 0); + }, + detach() {}, + }); + + try { + return await run({ window, document }); + } finally { + document.createRange = originalCreateRange; + elementPrototype.getBoundingClientRect = originalHtmlRect; + svgPrototype.getBoundingClientRect = originalSvgRect; + Object.entries(prototypeDescriptors).forEach(([key, descriptor]) => { + if (descriptor) Object.defineProperty(elementPrototype, key, descriptor); + else delete elementPrototype[key]; + }); + for (const [key, descriptor] of savedGlobals) { + if (descriptor) Object.defineProperty(globalThis, key, descriptor); + else delete globalThis[key]; + } + window.close(); + } +} + +test('DOM preparation main path exports editable OOXML plus local visual fallback', async () => { + await withControllableExportDom(async () => { + const [deckExportModule, slideExportModule, elementModelModule] = await Promise.all([ + import('../src/export-deck-browser.js'), + import('../src/export-slide-browser.js'), + import('../src/element-model-html.js'), + ]); + const { exportPptxPrepared } = deckExportModule; + const { prepareSlidesForPptxExport } = slideExportModule; + assert.equal(slideExportModule.buildElementSlideHtml, elementModelModule.buildElementSlideHtml); + const html = ` +
          +

          • First prepared bullet

          +

          • Second prepared bullet

          +

          Editable mixed text

          +
          +

          Merged prepared first

          Merged prepared second

          +
          + + +
          Prepared headerPrepared cell
          + + + Prepared SVG text + + native +
          +
          + + + + Prepared complex SVG label + +
          +

          Foreground prepared text

          + `; + const deck = { + title: 'Prepared DOM integration', + slides: [{ id: 'slide-dom', title: 'Prepared DOM integration', html }], + }; + const rasterPhases = []; + + const prepared = await prepareSlidesForPptxExport(deck.slides, { + renderRaster: async (_rasterHtml, _slideIndex, metadata) => { + rasterPhases.push(metadata.phase); + return PNG_1X1.replace(/^data:image\/png;base64,/, ''); + }, + }); + + assert.equal(prepared.length, 1); + assert.ok(rasterPhases.length >= 3); + assert.ok(rasterPhases.every((phase) => phase === 'local-visual')); + assert.ok(prepared[0].slideData.elements.some((item) => item.type === 'list')); + assert.ok(prepared[0].slideData.elements.some((item) => item.type === 'shape')); + assert.ok(prepared[0].slideData.elements.some((item) => item.type === 'image')); + assert.ok(prepared[0].slideData.fallbackLayers.some((item) => item.sourceId === 'gradient-card')); + assert.equal(prepared[0].slideData.fullPageFallback, null); + + const exported = await exportPptxPrepared(deck, prepared); + const pptxBuffer = Buffer.from(exported.base64, 'base64'); + assert.ok(Buffer.isBuffer(pptxBuffer) && pptxBuffer.length > 0); + const zip = await JSZip.loadAsync(pptxBuffer); + const [slideXml, relsXml] = await Promise.all([ + zipText(zip, 'ppt/slides/slide1.xml'), + zipText(zip, 'ppt/slides/_rels/slide1.xml.rels'), + ]); + const objects = topLevelSlideObjects(slideXml); + + for (const text of [ + 'First prepared bullet', + 'Second ', + 'prepared', + ' bullet', + 'Editable ', + 'mixed', + ' text', + 'Merged prepared first', + 'Merged prepared second', + 'Prepared header', + 'Prepared cell', + 'Prepared SVG text', + 'Prepared complex SVG label', + 'Foreground prepared text', + ]) { + assert.match(slideXml, new RegExp(`${text}`), text); + } + assert.match(slideXml, //); + assert.match(slideXml, //g) || []).length >= 4); + assert.ok((slideXml.match(//g) || []).length >= 4); + assert.ok(relatedMediaPaths(relsXml).length >= 4); + assert.ok(objects.some((item) => item.type === 'pic')); + assert.ok(objects.findIndex((item) => item.xml.includes('Foreground prepared text')) + > objects.map((item) => item.type).lastIndexOf('pic')); + assert.ok(!(objects.length === 1 && objects[0].type === 'pic')); + }); +}); + +test('prepare main path records security repairs and escalates unsafe geometry to page visual fallback', async () => { + await withControllableExportDom(async () => { + const { prepareSlidesForPptxExport } = await import('../src/export-slide-browser.js'); + const rendered = []; + const html = ` + +
          + +

          Overflow

          + `; + const prepared = await prepareSlidesForPptxExport([{ id: 'unsafe', html }], { + renderRaster: async (rasterHtml, _index, metadata) => { + rendered.push({ rasterHtml, metadata }); + return PNG_1X1.replace(/^data:image\/png;base64,/, ''); + }, + }); + + assert.ok(prepared[0].diagnostics.some((item) => ( + item.code === 'active_content_removed' && item.severity === 'repaired' + ))); + assert.ok(prepared[0].diagnostics.some((item) => item.code === 'text_out_of_bounds')); + assert.equal(rendered[0].metadata.phase, 'page-visual'); + assert.doesNotMatch(rendered[0].rasterHtml, / { + const { analyzeMountedSlideForPptx } = await import('../src/export-slide-browser.js'); + const result = analyzeMountedSlideForPptx(null, ''); + assert.equal(result.issues[0].code, 'unreadable_document'); + assert.equal(result.issues[0].severity, 'blocking'); +}); + +test('interactive thumbnail and export preview entry points mount only sanitized HTML', async () => { + await withControllableExportDom(async ({ document }) => { + const render = await import('../src/render.js'); + const { buildHtmlDeck } = await import('../src/export-html.js'); + const unsafe = ` +

          Safe text

          + + `; + + const exportStage = render.buildExportPreviewStage(unsafe); + document.body.append(exportStage); + const exportHtml = exportStage.querySelector('iframe').srcdoc; + + const thumbContainer = document.createElement('div'); + thumbContainer.innerHTML = render.slideHtml({ id: 'thumb', html: unsafe }); + document.body.append(thumbContainer); + render.hydrateHtmlSlideIframes(thumbContainer); + const thumbHtml = thumbContainer.querySelector('iframe').srcdoc; + + const canvas = document.createElement('div'); + canvas.id = 'slideCanvas'; + document.body.append(canvas); + render.renderSlideCanvas({ + title: 'Preview test', + outline: ['Preview test'], + brief: { topic: 'Preview test' }, + slides: [{ id: 'interactive', html: unsafe }], + activeSlideId: 'interactive', + selectedElementId: null, + generation: { phase: 'idle' }, + }, {}); + const interactiveHtml = canvas.querySelector('[data-slide-stage]').shadowRoot.innerHTML; + const standaloneDeckHtml = buildHtmlDeck({ + title: 'Sanitized deck', + slides: [{ id: 'standalone', html: unsafe }], + }); + + for (const mounted of [exportHtml, thumbHtml, interactiveHtml, standaloneDeckHtml]) { + assert.match(mounted, /Safe text/); + assert.doesNotMatch(mounted, /onclick|evil\.invalid|javascript:|\\75\\72\\6c/i); + } + }); +}); + +test('real PPTX keeps editable objects and local fallback in OOXML paint order', async () => { + const pptx = createPptxDeck({ title: 'OOXML regression' }); + const result = await buildSlideFromExtracted({ + background: { type: 'color', value: 'FFFFFF' }, + elements: [ + { + type: 'shape', + text: '', + sourceId: 'panel', + kind: 'native', + zIndex: 0, + paintOrder: 0, + position: { x: 0.5, y: 0.5, w: 5, h: 2.5 }, + shape: { fill: 'DDEEFF', line: { color: '224466', width: 1 }, rectRadius: 0 }, + }, + textElement({ + text: [{ text: 'Editable ', options: {} }, { text: 'title', options: { bold: true } }], + sourceId: 'title', + zIndex: 1, + paintOrder: 1, + }), + { + type: 'list', + sourceId: 'list', + kind: 'native', + zIndex: 2, + paintOrder: 2, + position: { x: 1, y: 2, w: 4, h: 1.2 }, + items: [ + { text: 'First bullet', options: { bullet: { indent: 18 }, breakLine: true } }, + { text: 'Second bullet', options: { bullet: { indent: 18 } } }, + ], + style: { + fontSize: 18, + fontFace: 'Arial', + color: '222222', + align: 'left', + lineSpacing: 22, + paraSpaceBefore: 0, + paraSpaceAfter: 0, + margin: 0, + }, + }, + { + type: 'image', + src: PNG_1X1, + sourceId: 'native-image', + kind: 'native', + zIndex: 3, + paintOrder: 3, + position: { x: 6, y: 1, w: 1, h: 1 }, + }, + textElement({ + text: 'Foreground label', + sourceId: 'foreground', + zIndex: 5, + paintOrder: 5, + x: 8, + y: 1, + }), + ], + fallbackLayers: [{ + sourceId: 'gradient-card', + kind: 'raster', + phase: 'local-visual', + zIndex: 4, + paintOrder: 4, + bbox: { x: 7, y: 3, w: 2, h: 1 }, + data: PNG_1X1, + diagnostics: [{ severity: 'fallback', code: 'css_gradient', sourceId: 'gradient-card' }], + }], + placeholders: [], + diagnostics: [{ severity: 'fallback', code: 'css_gradient', sourceId: 'gradient-card' }], + errors: [], + }, BODY_DIMENSIONS, pptx); + + assert.equal(result.diagnostics[0].sourceId, 'gradient-card'); + const zip = await writeAndOpen(pptx); + const [presentationXml, slideXml, relsXml] = await Promise.all([ + zipText(zip, 'ppt/presentation.xml'), + zipText(zip, 'ppt/slides/slide1.xml'), + zipText(zip, 'ppt/slides/_rels/slide1.xml.rels'), + ]); + + assert.match(presentationXml, /Editable <\/a:t>/); + assert.match(slideXml, /title<\/a:t>/); + assert.match(slideXml, /First bullet<\/a:t>/); + assert.match(slideXml, /Second bullet<\/a:t>/); + assert.match(slideXml, //); + assert.match(slideXml, / { + if (type === 'pic') return 'pic'; + if (xml.includes('Editable ')) return 'editable-title'; + if (xml.includes('First bullet')) return 'editable-list'; + if (xml.includes('Foreground label')) return 'foreground-text'; + return 'basic-shape'; + }), [ + 'basic-shape', + 'editable-title', + 'editable-list', + 'pic', + 'pic', + 'foreground-text', + ]); + assert.equal((slideXml.match(//g) || []).length, 4); + assert.equal((slideXml.match(//g) || []).length, 2); + assert.equal((relsXml.match(/relationships\/image"/g) || []).length, 2); + const mediaPaths = relatedMediaPaths(relsXml); + assert.equal(mediaPaths.length, 2); + mediaPaths.forEach((path) => assert.ok(zip.file(path), `${path} must exist`)); + + const pictureSizes = objects.filter((object) => object.type === 'pic').map((object) => pictureExtents(object.xml)); + assert.ok(pictureSizes.every(({ cx, cy }) => cx < 12192000 && cy < 6858000)); + assert.ok(!( + objects.length === 1 + && objects[0].type === 'pic' + ), 'a normal local fallback must not collapse the slide into one full-page image'); +}); + +test('real PPTX page visual suppresses native visuals but preserves editable text in paint order', async () => { + const pptx = createPptxDeck({ title: 'Page visual suppression' }); + await buildSlideFromExtracted({ + background: { type: 'color', value: 'FFFFFF' }, + elements: [ + { + type: 'shape', sourceId: 'panel', kind: 'native', zIndex: 0, paintOrder: 0, + position: { x: 0.5, y: 0.5, w: 3, h: 2 }, + shape: { fill: '123456', line: null, rectRadius: 0 }, + }, + { + type: 'image', sourceId: 'photo', kind: 'native', zIndex: 1, paintOrder: 1, + src: PNG_1X1, position: { x: 4, y: 1, w: 1, h: 1 }, + }, + textElement({ + text: 'Editable text survives', + sourceId: 'copy', + zIndex: 3, + paintOrder: 3, + }), + ], + fallbackLayers: [{ + sourceId: 'slide-visuals', + kind: 'raster', + phase: 'page-visual', + canvas: 'full-page', + zIndex: 0, + paintOrder: 0, + suppressedNativeVisualIds: ['panel', 'photo'], + bbox: { x: 0, y: 0, w: 13.333, h: 7.5 }, + data: PNG_1X1, + }], + placeholders: [], + diagnostics: [], + errors: [], + }, BODY_DIMENSIONS, pptx); + + const zip = await writeAndOpen(pptx); + const [slideXml, relsXml] = await Promise.all([ + zipText(zip, 'ppt/slides/slide1.xml'), + zipText(zip, 'ppt/slides/_rels/slide1.xml.rels'), + ]); + const objects = topLevelSlideObjects(slideXml); + assert.deepEqual(objects.map((object) => ( + object.type === 'pic' ? 'page-visual' : 'editable-text' + )), ['page-visual', 'editable-text']); + assert.match(slideXml, /Editable text survives/); + assert.doesNotMatch(slideXml, /123456/); + assert.equal((relsXml.match(/relationships\/image"/g) || []).length, 1); +}); + +test('real PPTX full-page final fallback is one located picture and nothing else', async () => { + const pptx = createPptxDeck({ title: 'Full-page fallback' }); + const diagnostic = { + severity: 'fallback', + code: 'full_page_fallback', + sourceId: 'slide-2', + slideNumber: 2, + phase: 'full-page', + reason: 'local and page visual rendering failed', + }; + const result = await buildSlideFromExtracted({ + background: { type: 'color', value: 'FFFFFF' }, + elements: [textElement({ + text: 'Must not survive final fallback', + sourceId: 'hidden-text', + zIndex: 1, + paintOrder: 1, + })], + fallbackLayers: [{ + sourceId: 'local-layer', + kind: 'raster', + zIndex: 0, + paintOrder: 0, + bbox: { x: 1, y: 1, w: 2, h: 2 }, + data: PNG_1X1, + }], + fullPageFallback: { + sourceId: 'slide-2', + kind: 'raster', + phase: 'full-page', + data: PNG_1X1, + }, + placeholders: [], + diagnostics: [diagnostic], + errors: [], + }, BODY_DIMENSIONS, pptx); + + assert.deepEqual(result.diagnostics, [diagnostic]); + const zip = await writeAndOpen(pptx); + const [presentationXml, slideXml, relsXml] = await Promise.all([ + zipText(zip, 'ppt/presentation.xml'), + zipText(zip, 'ppt/slides/slide1.xml'), + zipText(zip, 'ppt/slides/_rels/slide1.xml.rels'), + ]); + const objects = topLevelSlideObjects(slideXml); + + assert.equal(objects.length, 1); + assert.equal(objects[0].type, 'pic'); + assert.doesNotMatch(slideXml, /Must not survive final fallback/); + assert.equal((slideXml.match(//g) || []).length, 0); + assert.equal((slideXml.match(//g) || []).length, 1); + assert.equal((relsXml.match(/relationships\/image"/g) || []).length, 1); + const mediaPaths = relatedMediaPaths(relsXml); + assert.equal(mediaPaths.length, 1); + assert.ok(zip.file(mediaPaths[0]), `${mediaPaths[0]} must exist`); + + const slideSize = presentationXml.match(/ readDeckProjectFile(project, relPath), + ); } catch { return null; } } -/** Parsed `project.json`, or null when missing or not yet valid JSON. */ -async function tryReadDeckPlanFile(project) { - return await tryReadDeckJsonFile(project, 'project.json'); -} - /** Complete slide HTML from disk, or null when missing or incomplete. */ async function tryReadDeckSlideFile(project, slideNumber) { try { @@ -877,28 +885,16 @@ async function tryReadDeckSlideFileWithRetry(project, slideNumber, maxAttempts = * design, slides }` shaped for `applyDeckPayload`. */ async function readDeckFromProjectFiles(project) { - const plan = await tryReadDeckPlanFile(project); - if (!plan) throw new Error('PPT Live agent finished without a valid project.json'); - const slideOrder = Array.isArray(plan.slide_order) && plan.slide_order.length - ? plan.slide_order - : (Array.isArray(plan.outline) ? plan.outline.map((_, index) => `slide-${String(index + 1).padStart(2, '0')}`) : []); - const slides = []; - for (let index = 0; index < slideOrder.length; index += 1) { - const slideId = String(slideOrder[index] || `slide-${String(index + 1).padStart(2, '0')}`); - const slideNumber = index + 1; - const html = await tryReadDeckSlideFile(project, slideNumber); - const outlineEntry = plan.outline?.[index]; - const title = typeof outlineEntry === 'string' ? outlineEntry : (outlineEntry?.title || `${t('newSlideTitle')} ${slideNumber}`); - if (html) { - slides.push({ - id: `ppt-live-slide-${slideNumber}`, - slideNumber, - title, - html, - }); - } - } - if (!slides.length) throw new Error('PPT Live agent did not produce any slide files'); + const result = await readDeckProjectContract( + (relPath) => readDeckProjectFile(project, relPath), + ); + const { plan } = result; + const slides = result.slides.map((slide) => ({ + id: `ppt-live-slide-${slide.slideNumber}`, + slideNumber: slide.slideNumber, + title: slide.outlineEntry?.title || `${t('newSlideTitle')} ${slide.slideNumber}`, + html: slide.html, + })); return { title: resolveDeckTitle({ plan, slides }), language: plan.language || '', @@ -910,39 +906,40 @@ async function readDeckFromProjectFiles(project) { } /** - * Best-effort: write the current deck's slides into a fresh project directory - * so the cowork agent can read unchanged pages from disk during edits and only - * rewrite the ones it changes. Skips slides without HTML content. + * Seed the current deck into the cowork project directory before the agent runs. + * Failures carry a continuation diagnostic so the same session can repair files. */ async function seedDeckProjectFromState(project) { const fs = runtime().fs; - if (!project || !fs?.writeFile || !state.slides?.length) return; + if (!project || !fs?.writeFile || !fs?.mkdir) { + throw new DeckProjectContractError({ + code: 'seed_fs_unavailable', + summary: 'Deck project filesystem is unavailable.', + continuationPrompt: '请在同一会话中重新创建 deck 项目目录和 slides 子目录,然后继续生成。', + missingPaths: [`${project?.dir || 'deck-project'}/slides`], + }); + } const hasExistingProject = await tryReadDeckPlanFile(project); if (hasExistingProject) return; // directory already has files from a prior run try { - const outline = state.slides.map((slide, index) => ({ - id: `slide-${String(index + 1).padStart(2, '0')}`, - title: String(slide.title || ''), - bullets: [], - slide_id: `slide-${String(index + 1).padStart(2, '0')}`, - })); - const projectJson = { - title: state.title || '', + const seed = createDeckProjectSeed({ + hasExistingDeck: hasUsableDeckForRevision(), + title: isEphemeralDeckTitle(state.title) ? '' : state.title, language: getLocale(), - outline, - slide_order: outline.map((item) => item.slide_id), style: buildGenerationStyle(), - }; - await fs.writeFile(`${project.dir}/project.json`, `${JSON.stringify(projectJson, null, 2)}\n`); - for (let index = 0; index < state.slides.length; index += 1) { - const slide = state.slides[index]; - if (slide.html) { - await fs.writeFile(`${project.dir}/${deckSlideFileName(index + 1)}`, slide.html); - } - } - } catch { - // Seeding is best-effort; the agent can still work from the currentDeck - // snapshot in the prompt if disk seeding fails. + slides: state.slides, + serializeElementSlide: buildElementSlideHtml, + }); + await persistDeckProjectSeed(fs, project.dir, seed); + } catch (error) { + if (error instanceof DeckProjectContractError) throw error; + throw new DeckProjectContractError({ + code: 'seed_fs_write_failed', + summary: 'Deck project seed files could not be written.', + continuationPrompt: '请在同一会话中创建缺失的 slides 目录并重写失败的 seed 文件,然后继续生成。', + missingPaths: [`${project.dir}/slides`], + cause: String(error?.message || error), + }); } } @@ -1297,12 +1294,23 @@ async function runCoworkDeckGeneration(operation, instruction) { // appdata storage, following the ppt-design skill's native project.json + // slides/slide-NN.html layout. const project = backendUsesFileProtocol() ? (currentDeckProject() || newDeckProject()) : null; + let projectContractDiagnostic = null; if (project && !state.agentSession?.workspaceSubdir) { await pruneOldDeckProjects(project.runId); // For edits of an existing deck, seed the project directory with the // current slides so the agent can read unchanged pages from disk and // only rewrite the ones it changes. - await seedDeckProjectFromState(project); + try { + await seedDeckProjectFromState(project); + } catch (error) { + if (!(error instanceof DeckProjectContractError)) throw error; + projectContractDiagnostic = error.diagnostic; + addGenerationEvent({ + title: t('generationStageAudit'), + detail: error.diagnostic.continuationPrompt, + kind: 'start', + }); + } } const retrySession = { id: state.agentSession?.id || null, @@ -1331,10 +1339,13 @@ async function runCoworkDeckGeneration(operation, instruction) { setStatus(t('generationRetrying', { attempt, max: PPT_BACKEND_MAX_ATTEMPTS })); await new Promise((resolve) => setTimeout(resolve, retryDelayMs(lastError, attempt))); } - const requestInput = { - ...buildBackendRequestBase(operation, instruction), - ...(retrySession?.id ? { continueAfterInterruption: true } : {}), - }; + const requestInput = buildDeckRunRequestInput( + buildBackendRequestBase(operation, instruction), + { + sessionId: retrySession?.id, + projectContractDiagnostic, + }, + ); // Only attach currentDeck context for edit operations on an existing // deck. For first-pass generation, sending an empty/irrelevant // currentDeck wastes hundreds of tokens in the prompt's Input JSON. @@ -1460,6 +1471,7 @@ async function runCoworkDeckGeneration(operation, instruction) { break; } catch (error) { lastError = error; + if (error?.diagnostic) projectContractDiagnostic = error.diagnostic; if (isUnknownSessionBackendError(error)) retrySession.id = null; else if (error?.pptLiveSessionId) retrySession.id = error.pptLiveSessionId; if (!isRetryableBackendError(error) || attempt >= PPT_BACKEND_MAX_ATTEMPTS) throw error; @@ -2577,6 +2589,69 @@ function getExportLabels(format) { return labels[format] || null; } +function formatExportDiagnostics(summary) { + if (!summary?.hasWarnings && !summary?.hasBlocking) return ''; + const countLabels = [ + ['repaired', 'exportDiagnosticsRepaired'], + ['svgImage', 'exportDiagnosticsSvg'], + ['localPng', 'exportDiagnosticsLocalPng'], + ['pageVisual', 'exportDiagnosticsPageVisual'], + ['fullPage', 'exportDiagnosticsFullPage'], + ['blocking', 'exportDiagnosticsBlocking'], + ].filter(([countKey]) => summary.counts?.[countKey] > 0) + .map(([countKey, labelKey]) => t(labelKey, { count: summary.counts[countKey] })); + const phaseKeys = { + 'local-svg': 'exportDiagnosticsPhaseSvg', + 'local-visual': 'exportDiagnosticsPhaseLocalPng', + 'page-visual': 'exportDiagnosticsPhasePageVisual', + 'full-page': 'exportDiagnosticsPhaseFullPage', + }; + const locations = localizeExportDiagnosticLocations(summary.locations || [], getLocale()) + .filter((location) => location.sourceId) + .slice(0, 3) + .map((location) => t('exportDiagnosticsLocation', { + slide: location.slideNumber, + source: location.sourceId, + phase: t( + phaseKeys[location.phase] + || (location.severity === 'blocking' + ? 'exportDiagnosticsPhaseBlocking' + : 'exportDiagnosticsPhaseRepair'), + ), + reason: location.reason, + })); + return t('exportDiagnosticsSummary', { + counts: countLabels.join(', '), + locations: locations.join('; '), + }); +} + +function formatBlockingExportDiagnostics(diagnostics) { + const blocking = Array.isArray(diagnostics) + ? diagnostics.filter((diagnostic) => diagnostic?.severity === 'blocking') + : []; + if (!blocking.length) return ''; + return formatExportDiagnostics({ + counts: { + repaired: 0, + svgImage: 0, + localPng: 0, + pageVisual: 0, + fullPage: 0, + blocking: blocking.length, + }, + locations: blocking.map((diagnostic) => ({ + slideNumber: diagnostic.slideNumber || '?', + sourceId: diagnostic.sourceId || '?', + phase: diagnostic.phase || null, + severity: 'blocking', + code: diagnostic.code, + })), + hasWarnings: false, + hasBlocking: true, + }); +} + function setExportRenderProgress(index, total, format) { const labels = getExportLabels(format === 'pptx' ? 'pptx' : format); if (!labels || total <= 0) return; @@ -2647,6 +2722,7 @@ async function executeExport(format) { onRasterProgress: (index) => setExportRenderProgress(index, slides.length, 'pptx'), }); result = await exportPptxPrepared(deckPayload, preparedSlides); + result.exportSummary = summarizePptxExportDiagnostics(preparedSlides); } else { result = await exportPptxFromDeck(deckPayload); } @@ -2670,7 +2746,7 @@ async function executeExport(format) { filename, result.mimeType || 'application/octet-stream', ); - return { filename }; + return { filename, exportSummary: result?.exportSummary || null }; } let exportInFlight = false; @@ -3329,16 +3405,22 @@ async function confirmExportFromModal() { const previewFrame = $('exportPreviewFrame'); const previewSnapshot = previewFrame?.innerHTML || ''; try { - const { filename } = await executeExport(format); + const { filename, exportSummary } = await executeExport(format); const savedMessage = t('exportSavedTo', { path: filename }); + const diagnosticMessage = formatExportDiagnostics(exportSummary); + const completedMessage = diagnosticMessage + ? `${savedMessage} ${diagnosticMessage}` + : savedMessage; $('exportOverlay')?.classList.remove('is-exporting'); - setExportModalFeedback('success', savedMessage); - setExportStatus(savedMessage); + setExportModalFeedback('success', completedMessage); + setExportStatus(completedMessage); revealDownloadFolder(); await new Promise((resolve) => setTimeout(resolve, 1600)); closeExportModal(); } catch (error) { - const message = error instanceof Error ? error.message : String(error); + const localizedDiagnostics = formatBlockingExportDiagnostics(error?.diagnostics); + const message = localizedDiagnostics + || (error instanceof Error ? error.message : String(error)); runtime().log?.error?.(`PPT Live ${format} export failed`, { error: message }); $('exportOverlay')?.classList.remove('is-exporting'); setExportModalFeedback('error', `${labels.failed} ${message}`); From 2051e524cc5d42d965c57794136e6f429241a170 Mon Sep 17 00:00:00 2001 From: Bob Lee Date: Thu, 16 Jul 2026 10:34:22 +0800 Subject: [PATCH 4/4] fix(ppt-live): make Node contract tests resolvable in clean CI Declare pdf-lib/jszip at the workspace root and guard flat-select browser listeners so ppt-live source imports no longer depend on host node_modules or a DOM global during CI. --- package.json | 2 + pnpm-lock.yaml | 35 + .../product-domains/src/miniapp/builtin.rs | 2 +- .../builtin/assets/ppt-live/bundle.json | 2 +- .../builtin/assets/ppt-live/dist/ui.bundle.js | 2730 ++--------------- .../miniapp/builtin/assets/ppt-live/meta.json | 2 +- .../assets/ppt-live/src/flat-select.js | 2 +- 7 files changed, 223 insertions(+), 2552 deletions(-) diff --git a/package.json b/package.json index 4d430ddeb3..1baba40ccd 100644 --- a/package.json +++ b/package.json @@ -107,6 +107,8 @@ }, "packageManager": "pnpm@10.15.0+sha512.486ebc259d3e999a4e8691ce03b5cac4a71cbeca39372a9b762cb500cfdf0873e2cb16abe3d951b1ee2cf012503f027b98b6584e4df22524e0c7450d9ec7aa7b", "dependencies": { + "jszip": "^3.10.1", + "pdf-lib": "^1.17.1", "pnpm": "^10.32.1", "pptxgenjs": "^4.0.1" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d29ec065f4..30132d17c6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,12 @@ importers: .: dependencies: + jszip: + specifier: ^3.10.1 + version: 3.10.1 + pdf-lib: + specifier: ^1.17.1 + version: 1.17.1 pnpm: specifier: ^10.32.1 version: 10.32.1 @@ -1309,6 +1315,12 @@ packages: resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} engines: {node: '>= 10.0.0'} + '@pdf-lib/standard-fonts@1.0.0': + resolution: {integrity: sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==} + + '@pdf-lib/upng@1.0.1': + resolution: {integrity: sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==} + '@pinojs/redact@0.4.0': resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} @@ -4334,6 +4346,9 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pdf-lib@1.17.1: + resolution: {integrity: sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==} + pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} @@ -5068,6 +5083,9 @@ packages: '@swc/wasm': optional: true + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -6424,6 +6442,14 @@ snapshots: '@parcel/watcher-win32-x64': 2.5.6 optional: true + '@pdf-lib/standard-fonts@1.0.0': + dependencies: + pako: 1.0.11 + + '@pdf-lib/upng@1.0.1': + dependencies: + pako: 1.0.11 + '@pinojs/redact@0.4.0': {} '@pkgjs/parseargs@0.11.0': @@ -10172,6 +10198,13 @@ snapshots: pathe@2.0.3: {} + pdf-lib@1.17.1: + dependencies: + '@pdf-lib/standard-fonts': 1.0.0 + '@pdf-lib/upng': 1.0.1 + pako: 1.0.11 + tslib: 1.14.1 + pend@1.2.0: {} picocolors@1.1.1: {} @@ -11077,6 +11110,8 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + tslib@1.14.1: {} + tslib@2.8.1: {} tsx@4.21.0: diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin.rs b/src/crates/contracts/product-domains/src/miniapp/builtin.rs index b27b9a0fa8..24102cf780 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin.rs +++ b/src/crates/contracts/product-domains/src/miniapp/builtin.rs @@ -151,7 +151,7 @@ pub const BUILTIN_APPS: &[BuiltinMiniAppBundle] = &[ }, BuiltinMiniAppBundle { id: "builtin-ppt-live", - version: 216, + version: 217, meta_json: include_str!("builtin/assets/ppt-live/meta.json"), html: include_str!("builtin/assets/ppt-live/index.html"), css: include_str!("builtin/assets/ppt-live/style.css"), diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/bundle.json b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/bundle.json index a69b03a547..41c0d008f9 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/bundle.json +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/bundle.json @@ -1,5 +1,5 @@ { "schemaVersion": 1, "id": "builtin-ppt-live", - "version": 216 + "version": 217 } diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/dist/ui.bundle.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/dist/ui.bundle.js index 50c880c75a..414dc6ad7e 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/dist/ui.bundle.js +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/dist/ui.bundle.js @@ -30,9 +30,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge mod )); -// ../../../node_modules/pako/lib/utils/common.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/utils/common.js var require_common = __commonJS({ - "../../../node_modules/pako/lib/utils/common.js"(exports) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/utils/common.js"(exports) { "use strict"; var TYPED_OK = typeof Uint8Array !== "undefined" && typeof Uint16Array !== "undefined" && typeof Int32Array !== "undefined"; function _has(obj, key) { @@ -121,9 +121,9 @@ var require_common = __commonJS({ } }); -// ../../../node_modules/pako/lib/zlib/trees.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/trees.js var require_trees = __commonJS({ - "../../../node_modules/pako/lib/zlib/trees.js"(exports) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/trees.js"(exports) { "use strict"; var utils = require_common(); var Z_FIXED = 4; @@ -763,9 +763,9 @@ var require_trees = __commonJS({ } }); -// ../../../node_modules/pako/lib/zlib/adler32.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/adler32.js var require_adler32 = __commonJS({ - "../../../node_modules/pako/lib/zlib/adler32.js"(exports, module) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/adler32.js"(exports, module) { "use strict"; function adler32(adler, buf, len, pos) { var s1 = adler & 65535 | 0, s2 = adler >>> 16 & 65535 | 0, n = 0; @@ -785,9 +785,9 @@ var require_adler32 = __commonJS({ } }); -// ../../../node_modules/pako/lib/zlib/crc32.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/crc32.js var require_crc32 = __commonJS({ - "../../../node_modules/pako/lib/zlib/crc32.js"(exports, module) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/crc32.js"(exports, module) { "use strict"; function makeTable() { var c, table = []; @@ -813,9 +813,9 @@ var require_crc32 = __commonJS({ } }); -// ../../../node_modules/pako/lib/zlib/messages.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/messages.js var require_messages = __commonJS({ - "../../../node_modules/pako/lib/zlib/messages.js"(exports, module) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/messages.js"(exports, module) { "use strict"; module.exports = { 2: "need dictionary", @@ -840,9 +840,9 @@ var require_messages = __commonJS({ } }); -// ../../../node_modules/pako/lib/zlib/deflate.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/deflate.js var require_deflate = __commonJS({ - "../../../node_modules/pako/lib/zlib/deflate.js"(exports) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/deflate.js"(exports) { "use strict"; var utils = require_common(); var trees = require_trees(); @@ -1889,9 +1889,9 @@ var require_deflate = __commonJS({ } }); -// ../../../node_modules/pako/lib/utils/strings.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/utils/strings.js var require_strings = __commonJS({ - "../../../node_modules/pako/lib/utils/strings.js"(exports) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/utils/strings.js"(exports) { "use strict"; var utils = require_common(); var STR_APPLY_OK = true; @@ -2031,9 +2031,9 @@ var require_strings = __commonJS({ } }); -// ../../../node_modules/pako/lib/zlib/zstream.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/zstream.js var require_zstream = __commonJS({ - "../../../node_modules/pako/lib/zlib/zstream.js"(exports, module) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/zstream.js"(exports, module) { "use strict"; function ZStream() { this.input = null; @@ -2053,9 +2053,9 @@ var require_zstream = __commonJS({ } }); -// ../../../node_modules/pako/lib/deflate.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/deflate.js var require_deflate2 = __commonJS({ - "../../../node_modules/pako/lib/deflate.js"(exports) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/deflate.js"(exports) { "use strict"; var zlib_deflate = require_deflate(); var utils = require_common(); @@ -2214,9 +2214,9 @@ var require_deflate2 = __commonJS({ } }); -// ../../../node_modules/pako/lib/zlib/inffast.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/inffast.js var require_inffast = __commonJS({ - "../../../node_modules/pako/lib/zlib/inffast.js"(exports, module) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/inffast.js"(exports, module) { "use strict"; var BAD = 30; var TYPE = 12; @@ -2443,9 +2443,9 @@ var require_inffast = __commonJS({ } }); -// ../../../node_modules/pako/lib/zlib/inftrees.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/inftrees.js var require_inftrees = __commonJS({ - "../../../node_modules/pako/lib/zlib/inftrees.js"(exports, module) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/inftrees.js"(exports, module) { "use strict"; var utils = require_common(); var MAXBITS = 15; @@ -2759,9 +2759,9 @@ var require_inftrees = __commonJS({ } }); -// ../../../node_modules/pako/lib/zlib/inflate.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/inflate.js var require_inflate = __commonJS({ - "../../../node_modules/pako/lib/zlib/inflate.js"(exports) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/inflate.js"(exports) { "use strict"; var utils = require_common(); var adler32 = require_adler32(); @@ -3998,9 +3998,9 @@ var require_inflate = __commonJS({ } }); -// ../../../node_modules/pako/lib/zlib/constants.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/constants.js var require_constants = __commonJS({ - "../../../node_modules/pako/lib/zlib/constants.js"(exports, module) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/constants.js"(exports, module) { "use strict"; module.exports = { /* Allowed flush values; see deflate() and inflate() below for details */ @@ -4045,9 +4045,9 @@ var require_constants = __commonJS({ } }); -// ../../../node_modules/pako/lib/zlib/gzheader.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/gzheader.js var require_gzheader = __commonJS({ - "../../../node_modules/pako/lib/zlib/gzheader.js"(exports, module) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/gzheader.js"(exports, module) { "use strict"; function GZheader() { this.text = 0; @@ -4065,9 +4065,9 @@ var require_gzheader = __commonJS({ } }); -// ../../../node_modules/pako/lib/inflate.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/inflate.js var require_inflate2 = __commonJS({ - "../../../node_modules/pako/lib/inflate.js"(exports) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/inflate.js"(exports) { "use strict"; var zlib_inflate = require_inflate(); var utils = require_common(); @@ -4239,9 +4239,9 @@ var require_inflate2 = __commonJS({ } }); -// ../../../node_modules/pako/index.js +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/index.js var require_pako = __commonJS({ - "../../../node_modules/pako/index.js"(exports, module) { + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/index.js"(exports, module) { "use strict"; var assign = require_common().assign; var deflate = require_deflate2(); @@ -4253,2374 +4253,8 @@ var require_pako = __commonJS({ } }); -// node_modules/jszip/dist/jszip.min.js -var require_jszip_min = __commonJS({ - "node_modules/jszip/dist/jszip.min.js"(exports, module) { - !(function(e) { - if ("object" == typeof exports && "undefined" != typeof module) module.exports = e(); - else if ("function" == typeof define && define.amd) define([], e); - else { - ("undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : this).JSZip = e(); - } - })(function() { - return (function s(a, o, h) { - function u(r, e2) { - if (!o[r]) { - if (!a[r]) { - var t = "function" == typeof __require && __require; - if (!e2 && t) return t(r, true); - if (l) return l(r, true); - var n = new Error("Cannot find module '" + r + "'"); - throw n.code = "MODULE_NOT_FOUND", n; - } - var i = o[r] = { exports: {} }; - a[r][0].call(i.exports, function(e3) { - var t2 = a[r][1][e3]; - return u(t2 || e3); - }, i, i.exports, s, a, o, h); - } - return o[r].exports; - } - for (var l = "function" == typeof __require && __require, e = 0; e < h.length; e++) u(h[e]); - return u; - })({ 1: [function(e, t, r) { - "use strict"; - var d = e("./utils"), c = e("./support"), p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - r.encode = function(e2) { - for (var t2, r2, n, i, s, a, o, h = [], u = 0, l = e2.length, f = l, c2 = "string" !== d.getTypeOf(e2); u < e2.length; ) f = l - u, n = c2 ? (t2 = e2[u++], r2 = u < l ? e2[u++] : 0, u < l ? e2[u++] : 0) : (t2 = e2.charCodeAt(u++), r2 = u < l ? e2.charCodeAt(u++) : 0, u < l ? e2.charCodeAt(u++) : 0), i = t2 >> 2, s = (3 & t2) << 4 | r2 >> 4, a = 1 < f ? (15 & r2) << 2 | n >> 6 : 64, o = 2 < f ? 63 & n : 64, h.push(p.charAt(i) + p.charAt(s) + p.charAt(a) + p.charAt(o)); - return h.join(""); - }, r.decode = function(e2) { - var t2, r2, n, i, s, a, o = 0, h = 0, u = "data:"; - if (e2.substr(0, u.length) === u) throw new Error("Invalid base64 input, it looks like a data url."); - var l, f = 3 * (e2 = e2.replace(/[^A-Za-z0-9+/=]/g, "")).length / 4; - if (e2.charAt(e2.length - 1) === p.charAt(64) && f--, e2.charAt(e2.length - 2) === p.charAt(64) && f--, f % 1 != 0) throw new Error("Invalid base64 input, bad content length."); - for (l = c.uint8array ? new Uint8Array(0 | f) : new Array(0 | f); o < e2.length; ) t2 = p.indexOf(e2.charAt(o++)) << 2 | (i = p.indexOf(e2.charAt(o++))) >> 4, r2 = (15 & i) << 4 | (s = p.indexOf(e2.charAt(o++))) >> 2, n = (3 & s) << 6 | (a = p.indexOf(e2.charAt(o++))), l[h++] = t2, 64 !== s && (l[h++] = r2), 64 !== a && (l[h++] = n); - return l; - }; - }, { "./support": 30, "./utils": 32 }], 2: [function(e, t, r) { - "use strict"; - var n = e("./external"), i = e("./stream/DataWorker"), s = e("./stream/Crc32Probe"), a = e("./stream/DataLengthProbe"); - function o(e2, t2, r2, n2, i2) { - this.compressedSize = e2, this.uncompressedSize = t2, this.crc32 = r2, this.compression = n2, this.compressedContent = i2; - } - o.prototype = { getContentWorker: function() { - var e2 = new i(n.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a("data_length")), t2 = this; - return e2.on("end", function() { - if (this.streamInfo.data_length !== t2.uncompressedSize) throw new Error("Bug : uncompressed data size mismatch"); - }), e2; - }, getCompressedWorker: function() { - return new i(n.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize", this.compressedSize).withStreamInfo("uncompressedSize", this.uncompressedSize).withStreamInfo("crc32", this.crc32).withStreamInfo("compression", this.compression); - } }, o.createWorkerFrom = function(e2, t2, r2) { - return e2.pipe(new s()).pipe(new a("uncompressedSize")).pipe(t2.compressWorker(r2)).pipe(new a("compressedSize")).withStreamInfo("compression", t2); - }, t.exports = o; - }, { "./external": 6, "./stream/Crc32Probe": 25, "./stream/DataLengthProbe": 26, "./stream/DataWorker": 27 }], 3: [function(e, t, r) { - "use strict"; - var n = e("./stream/GenericWorker"); - r.STORE = { magic: "\0\0", compressWorker: function() { - return new n("STORE compression"); - }, uncompressWorker: function() { - return new n("STORE decompression"); - } }, r.DEFLATE = e("./flate"); - }, { "./flate": 7, "./stream/GenericWorker": 28 }], 4: [function(e, t, r) { - "use strict"; - var n = e("./utils"); - var o = (function() { - for (var e2, t2 = [], r2 = 0; r2 < 256; r2++) { - e2 = r2; - for (var n2 = 0; n2 < 8; n2++) e2 = 1 & e2 ? 3988292384 ^ e2 >>> 1 : e2 >>> 1; - t2[r2] = e2; - } - return t2; - })(); - t.exports = function(e2, t2) { - return void 0 !== e2 && e2.length ? "string" !== n.getTypeOf(e2) ? (function(e3, t3, r2, n2) { - var i = o, s = n2 + r2; - e3 ^= -1; - for (var a = n2; a < s; a++) e3 = e3 >>> 8 ^ i[255 & (e3 ^ t3[a])]; - return -1 ^ e3; - })(0 | t2, e2, e2.length, 0) : (function(e3, t3, r2, n2) { - var i = o, s = n2 + r2; - e3 ^= -1; - for (var a = n2; a < s; a++) e3 = e3 >>> 8 ^ i[255 & (e3 ^ t3.charCodeAt(a))]; - return -1 ^ e3; - })(0 | t2, e2, e2.length, 0) : 0; - }; - }, { "./utils": 32 }], 5: [function(e, t, r) { - "use strict"; - r.base64 = false, r.binary = false, r.dir = false, r.createFolders = true, r.date = null, r.compression = null, r.compressionOptions = null, r.comment = null, r.unixPermissions = null, r.dosPermissions = null; - }, {}], 6: [function(e, t, r) { - "use strict"; - var n = null; - n = "undefined" != typeof Promise ? Promise : e("lie"), t.exports = { Promise: n }; - }, { lie: 37 }], 7: [function(e, t, r) { - "use strict"; - var n = "undefined" != typeof Uint8Array && "undefined" != typeof Uint16Array && "undefined" != typeof Uint32Array, i = e("pako"), s = e("./utils"), a = e("./stream/GenericWorker"), o = n ? "uint8array" : "array"; - function h(e2, t2) { - a.call(this, "FlateWorker/" + e2), this._pako = null, this._pakoAction = e2, this._pakoOptions = t2, this.meta = {}; - } - r.magic = "\b\0", s.inherits(h, a), h.prototype.processChunk = function(e2) { - this.meta = e2.meta, null === this._pako && this._createPako(), this._pako.push(s.transformTo(o, e2.data), false); - }, h.prototype.flush = function() { - a.prototype.flush.call(this), null === this._pako && this._createPako(), this._pako.push([], true); - }, h.prototype.cleanUp = function() { - a.prototype.cleanUp.call(this), this._pako = null; - }, h.prototype._createPako = function() { - this._pako = new i[this._pakoAction]({ raw: true, level: this._pakoOptions.level || -1 }); - var t2 = this; - this._pako.onData = function(e2) { - t2.push({ data: e2, meta: t2.meta }); - }; - }, r.compressWorker = function(e2) { - return new h("Deflate", e2); - }, r.uncompressWorker = function() { - return new h("Inflate", {}); - }; - }, { "./stream/GenericWorker": 28, "./utils": 32, pako: 38 }], 8: [function(e, t, r) { - "use strict"; - function A(e2, t2) { - var r2, n2 = ""; - for (r2 = 0; r2 < t2; r2++) n2 += String.fromCharCode(255 & e2), e2 >>>= 8; - return n2; - } - function n(e2, t2, r2, n2, i2, s2) { - var a, o, h = e2.file, u = e2.compression, l = s2 !== O.utf8encode, f = I.transformTo("string", s2(h.name)), c = I.transformTo("string", O.utf8encode(h.name)), d = h.comment, p = I.transformTo("string", s2(d)), m = I.transformTo("string", O.utf8encode(d)), _ = c.length !== h.name.length, g = m.length !== d.length, b = "", v = "", y = "", w = h.dir, k = h.date, x = { crc32: 0, compressedSize: 0, uncompressedSize: 0 }; - t2 && !r2 || (x.crc32 = e2.crc32, x.compressedSize = e2.compressedSize, x.uncompressedSize = e2.uncompressedSize); - var S = 0; - t2 && (S |= 8), l || !_ && !g || (S |= 2048); - var z = 0, C = 0; - w && (z |= 16), "UNIX" === i2 ? (C = 798, z |= (function(e3, t3) { - var r3 = e3; - return e3 || (r3 = t3 ? 16893 : 33204), (65535 & r3) << 16; - })(h.unixPermissions, w)) : (C = 20, z |= (function(e3) { - return 63 & (e3 || 0); - })(h.dosPermissions)), a = k.getUTCHours(), a <<= 6, a |= k.getUTCMinutes(), a <<= 5, a |= k.getUTCSeconds() / 2, o = k.getUTCFullYear() - 1980, o <<= 4, o |= k.getUTCMonth() + 1, o <<= 5, o |= k.getUTCDate(), _ && (v = A(1, 1) + A(B(f), 4) + c, b += "up" + A(v.length, 2) + v), g && (y = A(1, 1) + A(B(p), 4) + m, b += "uc" + A(y.length, 2) + y); - var E = ""; - return E += "\n\0", E += A(S, 2), E += u.magic, E += A(a, 2), E += A(o, 2), E += A(x.crc32, 4), E += A(x.compressedSize, 4), E += A(x.uncompressedSize, 4), E += A(f.length, 2), E += A(b.length, 2), { fileRecord: R.LOCAL_FILE_HEADER + E + f + b, dirRecord: R.CENTRAL_FILE_HEADER + A(C, 2) + E + A(p.length, 2) + "\0\0\0\0" + A(z, 4) + A(n2, 4) + f + b + p }; - } - var I = e("../utils"), i = e("../stream/GenericWorker"), O = e("../utf8"), B = e("../crc32"), R = e("../signature"); - function s(e2, t2, r2, n2) { - i.call(this, "ZipFileWorker"), this.bytesWritten = 0, this.zipComment = t2, this.zipPlatform = r2, this.encodeFileName = n2, this.streamFiles = e2, this.accumulate = false, this.contentBuffer = [], this.dirRecords = [], this.currentSourceOffset = 0, this.entriesCount = 0, this.currentFile = null, this._sources = []; - } - I.inherits(s, i), s.prototype.push = function(e2) { - var t2 = e2.meta.percent || 0, r2 = this.entriesCount, n2 = this._sources.length; - this.accumulate ? this.contentBuffer.push(e2) : (this.bytesWritten += e2.data.length, i.prototype.push.call(this, { data: e2.data, meta: { currentFile: this.currentFile, percent: r2 ? (t2 + 100 * (r2 - n2 - 1)) / r2 : 100 } })); - }, s.prototype.openedSource = function(e2) { - this.currentSourceOffset = this.bytesWritten, this.currentFile = e2.file.name; - var t2 = this.streamFiles && !e2.file.dir; - if (t2) { - var r2 = n(e2, t2, false, this.currentSourceOffset, this.zipPlatform, this.encodeFileName); - this.push({ data: r2.fileRecord, meta: { percent: 0 } }); - } else this.accumulate = true; - }, s.prototype.closedSource = function(e2) { - this.accumulate = false; - var t2 = this.streamFiles && !e2.file.dir, r2 = n(e2, t2, true, this.currentSourceOffset, this.zipPlatform, this.encodeFileName); - if (this.dirRecords.push(r2.dirRecord), t2) this.push({ data: (function(e3) { - return R.DATA_DESCRIPTOR + A(e3.crc32, 4) + A(e3.compressedSize, 4) + A(e3.uncompressedSize, 4); - })(e2), meta: { percent: 100 } }); - else for (this.push({ data: r2.fileRecord, meta: { percent: 0 } }); this.contentBuffer.length; ) this.push(this.contentBuffer.shift()); - this.currentFile = null; - }, s.prototype.flush = function() { - for (var e2 = this.bytesWritten, t2 = 0; t2 < this.dirRecords.length; t2++) this.push({ data: this.dirRecords[t2], meta: { percent: 100 } }); - var r2 = this.bytesWritten - e2, n2 = (function(e3, t3, r3, n3, i2) { - var s2 = I.transformTo("string", i2(n3)); - return R.CENTRAL_DIRECTORY_END + "\0\0\0\0" + A(e3, 2) + A(e3, 2) + A(t3, 4) + A(r3, 4) + A(s2.length, 2) + s2; - })(this.dirRecords.length, r2, e2, this.zipComment, this.encodeFileName); - this.push({ data: n2, meta: { percent: 100 } }); - }, s.prototype.prepareNextSource = function() { - this.previous = this._sources.shift(), this.openedSource(this.previous.streamInfo), this.isPaused ? this.previous.pause() : this.previous.resume(); - }, s.prototype.registerPrevious = function(e2) { - this._sources.push(e2); - var t2 = this; - return e2.on("data", function(e3) { - t2.processChunk(e3); - }), e2.on("end", function() { - t2.closedSource(t2.previous.streamInfo), t2._sources.length ? t2.prepareNextSource() : t2.end(); - }), e2.on("error", function(e3) { - t2.error(e3); - }), this; - }, s.prototype.resume = function() { - return !!i.prototype.resume.call(this) && (!this.previous && this._sources.length ? (this.prepareNextSource(), true) : this.previous || this._sources.length || this.generatedError ? void 0 : (this.end(), true)); - }, s.prototype.error = function(e2) { - var t2 = this._sources; - if (!i.prototype.error.call(this, e2)) return false; - for (var r2 = 0; r2 < t2.length; r2++) try { - t2[r2].error(e2); - } catch (e3) { - } - return true; - }, s.prototype.lock = function() { - i.prototype.lock.call(this); - for (var e2 = this._sources, t2 = 0; t2 < e2.length; t2++) e2[t2].lock(); - }, t.exports = s; - }, { "../crc32": 4, "../signature": 23, "../stream/GenericWorker": 28, "../utf8": 31, "../utils": 32 }], 9: [function(e, t, r) { - "use strict"; - var u = e("../compressions"), n = e("./ZipFileWorker"); - r.generateWorker = function(e2, a, t2) { - var o = new n(a.streamFiles, t2, a.platform, a.encodeFileName), h = 0; - try { - e2.forEach(function(e3, t3) { - h++; - var r2 = (function(e4, t4) { - var r3 = e4 || t4, n3 = u[r3]; - if (!n3) throw new Error(r3 + " is not a valid compression method !"); - return n3; - })(t3.options.compression, a.compression), n2 = t3.options.compressionOptions || a.compressionOptions || {}, i = t3.dir, s = t3.date; - t3._compressWorker(r2, n2).withStreamInfo("file", { name: e3, dir: i, date: s, comment: t3.comment || "", unixPermissions: t3.unixPermissions, dosPermissions: t3.dosPermissions }).pipe(o); - }), o.entriesCount = h; - } catch (e3) { - o.error(e3); - } - return o; - }; - }, { "../compressions": 3, "./ZipFileWorker": 8 }], 10: [function(e, t, r) { - "use strict"; - function n() { - if (!(this instanceof n)) return new n(); - if (arguments.length) throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide."); - this.files = /* @__PURE__ */ Object.create(null), this.comment = null, this.root = "", this.clone = function() { - var e2 = new n(); - for (var t2 in this) "function" != typeof this[t2] && (e2[t2] = this[t2]); - return e2; - }; - } - (n.prototype = e("./object")).loadAsync = e("./load"), n.support = e("./support"), n.defaults = e("./defaults"), n.version = "3.10.1", n.loadAsync = function(e2, t2) { - return new n().loadAsync(e2, t2); - }, n.external = e("./external"), t.exports = n; - }, { "./defaults": 5, "./external": 6, "./load": 11, "./object": 15, "./support": 30 }], 11: [function(e, t, r) { - "use strict"; - var u = e("./utils"), i = e("./external"), n = e("./utf8"), s = e("./zipEntries"), a = e("./stream/Crc32Probe"), l = e("./nodejsUtils"); - function f(n2) { - return new i.Promise(function(e2, t2) { - var r2 = n2.decompressed.getContentWorker().pipe(new a()); - r2.on("error", function(e3) { - t2(e3); - }).on("end", function() { - r2.streamInfo.crc32 !== n2.decompressed.crc32 ? t2(new Error("Corrupted zip : CRC32 mismatch")) : e2(); - }).resume(); - }); - } - t.exports = function(e2, o) { - var h = this; - return o = u.extend(o || {}, { base64: false, checkCRC32: false, optimizedBinaryString: false, createFolders: false, decodeFileName: n.utf8decode }), l.isNode && l.isStream(e2) ? i.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file.")) : u.prepareContent("the loaded zip file", e2, true, o.optimizedBinaryString, o.base64).then(function(e3) { - var t2 = new s(o); - return t2.load(e3), t2; - }).then(function(e3) { - var t2 = [i.Promise.resolve(e3)], r2 = e3.files; - if (o.checkCRC32) for (var n2 = 0; n2 < r2.length; n2++) t2.push(f(r2[n2])); - return i.Promise.all(t2); - }).then(function(e3) { - for (var t2 = e3.shift(), r2 = t2.files, n2 = 0; n2 < r2.length; n2++) { - var i2 = r2[n2], s2 = i2.fileNameStr, a2 = u.resolve(i2.fileNameStr); - h.file(a2, i2.decompressed, { binary: true, optimizedBinaryString: true, date: i2.date, dir: i2.dir, comment: i2.fileCommentStr.length ? i2.fileCommentStr : null, unixPermissions: i2.unixPermissions, dosPermissions: i2.dosPermissions, createFolders: o.createFolders }), i2.dir || (h.file(a2).unsafeOriginalName = s2); - } - return t2.zipComment.length && (h.comment = t2.zipComment), h; - }); - }; - }, { "./external": 6, "./nodejsUtils": 14, "./stream/Crc32Probe": 25, "./utf8": 31, "./utils": 32, "./zipEntries": 33 }], 12: [function(e, t, r) { - "use strict"; - var n = e("../utils"), i = e("../stream/GenericWorker"); - function s(e2, t2) { - i.call(this, "Nodejs stream input adapter for " + e2), this._upstreamEnded = false, this._bindStream(t2); - } - n.inherits(s, i), s.prototype._bindStream = function(e2) { - var t2 = this; - (this._stream = e2).pause(), e2.on("data", function(e3) { - t2.push({ data: e3, meta: { percent: 0 } }); - }).on("error", function(e3) { - t2.isPaused ? this.generatedError = e3 : t2.error(e3); - }).on("end", function() { - t2.isPaused ? t2._upstreamEnded = true : t2.end(); - }); - }, s.prototype.pause = function() { - return !!i.prototype.pause.call(this) && (this._stream.pause(), true); - }, s.prototype.resume = function() { - return !!i.prototype.resume.call(this) && (this._upstreamEnded ? this.end() : this._stream.resume(), true); - }, t.exports = s; - }, { "../stream/GenericWorker": 28, "../utils": 32 }], 13: [function(e, t, r) { - "use strict"; - var i = e("readable-stream").Readable; - function n(e2, t2, r2) { - i.call(this, t2), this._helper = e2; - var n2 = this; - e2.on("data", function(e3, t3) { - n2.push(e3) || n2._helper.pause(), r2 && r2(t3); - }).on("error", function(e3) { - n2.emit("error", e3); - }).on("end", function() { - n2.push(null); - }); - } - e("../utils").inherits(n, i), n.prototype._read = function() { - this._helper.resume(); - }, t.exports = n; - }, { "../utils": 32, "readable-stream": 16 }], 14: [function(e, t, r) { - "use strict"; - t.exports = { isNode: "undefined" != typeof Buffer, newBufferFrom: function(e2, t2) { - if (Buffer.from && Buffer.from !== Uint8Array.from) return Buffer.from(e2, t2); - if ("number" == typeof e2) throw new Error('The "data" argument must not be a number'); - return new Buffer(e2, t2); - }, allocBuffer: function(e2) { - if (Buffer.alloc) return Buffer.alloc(e2); - var t2 = new Buffer(e2); - return t2.fill(0), t2; - }, isBuffer: function(e2) { - return Buffer.isBuffer(e2); - }, isStream: function(e2) { - return e2 && "function" == typeof e2.on && "function" == typeof e2.pause && "function" == typeof e2.resume; - } }; - }, {}], 15: [function(e, t, r) { - "use strict"; - function s(e2, t2, r2) { - var n2, i2 = u.getTypeOf(t2), s2 = u.extend(r2 || {}, f); - s2.date = s2.date || /* @__PURE__ */ new Date(), null !== s2.compression && (s2.compression = s2.compression.toUpperCase()), "string" == typeof s2.unixPermissions && (s2.unixPermissions = parseInt(s2.unixPermissions, 8)), s2.unixPermissions && 16384 & s2.unixPermissions && (s2.dir = true), s2.dosPermissions && 16 & s2.dosPermissions && (s2.dir = true), s2.dir && (e2 = g(e2)), s2.createFolders && (n2 = _(e2)) && b.call(this, n2, true); - var a2 = "string" === i2 && false === s2.binary && false === s2.base64; - r2 && void 0 !== r2.binary || (s2.binary = !a2), (t2 instanceof c && 0 === t2.uncompressedSize || s2.dir || !t2 || 0 === t2.length) && (s2.base64 = false, s2.binary = true, t2 = "", s2.compression = "STORE", i2 = "string"); - var o2 = null; - o2 = t2 instanceof c || t2 instanceof l ? t2 : p.isNode && p.isStream(t2) ? new m(e2, t2) : u.prepareContent(e2, t2, s2.binary, s2.optimizedBinaryString, s2.base64); - var h2 = new d(e2, o2, s2); - this.files[e2] = h2; - } - var i = e("./utf8"), u = e("./utils"), l = e("./stream/GenericWorker"), a = e("./stream/StreamHelper"), f = e("./defaults"), c = e("./compressedObject"), d = e("./zipObject"), o = e("./generate"), p = e("./nodejsUtils"), m = e("./nodejs/NodejsStreamInputAdapter"), _ = function(e2) { - "/" === e2.slice(-1) && (e2 = e2.substring(0, e2.length - 1)); - var t2 = e2.lastIndexOf("/"); - return 0 < t2 ? e2.substring(0, t2) : ""; - }, g = function(e2) { - return "/" !== e2.slice(-1) && (e2 += "/"), e2; - }, b = function(e2, t2) { - return t2 = void 0 !== t2 ? t2 : f.createFolders, e2 = g(e2), this.files[e2] || s.call(this, e2, null, { dir: true, createFolders: t2 }), this.files[e2]; - }; - function h(e2) { - return "[object RegExp]" === Object.prototype.toString.call(e2); - } - var n = { load: function() { - throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); - }, forEach: function(e2) { - var t2, r2, n2; - for (t2 in this.files) n2 = this.files[t2], (r2 = t2.slice(this.root.length, t2.length)) && t2.slice(0, this.root.length) === this.root && e2(r2, n2); - }, filter: function(r2) { - var n2 = []; - return this.forEach(function(e2, t2) { - r2(e2, t2) && n2.push(t2); - }), n2; - }, file: function(e2, t2, r2) { - if (1 !== arguments.length) return e2 = this.root + e2, s.call(this, e2, t2, r2), this; - if (h(e2)) { - var n2 = e2; - return this.filter(function(e3, t3) { - return !t3.dir && n2.test(e3); - }); - } - var i2 = this.files[this.root + e2]; - return i2 && !i2.dir ? i2 : null; - }, folder: function(r2) { - if (!r2) return this; - if (h(r2)) return this.filter(function(e3, t3) { - return t3.dir && r2.test(e3); - }); - var e2 = this.root + r2, t2 = b.call(this, e2), n2 = this.clone(); - return n2.root = t2.name, n2; - }, remove: function(r2) { - r2 = this.root + r2; - var e2 = this.files[r2]; - if (e2 || ("/" !== r2.slice(-1) && (r2 += "/"), e2 = this.files[r2]), e2 && !e2.dir) delete this.files[r2]; - else for (var t2 = this.filter(function(e3, t3) { - return t3.name.slice(0, r2.length) === r2; - }), n2 = 0; n2 < t2.length; n2++) delete this.files[t2[n2].name]; - return this; - }, generate: function() { - throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); - }, generateInternalStream: function(e2) { - var t2, r2 = {}; - try { - if ((r2 = u.extend(e2 || {}, { streamFiles: false, compression: "STORE", compressionOptions: null, type: "", platform: "DOS", comment: null, mimeType: "application/zip", encodeFileName: i.utf8encode })).type = r2.type.toLowerCase(), r2.compression = r2.compression.toUpperCase(), "binarystring" === r2.type && (r2.type = "string"), !r2.type) throw new Error("No output type specified."); - u.checkSupport(r2.type), "darwin" !== r2.platform && "freebsd" !== r2.platform && "linux" !== r2.platform && "sunos" !== r2.platform || (r2.platform = "UNIX"), "win32" === r2.platform && (r2.platform = "DOS"); - var n2 = r2.comment || this.comment || ""; - t2 = o.generateWorker(this, r2, n2); - } catch (e3) { - (t2 = new l("error")).error(e3); - } - return new a(t2, r2.type || "string", r2.mimeType); - }, generateAsync: function(e2, t2) { - return this.generateInternalStream(e2).accumulate(t2); - }, generateNodeStream: function(e2, t2) { - return (e2 = e2 || {}).type || (e2.type = "nodebuffer"), this.generateInternalStream(e2).toNodejsStream(t2); - } }; - t.exports = n; - }, { "./compressedObject": 2, "./defaults": 5, "./generate": 9, "./nodejs/NodejsStreamInputAdapter": 12, "./nodejsUtils": 14, "./stream/GenericWorker": 28, "./stream/StreamHelper": 29, "./utf8": 31, "./utils": 32, "./zipObject": 35 }], 16: [function(e, t, r) { - "use strict"; - t.exports = e("stream"); - }, { stream: void 0 }], 17: [function(e, t, r) { - "use strict"; - var n = e("./DataReader"); - function i(e2) { - n.call(this, e2); - for (var t2 = 0; t2 < this.data.length; t2++) e2[t2] = 255 & e2[t2]; - } - e("../utils").inherits(i, n), i.prototype.byteAt = function(e2) { - return this.data[this.zero + e2]; - }, i.prototype.lastIndexOfSignature = function(e2) { - for (var t2 = e2.charCodeAt(0), r2 = e2.charCodeAt(1), n2 = e2.charCodeAt(2), i2 = e2.charCodeAt(3), s = this.length - 4; 0 <= s; --s) if (this.data[s] === t2 && this.data[s + 1] === r2 && this.data[s + 2] === n2 && this.data[s + 3] === i2) return s - this.zero; - return -1; - }, i.prototype.readAndCheckSignature = function(e2) { - var t2 = e2.charCodeAt(0), r2 = e2.charCodeAt(1), n2 = e2.charCodeAt(2), i2 = e2.charCodeAt(3), s = this.readData(4); - return t2 === s[0] && r2 === s[1] && n2 === s[2] && i2 === s[3]; - }, i.prototype.readData = function(e2) { - if (this.checkOffset(e2), 0 === e2) return []; - var t2 = this.data.slice(this.zero + this.index, this.zero + this.index + e2); - return this.index += e2, t2; - }, t.exports = i; - }, { "../utils": 32, "./DataReader": 18 }], 18: [function(e, t, r) { - "use strict"; - var n = e("../utils"); - function i(e2) { - this.data = e2, this.length = e2.length, this.index = 0, this.zero = 0; - } - i.prototype = { checkOffset: function(e2) { - this.checkIndex(this.index + e2); - }, checkIndex: function(e2) { - if (this.length < this.zero + e2 || e2 < 0) throw new Error("End of data reached (data length = " + this.length + ", asked index = " + e2 + "). Corrupted zip ?"); - }, setIndex: function(e2) { - this.checkIndex(e2), this.index = e2; - }, skip: function(e2) { - this.setIndex(this.index + e2); - }, byteAt: function() { - }, readInt: function(e2) { - var t2, r2 = 0; - for (this.checkOffset(e2), t2 = this.index + e2 - 1; t2 >= this.index; t2--) r2 = (r2 << 8) + this.byteAt(t2); - return this.index += e2, r2; - }, readString: function(e2) { - return n.transformTo("string", this.readData(e2)); - }, readData: function() { - }, lastIndexOfSignature: function() { - }, readAndCheckSignature: function() { - }, readDate: function() { - var e2 = this.readInt(4); - return new Date(Date.UTC(1980 + (e2 >> 25 & 127), (e2 >> 21 & 15) - 1, e2 >> 16 & 31, e2 >> 11 & 31, e2 >> 5 & 63, (31 & e2) << 1)); - } }, t.exports = i; - }, { "../utils": 32 }], 19: [function(e, t, r) { - "use strict"; - var n = e("./Uint8ArrayReader"); - function i(e2) { - n.call(this, e2); - } - e("../utils").inherits(i, n), i.prototype.readData = function(e2) { - this.checkOffset(e2); - var t2 = this.data.slice(this.zero + this.index, this.zero + this.index + e2); - return this.index += e2, t2; - }, t.exports = i; - }, { "../utils": 32, "./Uint8ArrayReader": 21 }], 20: [function(e, t, r) { - "use strict"; - var n = e("./DataReader"); - function i(e2) { - n.call(this, e2); - } - e("../utils").inherits(i, n), i.prototype.byteAt = function(e2) { - return this.data.charCodeAt(this.zero + e2); - }, i.prototype.lastIndexOfSignature = function(e2) { - return this.data.lastIndexOf(e2) - this.zero; - }, i.prototype.readAndCheckSignature = function(e2) { - return e2 === this.readData(4); - }, i.prototype.readData = function(e2) { - this.checkOffset(e2); - var t2 = this.data.slice(this.zero + this.index, this.zero + this.index + e2); - return this.index += e2, t2; - }, t.exports = i; - }, { "../utils": 32, "./DataReader": 18 }], 21: [function(e, t, r) { - "use strict"; - var n = e("./ArrayReader"); - function i(e2) { - n.call(this, e2); - } - e("../utils").inherits(i, n), i.prototype.readData = function(e2) { - if (this.checkOffset(e2), 0 === e2) return new Uint8Array(0); - var t2 = this.data.subarray(this.zero + this.index, this.zero + this.index + e2); - return this.index += e2, t2; - }, t.exports = i; - }, { "../utils": 32, "./ArrayReader": 17 }], 22: [function(e, t, r) { - "use strict"; - var n = e("../utils"), i = e("../support"), s = e("./ArrayReader"), a = e("./StringReader"), o = e("./NodeBufferReader"), h = e("./Uint8ArrayReader"); - t.exports = function(e2) { - var t2 = n.getTypeOf(e2); - return n.checkSupport(t2), "string" !== t2 || i.uint8array ? "nodebuffer" === t2 ? new o(e2) : i.uint8array ? new h(n.transformTo("uint8array", e2)) : new s(n.transformTo("array", e2)) : new a(e2); - }; - }, { "../support": 30, "../utils": 32, "./ArrayReader": 17, "./NodeBufferReader": 19, "./StringReader": 20, "./Uint8ArrayReader": 21 }], 23: [function(e, t, r) { - "use strict"; - r.LOCAL_FILE_HEADER = "PK", r.CENTRAL_FILE_HEADER = "PK", r.CENTRAL_DIRECTORY_END = "PK", r.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x07", r.ZIP64_CENTRAL_DIRECTORY_END = "PK", r.DATA_DESCRIPTOR = "PK\x07\b"; - }, {}], 24: [function(e, t, r) { - "use strict"; - var n = e("./GenericWorker"), i = e("../utils"); - function s(e2) { - n.call(this, "ConvertWorker to " + e2), this.destType = e2; - } - i.inherits(s, n), s.prototype.processChunk = function(e2) { - this.push({ data: i.transformTo(this.destType, e2.data), meta: e2.meta }); - }, t.exports = s; - }, { "../utils": 32, "./GenericWorker": 28 }], 25: [function(e, t, r) { - "use strict"; - var n = e("./GenericWorker"), i = e("../crc32"); - function s() { - n.call(this, "Crc32Probe"), this.withStreamInfo("crc32", 0); - } - e("../utils").inherits(s, n), s.prototype.processChunk = function(e2) { - this.streamInfo.crc32 = i(e2.data, this.streamInfo.crc32 || 0), this.push(e2); - }, t.exports = s; - }, { "../crc32": 4, "../utils": 32, "./GenericWorker": 28 }], 26: [function(e, t, r) { - "use strict"; - var n = e("../utils"), i = e("./GenericWorker"); - function s(e2) { - i.call(this, "DataLengthProbe for " + e2), this.propName = e2, this.withStreamInfo(e2, 0); - } - n.inherits(s, i), s.prototype.processChunk = function(e2) { - if (e2) { - var t2 = this.streamInfo[this.propName] || 0; - this.streamInfo[this.propName] = t2 + e2.data.length; - } - i.prototype.processChunk.call(this, e2); - }, t.exports = s; - }, { "../utils": 32, "./GenericWorker": 28 }], 27: [function(e, t, r) { - "use strict"; - var n = e("../utils"), i = e("./GenericWorker"); - function s(e2) { - i.call(this, "DataWorker"); - var t2 = this; - this.dataIsReady = false, this.index = 0, this.max = 0, this.data = null, this.type = "", this._tickScheduled = false, e2.then(function(e3) { - t2.dataIsReady = true, t2.data = e3, t2.max = e3 && e3.length || 0, t2.type = n.getTypeOf(e3), t2.isPaused || t2._tickAndRepeat(); - }, function(e3) { - t2.error(e3); - }); - } - n.inherits(s, i), s.prototype.cleanUp = function() { - i.prototype.cleanUp.call(this), this.data = null; - }, s.prototype.resume = function() { - return !!i.prototype.resume.call(this) && (!this._tickScheduled && this.dataIsReady && (this._tickScheduled = true, n.delay(this._tickAndRepeat, [], this)), true); - }, s.prototype._tickAndRepeat = function() { - this._tickScheduled = false, this.isPaused || this.isFinished || (this._tick(), this.isFinished || (n.delay(this._tickAndRepeat, [], this), this._tickScheduled = true)); - }, s.prototype._tick = function() { - if (this.isPaused || this.isFinished) return false; - var e2 = null, t2 = Math.min(this.max, this.index + 16384); - if (this.index >= this.max) return this.end(); - switch (this.type) { - case "string": - e2 = this.data.substring(this.index, t2); - break; - case "uint8array": - e2 = this.data.subarray(this.index, t2); - break; - case "array": - case "nodebuffer": - e2 = this.data.slice(this.index, t2); - } - return this.index = t2, this.push({ data: e2, meta: { percent: this.max ? this.index / this.max * 100 : 0 } }); - }, t.exports = s; - }, { "../utils": 32, "./GenericWorker": 28 }], 28: [function(e, t, r) { - "use strict"; - function n(e2) { - this.name = e2 || "default", this.streamInfo = {}, this.generatedError = null, this.extraStreamInfo = {}, this.isPaused = true, this.isFinished = false, this.isLocked = false, this._listeners = { data: [], end: [], error: [] }, this.previous = null; - } - n.prototype = { push: function(e2) { - this.emit("data", e2); - }, end: function() { - if (this.isFinished) return false; - this.flush(); - try { - this.emit("end"), this.cleanUp(), this.isFinished = true; - } catch (e2) { - this.emit("error", e2); - } - return true; - }, error: function(e2) { - return !this.isFinished && (this.isPaused ? this.generatedError = e2 : (this.isFinished = true, this.emit("error", e2), this.previous && this.previous.error(e2), this.cleanUp()), true); - }, on: function(e2, t2) { - return this._listeners[e2].push(t2), this; - }, cleanUp: function() { - this.streamInfo = this.generatedError = this.extraStreamInfo = null, this._listeners = []; - }, emit: function(e2, t2) { - if (this._listeners[e2]) for (var r2 = 0; r2 < this._listeners[e2].length; r2++) this._listeners[e2][r2].call(this, t2); - }, pipe: function(e2) { - return e2.registerPrevious(this); - }, registerPrevious: function(e2) { - if (this.isLocked) throw new Error("The stream '" + this + "' has already been used."); - this.streamInfo = e2.streamInfo, this.mergeStreamInfo(), this.previous = e2; - var t2 = this; - return e2.on("data", function(e3) { - t2.processChunk(e3); - }), e2.on("end", function() { - t2.end(); - }), e2.on("error", function(e3) { - t2.error(e3); - }), this; - }, pause: function() { - return !this.isPaused && !this.isFinished && (this.isPaused = true, this.previous && this.previous.pause(), true); - }, resume: function() { - if (!this.isPaused || this.isFinished) return false; - var e2 = this.isPaused = false; - return this.generatedError && (this.error(this.generatedError), e2 = true), this.previous && this.previous.resume(), !e2; - }, flush: function() { - }, processChunk: function(e2) { - this.push(e2); - }, withStreamInfo: function(e2, t2) { - return this.extraStreamInfo[e2] = t2, this.mergeStreamInfo(), this; - }, mergeStreamInfo: function() { - for (var e2 in this.extraStreamInfo) Object.prototype.hasOwnProperty.call(this.extraStreamInfo, e2) && (this.streamInfo[e2] = this.extraStreamInfo[e2]); - }, lock: function() { - if (this.isLocked) throw new Error("The stream '" + this + "' has already been used."); - this.isLocked = true, this.previous && this.previous.lock(); - }, toString: function() { - var e2 = "Worker " + this.name; - return this.previous ? this.previous + " -> " + e2 : e2; - } }, t.exports = n; - }, {}], 29: [function(e, t, r) { - "use strict"; - var h = e("../utils"), i = e("./ConvertWorker"), s = e("./GenericWorker"), u = e("../base64"), n = e("../support"), a = e("../external"), o = null; - if (n.nodestream) try { - o = e("../nodejs/NodejsStreamOutputAdapter"); - } catch (e2) { - } - function l(e2, o2) { - return new a.Promise(function(t2, r2) { - var n2 = [], i2 = e2._internalType, s2 = e2._outputType, a2 = e2._mimeType; - e2.on("data", function(e3, t3) { - n2.push(e3), o2 && o2(t3); - }).on("error", function(e3) { - n2 = [], r2(e3); - }).on("end", function() { - try { - var e3 = (function(e4, t3, r3) { - switch (e4) { - case "blob": - return h.newBlob(h.transformTo("arraybuffer", t3), r3); - case "base64": - return u.encode(t3); - default: - return h.transformTo(e4, t3); - } - })(s2, (function(e4, t3) { - var r3, n3 = 0, i3 = null, s3 = 0; - for (r3 = 0; r3 < t3.length; r3++) s3 += t3[r3].length; - switch (e4) { - case "string": - return t3.join(""); - case "array": - return Array.prototype.concat.apply([], t3); - case "uint8array": - for (i3 = new Uint8Array(s3), r3 = 0; r3 < t3.length; r3++) i3.set(t3[r3], n3), n3 += t3[r3].length; - return i3; - case "nodebuffer": - return Buffer.concat(t3); - default: - throw new Error("concat : unsupported type '" + e4 + "'"); - } - })(i2, n2), a2); - t2(e3); - } catch (e4) { - r2(e4); - } - n2 = []; - }).resume(); - }); - } - function f(e2, t2, r2) { - var n2 = t2; - switch (t2) { - case "blob": - case "arraybuffer": - n2 = "uint8array"; - break; - case "base64": - n2 = "string"; - } - try { - this._internalType = n2, this._outputType = t2, this._mimeType = r2, h.checkSupport(n2), this._worker = e2.pipe(new i(n2)), e2.lock(); - } catch (e3) { - this._worker = new s("error"), this._worker.error(e3); - } - } - f.prototype = { accumulate: function(e2) { - return l(this, e2); - }, on: function(e2, t2) { - var r2 = this; - return "data" === e2 ? this._worker.on(e2, function(e3) { - t2.call(r2, e3.data, e3.meta); - }) : this._worker.on(e2, function() { - h.delay(t2, arguments, r2); - }), this; - }, resume: function() { - return h.delay(this._worker.resume, [], this._worker), this; - }, pause: function() { - return this._worker.pause(), this; - }, toNodejsStream: function(e2) { - if (h.checkSupport("nodestream"), "nodebuffer" !== this._outputType) throw new Error(this._outputType + " is not supported by this method"); - return new o(this, { objectMode: "nodebuffer" !== this._outputType }, e2); - } }, t.exports = f; - }, { "../base64": 1, "../external": 6, "../nodejs/NodejsStreamOutputAdapter": 13, "../support": 30, "../utils": 32, "./ConvertWorker": 24, "./GenericWorker": 28 }], 30: [function(e, t, r) { - "use strict"; - if (r.base64 = true, r.array = true, r.string = true, r.arraybuffer = "undefined" != typeof ArrayBuffer && "undefined" != typeof Uint8Array, r.nodebuffer = "undefined" != typeof Buffer, r.uint8array = "undefined" != typeof Uint8Array, "undefined" == typeof ArrayBuffer) r.blob = false; - else { - var n = new ArrayBuffer(0); - try { - r.blob = 0 === new Blob([n], { type: "application/zip" }).size; - } catch (e2) { - try { - var i = new (self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder)(); - i.append(n), r.blob = 0 === i.getBlob("application/zip").size; - } catch (e3) { - r.blob = false; - } - } - } - try { - r.nodestream = !!e("readable-stream").Readable; - } catch (e2) { - r.nodestream = false; - } - }, { "readable-stream": 16 }], 31: [function(e, t, s) { - "use strict"; - for (var o = e("./utils"), h = e("./support"), r = e("./nodejsUtils"), n = e("./stream/GenericWorker"), u = new Array(256), i = 0; i < 256; i++) u[i] = 252 <= i ? 6 : 248 <= i ? 5 : 240 <= i ? 4 : 224 <= i ? 3 : 192 <= i ? 2 : 1; - u[254] = u[254] = 1; - function a() { - n.call(this, "utf-8 decode"), this.leftOver = null; - } - function l() { - n.call(this, "utf-8 encode"); - } - s.utf8encode = function(e2) { - return h.nodebuffer ? r.newBufferFrom(e2, "utf-8") : (function(e3) { - var t2, r2, n2, i2, s2, a2 = e3.length, o2 = 0; - for (i2 = 0; i2 < a2; i2++) 55296 == (64512 & (r2 = e3.charCodeAt(i2))) && i2 + 1 < a2 && 56320 == (64512 & (n2 = e3.charCodeAt(i2 + 1))) && (r2 = 65536 + (r2 - 55296 << 10) + (n2 - 56320), i2++), o2 += r2 < 128 ? 1 : r2 < 2048 ? 2 : r2 < 65536 ? 3 : 4; - for (t2 = h.uint8array ? new Uint8Array(o2) : new Array(o2), i2 = s2 = 0; s2 < o2; i2++) 55296 == (64512 & (r2 = e3.charCodeAt(i2))) && i2 + 1 < a2 && 56320 == (64512 & (n2 = e3.charCodeAt(i2 + 1))) && (r2 = 65536 + (r2 - 55296 << 10) + (n2 - 56320), i2++), r2 < 128 ? t2[s2++] = r2 : (r2 < 2048 ? t2[s2++] = 192 | r2 >>> 6 : (r2 < 65536 ? t2[s2++] = 224 | r2 >>> 12 : (t2[s2++] = 240 | r2 >>> 18, t2[s2++] = 128 | r2 >>> 12 & 63), t2[s2++] = 128 | r2 >>> 6 & 63), t2[s2++] = 128 | 63 & r2); - return t2; - })(e2); - }, s.utf8decode = function(e2) { - return h.nodebuffer ? o.transformTo("nodebuffer", e2).toString("utf-8") : (function(e3) { - var t2, r2, n2, i2, s2 = e3.length, a2 = new Array(2 * s2); - for (t2 = r2 = 0; t2 < s2; ) if ((n2 = e3[t2++]) < 128) a2[r2++] = n2; - else if (4 < (i2 = u[n2])) a2[r2++] = 65533, t2 += i2 - 1; - else { - for (n2 &= 2 === i2 ? 31 : 3 === i2 ? 15 : 7; 1 < i2 && t2 < s2; ) n2 = n2 << 6 | 63 & e3[t2++], i2--; - 1 < i2 ? a2[r2++] = 65533 : n2 < 65536 ? a2[r2++] = n2 : (n2 -= 65536, a2[r2++] = 55296 | n2 >> 10 & 1023, a2[r2++] = 56320 | 1023 & n2); - } - return a2.length !== r2 && (a2.subarray ? a2 = a2.subarray(0, r2) : a2.length = r2), o.applyFromCharCode(a2); - })(e2 = o.transformTo(h.uint8array ? "uint8array" : "array", e2)); - }, o.inherits(a, n), a.prototype.processChunk = function(e2) { - var t2 = o.transformTo(h.uint8array ? "uint8array" : "array", e2.data); - if (this.leftOver && this.leftOver.length) { - if (h.uint8array) { - var r2 = t2; - (t2 = new Uint8Array(r2.length + this.leftOver.length)).set(this.leftOver, 0), t2.set(r2, this.leftOver.length); - } else t2 = this.leftOver.concat(t2); - this.leftOver = null; - } - var n2 = (function(e3, t3) { - var r3; - for ((t3 = t3 || e3.length) > e3.length && (t3 = e3.length), r3 = t3 - 1; 0 <= r3 && 128 == (192 & e3[r3]); ) r3--; - return r3 < 0 ? t3 : 0 === r3 ? t3 : r3 + u[e3[r3]] > t3 ? r3 : t3; - })(t2), i2 = t2; - n2 !== t2.length && (h.uint8array ? (i2 = t2.subarray(0, n2), this.leftOver = t2.subarray(n2, t2.length)) : (i2 = t2.slice(0, n2), this.leftOver = t2.slice(n2, t2.length))), this.push({ data: s.utf8decode(i2), meta: e2.meta }); - }, a.prototype.flush = function() { - this.leftOver && this.leftOver.length && (this.push({ data: s.utf8decode(this.leftOver), meta: {} }), this.leftOver = null); - }, s.Utf8DecodeWorker = a, o.inherits(l, n), l.prototype.processChunk = function(e2) { - this.push({ data: s.utf8encode(e2.data), meta: e2.meta }); - }, s.Utf8EncodeWorker = l; - }, { "./nodejsUtils": 14, "./stream/GenericWorker": 28, "./support": 30, "./utils": 32 }], 32: [function(e, t, a) { - "use strict"; - var o = e("./support"), h = e("./base64"), r = e("./nodejsUtils"), u = e("./external"); - function n(e2) { - return e2; - } - function l(e2, t2) { - for (var r2 = 0; r2 < e2.length; ++r2) t2[r2] = 255 & e2.charCodeAt(r2); - return t2; - } - e("setimmediate"), a.newBlob = function(t2, r2) { - a.checkSupport("blob"); - try { - return new Blob([t2], { type: r2 }); - } catch (e2) { - try { - var n2 = new (self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder)(); - return n2.append(t2), n2.getBlob(r2); - } catch (e3) { - throw new Error("Bug : can't construct the Blob."); - } - } - }; - var i = { stringifyByChunk: function(e2, t2, r2) { - var n2 = [], i2 = 0, s2 = e2.length; - if (s2 <= r2) return String.fromCharCode.apply(null, e2); - for (; i2 < s2; ) "array" === t2 || "nodebuffer" === t2 ? n2.push(String.fromCharCode.apply(null, e2.slice(i2, Math.min(i2 + r2, s2)))) : n2.push(String.fromCharCode.apply(null, e2.subarray(i2, Math.min(i2 + r2, s2)))), i2 += r2; - return n2.join(""); - }, stringifyByChar: function(e2) { - for (var t2 = "", r2 = 0; r2 < e2.length; r2++) t2 += String.fromCharCode(e2[r2]); - return t2; - }, applyCanBeUsed: { uint8array: (function() { - try { - return o.uint8array && 1 === String.fromCharCode.apply(null, new Uint8Array(1)).length; - } catch (e2) { - return false; - } - })(), nodebuffer: (function() { - try { - return o.nodebuffer && 1 === String.fromCharCode.apply(null, r.allocBuffer(1)).length; - } catch (e2) { - return false; - } - })() } }; - function s(e2) { - var t2 = 65536, r2 = a.getTypeOf(e2), n2 = true; - if ("uint8array" === r2 ? n2 = i.applyCanBeUsed.uint8array : "nodebuffer" === r2 && (n2 = i.applyCanBeUsed.nodebuffer), n2) for (; 1 < t2; ) try { - return i.stringifyByChunk(e2, r2, t2); - } catch (e3) { - t2 = Math.floor(t2 / 2); - } - return i.stringifyByChar(e2); - } - function f(e2, t2) { - for (var r2 = 0; r2 < e2.length; r2++) t2[r2] = e2[r2]; - return t2; - } - a.applyFromCharCode = s; - var c = {}; - c.string = { string: n, array: function(e2) { - return l(e2, new Array(e2.length)); - }, arraybuffer: function(e2) { - return c.string.uint8array(e2).buffer; - }, uint8array: function(e2) { - return l(e2, new Uint8Array(e2.length)); - }, nodebuffer: function(e2) { - return l(e2, r.allocBuffer(e2.length)); - } }, c.array = { string: s, array: n, arraybuffer: function(e2) { - return new Uint8Array(e2).buffer; - }, uint8array: function(e2) { - return new Uint8Array(e2); - }, nodebuffer: function(e2) { - return r.newBufferFrom(e2); - } }, c.arraybuffer = { string: function(e2) { - return s(new Uint8Array(e2)); - }, array: function(e2) { - return f(new Uint8Array(e2), new Array(e2.byteLength)); - }, arraybuffer: n, uint8array: function(e2) { - return new Uint8Array(e2); - }, nodebuffer: function(e2) { - return r.newBufferFrom(new Uint8Array(e2)); - } }, c.uint8array = { string: s, array: function(e2) { - return f(e2, new Array(e2.length)); - }, arraybuffer: function(e2) { - return e2.buffer; - }, uint8array: n, nodebuffer: function(e2) { - return r.newBufferFrom(e2); - } }, c.nodebuffer = { string: s, array: function(e2) { - return f(e2, new Array(e2.length)); - }, arraybuffer: function(e2) { - return c.nodebuffer.uint8array(e2).buffer; - }, uint8array: function(e2) { - return f(e2, new Uint8Array(e2.length)); - }, nodebuffer: n }, a.transformTo = function(e2, t2) { - if (t2 = t2 || "", !e2) return t2; - a.checkSupport(e2); - var r2 = a.getTypeOf(t2); - return c[r2][e2](t2); - }, a.resolve = function(e2) { - for (var t2 = e2.split("/"), r2 = [], n2 = 0; n2 < t2.length; n2++) { - var i2 = t2[n2]; - "." === i2 || "" === i2 && 0 !== n2 && n2 !== t2.length - 1 || (".." === i2 ? r2.pop() : r2.push(i2)); - } - return r2.join("/"); - }, a.getTypeOf = function(e2) { - return "string" == typeof e2 ? "string" : "[object Array]" === Object.prototype.toString.call(e2) ? "array" : o.nodebuffer && r.isBuffer(e2) ? "nodebuffer" : o.uint8array && e2 instanceof Uint8Array ? "uint8array" : o.arraybuffer && e2 instanceof ArrayBuffer ? "arraybuffer" : void 0; - }, a.checkSupport = function(e2) { - if (!o[e2.toLowerCase()]) throw new Error(e2 + " is not supported by this platform"); - }, a.MAX_VALUE_16BITS = 65535, a.MAX_VALUE_32BITS = -1, a.pretty = function(e2) { - var t2, r2, n2 = ""; - for (r2 = 0; r2 < (e2 || "").length; r2++) n2 += "\\x" + ((t2 = e2.charCodeAt(r2)) < 16 ? "0" : "") + t2.toString(16).toUpperCase(); - return n2; - }, a.delay = function(e2, t2, r2) { - setImmediate(function() { - e2.apply(r2 || null, t2 || []); - }); - }, a.inherits = function(e2, t2) { - function r2() { - } - r2.prototype = t2.prototype, e2.prototype = new r2(); - }, a.extend = function() { - var e2, t2, r2 = {}; - for (e2 = 0; e2 < arguments.length; e2++) for (t2 in arguments[e2]) Object.prototype.hasOwnProperty.call(arguments[e2], t2) && void 0 === r2[t2] && (r2[t2] = arguments[e2][t2]); - return r2; - }, a.prepareContent = function(r2, e2, n2, i2, s2) { - return u.Promise.resolve(e2).then(function(n3) { - return o.blob && (n3 instanceof Blob || -1 !== ["[object File]", "[object Blob]"].indexOf(Object.prototype.toString.call(n3))) && "undefined" != typeof FileReader ? new u.Promise(function(t2, r3) { - var e3 = new FileReader(); - e3.onload = function(e4) { - t2(e4.target.result); - }, e3.onerror = function(e4) { - r3(e4.target.error); - }, e3.readAsArrayBuffer(n3); - }) : n3; - }).then(function(e3) { - var t2 = a.getTypeOf(e3); - return t2 ? ("arraybuffer" === t2 ? e3 = a.transformTo("uint8array", e3) : "string" === t2 && (s2 ? e3 = h.decode(e3) : n2 && true !== i2 && (e3 = (function(e4) { - return l(e4, o.uint8array ? new Uint8Array(e4.length) : new Array(e4.length)); - })(e3))), e3) : u.Promise.reject(new Error("Can't read the data of '" + r2 + "'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?")); - }); - }; - }, { "./base64": 1, "./external": 6, "./nodejsUtils": 14, "./support": 30, setimmediate: 54 }], 33: [function(e, t, r) { - "use strict"; - var n = e("./reader/readerFor"), i = e("./utils"), s = e("./signature"), a = e("./zipEntry"), o = e("./support"); - function h(e2) { - this.files = [], this.loadOptions = e2; - } - h.prototype = { checkSignature: function(e2) { - if (!this.reader.readAndCheckSignature(e2)) { - this.reader.index -= 4; - var t2 = this.reader.readString(4); - throw new Error("Corrupted zip or bug: unexpected signature (" + i.pretty(t2) + ", expected " + i.pretty(e2) + ")"); - } - }, isSignature: function(e2, t2) { - var r2 = this.reader.index; - this.reader.setIndex(e2); - var n2 = this.reader.readString(4) === t2; - return this.reader.setIndex(r2), n2; - }, readBlockEndOfCentral: function() { - this.diskNumber = this.reader.readInt(2), this.diskWithCentralDirStart = this.reader.readInt(2), this.centralDirRecordsOnThisDisk = this.reader.readInt(2), this.centralDirRecords = this.reader.readInt(2), this.centralDirSize = this.reader.readInt(4), this.centralDirOffset = this.reader.readInt(4), this.zipCommentLength = this.reader.readInt(2); - var e2 = this.reader.readData(this.zipCommentLength), t2 = o.uint8array ? "uint8array" : "array", r2 = i.transformTo(t2, e2); - this.zipComment = this.loadOptions.decodeFileName(r2); - }, readBlockZip64EndOfCentral: function() { - this.zip64EndOfCentralSize = this.reader.readInt(8), this.reader.skip(4), this.diskNumber = this.reader.readInt(4), this.diskWithCentralDirStart = this.reader.readInt(4), this.centralDirRecordsOnThisDisk = this.reader.readInt(8), this.centralDirRecords = this.reader.readInt(8), this.centralDirSize = this.reader.readInt(8), this.centralDirOffset = this.reader.readInt(8), this.zip64ExtensibleData = {}; - for (var e2, t2, r2, n2 = this.zip64EndOfCentralSize - 44; 0 < n2; ) e2 = this.reader.readInt(2), t2 = this.reader.readInt(4), r2 = this.reader.readData(t2), this.zip64ExtensibleData[e2] = { id: e2, length: t2, value: r2 }; - }, readBlockZip64EndOfCentralLocator: function() { - if (this.diskWithZip64CentralDirStart = this.reader.readInt(4), this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8), this.disksCount = this.reader.readInt(4), 1 < this.disksCount) throw new Error("Multi-volumes zip are not supported"); - }, readLocalFiles: function() { - var e2, t2; - for (e2 = 0; e2 < this.files.length; e2++) t2 = this.files[e2], this.reader.setIndex(t2.localHeaderOffset), this.checkSignature(s.LOCAL_FILE_HEADER), t2.readLocalPart(this.reader), t2.handleUTF8(), t2.processAttributes(); - }, readCentralDir: function() { - var e2; - for (this.reader.setIndex(this.centralDirOffset); this.reader.readAndCheckSignature(s.CENTRAL_FILE_HEADER); ) (e2 = new a({ zip64: this.zip64 }, this.loadOptions)).readCentralPart(this.reader), this.files.push(e2); - if (this.centralDirRecords !== this.files.length && 0 !== this.centralDirRecords && 0 === this.files.length) throw new Error("Corrupted zip or bug: expected " + this.centralDirRecords + " records in central dir, got " + this.files.length); - }, readEndOfCentral: function() { - var e2 = this.reader.lastIndexOfSignature(s.CENTRAL_DIRECTORY_END); - if (e2 < 0) throw !this.isSignature(0, s.LOCAL_FILE_HEADER) ? new Error("Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html") : new Error("Corrupted zip: can't find end of central directory"); - this.reader.setIndex(e2); - var t2 = e2; - if (this.checkSignature(s.CENTRAL_DIRECTORY_END), this.readBlockEndOfCentral(), this.diskNumber === i.MAX_VALUE_16BITS || this.diskWithCentralDirStart === i.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === i.MAX_VALUE_16BITS || this.centralDirRecords === i.MAX_VALUE_16BITS || this.centralDirSize === i.MAX_VALUE_32BITS || this.centralDirOffset === i.MAX_VALUE_32BITS) { - if (this.zip64 = true, (e2 = this.reader.lastIndexOfSignature(s.ZIP64_CENTRAL_DIRECTORY_LOCATOR)) < 0) throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator"); - if (this.reader.setIndex(e2), this.checkSignature(s.ZIP64_CENTRAL_DIRECTORY_LOCATOR), this.readBlockZip64EndOfCentralLocator(), !this.isSignature(this.relativeOffsetEndOfZip64CentralDir, s.ZIP64_CENTRAL_DIRECTORY_END) && (this.relativeOffsetEndOfZip64CentralDir = this.reader.lastIndexOfSignature(s.ZIP64_CENTRAL_DIRECTORY_END), this.relativeOffsetEndOfZip64CentralDir < 0)) throw new Error("Corrupted zip: can't find the ZIP64 end of central directory"); - this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir), this.checkSignature(s.ZIP64_CENTRAL_DIRECTORY_END), this.readBlockZip64EndOfCentral(); - } - var r2 = this.centralDirOffset + this.centralDirSize; - this.zip64 && (r2 += 20, r2 += 12 + this.zip64EndOfCentralSize); - var n2 = t2 - r2; - if (0 < n2) this.isSignature(t2, s.CENTRAL_FILE_HEADER) || (this.reader.zero = n2); - else if (n2 < 0) throw new Error("Corrupted zip: missing " + Math.abs(n2) + " bytes."); - }, prepareReader: function(e2) { - this.reader = n(e2); - }, load: function(e2) { - this.prepareReader(e2), this.readEndOfCentral(), this.readCentralDir(), this.readLocalFiles(); - } }, t.exports = h; - }, { "./reader/readerFor": 22, "./signature": 23, "./support": 30, "./utils": 32, "./zipEntry": 34 }], 34: [function(e, t, r) { - "use strict"; - var n = e("./reader/readerFor"), s = e("./utils"), i = e("./compressedObject"), a = e("./crc32"), o = e("./utf8"), h = e("./compressions"), u = e("./support"); - function l(e2, t2) { - this.options = e2, this.loadOptions = t2; - } - l.prototype = { isEncrypted: function() { - return 1 == (1 & this.bitFlag); - }, useUTF8: function() { - return 2048 == (2048 & this.bitFlag); - }, readLocalPart: function(e2) { - var t2, r2; - if (e2.skip(22), this.fileNameLength = e2.readInt(2), r2 = e2.readInt(2), this.fileName = e2.readData(this.fileNameLength), e2.skip(r2), -1 === this.compressedSize || -1 === this.uncompressedSize) throw new Error("Bug or corrupted zip : didn't get enough information from the central directory (compressedSize === -1 || uncompressedSize === -1)"); - if (null === (t2 = (function(e3) { - for (var t3 in h) if (Object.prototype.hasOwnProperty.call(h, t3) && h[t3].magic === e3) return h[t3]; - return null; - })(this.compressionMethod))) throw new Error("Corrupted zip : compression " + s.pretty(this.compressionMethod) + " unknown (inner file : " + s.transformTo("string", this.fileName) + ")"); - this.decompressed = new i(this.compressedSize, this.uncompressedSize, this.crc32, t2, e2.readData(this.compressedSize)); - }, readCentralPart: function(e2) { - this.versionMadeBy = e2.readInt(2), e2.skip(2), this.bitFlag = e2.readInt(2), this.compressionMethod = e2.readString(2), this.date = e2.readDate(), this.crc32 = e2.readInt(4), this.compressedSize = e2.readInt(4), this.uncompressedSize = e2.readInt(4); - var t2 = e2.readInt(2); - if (this.extraFieldsLength = e2.readInt(2), this.fileCommentLength = e2.readInt(2), this.diskNumberStart = e2.readInt(2), this.internalFileAttributes = e2.readInt(2), this.externalFileAttributes = e2.readInt(4), this.localHeaderOffset = e2.readInt(4), this.isEncrypted()) throw new Error("Encrypted zip are not supported"); - e2.skip(t2), this.readExtraFields(e2), this.parseZIP64ExtraField(e2), this.fileComment = e2.readData(this.fileCommentLength); - }, processAttributes: function() { - this.unixPermissions = null, this.dosPermissions = null; - var e2 = this.versionMadeBy >> 8; - this.dir = !!(16 & this.externalFileAttributes), 0 == e2 && (this.dosPermissions = 63 & this.externalFileAttributes), 3 == e2 && (this.unixPermissions = this.externalFileAttributes >> 16 & 65535), this.dir || "/" !== this.fileNameStr.slice(-1) || (this.dir = true); - }, parseZIP64ExtraField: function() { - if (this.extraFields[1]) { - var e2 = n(this.extraFields[1].value); - this.uncompressedSize === s.MAX_VALUE_32BITS && (this.uncompressedSize = e2.readInt(8)), this.compressedSize === s.MAX_VALUE_32BITS && (this.compressedSize = e2.readInt(8)), this.localHeaderOffset === s.MAX_VALUE_32BITS && (this.localHeaderOffset = e2.readInt(8)), this.diskNumberStart === s.MAX_VALUE_32BITS && (this.diskNumberStart = e2.readInt(4)); - } - }, readExtraFields: function(e2) { - var t2, r2, n2, i2 = e2.index + this.extraFieldsLength; - for (this.extraFields || (this.extraFields = {}); e2.index + 4 < i2; ) t2 = e2.readInt(2), r2 = e2.readInt(2), n2 = e2.readData(r2), this.extraFields[t2] = { id: t2, length: r2, value: n2 }; - e2.setIndex(i2); - }, handleUTF8: function() { - var e2 = u.uint8array ? "uint8array" : "array"; - if (this.useUTF8()) this.fileNameStr = o.utf8decode(this.fileName), this.fileCommentStr = o.utf8decode(this.fileComment); - else { - var t2 = this.findExtraFieldUnicodePath(); - if (null !== t2) this.fileNameStr = t2; - else { - var r2 = s.transformTo(e2, this.fileName); - this.fileNameStr = this.loadOptions.decodeFileName(r2); - } - var n2 = this.findExtraFieldUnicodeComment(); - if (null !== n2) this.fileCommentStr = n2; - else { - var i2 = s.transformTo(e2, this.fileComment); - this.fileCommentStr = this.loadOptions.decodeFileName(i2); - } - } - }, findExtraFieldUnicodePath: function() { - var e2 = this.extraFields[28789]; - if (e2) { - var t2 = n(e2.value); - return 1 !== t2.readInt(1) ? null : a(this.fileName) !== t2.readInt(4) ? null : o.utf8decode(t2.readData(e2.length - 5)); - } - return null; - }, findExtraFieldUnicodeComment: function() { - var e2 = this.extraFields[25461]; - if (e2) { - var t2 = n(e2.value); - return 1 !== t2.readInt(1) ? null : a(this.fileComment) !== t2.readInt(4) ? null : o.utf8decode(t2.readData(e2.length - 5)); - } - return null; - } }, t.exports = l; - }, { "./compressedObject": 2, "./compressions": 3, "./crc32": 4, "./reader/readerFor": 22, "./support": 30, "./utf8": 31, "./utils": 32 }], 35: [function(e, t, r) { - "use strict"; - function n(e2, t2, r2) { - this.name = e2, this.dir = r2.dir, this.date = r2.date, this.comment = r2.comment, this.unixPermissions = r2.unixPermissions, this.dosPermissions = r2.dosPermissions, this._data = t2, this._dataBinary = r2.binary, this.options = { compression: r2.compression, compressionOptions: r2.compressionOptions }; - } - var s = e("./stream/StreamHelper"), i = e("./stream/DataWorker"), a = e("./utf8"), o = e("./compressedObject"), h = e("./stream/GenericWorker"); - n.prototype = { internalStream: function(e2) { - var t2 = null, r2 = "string"; - try { - if (!e2) throw new Error("No output type specified."); - var n2 = "string" === (r2 = e2.toLowerCase()) || "text" === r2; - "binarystring" !== r2 && "text" !== r2 || (r2 = "string"), t2 = this._decompressWorker(); - var i2 = !this._dataBinary; - i2 && !n2 && (t2 = t2.pipe(new a.Utf8EncodeWorker())), !i2 && n2 && (t2 = t2.pipe(new a.Utf8DecodeWorker())); - } catch (e3) { - (t2 = new h("error")).error(e3); - } - return new s(t2, r2, ""); - }, async: function(e2, t2) { - return this.internalStream(e2).accumulate(t2); - }, nodeStream: function(e2, t2) { - return this.internalStream(e2 || "nodebuffer").toNodejsStream(t2); - }, _compressWorker: function(e2, t2) { - if (this._data instanceof o && this._data.compression.magic === e2.magic) return this._data.getCompressedWorker(); - var r2 = this._decompressWorker(); - return this._dataBinary || (r2 = r2.pipe(new a.Utf8EncodeWorker())), o.createWorkerFrom(r2, e2, t2); - }, _decompressWorker: function() { - return this._data instanceof o ? this._data.getContentWorker() : this._data instanceof h ? this._data : new i(this._data); - } }; - for (var u = ["asText", "asBinary", "asNodeBuffer", "asUint8Array", "asArrayBuffer"], l = function() { - throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); - }, f = 0; f < u.length; f++) n.prototype[u[f]] = l; - t.exports = n; - }, { "./compressedObject": 2, "./stream/DataWorker": 27, "./stream/GenericWorker": 28, "./stream/StreamHelper": 29, "./utf8": 31 }], 36: [function(e, l, t) { - (function(t2) { - "use strict"; - var r, n, e2 = t2.MutationObserver || t2.WebKitMutationObserver; - if (e2) { - var i = 0, s = new e2(u), a = t2.document.createTextNode(""); - s.observe(a, { characterData: true }), r = function() { - a.data = i = ++i % 2; - }; - } else if (t2.setImmediate || void 0 === t2.MessageChannel) r = "document" in t2 && "onreadystatechange" in t2.document.createElement("script") ? function() { - var e3 = t2.document.createElement("script"); - e3.onreadystatechange = function() { - u(), e3.onreadystatechange = null, e3.parentNode.removeChild(e3), e3 = null; - }, t2.document.documentElement.appendChild(e3); - } : function() { - setTimeout(u, 0); - }; - else { - var o = new t2.MessageChannel(); - o.port1.onmessage = u, r = function() { - o.port2.postMessage(0); - }; - } - var h = []; - function u() { - var e3, t3; - n = true; - for (var r2 = h.length; r2; ) { - for (t3 = h, h = [], e3 = -1; ++e3 < r2; ) t3[e3](); - r2 = h.length; - } - n = false; - } - l.exports = function(e3) { - 1 !== h.push(e3) || n || r(); - }; - }).call(this, "undefined" != typeof global ? global : "undefined" != typeof self ? self : "undefined" != typeof window ? window : {}); - }, {}], 37: [function(e, t, r) { - "use strict"; - var i = e("immediate"); - function u() { - } - var l = {}, s = ["REJECTED"], a = ["FULFILLED"], n = ["PENDING"]; - function o(e2) { - if ("function" != typeof e2) throw new TypeError("resolver must be a function"); - this.state = n, this.queue = [], this.outcome = void 0, e2 !== u && d(this, e2); - } - function h(e2, t2, r2) { - this.promise = e2, "function" == typeof t2 && (this.onFulfilled = t2, this.callFulfilled = this.otherCallFulfilled), "function" == typeof r2 && (this.onRejected = r2, this.callRejected = this.otherCallRejected); - } - function f(t2, r2, n2) { - i(function() { - var e2; - try { - e2 = r2(n2); - } catch (e3) { - return l.reject(t2, e3); - } - e2 === t2 ? l.reject(t2, new TypeError("Cannot resolve promise with itself")) : l.resolve(t2, e2); - }); - } - function c(e2) { - var t2 = e2 && e2.then; - if (e2 && ("object" == typeof e2 || "function" == typeof e2) && "function" == typeof t2) return function() { - t2.apply(e2, arguments); - }; - } - function d(t2, e2) { - var r2 = false; - function n2(e3) { - r2 || (r2 = true, l.reject(t2, e3)); - } - function i2(e3) { - r2 || (r2 = true, l.resolve(t2, e3)); - } - var s2 = p(function() { - e2(i2, n2); - }); - "error" === s2.status && n2(s2.value); - } - function p(e2, t2) { - var r2 = {}; - try { - r2.value = e2(t2), r2.status = "success"; - } catch (e3) { - r2.status = "error", r2.value = e3; - } - return r2; - } - (t.exports = o).prototype.finally = function(t2) { - if ("function" != typeof t2) return this; - var r2 = this.constructor; - return this.then(function(e2) { - return r2.resolve(t2()).then(function() { - return e2; - }); - }, function(e2) { - return r2.resolve(t2()).then(function() { - throw e2; - }); - }); - }, o.prototype.catch = function(e2) { - return this.then(null, e2); - }, o.prototype.then = function(e2, t2) { - if ("function" != typeof e2 && this.state === a || "function" != typeof t2 && this.state === s) return this; - var r2 = new this.constructor(u); - this.state !== n ? f(r2, this.state === a ? e2 : t2, this.outcome) : this.queue.push(new h(r2, e2, t2)); - return r2; - }, h.prototype.callFulfilled = function(e2) { - l.resolve(this.promise, e2); - }, h.prototype.otherCallFulfilled = function(e2) { - f(this.promise, this.onFulfilled, e2); - }, h.prototype.callRejected = function(e2) { - l.reject(this.promise, e2); - }, h.prototype.otherCallRejected = function(e2) { - f(this.promise, this.onRejected, e2); - }, l.resolve = function(e2, t2) { - var r2 = p(c, t2); - if ("error" === r2.status) return l.reject(e2, r2.value); - var n2 = r2.value; - if (n2) d(e2, n2); - else { - e2.state = a, e2.outcome = t2; - for (var i2 = -1, s2 = e2.queue.length; ++i2 < s2; ) e2.queue[i2].callFulfilled(t2); - } - return e2; - }, l.reject = function(e2, t2) { - e2.state = s, e2.outcome = t2; - for (var r2 = -1, n2 = e2.queue.length; ++r2 < n2; ) e2.queue[r2].callRejected(t2); - return e2; - }, o.resolve = function(e2) { - if (e2 instanceof this) return e2; - return l.resolve(new this(u), e2); - }, o.reject = function(e2) { - var t2 = new this(u); - return l.reject(t2, e2); - }, o.all = function(e2) { - var r2 = this; - if ("[object Array]" !== Object.prototype.toString.call(e2)) return this.reject(new TypeError("must be an array")); - var n2 = e2.length, i2 = false; - if (!n2) return this.resolve([]); - var s2 = new Array(n2), a2 = 0, t2 = -1, o2 = new this(u); - for (; ++t2 < n2; ) h2(e2[t2], t2); - return o2; - function h2(e3, t3) { - r2.resolve(e3).then(function(e4) { - s2[t3] = e4, ++a2 !== n2 || i2 || (i2 = true, l.resolve(o2, s2)); - }, function(e4) { - i2 || (i2 = true, l.reject(o2, e4)); - }); - } - }, o.race = function(e2) { - var t2 = this; - if ("[object Array]" !== Object.prototype.toString.call(e2)) return this.reject(new TypeError("must be an array")); - var r2 = e2.length, n2 = false; - if (!r2) return this.resolve([]); - var i2 = -1, s2 = new this(u); - for (; ++i2 < r2; ) a2 = e2[i2], t2.resolve(a2).then(function(e3) { - n2 || (n2 = true, l.resolve(s2, e3)); - }, function(e3) { - n2 || (n2 = true, l.reject(s2, e3)); - }); - var a2; - return s2; - }; - }, { immediate: 36 }], 38: [function(e, t, r) { - "use strict"; - var n = {}; - (0, e("./lib/utils/common").assign)(n, e("./lib/deflate"), e("./lib/inflate"), e("./lib/zlib/constants")), t.exports = n; - }, { "./lib/deflate": 39, "./lib/inflate": 40, "./lib/utils/common": 41, "./lib/zlib/constants": 44 }], 39: [function(e, t, r) { - "use strict"; - var a = e("./zlib/deflate"), o = e("./utils/common"), h = e("./utils/strings"), i = e("./zlib/messages"), s = e("./zlib/zstream"), u = Object.prototype.toString, l = 0, f = -1, c = 0, d = 8; - function p(e2) { - if (!(this instanceof p)) return new p(e2); - this.options = o.assign({ level: f, method: d, chunkSize: 16384, windowBits: 15, memLevel: 8, strategy: c, to: "" }, e2 || {}); - var t2 = this.options; - t2.raw && 0 < t2.windowBits ? t2.windowBits = -t2.windowBits : t2.gzip && 0 < t2.windowBits && t2.windowBits < 16 && (t2.windowBits += 16), this.err = 0, this.msg = "", this.ended = false, this.chunks = [], this.strm = new s(), this.strm.avail_out = 0; - var r2 = a.deflateInit2(this.strm, t2.level, t2.method, t2.windowBits, t2.memLevel, t2.strategy); - if (r2 !== l) throw new Error(i[r2]); - if (t2.header && a.deflateSetHeader(this.strm, t2.header), t2.dictionary) { - var n2; - if (n2 = "string" == typeof t2.dictionary ? h.string2buf(t2.dictionary) : "[object ArrayBuffer]" === u.call(t2.dictionary) ? new Uint8Array(t2.dictionary) : t2.dictionary, (r2 = a.deflateSetDictionary(this.strm, n2)) !== l) throw new Error(i[r2]); - this._dict_set = true; - } - } - function n(e2, t2) { - var r2 = new p(t2); - if (r2.push(e2, true), r2.err) throw r2.msg || i[r2.err]; - return r2.result; - } - p.prototype.push = function(e2, t2) { - var r2, n2, i2 = this.strm, s2 = this.options.chunkSize; - if (this.ended) return false; - n2 = t2 === ~~t2 ? t2 : true === t2 ? 4 : 0, "string" == typeof e2 ? i2.input = h.string2buf(e2) : "[object ArrayBuffer]" === u.call(e2) ? i2.input = new Uint8Array(e2) : i2.input = e2, i2.next_in = 0, i2.avail_in = i2.input.length; - do { - if (0 === i2.avail_out && (i2.output = new o.Buf8(s2), i2.next_out = 0, i2.avail_out = s2), 1 !== (r2 = a.deflate(i2, n2)) && r2 !== l) return this.onEnd(r2), !(this.ended = true); - 0 !== i2.avail_out && (0 !== i2.avail_in || 4 !== n2 && 2 !== n2) || ("string" === this.options.to ? this.onData(h.buf2binstring(o.shrinkBuf(i2.output, i2.next_out))) : this.onData(o.shrinkBuf(i2.output, i2.next_out))); - } while ((0 < i2.avail_in || 0 === i2.avail_out) && 1 !== r2); - return 4 === n2 ? (r2 = a.deflateEnd(this.strm), this.onEnd(r2), this.ended = true, r2 === l) : 2 !== n2 || (this.onEnd(l), !(i2.avail_out = 0)); - }, p.prototype.onData = function(e2) { - this.chunks.push(e2); - }, p.prototype.onEnd = function(e2) { - e2 === l && ("string" === this.options.to ? this.result = this.chunks.join("") : this.result = o.flattenChunks(this.chunks)), this.chunks = [], this.err = e2, this.msg = this.strm.msg; - }, r.Deflate = p, r.deflate = n, r.deflateRaw = function(e2, t2) { - return (t2 = t2 || {}).raw = true, n(e2, t2); - }, r.gzip = function(e2, t2) { - return (t2 = t2 || {}).gzip = true, n(e2, t2); - }; - }, { "./utils/common": 41, "./utils/strings": 42, "./zlib/deflate": 46, "./zlib/messages": 51, "./zlib/zstream": 53 }], 40: [function(e, t, r) { - "use strict"; - var c = e("./zlib/inflate"), d = e("./utils/common"), p = e("./utils/strings"), m = e("./zlib/constants"), n = e("./zlib/messages"), i = e("./zlib/zstream"), s = e("./zlib/gzheader"), _ = Object.prototype.toString; - function a(e2) { - if (!(this instanceof a)) return new a(e2); - this.options = d.assign({ chunkSize: 16384, windowBits: 0, to: "" }, e2 || {}); - var t2 = this.options; - t2.raw && 0 <= t2.windowBits && t2.windowBits < 16 && (t2.windowBits = -t2.windowBits, 0 === t2.windowBits && (t2.windowBits = -15)), !(0 <= t2.windowBits && t2.windowBits < 16) || e2 && e2.windowBits || (t2.windowBits += 32), 15 < t2.windowBits && t2.windowBits < 48 && 0 == (15 & t2.windowBits) && (t2.windowBits |= 15), this.err = 0, this.msg = "", this.ended = false, this.chunks = [], this.strm = new i(), this.strm.avail_out = 0; - var r2 = c.inflateInit2(this.strm, t2.windowBits); - if (r2 !== m.Z_OK) throw new Error(n[r2]); - this.header = new s(), c.inflateGetHeader(this.strm, this.header); - } - function o(e2, t2) { - var r2 = new a(t2); - if (r2.push(e2, true), r2.err) throw r2.msg || n[r2.err]; - return r2.result; - } - a.prototype.push = function(e2, t2) { - var r2, n2, i2, s2, a2, o2, h = this.strm, u = this.options.chunkSize, l = this.options.dictionary, f = false; - if (this.ended) return false; - n2 = t2 === ~~t2 ? t2 : true === t2 ? m.Z_FINISH : m.Z_NO_FLUSH, "string" == typeof e2 ? h.input = p.binstring2buf(e2) : "[object ArrayBuffer]" === _.call(e2) ? h.input = new Uint8Array(e2) : h.input = e2, h.next_in = 0, h.avail_in = h.input.length; - do { - if (0 === h.avail_out && (h.output = new d.Buf8(u), h.next_out = 0, h.avail_out = u), (r2 = c.inflate(h, m.Z_NO_FLUSH)) === m.Z_NEED_DICT && l && (o2 = "string" == typeof l ? p.string2buf(l) : "[object ArrayBuffer]" === _.call(l) ? new Uint8Array(l) : l, r2 = c.inflateSetDictionary(this.strm, o2)), r2 === m.Z_BUF_ERROR && true === f && (r2 = m.Z_OK, f = false), r2 !== m.Z_STREAM_END && r2 !== m.Z_OK) return this.onEnd(r2), !(this.ended = true); - h.next_out && (0 !== h.avail_out && r2 !== m.Z_STREAM_END && (0 !== h.avail_in || n2 !== m.Z_FINISH && n2 !== m.Z_SYNC_FLUSH) || ("string" === this.options.to ? (i2 = p.utf8border(h.output, h.next_out), s2 = h.next_out - i2, a2 = p.buf2string(h.output, i2), h.next_out = s2, h.avail_out = u - s2, s2 && d.arraySet(h.output, h.output, i2, s2, 0), this.onData(a2)) : this.onData(d.shrinkBuf(h.output, h.next_out)))), 0 === h.avail_in && 0 === h.avail_out && (f = true); - } while ((0 < h.avail_in || 0 === h.avail_out) && r2 !== m.Z_STREAM_END); - return r2 === m.Z_STREAM_END && (n2 = m.Z_FINISH), n2 === m.Z_FINISH ? (r2 = c.inflateEnd(this.strm), this.onEnd(r2), this.ended = true, r2 === m.Z_OK) : n2 !== m.Z_SYNC_FLUSH || (this.onEnd(m.Z_OK), !(h.avail_out = 0)); - }, a.prototype.onData = function(e2) { - this.chunks.push(e2); - }, a.prototype.onEnd = function(e2) { - e2 === m.Z_OK && ("string" === this.options.to ? this.result = this.chunks.join("") : this.result = d.flattenChunks(this.chunks)), this.chunks = [], this.err = e2, this.msg = this.strm.msg; - }, r.Inflate = a, r.inflate = o, r.inflateRaw = function(e2, t2) { - return (t2 = t2 || {}).raw = true, o(e2, t2); - }, r.ungzip = o; - }, { "./utils/common": 41, "./utils/strings": 42, "./zlib/constants": 44, "./zlib/gzheader": 47, "./zlib/inflate": 49, "./zlib/messages": 51, "./zlib/zstream": 53 }], 41: [function(e, t, r) { - "use strict"; - var n = "undefined" != typeof Uint8Array && "undefined" != typeof Uint16Array && "undefined" != typeof Int32Array; - r.assign = function(e2) { - for (var t2 = Array.prototype.slice.call(arguments, 1); t2.length; ) { - var r2 = t2.shift(); - if (r2) { - if ("object" != typeof r2) throw new TypeError(r2 + "must be non-object"); - for (var n2 in r2) r2.hasOwnProperty(n2) && (e2[n2] = r2[n2]); - } - } - return e2; - }, r.shrinkBuf = function(e2, t2) { - return e2.length === t2 ? e2 : e2.subarray ? e2.subarray(0, t2) : (e2.length = t2, e2); - }; - var i = { arraySet: function(e2, t2, r2, n2, i2) { - if (t2.subarray && e2.subarray) e2.set(t2.subarray(r2, r2 + n2), i2); - else for (var s2 = 0; s2 < n2; s2++) e2[i2 + s2] = t2[r2 + s2]; - }, flattenChunks: function(e2) { - var t2, r2, n2, i2, s2, a; - for (t2 = n2 = 0, r2 = e2.length; t2 < r2; t2++) n2 += e2[t2].length; - for (a = new Uint8Array(n2), t2 = i2 = 0, r2 = e2.length; t2 < r2; t2++) s2 = e2[t2], a.set(s2, i2), i2 += s2.length; - return a; - } }, s = { arraySet: function(e2, t2, r2, n2, i2) { - for (var s2 = 0; s2 < n2; s2++) e2[i2 + s2] = t2[r2 + s2]; - }, flattenChunks: function(e2) { - return [].concat.apply([], e2); - } }; - r.setTyped = function(e2) { - e2 ? (r.Buf8 = Uint8Array, r.Buf16 = Uint16Array, r.Buf32 = Int32Array, r.assign(r, i)) : (r.Buf8 = Array, r.Buf16 = Array, r.Buf32 = Array, r.assign(r, s)); - }, r.setTyped(n); - }, {}], 42: [function(e, t, r) { - "use strict"; - var h = e("./common"), i = true, s = true; - try { - String.fromCharCode.apply(null, [0]); - } catch (e2) { - i = false; - } - try { - String.fromCharCode.apply(null, new Uint8Array(1)); - } catch (e2) { - s = false; - } - for (var u = new h.Buf8(256), n = 0; n < 256; n++) u[n] = 252 <= n ? 6 : 248 <= n ? 5 : 240 <= n ? 4 : 224 <= n ? 3 : 192 <= n ? 2 : 1; - function l(e2, t2) { - if (t2 < 65537 && (e2.subarray && s || !e2.subarray && i)) return String.fromCharCode.apply(null, h.shrinkBuf(e2, t2)); - for (var r2 = "", n2 = 0; n2 < t2; n2++) r2 += String.fromCharCode(e2[n2]); - return r2; - } - u[254] = u[254] = 1, r.string2buf = function(e2) { - var t2, r2, n2, i2, s2, a = e2.length, o = 0; - for (i2 = 0; i2 < a; i2++) 55296 == (64512 & (r2 = e2.charCodeAt(i2))) && i2 + 1 < a && 56320 == (64512 & (n2 = e2.charCodeAt(i2 + 1))) && (r2 = 65536 + (r2 - 55296 << 10) + (n2 - 56320), i2++), o += r2 < 128 ? 1 : r2 < 2048 ? 2 : r2 < 65536 ? 3 : 4; - for (t2 = new h.Buf8(o), i2 = s2 = 0; s2 < o; i2++) 55296 == (64512 & (r2 = e2.charCodeAt(i2))) && i2 + 1 < a && 56320 == (64512 & (n2 = e2.charCodeAt(i2 + 1))) && (r2 = 65536 + (r2 - 55296 << 10) + (n2 - 56320), i2++), r2 < 128 ? t2[s2++] = r2 : (r2 < 2048 ? t2[s2++] = 192 | r2 >>> 6 : (r2 < 65536 ? t2[s2++] = 224 | r2 >>> 12 : (t2[s2++] = 240 | r2 >>> 18, t2[s2++] = 128 | r2 >>> 12 & 63), t2[s2++] = 128 | r2 >>> 6 & 63), t2[s2++] = 128 | 63 & r2); - return t2; - }, r.buf2binstring = function(e2) { - return l(e2, e2.length); - }, r.binstring2buf = function(e2) { - for (var t2 = new h.Buf8(e2.length), r2 = 0, n2 = t2.length; r2 < n2; r2++) t2[r2] = e2.charCodeAt(r2); - return t2; - }, r.buf2string = function(e2, t2) { - var r2, n2, i2, s2, a = t2 || e2.length, o = new Array(2 * a); - for (r2 = n2 = 0; r2 < a; ) if ((i2 = e2[r2++]) < 128) o[n2++] = i2; - else if (4 < (s2 = u[i2])) o[n2++] = 65533, r2 += s2 - 1; - else { - for (i2 &= 2 === s2 ? 31 : 3 === s2 ? 15 : 7; 1 < s2 && r2 < a; ) i2 = i2 << 6 | 63 & e2[r2++], s2--; - 1 < s2 ? o[n2++] = 65533 : i2 < 65536 ? o[n2++] = i2 : (i2 -= 65536, o[n2++] = 55296 | i2 >> 10 & 1023, o[n2++] = 56320 | 1023 & i2); - } - return l(o, n2); - }, r.utf8border = function(e2, t2) { - var r2; - for ((t2 = t2 || e2.length) > e2.length && (t2 = e2.length), r2 = t2 - 1; 0 <= r2 && 128 == (192 & e2[r2]); ) r2--; - return r2 < 0 ? t2 : 0 === r2 ? t2 : r2 + u[e2[r2]] > t2 ? r2 : t2; - }; - }, { "./common": 41 }], 43: [function(e, t, r) { - "use strict"; - t.exports = function(e2, t2, r2, n) { - for (var i = 65535 & e2 | 0, s = e2 >>> 16 & 65535 | 0, a = 0; 0 !== r2; ) { - for (r2 -= a = 2e3 < r2 ? 2e3 : r2; s = s + (i = i + t2[n++] | 0) | 0, --a; ) ; - i %= 65521, s %= 65521; - } - return i | s << 16 | 0; - }; - }, {}], 44: [function(e, t, r) { - "use strict"; - t.exports = { Z_NO_FLUSH: 0, Z_PARTIAL_FLUSH: 1, Z_SYNC_FLUSH: 2, Z_FULL_FLUSH: 3, Z_FINISH: 4, Z_BLOCK: 5, Z_TREES: 6, Z_OK: 0, Z_STREAM_END: 1, Z_NEED_DICT: 2, Z_ERRNO: -1, Z_STREAM_ERROR: -2, Z_DATA_ERROR: -3, Z_BUF_ERROR: -5, Z_NO_COMPRESSION: 0, Z_BEST_SPEED: 1, Z_BEST_COMPRESSION: 9, Z_DEFAULT_COMPRESSION: -1, Z_FILTERED: 1, Z_HUFFMAN_ONLY: 2, Z_RLE: 3, Z_FIXED: 4, Z_DEFAULT_STRATEGY: 0, Z_BINARY: 0, Z_TEXT: 1, Z_UNKNOWN: 2, Z_DEFLATED: 8 }; - }, {}], 45: [function(e, t, r) { - "use strict"; - var o = (function() { - for (var e2, t2 = [], r2 = 0; r2 < 256; r2++) { - e2 = r2; - for (var n = 0; n < 8; n++) e2 = 1 & e2 ? 3988292384 ^ e2 >>> 1 : e2 >>> 1; - t2[r2] = e2; - } - return t2; - })(); - t.exports = function(e2, t2, r2, n) { - var i = o, s = n + r2; - e2 ^= -1; - for (var a = n; a < s; a++) e2 = e2 >>> 8 ^ i[255 & (e2 ^ t2[a])]; - return -1 ^ e2; - }; - }, {}], 46: [function(e, t, r) { - "use strict"; - var h, c = e("../utils/common"), u = e("./trees"), d = e("./adler32"), p = e("./crc32"), n = e("./messages"), l = 0, f = 4, m = 0, _ = -2, g = -1, b = 4, i = 2, v = 8, y = 9, s = 286, a = 30, o = 19, w = 2 * s + 1, k = 15, x = 3, S = 258, z = S + x + 1, C = 42, E = 113, A = 1, I = 2, O = 3, B = 4; - function R(e2, t2) { - return e2.msg = n[t2], t2; - } - function T(e2) { - return (e2 << 1) - (4 < e2 ? 9 : 0); - } - function D(e2) { - for (var t2 = e2.length; 0 <= --t2; ) e2[t2] = 0; - } - function F(e2) { - var t2 = e2.state, r2 = t2.pending; - r2 > e2.avail_out && (r2 = e2.avail_out), 0 !== r2 && (c.arraySet(e2.output, t2.pending_buf, t2.pending_out, r2, e2.next_out), e2.next_out += r2, t2.pending_out += r2, e2.total_out += r2, e2.avail_out -= r2, t2.pending -= r2, 0 === t2.pending && (t2.pending_out = 0)); - } - function N(e2, t2) { - u._tr_flush_block(e2, 0 <= e2.block_start ? e2.block_start : -1, e2.strstart - e2.block_start, t2), e2.block_start = e2.strstart, F(e2.strm); - } - function U(e2, t2) { - e2.pending_buf[e2.pending++] = t2; - } - function P(e2, t2) { - e2.pending_buf[e2.pending++] = t2 >>> 8 & 255, e2.pending_buf[e2.pending++] = 255 & t2; - } - function L(e2, t2) { - var r2, n2, i2 = e2.max_chain_length, s2 = e2.strstart, a2 = e2.prev_length, o2 = e2.nice_match, h2 = e2.strstart > e2.w_size - z ? e2.strstart - (e2.w_size - z) : 0, u2 = e2.window, l2 = e2.w_mask, f2 = e2.prev, c2 = e2.strstart + S, d2 = u2[s2 + a2 - 1], p2 = u2[s2 + a2]; - e2.prev_length >= e2.good_match && (i2 >>= 2), o2 > e2.lookahead && (o2 = e2.lookahead); - do { - if (u2[(r2 = t2) + a2] === p2 && u2[r2 + a2 - 1] === d2 && u2[r2] === u2[s2] && u2[++r2] === u2[s2 + 1]) { - s2 += 2, r2++; - do { - } while (u2[++s2] === u2[++r2] && u2[++s2] === u2[++r2] && u2[++s2] === u2[++r2] && u2[++s2] === u2[++r2] && u2[++s2] === u2[++r2] && u2[++s2] === u2[++r2] && u2[++s2] === u2[++r2] && u2[++s2] === u2[++r2] && s2 < c2); - if (n2 = S - (c2 - s2), s2 = c2 - S, a2 < n2) { - if (e2.match_start = t2, o2 <= (a2 = n2)) break; - d2 = u2[s2 + a2 - 1], p2 = u2[s2 + a2]; - } - } - } while ((t2 = f2[t2 & l2]) > h2 && 0 != --i2); - return a2 <= e2.lookahead ? a2 : e2.lookahead; - } - function j(e2) { - var t2, r2, n2, i2, s2, a2, o2, h2, u2, l2, f2 = e2.w_size; - do { - if (i2 = e2.window_size - e2.lookahead - e2.strstart, e2.strstart >= f2 + (f2 - z)) { - for (c.arraySet(e2.window, e2.window, f2, f2, 0), e2.match_start -= f2, e2.strstart -= f2, e2.block_start -= f2, t2 = r2 = e2.hash_size; n2 = e2.head[--t2], e2.head[t2] = f2 <= n2 ? n2 - f2 : 0, --r2; ) ; - for (t2 = r2 = f2; n2 = e2.prev[--t2], e2.prev[t2] = f2 <= n2 ? n2 - f2 : 0, --r2; ) ; - i2 += f2; - } - if (0 === e2.strm.avail_in) break; - if (a2 = e2.strm, o2 = e2.window, h2 = e2.strstart + e2.lookahead, u2 = i2, l2 = void 0, l2 = a2.avail_in, u2 < l2 && (l2 = u2), r2 = 0 === l2 ? 0 : (a2.avail_in -= l2, c.arraySet(o2, a2.input, a2.next_in, l2, h2), 1 === a2.state.wrap ? a2.adler = d(a2.adler, o2, l2, h2) : 2 === a2.state.wrap && (a2.adler = p(a2.adler, o2, l2, h2)), a2.next_in += l2, a2.total_in += l2, l2), e2.lookahead += r2, e2.lookahead + e2.insert >= x) for (s2 = e2.strstart - e2.insert, e2.ins_h = e2.window[s2], e2.ins_h = (e2.ins_h << e2.hash_shift ^ e2.window[s2 + 1]) & e2.hash_mask; e2.insert && (e2.ins_h = (e2.ins_h << e2.hash_shift ^ e2.window[s2 + x - 1]) & e2.hash_mask, e2.prev[s2 & e2.w_mask] = e2.head[e2.ins_h], e2.head[e2.ins_h] = s2, s2++, e2.insert--, !(e2.lookahead + e2.insert < x)); ) ; - } while (e2.lookahead < z && 0 !== e2.strm.avail_in); - } - function Z(e2, t2) { - for (var r2, n2; ; ) { - if (e2.lookahead < z) { - if (j(e2), e2.lookahead < z && t2 === l) return A; - if (0 === e2.lookahead) break; - } - if (r2 = 0, e2.lookahead >= x && (e2.ins_h = (e2.ins_h << e2.hash_shift ^ e2.window[e2.strstart + x - 1]) & e2.hash_mask, r2 = e2.prev[e2.strstart & e2.w_mask] = e2.head[e2.ins_h], e2.head[e2.ins_h] = e2.strstart), 0 !== r2 && e2.strstart - r2 <= e2.w_size - z && (e2.match_length = L(e2, r2)), e2.match_length >= x) if (n2 = u._tr_tally(e2, e2.strstart - e2.match_start, e2.match_length - x), e2.lookahead -= e2.match_length, e2.match_length <= e2.max_lazy_match && e2.lookahead >= x) { - for (e2.match_length--; e2.strstart++, e2.ins_h = (e2.ins_h << e2.hash_shift ^ e2.window[e2.strstart + x - 1]) & e2.hash_mask, r2 = e2.prev[e2.strstart & e2.w_mask] = e2.head[e2.ins_h], e2.head[e2.ins_h] = e2.strstart, 0 != --e2.match_length; ) ; - e2.strstart++; - } else e2.strstart += e2.match_length, e2.match_length = 0, e2.ins_h = e2.window[e2.strstart], e2.ins_h = (e2.ins_h << e2.hash_shift ^ e2.window[e2.strstart + 1]) & e2.hash_mask; - else n2 = u._tr_tally(e2, 0, e2.window[e2.strstart]), e2.lookahead--, e2.strstart++; - if (n2 && (N(e2, false), 0 === e2.strm.avail_out)) return A; - } - return e2.insert = e2.strstart < x - 1 ? e2.strstart : x - 1, t2 === f ? (N(e2, true), 0 === e2.strm.avail_out ? O : B) : e2.last_lit && (N(e2, false), 0 === e2.strm.avail_out) ? A : I; - } - function W(e2, t2) { - for (var r2, n2, i2; ; ) { - if (e2.lookahead < z) { - if (j(e2), e2.lookahead < z && t2 === l) return A; - if (0 === e2.lookahead) break; - } - if (r2 = 0, e2.lookahead >= x && (e2.ins_h = (e2.ins_h << e2.hash_shift ^ e2.window[e2.strstart + x - 1]) & e2.hash_mask, r2 = e2.prev[e2.strstart & e2.w_mask] = e2.head[e2.ins_h], e2.head[e2.ins_h] = e2.strstart), e2.prev_length = e2.match_length, e2.prev_match = e2.match_start, e2.match_length = x - 1, 0 !== r2 && e2.prev_length < e2.max_lazy_match && e2.strstart - r2 <= e2.w_size - z && (e2.match_length = L(e2, r2), e2.match_length <= 5 && (1 === e2.strategy || e2.match_length === x && 4096 < e2.strstart - e2.match_start) && (e2.match_length = x - 1)), e2.prev_length >= x && e2.match_length <= e2.prev_length) { - for (i2 = e2.strstart + e2.lookahead - x, n2 = u._tr_tally(e2, e2.strstart - 1 - e2.prev_match, e2.prev_length - x), e2.lookahead -= e2.prev_length - 1, e2.prev_length -= 2; ++e2.strstart <= i2 && (e2.ins_h = (e2.ins_h << e2.hash_shift ^ e2.window[e2.strstart + x - 1]) & e2.hash_mask, r2 = e2.prev[e2.strstart & e2.w_mask] = e2.head[e2.ins_h], e2.head[e2.ins_h] = e2.strstart), 0 != --e2.prev_length; ) ; - if (e2.match_available = 0, e2.match_length = x - 1, e2.strstart++, n2 && (N(e2, false), 0 === e2.strm.avail_out)) return A; - } else if (e2.match_available) { - if ((n2 = u._tr_tally(e2, 0, e2.window[e2.strstart - 1])) && N(e2, false), e2.strstart++, e2.lookahead--, 0 === e2.strm.avail_out) return A; - } else e2.match_available = 1, e2.strstart++, e2.lookahead--; - } - return e2.match_available && (n2 = u._tr_tally(e2, 0, e2.window[e2.strstart - 1]), e2.match_available = 0), e2.insert = e2.strstart < x - 1 ? e2.strstart : x - 1, t2 === f ? (N(e2, true), 0 === e2.strm.avail_out ? O : B) : e2.last_lit && (N(e2, false), 0 === e2.strm.avail_out) ? A : I; - } - function M(e2, t2, r2, n2, i2) { - this.good_length = e2, this.max_lazy = t2, this.nice_length = r2, this.max_chain = n2, this.func = i2; - } - function H() { - this.strm = null, this.status = 0, this.pending_buf = null, this.pending_buf_size = 0, this.pending_out = 0, this.pending = 0, this.wrap = 0, this.gzhead = null, this.gzindex = 0, this.method = v, this.last_flush = -1, this.w_size = 0, this.w_bits = 0, this.w_mask = 0, this.window = null, this.window_size = 0, this.prev = null, this.head = null, this.ins_h = 0, this.hash_size = 0, this.hash_bits = 0, this.hash_mask = 0, this.hash_shift = 0, this.block_start = 0, this.match_length = 0, this.prev_match = 0, this.match_available = 0, this.strstart = 0, this.match_start = 0, this.lookahead = 0, this.prev_length = 0, this.max_chain_length = 0, this.max_lazy_match = 0, this.level = 0, this.strategy = 0, this.good_match = 0, this.nice_match = 0, this.dyn_ltree = new c.Buf16(2 * w), this.dyn_dtree = new c.Buf16(2 * (2 * a + 1)), this.bl_tree = new c.Buf16(2 * (2 * o + 1)), D(this.dyn_ltree), D(this.dyn_dtree), D(this.bl_tree), this.l_desc = null, this.d_desc = null, this.bl_desc = null, this.bl_count = new c.Buf16(k + 1), this.heap = new c.Buf16(2 * s + 1), D(this.heap), this.heap_len = 0, this.heap_max = 0, this.depth = new c.Buf16(2 * s + 1), D(this.depth), this.l_buf = 0, this.lit_bufsize = 0, this.last_lit = 0, this.d_buf = 0, this.opt_len = 0, this.static_len = 0, this.matches = 0, this.insert = 0, this.bi_buf = 0, this.bi_valid = 0; - } - function G(e2) { - var t2; - return e2 && e2.state ? (e2.total_in = e2.total_out = 0, e2.data_type = i, (t2 = e2.state).pending = 0, t2.pending_out = 0, t2.wrap < 0 && (t2.wrap = -t2.wrap), t2.status = t2.wrap ? C : E, e2.adler = 2 === t2.wrap ? 0 : 1, t2.last_flush = l, u._tr_init(t2), m) : R(e2, _); - } - function K(e2) { - var t2 = G(e2); - return t2 === m && (function(e3) { - e3.window_size = 2 * e3.w_size, D(e3.head), e3.max_lazy_match = h[e3.level].max_lazy, e3.good_match = h[e3.level].good_length, e3.nice_match = h[e3.level].nice_length, e3.max_chain_length = h[e3.level].max_chain, e3.strstart = 0, e3.block_start = 0, e3.lookahead = 0, e3.insert = 0, e3.match_length = e3.prev_length = x - 1, e3.match_available = 0, e3.ins_h = 0; - })(e2.state), t2; - } - function Y(e2, t2, r2, n2, i2, s2) { - if (!e2) return _; - var a2 = 1; - if (t2 === g && (t2 = 6), n2 < 0 ? (a2 = 0, n2 = -n2) : 15 < n2 && (a2 = 2, n2 -= 16), i2 < 1 || y < i2 || r2 !== v || n2 < 8 || 15 < n2 || t2 < 0 || 9 < t2 || s2 < 0 || b < s2) return R(e2, _); - 8 === n2 && (n2 = 9); - var o2 = new H(); - return (e2.state = o2).strm = e2, o2.wrap = a2, o2.gzhead = null, o2.w_bits = n2, o2.w_size = 1 << o2.w_bits, o2.w_mask = o2.w_size - 1, o2.hash_bits = i2 + 7, o2.hash_size = 1 << o2.hash_bits, o2.hash_mask = o2.hash_size - 1, o2.hash_shift = ~~((o2.hash_bits + x - 1) / x), o2.window = new c.Buf8(2 * o2.w_size), o2.head = new c.Buf16(o2.hash_size), o2.prev = new c.Buf16(o2.w_size), o2.lit_bufsize = 1 << i2 + 6, o2.pending_buf_size = 4 * o2.lit_bufsize, o2.pending_buf = new c.Buf8(o2.pending_buf_size), o2.d_buf = 1 * o2.lit_bufsize, o2.l_buf = 3 * o2.lit_bufsize, o2.level = t2, o2.strategy = s2, o2.method = r2, K(e2); - } - h = [new M(0, 0, 0, 0, function(e2, t2) { - var r2 = 65535; - for (r2 > e2.pending_buf_size - 5 && (r2 = e2.pending_buf_size - 5); ; ) { - if (e2.lookahead <= 1) { - if (j(e2), 0 === e2.lookahead && t2 === l) return A; - if (0 === e2.lookahead) break; - } - e2.strstart += e2.lookahead, e2.lookahead = 0; - var n2 = e2.block_start + r2; - if ((0 === e2.strstart || e2.strstart >= n2) && (e2.lookahead = e2.strstart - n2, e2.strstart = n2, N(e2, false), 0 === e2.strm.avail_out)) return A; - if (e2.strstart - e2.block_start >= e2.w_size - z && (N(e2, false), 0 === e2.strm.avail_out)) return A; - } - return e2.insert = 0, t2 === f ? (N(e2, true), 0 === e2.strm.avail_out ? O : B) : (e2.strstart > e2.block_start && (N(e2, false), e2.strm.avail_out), A); - }), new M(4, 4, 8, 4, Z), new M(4, 5, 16, 8, Z), new M(4, 6, 32, 32, Z), new M(4, 4, 16, 16, W), new M(8, 16, 32, 32, W), new M(8, 16, 128, 128, W), new M(8, 32, 128, 256, W), new M(32, 128, 258, 1024, W), new M(32, 258, 258, 4096, W)], r.deflateInit = function(e2, t2) { - return Y(e2, t2, v, 15, 8, 0); - }, r.deflateInit2 = Y, r.deflateReset = K, r.deflateResetKeep = G, r.deflateSetHeader = function(e2, t2) { - return e2 && e2.state ? 2 !== e2.state.wrap ? _ : (e2.state.gzhead = t2, m) : _; - }, r.deflate = function(e2, t2) { - var r2, n2, i2, s2; - if (!e2 || !e2.state || 5 < t2 || t2 < 0) return e2 ? R(e2, _) : _; - if (n2 = e2.state, !e2.output || !e2.input && 0 !== e2.avail_in || 666 === n2.status && t2 !== f) return R(e2, 0 === e2.avail_out ? -5 : _); - if (n2.strm = e2, r2 = n2.last_flush, n2.last_flush = t2, n2.status === C) if (2 === n2.wrap) e2.adler = 0, U(n2, 31), U(n2, 139), U(n2, 8), n2.gzhead ? (U(n2, (n2.gzhead.text ? 1 : 0) + (n2.gzhead.hcrc ? 2 : 0) + (n2.gzhead.extra ? 4 : 0) + (n2.gzhead.name ? 8 : 0) + (n2.gzhead.comment ? 16 : 0)), U(n2, 255 & n2.gzhead.time), U(n2, n2.gzhead.time >> 8 & 255), U(n2, n2.gzhead.time >> 16 & 255), U(n2, n2.gzhead.time >> 24 & 255), U(n2, 9 === n2.level ? 2 : 2 <= n2.strategy || n2.level < 2 ? 4 : 0), U(n2, 255 & n2.gzhead.os), n2.gzhead.extra && n2.gzhead.extra.length && (U(n2, 255 & n2.gzhead.extra.length), U(n2, n2.gzhead.extra.length >> 8 & 255)), n2.gzhead.hcrc && (e2.adler = p(e2.adler, n2.pending_buf, n2.pending, 0)), n2.gzindex = 0, n2.status = 69) : (U(n2, 0), U(n2, 0), U(n2, 0), U(n2, 0), U(n2, 0), U(n2, 9 === n2.level ? 2 : 2 <= n2.strategy || n2.level < 2 ? 4 : 0), U(n2, 3), n2.status = E); - else { - var a2 = v + (n2.w_bits - 8 << 4) << 8; - a2 |= (2 <= n2.strategy || n2.level < 2 ? 0 : n2.level < 6 ? 1 : 6 === n2.level ? 2 : 3) << 6, 0 !== n2.strstart && (a2 |= 32), a2 += 31 - a2 % 31, n2.status = E, P(n2, a2), 0 !== n2.strstart && (P(n2, e2.adler >>> 16), P(n2, 65535 & e2.adler)), e2.adler = 1; - } - if (69 === n2.status) if (n2.gzhead.extra) { - for (i2 = n2.pending; n2.gzindex < (65535 & n2.gzhead.extra.length) && (n2.pending !== n2.pending_buf_size || (n2.gzhead.hcrc && n2.pending > i2 && (e2.adler = p(e2.adler, n2.pending_buf, n2.pending - i2, i2)), F(e2), i2 = n2.pending, n2.pending !== n2.pending_buf_size)); ) U(n2, 255 & n2.gzhead.extra[n2.gzindex]), n2.gzindex++; - n2.gzhead.hcrc && n2.pending > i2 && (e2.adler = p(e2.adler, n2.pending_buf, n2.pending - i2, i2)), n2.gzindex === n2.gzhead.extra.length && (n2.gzindex = 0, n2.status = 73); - } else n2.status = 73; - if (73 === n2.status) if (n2.gzhead.name) { - i2 = n2.pending; - do { - if (n2.pending === n2.pending_buf_size && (n2.gzhead.hcrc && n2.pending > i2 && (e2.adler = p(e2.adler, n2.pending_buf, n2.pending - i2, i2)), F(e2), i2 = n2.pending, n2.pending === n2.pending_buf_size)) { - s2 = 1; - break; - } - s2 = n2.gzindex < n2.gzhead.name.length ? 255 & n2.gzhead.name.charCodeAt(n2.gzindex++) : 0, U(n2, s2); - } while (0 !== s2); - n2.gzhead.hcrc && n2.pending > i2 && (e2.adler = p(e2.adler, n2.pending_buf, n2.pending - i2, i2)), 0 === s2 && (n2.gzindex = 0, n2.status = 91); - } else n2.status = 91; - if (91 === n2.status) if (n2.gzhead.comment) { - i2 = n2.pending; - do { - if (n2.pending === n2.pending_buf_size && (n2.gzhead.hcrc && n2.pending > i2 && (e2.adler = p(e2.adler, n2.pending_buf, n2.pending - i2, i2)), F(e2), i2 = n2.pending, n2.pending === n2.pending_buf_size)) { - s2 = 1; - break; - } - s2 = n2.gzindex < n2.gzhead.comment.length ? 255 & n2.gzhead.comment.charCodeAt(n2.gzindex++) : 0, U(n2, s2); - } while (0 !== s2); - n2.gzhead.hcrc && n2.pending > i2 && (e2.adler = p(e2.adler, n2.pending_buf, n2.pending - i2, i2)), 0 === s2 && (n2.status = 103); - } else n2.status = 103; - if (103 === n2.status && (n2.gzhead.hcrc ? (n2.pending + 2 > n2.pending_buf_size && F(e2), n2.pending + 2 <= n2.pending_buf_size && (U(n2, 255 & e2.adler), U(n2, e2.adler >> 8 & 255), e2.adler = 0, n2.status = E)) : n2.status = E), 0 !== n2.pending) { - if (F(e2), 0 === e2.avail_out) return n2.last_flush = -1, m; - } else if (0 === e2.avail_in && T(t2) <= T(r2) && t2 !== f) return R(e2, -5); - if (666 === n2.status && 0 !== e2.avail_in) return R(e2, -5); - if (0 !== e2.avail_in || 0 !== n2.lookahead || t2 !== l && 666 !== n2.status) { - var o2 = 2 === n2.strategy ? (function(e3, t3) { - for (var r3; ; ) { - if (0 === e3.lookahead && (j(e3), 0 === e3.lookahead)) { - if (t3 === l) return A; - break; - } - if (e3.match_length = 0, r3 = u._tr_tally(e3, 0, e3.window[e3.strstart]), e3.lookahead--, e3.strstart++, r3 && (N(e3, false), 0 === e3.strm.avail_out)) return A; - } - return e3.insert = 0, t3 === f ? (N(e3, true), 0 === e3.strm.avail_out ? O : B) : e3.last_lit && (N(e3, false), 0 === e3.strm.avail_out) ? A : I; - })(n2, t2) : 3 === n2.strategy ? (function(e3, t3) { - for (var r3, n3, i3, s3, a3 = e3.window; ; ) { - if (e3.lookahead <= S) { - if (j(e3), e3.lookahead <= S && t3 === l) return A; - if (0 === e3.lookahead) break; - } - if (e3.match_length = 0, e3.lookahead >= x && 0 < e3.strstart && (n3 = a3[i3 = e3.strstart - 1]) === a3[++i3] && n3 === a3[++i3] && n3 === a3[++i3]) { - s3 = e3.strstart + S; - do { - } while (n3 === a3[++i3] && n3 === a3[++i3] && n3 === a3[++i3] && n3 === a3[++i3] && n3 === a3[++i3] && n3 === a3[++i3] && n3 === a3[++i3] && n3 === a3[++i3] && i3 < s3); - e3.match_length = S - (s3 - i3), e3.match_length > e3.lookahead && (e3.match_length = e3.lookahead); - } - if (e3.match_length >= x ? (r3 = u._tr_tally(e3, 1, e3.match_length - x), e3.lookahead -= e3.match_length, e3.strstart += e3.match_length, e3.match_length = 0) : (r3 = u._tr_tally(e3, 0, e3.window[e3.strstart]), e3.lookahead--, e3.strstart++), r3 && (N(e3, false), 0 === e3.strm.avail_out)) return A; - } - return e3.insert = 0, t3 === f ? (N(e3, true), 0 === e3.strm.avail_out ? O : B) : e3.last_lit && (N(e3, false), 0 === e3.strm.avail_out) ? A : I; - })(n2, t2) : h[n2.level].func(n2, t2); - if (o2 !== O && o2 !== B || (n2.status = 666), o2 === A || o2 === O) return 0 === e2.avail_out && (n2.last_flush = -1), m; - if (o2 === I && (1 === t2 ? u._tr_align(n2) : 5 !== t2 && (u._tr_stored_block(n2, 0, 0, false), 3 === t2 && (D(n2.head), 0 === n2.lookahead && (n2.strstart = 0, n2.block_start = 0, n2.insert = 0))), F(e2), 0 === e2.avail_out)) return n2.last_flush = -1, m; - } - return t2 !== f ? m : n2.wrap <= 0 ? 1 : (2 === n2.wrap ? (U(n2, 255 & e2.adler), U(n2, e2.adler >> 8 & 255), U(n2, e2.adler >> 16 & 255), U(n2, e2.adler >> 24 & 255), U(n2, 255 & e2.total_in), U(n2, e2.total_in >> 8 & 255), U(n2, e2.total_in >> 16 & 255), U(n2, e2.total_in >> 24 & 255)) : (P(n2, e2.adler >>> 16), P(n2, 65535 & e2.adler)), F(e2), 0 < n2.wrap && (n2.wrap = -n2.wrap), 0 !== n2.pending ? m : 1); - }, r.deflateEnd = function(e2) { - var t2; - return e2 && e2.state ? (t2 = e2.state.status) !== C && 69 !== t2 && 73 !== t2 && 91 !== t2 && 103 !== t2 && t2 !== E && 666 !== t2 ? R(e2, _) : (e2.state = null, t2 === E ? R(e2, -3) : m) : _; - }, r.deflateSetDictionary = function(e2, t2) { - var r2, n2, i2, s2, a2, o2, h2, u2, l2 = t2.length; - if (!e2 || !e2.state) return _; - if (2 === (s2 = (r2 = e2.state).wrap) || 1 === s2 && r2.status !== C || r2.lookahead) return _; - for (1 === s2 && (e2.adler = d(e2.adler, t2, l2, 0)), r2.wrap = 0, l2 >= r2.w_size && (0 === s2 && (D(r2.head), r2.strstart = 0, r2.block_start = 0, r2.insert = 0), u2 = new c.Buf8(r2.w_size), c.arraySet(u2, t2, l2 - r2.w_size, r2.w_size, 0), t2 = u2, l2 = r2.w_size), a2 = e2.avail_in, o2 = e2.next_in, h2 = e2.input, e2.avail_in = l2, e2.next_in = 0, e2.input = t2, j(r2); r2.lookahead >= x; ) { - for (n2 = r2.strstart, i2 = r2.lookahead - (x - 1); r2.ins_h = (r2.ins_h << r2.hash_shift ^ r2.window[n2 + x - 1]) & r2.hash_mask, r2.prev[n2 & r2.w_mask] = r2.head[r2.ins_h], r2.head[r2.ins_h] = n2, n2++, --i2; ) ; - r2.strstart = n2, r2.lookahead = x - 1, j(r2); - } - return r2.strstart += r2.lookahead, r2.block_start = r2.strstart, r2.insert = r2.lookahead, r2.lookahead = 0, r2.match_length = r2.prev_length = x - 1, r2.match_available = 0, e2.next_in = o2, e2.input = h2, e2.avail_in = a2, r2.wrap = s2, m; - }, r.deflateInfo = "pako deflate (from Nodeca project)"; - }, { "../utils/common": 41, "./adler32": 43, "./crc32": 45, "./messages": 51, "./trees": 52 }], 47: [function(e, t, r) { - "use strict"; - t.exports = function() { - this.text = 0, this.time = 0, this.xflags = 0, this.os = 0, this.extra = null, this.extra_len = 0, this.name = "", this.comment = "", this.hcrc = 0, this.done = false; - }; - }, {}], 48: [function(e, t, r) { - "use strict"; - t.exports = function(e2, t2) { - var r2, n, i, s, a, o, h, u, l, f, c, d, p, m, _, g, b, v, y, w, k, x, S, z, C; - r2 = e2.state, n = e2.next_in, z = e2.input, i = n + (e2.avail_in - 5), s = e2.next_out, C = e2.output, a = s - (t2 - e2.avail_out), o = s + (e2.avail_out - 257), h = r2.dmax, u = r2.wsize, l = r2.whave, f = r2.wnext, c = r2.window, d = r2.hold, p = r2.bits, m = r2.lencode, _ = r2.distcode, g = (1 << r2.lenbits) - 1, b = (1 << r2.distbits) - 1; - e: do { - p < 15 && (d += z[n++] << p, p += 8, d += z[n++] << p, p += 8), v = m[d & g]; - t: for (; ; ) { - if (d >>>= y = v >>> 24, p -= y, 0 === (y = v >>> 16 & 255)) C[s++] = 65535 & v; - else { - if (!(16 & y)) { - if (0 == (64 & y)) { - v = m[(65535 & v) + (d & (1 << y) - 1)]; - continue t; - } - if (32 & y) { - r2.mode = 12; - break e; - } - e2.msg = "invalid literal/length code", r2.mode = 30; - break e; - } - w = 65535 & v, (y &= 15) && (p < y && (d += z[n++] << p, p += 8), w += d & (1 << y) - 1, d >>>= y, p -= y), p < 15 && (d += z[n++] << p, p += 8, d += z[n++] << p, p += 8), v = _[d & b]; - r: for (; ; ) { - if (d >>>= y = v >>> 24, p -= y, !(16 & (y = v >>> 16 & 255))) { - if (0 == (64 & y)) { - v = _[(65535 & v) + (d & (1 << y) - 1)]; - continue r; - } - e2.msg = "invalid distance code", r2.mode = 30; - break e; - } - if (k = 65535 & v, p < (y &= 15) && (d += z[n++] << p, (p += 8) < y && (d += z[n++] << p, p += 8)), h < (k += d & (1 << y) - 1)) { - e2.msg = "invalid distance too far back", r2.mode = 30; - break e; - } - if (d >>>= y, p -= y, (y = s - a) < k) { - if (l < (y = k - y) && r2.sane) { - e2.msg = "invalid distance too far back", r2.mode = 30; - break e; - } - if (S = c, (x = 0) === f) { - if (x += u - y, y < w) { - for (w -= y; C[s++] = c[x++], --y; ) ; - x = s - k, S = C; - } - } else if (f < y) { - if (x += u + f - y, (y -= f) < w) { - for (w -= y; C[s++] = c[x++], --y; ) ; - if (x = 0, f < w) { - for (w -= y = f; C[s++] = c[x++], --y; ) ; - x = s - k, S = C; - } - } - } else if (x += f - y, y < w) { - for (w -= y; C[s++] = c[x++], --y; ) ; - x = s - k, S = C; - } - for (; 2 < w; ) C[s++] = S[x++], C[s++] = S[x++], C[s++] = S[x++], w -= 3; - w && (C[s++] = S[x++], 1 < w && (C[s++] = S[x++])); - } else { - for (x = s - k; C[s++] = C[x++], C[s++] = C[x++], C[s++] = C[x++], 2 < (w -= 3); ) ; - w && (C[s++] = C[x++], 1 < w && (C[s++] = C[x++])); - } - break; - } - } - break; - } - } while (n < i && s < o); - n -= w = p >> 3, d &= (1 << (p -= w << 3)) - 1, e2.next_in = n, e2.next_out = s, e2.avail_in = n < i ? i - n + 5 : 5 - (n - i), e2.avail_out = s < o ? o - s + 257 : 257 - (s - o), r2.hold = d, r2.bits = p; - }; - }, {}], 49: [function(e, t, r) { - "use strict"; - var I = e("../utils/common"), O = e("./adler32"), B = e("./crc32"), R = e("./inffast"), T = e("./inftrees"), D = 1, F = 2, N = 0, U = -2, P = 1, n = 852, i = 592; - function L(e2) { - return (e2 >>> 24 & 255) + (e2 >>> 8 & 65280) + ((65280 & e2) << 8) + ((255 & e2) << 24); - } - function s() { - this.mode = 0, this.last = false, this.wrap = 0, this.havedict = false, this.flags = 0, this.dmax = 0, this.check = 0, this.total = 0, this.head = null, this.wbits = 0, this.wsize = 0, this.whave = 0, this.wnext = 0, this.window = null, this.hold = 0, this.bits = 0, this.length = 0, this.offset = 0, this.extra = 0, this.lencode = null, this.distcode = null, this.lenbits = 0, this.distbits = 0, this.ncode = 0, this.nlen = 0, this.ndist = 0, this.have = 0, this.next = null, this.lens = new I.Buf16(320), this.work = new I.Buf16(288), this.lendyn = null, this.distdyn = null, this.sane = 0, this.back = 0, this.was = 0; - } - function a(e2) { - var t2; - return e2 && e2.state ? (t2 = e2.state, e2.total_in = e2.total_out = t2.total = 0, e2.msg = "", t2.wrap && (e2.adler = 1 & t2.wrap), t2.mode = P, t2.last = 0, t2.havedict = 0, t2.dmax = 32768, t2.head = null, t2.hold = 0, t2.bits = 0, t2.lencode = t2.lendyn = new I.Buf32(n), t2.distcode = t2.distdyn = new I.Buf32(i), t2.sane = 1, t2.back = -1, N) : U; - } - function o(e2) { - var t2; - return e2 && e2.state ? ((t2 = e2.state).wsize = 0, t2.whave = 0, t2.wnext = 0, a(e2)) : U; - } - function h(e2, t2) { - var r2, n2; - return e2 && e2.state ? (n2 = e2.state, t2 < 0 ? (r2 = 0, t2 = -t2) : (r2 = 1 + (t2 >> 4), t2 < 48 && (t2 &= 15)), t2 && (t2 < 8 || 15 < t2) ? U : (null !== n2.window && n2.wbits !== t2 && (n2.window = null), n2.wrap = r2, n2.wbits = t2, o(e2))) : U; - } - function u(e2, t2) { - var r2, n2; - return e2 ? (n2 = new s(), (e2.state = n2).window = null, (r2 = h(e2, t2)) !== N && (e2.state = null), r2) : U; - } - var l, f, c = true; - function j(e2) { - if (c) { - var t2; - for (l = new I.Buf32(512), f = new I.Buf32(32), t2 = 0; t2 < 144; ) e2.lens[t2++] = 8; - for (; t2 < 256; ) e2.lens[t2++] = 9; - for (; t2 < 280; ) e2.lens[t2++] = 7; - for (; t2 < 288; ) e2.lens[t2++] = 8; - for (T(D, e2.lens, 0, 288, l, 0, e2.work, { bits: 9 }), t2 = 0; t2 < 32; ) e2.lens[t2++] = 5; - T(F, e2.lens, 0, 32, f, 0, e2.work, { bits: 5 }), c = false; - } - e2.lencode = l, e2.lenbits = 9, e2.distcode = f, e2.distbits = 5; - } - function Z(e2, t2, r2, n2) { - var i2, s2 = e2.state; - return null === s2.window && (s2.wsize = 1 << s2.wbits, s2.wnext = 0, s2.whave = 0, s2.window = new I.Buf8(s2.wsize)), n2 >= s2.wsize ? (I.arraySet(s2.window, t2, r2 - s2.wsize, s2.wsize, 0), s2.wnext = 0, s2.whave = s2.wsize) : (n2 < (i2 = s2.wsize - s2.wnext) && (i2 = n2), I.arraySet(s2.window, t2, r2 - n2, i2, s2.wnext), (n2 -= i2) ? (I.arraySet(s2.window, t2, r2 - n2, n2, 0), s2.wnext = n2, s2.whave = s2.wsize) : (s2.wnext += i2, s2.wnext === s2.wsize && (s2.wnext = 0), s2.whave < s2.wsize && (s2.whave += i2))), 0; - } - r.inflateReset = o, r.inflateReset2 = h, r.inflateResetKeep = a, r.inflateInit = function(e2) { - return u(e2, 15); - }, r.inflateInit2 = u, r.inflate = function(e2, t2) { - var r2, n2, i2, s2, a2, o2, h2, u2, l2, f2, c2, d, p, m, _, g, b, v, y, w, k, x, S, z, C = 0, E = new I.Buf8(4), A = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; - if (!e2 || !e2.state || !e2.output || !e2.input && 0 !== e2.avail_in) return U; - 12 === (r2 = e2.state).mode && (r2.mode = 13), a2 = e2.next_out, i2 = e2.output, h2 = e2.avail_out, s2 = e2.next_in, n2 = e2.input, o2 = e2.avail_in, u2 = r2.hold, l2 = r2.bits, f2 = o2, c2 = h2, x = N; - e: for (; ; ) switch (r2.mode) { - case P: - if (0 === r2.wrap) { - r2.mode = 13; - break; - } - for (; l2 < 16; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - if (2 & r2.wrap && 35615 === u2) { - E[r2.check = 0] = 255 & u2, E[1] = u2 >>> 8 & 255, r2.check = B(r2.check, E, 2, 0), l2 = u2 = 0, r2.mode = 2; - break; - } - if (r2.flags = 0, r2.head && (r2.head.done = false), !(1 & r2.wrap) || (((255 & u2) << 8) + (u2 >> 8)) % 31) { - e2.msg = "incorrect header check", r2.mode = 30; - break; - } - if (8 != (15 & u2)) { - e2.msg = "unknown compression method", r2.mode = 30; - break; - } - if (l2 -= 4, k = 8 + (15 & (u2 >>>= 4)), 0 === r2.wbits) r2.wbits = k; - else if (k > r2.wbits) { - e2.msg = "invalid window size", r2.mode = 30; - break; - } - r2.dmax = 1 << k, e2.adler = r2.check = 1, r2.mode = 512 & u2 ? 10 : 12, l2 = u2 = 0; - break; - case 2: - for (; l2 < 16; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - if (r2.flags = u2, 8 != (255 & r2.flags)) { - e2.msg = "unknown compression method", r2.mode = 30; - break; - } - if (57344 & r2.flags) { - e2.msg = "unknown header flags set", r2.mode = 30; - break; - } - r2.head && (r2.head.text = u2 >> 8 & 1), 512 & r2.flags && (E[0] = 255 & u2, E[1] = u2 >>> 8 & 255, r2.check = B(r2.check, E, 2, 0)), l2 = u2 = 0, r2.mode = 3; - case 3: - for (; l2 < 32; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - r2.head && (r2.head.time = u2), 512 & r2.flags && (E[0] = 255 & u2, E[1] = u2 >>> 8 & 255, E[2] = u2 >>> 16 & 255, E[3] = u2 >>> 24 & 255, r2.check = B(r2.check, E, 4, 0)), l2 = u2 = 0, r2.mode = 4; - case 4: - for (; l2 < 16; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - r2.head && (r2.head.xflags = 255 & u2, r2.head.os = u2 >> 8), 512 & r2.flags && (E[0] = 255 & u2, E[1] = u2 >>> 8 & 255, r2.check = B(r2.check, E, 2, 0)), l2 = u2 = 0, r2.mode = 5; - case 5: - if (1024 & r2.flags) { - for (; l2 < 16; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - r2.length = u2, r2.head && (r2.head.extra_len = u2), 512 & r2.flags && (E[0] = 255 & u2, E[1] = u2 >>> 8 & 255, r2.check = B(r2.check, E, 2, 0)), l2 = u2 = 0; - } else r2.head && (r2.head.extra = null); - r2.mode = 6; - case 6: - if (1024 & r2.flags && (o2 < (d = r2.length) && (d = o2), d && (r2.head && (k = r2.head.extra_len - r2.length, r2.head.extra || (r2.head.extra = new Array(r2.head.extra_len)), I.arraySet(r2.head.extra, n2, s2, d, k)), 512 & r2.flags && (r2.check = B(r2.check, n2, d, s2)), o2 -= d, s2 += d, r2.length -= d), r2.length)) break e; - r2.length = 0, r2.mode = 7; - case 7: - if (2048 & r2.flags) { - if (0 === o2) break e; - for (d = 0; k = n2[s2 + d++], r2.head && k && r2.length < 65536 && (r2.head.name += String.fromCharCode(k)), k && d < o2; ) ; - if (512 & r2.flags && (r2.check = B(r2.check, n2, d, s2)), o2 -= d, s2 += d, k) break e; - } else r2.head && (r2.head.name = null); - r2.length = 0, r2.mode = 8; - case 8: - if (4096 & r2.flags) { - if (0 === o2) break e; - for (d = 0; k = n2[s2 + d++], r2.head && k && r2.length < 65536 && (r2.head.comment += String.fromCharCode(k)), k && d < o2; ) ; - if (512 & r2.flags && (r2.check = B(r2.check, n2, d, s2)), o2 -= d, s2 += d, k) break e; - } else r2.head && (r2.head.comment = null); - r2.mode = 9; - case 9: - if (512 & r2.flags) { - for (; l2 < 16; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - if (u2 !== (65535 & r2.check)) { - e2.msg = "header crc mismatch", r2.mode = 30; - break; - } - l2 = u2 = 0; - } - r2.head && (r2.head.hcrc = r2.flags >> 9 & 1, r2.head.done = true), e2.adler = r2.check = 0, r2.mode = 12; - break; - case 10: - for (; l2 < 32; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - e2.adler = r2.check = L(u2), l2 = u2 = 0, r2.mode = 11; - case 11: - if (0 === r2.havedict) return e2.next_out = a2, e2.avail_out = h2, e2.next_in = s2, e2.avail_in = o2, r2.hold = u2, r2.bits = l2, 2; - e2.adler = r2.check = 1, r2.mode = 12; - case 12: - if (5 === t2 || 6 === t2) break e; - case 13: - if (r2.last) { - u2 >>>= 7 & l2, l2 -= 7 & l2, r2.mode = 27; - break; - } - for (; l2 < 3; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - switch (r2.last = 1 & u2, l2 -= 1, 3 & (u2 >>>= 1)) { - case 0: - r2.mode = 14; - break; - case 1: - if (j(r2), r2.mode = 20, 6 !== t2) break; - u2 >>>= 2, l2 -= 2; - break e; - case 2: - r2.mode = 17; - break; - case 3: - e2.msg = "invalid block type", r2.mode = 30; - } - u2 >>>= 2, l2 -= 2; - break; - case 14: - for (u2 >>>= 7 & l2, l2 -= 7 & l2; l2 < 32; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - if ((65535 & u2) != (u2 >>> 16 ^ 65535)) { - e2.msg = "invalid stored block lengths", r2.mode = 30; - break; - } - if (r2.length = 65535 & u2, l2 = u2 = 0, r2.mode = 15, 6 === t2) break e; - case 15: - r2.mode = 16; - case 16: - if (d = r2.length) { - if (o2 < d && (d = o2), h2 < d && (d = h2), 0 === d) break e; - I.arraySet(i2, n2, s2, d, a2), o2 -= d, s2 += d, h2 -= d, a2 += d, r2.length -= d; - break; - } - r2.mode = 12; - break; - case 17: - for (; l2 < 14; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - if (r2.nlen = 257 + (31 & u2), u2 >>>= 5, l2 -= 5, r2.ndist = 1 + (31 & u2), u2 >>>= 5, l2 -= 5, r2.ncode = 4 + (15 & u2), u2 >>>= 4, l2 -= 4, 286 < r2.nlen || 30 < r2.ndist) { - e2.msg = "too many length or distance symbols", r2.mode = 30; - break; - } - r2.have = 0, r2.mode = 18; - case 18: - for (; r2.have < r2.ncode; ) { - for (; l2 < 3; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - r2.lens[A[r2.have++]] = 7 & u2, u2 >>>= 3, l2 -= 3; - } - for (; r2.have < 19; ) r2.lens[A[r2.have++]] = 0; - if (r2.lencode = r2.lendyn, r2.lenbits = 7, S = { bits: r2.lenbits }, x = T(0, r2.lens, 0, 19, r2.lencode, 0, r2.work, S), r2.lenbits = S.bits, x) { - e2.msg = "invalid code lengths set", r2.mode = 30; - break; - } - r2.have = 0, r2.mode = 19; - case 19: - for (; r2.have < r2.nlen + r2.ndist; ) { - for (; g = (C = r2.lencode[u2 & (1 << r2.lenbits) - 1]) >>> 16 & 255, b = 65535 & C, !((_ = C >>> 24) <= l2); ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - if (b < 16) u2 >>>= _, l2 -= _, r2.lens[r2.have++] = b; - else { - if (16 === b) { - for (z = _ + 2; l2 < z; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - if (u2 >>>= _, l2 -= _, 0 === r2.have) { - e2.msg = "invalid bit length repeat", r2.mode = 30; - break; - } - k = r2.lens[r2.have - 1], d = 3 + (3 & u2), u2 >>>= 2, l2 -= 2; - } else if (17 === b) { - for (z = _ + 3; l2 < z; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - l2 -= _, k = 0, d = 3 + (7 & (u2 >>>= _)), u2 >>>= 3, l2 -= 3; - } else { - for (z = _ + 7; l2 < z; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - l2 -= _, k = 0, d = 11 + (127 & (u2 >>>= _)), u2 >>>= 7, l2 -= 7; - } - if (r2.have + d > r2.nlen + r2.ndist) { - e2.msg = "invalid bit length repeat", r2.mode = 30; - break; - } - for (; d--; ) r2.lens[r2.have++] = k; - } - } - if (30 === r2.mode) break; - if (0 === r2.lens[256]) { - e2.msg = "invalid code -- missing end-of-block", r2.mode = 30; - break; - } - if (r2.lenbits = 9, S = { bits: r2.lenbits }, x = T(D, r2.lens, 0, r2.nlen, r2.lencode, 0, r2.work, S), r2.lenbits = S.bits, x) { - e2.msg = "invalid literal/lengths set", r2.mode = 30; - break; - } - if (r2.distbits = 6, r2.distcode = r2.distdyn, S = { bits: r2.distbits }, x = T(F, r2.lens, r2.nlen, r2.ndist, r2.distcode, 0, r2.work, S), r2.distbits = S.bits, x) { - e2.msg = "invalid distances set", r2.mode = 30; - break; - } - if (r2.mode = 20, 6 === t2) break e; - case 20: - r2.mode = 21; - case 21: - if (6 <= o2 && 258 <= h2) { - e2.next_out = a2, e2.avail_out = h2, e2.next_in = s2, e2.avail_in = o2, r2.hold = u2, r2.bits = l2, R(e2, c2), a2 = e2.next_out, i2 = e2.output, h2 = e2.avail_out, s2 = e2.next_in, n2 = e2.input, o2 = e2.avail_in, u2 = r2.hold, l2 = r2.bits, 12 === r2.mode && (r2.back = -1); - break; - } - for (r2.back = 0; g = (C = r2.lencode[u2 & (1 << r2.lenbits) - 1]) >>> 16 & 255, b = 65535 & C, !((_ = C >>> 24) <= l2); ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - if (g && 0 == (240 & g)) { - for (v = _, y = g, w = b; g = (C = r2.lencode[w + ((u2 & (1 << v + y) - 1) >> v)]) >>> 16 & 255, b = 65535 & C, !(v + (_ = C >>> 24) <= l2); ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - u2 >>>= v, l2 -= v, r2.back += v; - } - if (u2 >>>= _, l2 -= _, r2.back += _, r2.length = b, 0 === g) { - r2.mode = 26; - break; - } - if (32 & g) { - r2.back = -1, r2.mode = 12; - break; - } - if (64 & g) { - e2.msg = "invalid literal/length code", r2.mode = 30; - break; - } - r2.extra = 15 & g, r2.mode = 22; - case 22: - if (r2.extra) { - for (z = r2.extra; l2 < z; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - r2.length += u2 & (1 << r2.extra) - 1, u2 >>>= r2.extra, l2 -= r2.extra, r2.back += r2.extra; - } - r2.was = r2.length, r2.mode = 23; - case 23: - for (; g = (C = r2.distcode[u2 & (1 << r2.distbits) - 1]) >>> 16 & 255, b = 65535 & C, !((_ = C >>> 24) <= l2); ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - if (0 == (240 & g)) { - for (v = _, y = g, w = b; g = (C = r2.distcode[w + ((u2 & (1 << v + y) - 1) >> v)]) >>> 16 & 255, b = 65535 & C, !(v + (_ = C >>> 24) <= l2); ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - u2 >>>= v, l2 -= v, r2.back += v; - } - if (u2 >>>= _, l2 -= _, r2.back += _, 64 & g) { - e2.msg = "invalid distance code", r2.mode = 30; - break; - } - r2.offset = b, r2.extra = 15 & g, r2.mode = 24; - case 24: - if (r2.extra) { - for (z = r2.extra; l2 < z; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - r2.offset += u2 & (1 << r2.extra) - 1, u2 >>>= r2.extra, l2 -= r2.extra, r2.back += r2.extra; - } - if (r2.offset > r2.dmax) { - e2.msg = "invalid distance too far back", r2.mode = 30; - break; - } - r2.mode = 25; - case 25: - if (0 === h2) break e; - if (d = c2 - h2, r2.offset > d) { - if ((d = r2.offset - d) > r2.whave && r2.sane) { - e2.msg = "invalid distance too far back", r2.mode = 30; - break; - } - p = d > r2.wnext ? (d -= r2.wnext, r2.wsize - d) : r2.wnext - d, d > r2.length && (d = r2.length), m = r2.window; - } else m = i2, p = a2 - r2.offset, d = r2.length; - for (h2 < d && (d = h2), h2 -= d, r2.length -= d; i2[a2++] = m[p++], --d; ) ; - 0 === r2.length && (r2.mode = 21); - break; - case 26: - if (0 === h2) break e; - i2[a2++] = r2.length, h2--, r2.mode = 21; - break; - case 27: - if (r2.wrap) { - for (; l2 < 32; ) { - if (0 === o2) break e; - o2--, u2 |= n2[s2++] << l2, l2 += 8; - } - if (c2 -= h2, e2.total_out += c2, r2.total += c2, c2 && (e2.adler = r2.check = r2.flags ? B(r2.check, i2, c2, a2 - c2) : O(r2.check, i2, c2, a2 - c2)), c2 = h2, (r2.flags ? u2 : L(u2)) !== r2.check) { - e2.msg = "incorrect data check", r2.mode = 30; - break; - } - l2 = u2 = 0; - } - r2.mode = 28; - case 28: - if (r2.wrap && r2.flags) { - for (; l2 < 32; ) { - if (0 === o2) break e; - o2--, u2 += n2[s2++] << l2, l2 += 8; - } - if (u2 !== (4294967295 & r2.total)) { - e2.msg = "incorrect length check", r2.mode = 30; - break; - } - l2 = u2 = 0; - } - r2.mode = 29; - case 29: - x = 1; - break e; - case 30: - x = -3; - break e; - case 31: - return -4; - case 32: - default: - return U; - } - return e2.next_out = a2, e2.avail_out = h2, e2.next_in = s2, e2.avail_in = o2, r2.hold = u2, r2.bits = l2, (r2.wsize || c2 !== e2.avail_out && r2.mode < 30 && (r2.mode < 27 || 4 !== t2)) && Z(e2, e2.output, e2.next_out, c2 - e2.avail_out) ? (r2.mode = 31, -4) : (f2 -= e2.avail_in, c2 -= e2.avail_out, e2.total_in += f2, e2.total_out += c2, r2.total += c2, r2.wrap && c2 && (e2.adler = r2.check = r2.flags ? B(r2.check, i2, c2, e2.next_out - c2) : O(r2.check, i2, c2, e2.next_out - c2)), e2.data_type = r2.bits + (r2.last ? 64 : 0) + (12 === r2.mode ? 128 : 0) + (20 === r2.mode || 15 === r2.mode ? 256 : 0), (0 == f2 && 0 === c2 || 4 === t2) && x === N && (x = -5), x); - }, r.inflateEnd = function(e2) { - if (!e2 || !e2.state) return U; - var t2 = e2.state; - return t2.window && (t2.window = null), e2.state = null, N; - }, r.inflateGetHeader = function(e2, t2) { - var r2; - return e2 && e2.state ? 0 == (2 & (r2 = e2.state).wrap) ? U : ((r2.head = t2).done = false, N) : U; - }, r.inflateSetDictionary = function(e2, t2) { - var r2, n2 = t2.length; - return e2 && e2.state ? 0 !== (r2 = e2.state).wrap && 11 !== r2.mode ? U : 11 === r2.mode && O(1, t2, n2, 0) !== r2.check ? -3 : Z(e2, t2, n2, n2) ? (r2.mode = 31, -4) : (r2.havedict = 1, N) : U; - }, r.inflateInfo = "pako inflate (from Nodeca project)"; - }, { "../utils/common": 41, "./adler32": 43, "./crc32": 45, "./inffast": 48, "./inftrees": 50 }], 50: [function(e, t, r) { - "use strict"; - var D = e("../utils/common"), F = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0], N = [16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78], U = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0], P = [16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64]; - t.exports = function(e2, t2, r2, n, i, s, a, o) { - var h, u, l, f, c, d, p, m, _, g = o.bits, b = 0, v = 0, y = 0, w = 0, k = 0, x = 0, S = 0, z = 0, C = 0, E = 0, A = null, I = 0, O = new D.Buf16(16), B = new D.Buf16(16), R = null, T = 0; - for (b = 0; b <= 15; b++) O[b] = 0; - for (v = 0; v < n; v++) O[t2[r2 + v]]++; - for (k = g, w = 15; 1 <= w && 0 === O[w]; w--) ; - if (w < k && (k = w), 0 === w) return i[s++] = 20971520, i[s++] = 20971520, o.bits = 1, 0; - for (y = 1; y < w && 0 === O[y]; y++) ; - for (k < y && (k = y), b = z = 1; b <= 15; b++) if (z <<= 1, (z -= O[b]) < 0) return -1; - if (0 < z && (0 === e2 || 1 !== w)) return -1; - for (B[1] = 0, b = 1; b < 15; b++) B[b + 1] = B[b] + O[b]; - for (v = 0; v < n; v++) 0 !== t2[r2 + v] && (a[B[t2[r2 + v]]++] = v); - if (d = 0 === e2 ? (A = R = a, 19) : 1 === e2 ? (A = F, I -= 257, R = N, T -= 257, 256) : (A = U, R = P, -1), b = y, c = s, S = v = E = 0, l = -1, f = (C = 1 << (x = k)) - 1, 1 === e2 && 852 < C || 2 === e2 && 592 < C) return 1; - for (; ; ) { - for (p = b - S, _ = a[v] < d ? (m = 0, a[v]) : a[v] > d ? (m = R[T + a[v]], A[I + a[v]]) : (m = 96, 0), h = 1 << b - S, y = u = 1 << x; i[c + (E >> S) + (u -= h)] = p << 24 | m << 16 | _ | 0, 0 !== u; ) ; - for (h = 1 << b - 1; E & h; ) h >>= 1; - if (0 !== h ? (E &= h - 1, E += h) : E = 0, v++, 0 == --O[b]) { - if (b === w) break; - b = t2[r2 + a[v]]; - } - if (k < b && (E & f) !== l) { - for (0 === S && (S = k), c += y, z = 1 << (x = b - S); x + S < w && !((z -= O[x + S]) <= 0); ) x++, z <<= 1; - if (C += 1 << x, 1 === e2 && 852 < C || 2 === e2 && 592 < C) return 1; - i[l = E & f] = k << 24 | x << 16 | c - s | 0; - } - } - return 0 !== E && (i[c + E] = b - S << 24 | 64 << 16 | 0), o.bits = k, 0; - }; - }, { "../utils/common": 41 }], 51: [function(e, t, r) { - "use strict"; - t.exports = { 2: "need dictionary", 1: "stream end", 0: "", "-1": "file error", "-2": "stream error", "-3": "data error", "-4": "insufficient memory", "-5": "buffer error", "-6": "incompatible version" }; - }, {}], 52: [function(e, t, r) { - "use strict"; - var i = e("../utils/common"), o = 0, h = 1; - function n(e2) { - for (var t2 = e2.length; 0 <= --t2; ) e2[t2] = 0; - } - var s = 0, a = 29, u = 256, l = u + 1 + a, f = 30, c = 19, _ = 2 * l + 1, g = 15, d = 16, p = 7, m = 256, b = 16, v = 17, y = 18, w = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0], k = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13], x = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7], S = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15], z = new Array(2 * (l + 2)); - n(z); - var C = new Array(2 * f); - n(C); - var E = new Array(512); - n(E); - var A = new Array(256); - n(A); - var I = new Array(a); - n(I); - var O, B, R, T = new Array(f); - function D(e2, t2, r2, n2, i2) { - this.static_tree = e2, this.extra_bits = t2, this.extra_base = r2, this.elems = n2, this.max_length = i2, this.has_stree = e2 && e2.length; - } - function F(e2, t2) { - this.dyn_tree = e2, this.max_code = 0, this.stat_desc = t2; - } - function N(e2) { - return e2 < 256 ? E[e2] : E[256 + (e2 >>> 7)]; - } - function U(e2, t2) { - e2.pending_buf[e2.pending++] = 255 & t2, e2.pending_buf[e2.pending++] = t2 >>> 8 & 255; - } - function P(e2, t2, r2) { - e2.bi_valid > d - r2 ? (e2.bi_buf |= t2 << e2.bi_valid & 65535, U(e2, e2.bi_buf), e2.bi_buf = t2 >> d - e2.bi_valid, e2.bi_valid += r2 - d) : (e2.bi_buf |= t2 << e2.bi_valid & 65535, e2.bi_valid += r2); - } - function L(e2, t2, r2) { - P(e2, r2[2 * t2], r2[2 * t2 + 1]); - } - function j(e2, t2) { - for (var r2 = 0; r2 |= 1 & e2, e2 >>>= 1, r2 <<= 1, 0 < --t2; ) ; - return r2 >>> 1; - } - function Z(e2, t2, r2) { - var n2, i2, s2 = new Array(g + 1), a2 = 0; - for (n2 = 1; n2 <= g; n2++) s2[n2] = a2 = a2 + r2[n2 - 1] << 1; - for (i2 = 0; i2 <= t2; i2++) { - var o2 = e2[2 * i2 + 1]; - 0 !== o2 && (e2[2 * i2] = j(s2[o2]++, o2)); - } - } - function W(e2) { - var t2; - for (t2 = 0; t2 < l; t2++) e2.dyn_ltree[2 * t2] = 0; - for (t2 = 0; t2 < f; t2++) e2.dyn_dtree[2 * t2] = 0; - for (t2 = 0; t2 < c; t2++) e2.bl_tree[2 * t2] = 0; - e2.dyn_ltree[2 * m] = 1, e2.opt_len = e2.static_len = 0, e2.last_lit = e2.matches = 0; - } - function M(e2) { - 8 < e2.bi_valid ? U(e2, e2.bi_buf) : 0 < e2.bi_valid && (e2.pending_buf[e2.pending++] = e2.bi_buf), e2.bi_buf = 0, e2.bi_valid = 0; - } - function H(e2, t2, r2, n2) { - var i2 = 2 * t2, s2 = 2 * r2; - return e2[i2] < e2[s2] || e2[i2] === e2[s2] && n2[t2] <= n2[r2]; - } - function G(e2, t2, r2) { - for (var n2 = e2.heap[r2], i2 = r2 << 1; i2 <= e2.heap_len && (i2 < e2.heap_len && H(t2, e2.heap[i2 + 1], e2.heap[i2], e2.depth) && i2++, !H(t2, n2, e2.heap[i2], e2.depth)); ) e2.heap[r2] = e2.heap[i2], r2 = i2, i2 <<= 1; - e2.heap[r2] = n2; - } - function K(e2, t2, r2) { - var n2, i2, s2, a2, o2 = 0; - if (0 !== e2.last_lit) for (; n2 = e2.pending_buf[e2.d_buf + 2 * o2] << 8 | e2.pending_buf[e2.d_buf + 2 * o2 + 1], i2 = e2.pending_buf[e2.l_buf + o2], o2++, 0 === n2 ? L(e2, i2, t2) : (L(e2, (s2 = A[i2]) + u + 1, t2), 0 !== (a2 = w[s2]) && P(e2, i2 -= I[s2], a2), L(e2, s2 = N(--n2), r2), 0 !== (a2 = k[s2]) && P(e2, n2 -= T[s2], a2)), o2 < e2.last_lit; ) ; - L(e2, m, t2); - } - function Y(e2, t2) { - var r2, n2, i2, s2 = t2.dyn_tree, a2 = t2.stat_desc.static_tree, o2 = t2.stat_desc.has_stree, h2 = t2.stat_desc.elems, u2 = -1; - for (e2.heap_len = 0, e2.heap_max = _, r2 = 0; r2 < h2; r2++) 0 !== s2[2 * r2] ? (e2.heap[++e2.heap_len] = u2 = r2, e2.depth[r2] = 0) : s2[2 * r2 + 1] = 0; - for (; e2.heap_len < 2; ) s2[2 * (i2 = e2.heap[++e2.heap_len] = u2 < 2 ? ++u2 : 0)] = 1, e2.depth[i2] = 0, e2.opt_len--, o2 && (e2.static_len -= a2[2 * i2 + 1]); - for (t2.max_code = u2, r2 = e2.heap_len >> 1; 1 <= r2; r2--) G(e2, s2, r2); - for (i2 = h2; r2 = e2.heap[1], e2.heap[1] = e2.heap[e2.heap_len--], G(e2, s2, 1), n2 = e2.heap[1], e2.heap[--e2.heap_max] = r2, e2.heap[--e2.heap_max] = n2, s2[2 * i2] = s2[2 * r2] + s2[2 * n2], e2.depth[i2] = (e2.depth[r2] >= e2.depth[n2] ? e2.depth[r2] : e2.depth[n2]) + 1, s2[2 * r2 + 1] = s2[2 * n2 + 1] = i2, e2.heap[1] = i2++, G(e2, s2, 1), 2 <= e2.heap_len; ) ; - e2.heap[--e2.heap_max] = e2.heap[1], (function(e3, t3) { - var r3, n3, i3, s3, a3, o3, h3 = t3.dyn_tree, u3 = t3.max_code, l2 = t3.stat_desc.static_tree, f2 = t3.stat_desc.has_stree, c2 = t3.stat_desc.extra_bits, d2 = t3.stat_desc.extra_base, p2 = t3.stat_desc.max_length, m2 = 0; - for (s3 = 0; s3 <= g; s3++) e3.bl_count[s3] = 0; - for (h3[2 * e3.heap[e3.heap_max] + 1] = 0, r3 = e3.heap_max + 1; r3 < _; r3++) p2 < (s3 = h3[2 * h3[2 * (n3 = e3.heap[r3]) + 1] + 1] + 1) && (s3 = p2, m2++), h3[2 * n3 + 1] = s3, u3 < n3 || (e3.bl_count[s3]++, a3 = 0, d2 <= n3 && (a3 = c2[n3 - d2]), o3 = h3[2 * n3], e3.opt_len += o3 * (s3 + a3), f2 && (e3.static_len += o3 * (l2[2 * n3 + 1] + a3))); - if (0 !== m2) { - do { - for (s3 = p2 - 1; 0 === e3.bl_count[s3]; ) s3--; - e3.bl_count[s3]--, e3.bl_count[s3 + 1] += 2, e3.bl_count[p2]--, m2 -= 2; - } while (0 < m2); - for (s3 = p2; 0 !== s3; s3--) for (n3 = e3.bl_count[s3]; 0 !== n3; ) u3 < (i3 = e3.heap[--r3]) || (h3[2 * i3 + 1] !== s3 && (e3.opt_len += (s3 - h3[2 * i3 + 1]) * h3[2 * i3], h3[2 * i3 + 1] = s3), n3--); - } - })(e2, t2), Z(s2, u2, e2.bl_count); - } - function X(e2, t2, r2) { - var n2, i2, s2 = -1, a2 = t2[1], o2 = 0, h2 = 7, u2 = 4; - for (0 === a2 && (h2 = 138, u2 = 3), t2[2 * (r2 + 1) + 1] = 65535, n2 = 0; n2 <= r2; n2++) i2 = a2, a2 = t2[2 * (n2 + 1) + 1], ++o2 < h2 && i2 === a2 || (o2 < u2 ? e2.bl_tree[2 * i2] += o2 : 0 !== i2 ? (i2 !== s2 && e2.bl_tree[2 * i2]++, e2.bl_tree[2 * b]++) : o2 <= 10 ? e2.bl_tree[2 * v]++ : e2.bl_tree[2 * y]++, s2 = i2, u2 = (o2 = 0) === a2 ? (h2 = 138, 3) : i2 === a2 ? (h2 = 6, 3) : (h2 = 7, 4)); - } - function V(e2, t2, r2) { - var n2, i2, s2 = -1, a2 = t2[1], o2 = 0, h2 = 7, u2 = 4; - for (0 === a2 && (h2 = 138, u2 = 3), n2 = 0; n2 <= r2; n2++) if (i2 = a2, a2 = t2[2 * (n2 + 1) + 1], !(++o2 < h2 && i2 === a2)) { - if (o2 < u2) for (; L(e2, i2, e2.bl_tree), 0 != --o2; ) ; - else 0 !== i2 ? (i2 !== s2 && (L(e2, i2, e2.bl_tree), o2--), L(e2, b, e2.bl_tree), P(e2, o2 - 3, 2)) : o2 <= 10 ? (L(e2, v, e2.bl_tree), P(e2, o2 - 3, 3)) : (L(e2, y, e2.bl_tree), P(e2, o2 - 11, 7)); - s2 = i2, u2 = (o2 = 0) === a2 ? (h2 = 138, 3) : i2 === a2 ? (h2 = 6, 3) : (h2 = 7, 4); - } - } - n(T); - var q = false; - function J(e2, t2, r2, n2) { - P(e2, (s << 1) + (n2 ? 1 : 0), 3), (function(e3, t3, r3, n3) { - M(e3), n3 && (U(e3, r3), U(e3, ~r3)), i.arraySet(e3.pending_buf, e3.window, t3, r3, e3.pending), e3.pending += r3; - })(e2, t2, r2, true); - } - r._tr_init = function(e2) { - q || ((function() { - var e3, t2, r2, n2, i2, s2 = new Array(g + 1); - for (n2 = r2 = 0; n2 < a - 1; n2++) for (I[n2] = r2, e3 = 0; e3 < 1 << w[n2]; e3++) A[r2++] = n2; - for (A[r2 - 1] = n2, n2 = i2 = 0; n2 < 16; n2++) for (T[n2] = i2, e3 = 0; e3 < 1 << k[n2]; e3++) E[i2++] = n2; - for (i2 >>= 7; n2 < f; n2++) for (T[n2] = i2 << 7, e3 = 0; e3 < 1 << k[n2] - 7; e3++) E[256 + i2++] = n2; - for (t2 = 0; t2 <= g; t2++) s2[t2] = 0; - for (e3 = 0; e3 <= 143; ) z[2 * e3 + 1] = 8, e3++, s2[8]++; - for (; e3 <= 255; ) z[2 * e3 + 1] = 9, e3++, s2[9]++; - for (; e3 <= 279; ) z[2 * e3 + 1] = 7, e3++, s2[7]++; - for (; e3 <= 287; ) z[2 * e3 + 1] = 8, e3++, s2[8]++; - for (Z(z, l + 1, s2), e3 = 0; e3 < f; e3++) C[2 * e3 + 1] = 5, C[2 * e3] = j(e3, 5); - O = new D(z, w, u + 1, l, g), B = new D(C, k, 0, f, g), R = new D(new Array(0), x, 0, c, p); - })(), q = true), e2.l_desc = new F(e2.dyn_ltree, O), e2.d_desc = new F(e2.dyn_dtree, B), e2.bl_desc = new F(e2.bl_tree, R), e2.bi_buf = 0, e2.bi_valid = 0, W(e2); - }, r._tr_stored_block = J, r._tr_flush_block = function(e2, t2, r2, n2) { - var i2, s2, a2 = 0; - 0 < e2.level ? (2 === e2.strm.data_type && (e2.strm.data_type = (function(e3) { - var t3, r3 = 4093624447; - for (t3 = 0; t3 <= 31; t3++, r3 >>>= 1) if (1 & r3 && 0 !== e3.dyn_ltree[2 * t3]) return o; - if (0 !== e3.dyn_ltree[18] || 0 !== e3.dyn_ltree[20] || 0 !== e3.dyn_ltree[26]) return h; - for (t3 = 32; t3 < u; t3++) if (0 !== e3.dyn_ltree[2 * t3]) return h; - return o; - })(e2)), Y(e2, e2.l_desc), Y(e2, e2.d_desc), a2 = (function(e3) { - var t3; - for (X(e3, e3.dyn_ltree, e3.l_desc.max_code), X(e3, e3.dyn_dtree, e3.d_desc.max_code), Y(e3, e3.bl_desc), t3 = c - 1; 3 <= t3 && 0 === e3.bl_tree[2 * S[t3] + 1]; t3--) ; - return e3.opt_len += 3 * (t3 + 1) + 5 + 5 + 4, t3; - })(e2), i2 = e2.opt_len + 3 + 7 >>> 3, (s2 = e2.static_len + 3 + 7 >>> 3) <= i2 && (i2 = s2)) : i2 = s2 = r2 + 5, r2 + 4 <= i2 && -1 !== t2 ? J(e2, t2, r2, n2) : 4 === e2.strategy || s2 === i2 ? (P(e2, 2 + (n2 ? 1 : 0), 3), K(e2, z, C)) : (P(e2, 4 + (n2 ? 1 : 0), 3), (function(e3, t3, r3, n3) { - var i3; - for (P(e3, t3 - 257, 5), P(e3, r3 - 1, 5), P(e3, n3 - 4, 4), i3 = 0; i3 < n3; i3++) P(e3, e3.bl_tree[2 * S[i3] + 1], 3); - V(e3, e3.dyn_ltree, t3 - 1), V(e3, e3.dyn_dtree, r3 - 1); - })(e2, e2.l_desc.max_code + 1, e2.d_desc.max_code + 1, a2 + 1), K(e2, e2.dyn_ltree, e2.dyn_dtree)), W(e2), n2 && M(e2); - }, r._tr_tally = function(e2, t2, r2) { - return e2.pending_buf[e2.d_buf + 2 * e2.last_lit] = t2 >>> 8 & 255, e2.pending_buf[e2.d_buf + 2 * e2.last_lit + 1] = 255 & t2, e2.pending_buf[e2.l_buf + e2.last_lit] = 255 & r2, e2.last_lit++, 0 === t2 ? e2.dyn_ltree[2 * r2]++ : (e2.matches++, t2--, e2.dyn_ltree[2 * (A[r2] + u + 1)]++, e2.dyn_dtree[2 * N(t2)]++), e2.last_lit === e2.lit_bufsize - 1; - }, r._tr_align = function(e2) { - P(e2, 2, 3), L(e2, m, z), (function(e3) { - 16 === e3.bi_valid ? (U(e3, e3.bi_buf), e3.bi_buf = 0, e3.bi_valid = 0) : 8 <= e3.bi_valid && (e3.pending_buf[e3.pending++] = 255 & e3.bi_buf, e3.bi_buf >>= 8, e3.bi_valid -= 8); - })(e2); - }; - }, { "../utils/common": 41 }], 53: [function(e, t, r) { - "use strict"; - t.exports = function() { - this.input = null, this.next_in = 0, this.avail_in = 0, this.total_in = 0, this.output = null, this.next_out = 0, this.avail_out = 0, this.total_out = 0, this.msg = "", this.state = null, this.data_type = 2, this.adler = 0; - }; - }, {}], 54: [function(e, t, r) { - (function(e2) { - !(function(r2, n) { - "use strict"; - if (!r2.setImmediate) { - var i, s, t2, a, o = 1, h = {}, u = false, l = r2.document, e3 = Object.getPrototypeOf && Object.getPrototypeOf(r2); - e3 = e3 && e3.setTimeout ? e3 : r2, i = "[object process]" === {}.toString.call(r2.process) ? function(e4) { - process.nextTick(function() { - c(e4); - }); - } : (function() { - if (r2.postMessage && !r2.importScripts) { - var e4 = true, t3 = r2.onmessage; - return r2.onmessage = function() { - e4 = false; - }, r2.postMessage("", "*"), r2.onmessage = t3, e4; - } - })() ? (a = "setImmediate$" + Math.random() + "$", r2.addEventListener ? r2.addEventListener("message", d, false) : r2.attachEvent("onmessage", d), function(e4) { - r2.postMessage(a + e4, "*"); - }) : r2.MessageChannel ? ((t2 = new MessageChannel()).port1.onmessage = function(e4) { - c(e4.data); - }, function(e4) { - t2.port2.postMessage(e4); - }) : l && "onreadystatechange" in l.createElement("script") ? (s = l.documentElement, function(e4) { - var t3 = l.createElement("script"); - t3.onreadystatechange = function() { - c(e4), t3.onreadystatechange = null, s.removeChild(t3), t3 = null; - }, s.appendChild(t3); - }) : function(e4) { - setTimeout(c, 0, e4); - }, e3.setImmediate = function(e4) { - "function" != typeof e4 && (e4 = new Function("" + e4)); - for (var t3 = new Array(arguments.length - 1), r3 = 0; r3 < t3.length; r3++) t3[r3] = arguments[r3 + 1]; - var n2 = { callback: e4, args: t3 }; - return h[o] = n2, i(o), o++; - }, e3.clearImmediate = f; - } - function f(e4) { - delete h[e4]; - } - function c(e4) { - if (u) setTimeout(c, 0, e4); - else { - var t3 = h[e4]; - if (t3) { - u = true; - try { - !(function(e5) { - var t4 = e5.callback, r3 = e5.args; - switch (r3.length) { - case 0: - t4(); - break; - case 1: - t4(r3[0]); - break; - case 2: - t4(r3[0], r3[1]); - break; - case 3: - t4(r3[0], r3[1], r3[2]); - break; - default: - t4.apply(n, r3); - } - })(t3); - } finally { - f(e4), u = false; - } - } - } - } - function d(e4) { - e4.source === r2 && "string" == typeof e4.data && 0 === e4.data.indexOf(a) && c(+e4.data.slice(a.length)); - } - })("undefined" == typeof self ? void 0 === e2 ? this : e2 : self); - }).call(this, "undefined" != typeof global ? global : "undefined" != typeof self ? self : "undefined" != typeof window ? window : {}); - }, {}] }, {}, [10])(10); - }); - } -}); - // node_modules/.pnpm/jszip@3.10.1/node_modules/jszip/dist/jszip.min.js -var require_jszip_min2 = __commonJS({ +var require_jszip_min = __commonJS({ "node_modules/.pnpm/jszip@3.10.1/node_modules/jszip/dist/jszip.min.js"(exports, module) { !(function(e) { if ("object" == typeof exports && "undefined" != typeof module) module.exports = e(); @@ -10972,7 +8606,7 @@ function enhanceFlatSelect(select) { function refreshFlatSelect(select) { syncFlatSelect(select); } -if (!window.__pptLiveFlatSelectBound) { +if (typeof window !== "undefined" && typeof document !== "undefined" && !window.__pptLiveFlatSelectBound) { window.__pptLiveFlatSelectBound = true; document.addEventListener("click", handleOutsideClick); document.addEventListener("keydown", (event) => { @@ -15775,7 +13409,7 @@ function slideExportHtml(slide) { return sanitizeSlideMarkup(buildElementSlideHtml(slide)); } -// ../../../node_modules/tslib/tslib.es6.js +// node_modules/.pnpm/tslib@1.14.1/node_modules/tslib/tslib.es6.js var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { d2.__proto__ = b2; @@ -15916,7 +13550,7 @@ function __spreadArrays() { return r; } -// ../../../node_modules/pdf-lib/es/utils/base64.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/utils/base64.js var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var lookup = new Uint8Array(256); for (i = 0; i < chars.length; i++) { @@ -15978,7 +13612,7 @@ var decodeFromBase64DataUri = function(dataUri) { return decodeFromBase64(data); }; -// ../../../node_modules/pdf-lib/es/utils/strings.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/utils/strings.js var toCharCode = function(character) { return character.charCodeAt(0); }; @@ -16116,7 +13750,7 @@ var findLastMatch = function(value2, regex) { return { match: lastMatch, pos: position }; }; -// ../../../node_modules/pdf-lib/es/utils/arrays.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/utils/arrays.js var last = function(array) { return array[array.length - 1]; }; @@ -16237,7 +13871,7 @@ var toUint8Array = function(input) { } }; -// ../../../node_modules/pdf-lib/es/utils/async.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/utils/async.js var waitForTick = function() { return new Promise(function(resolve) { setTimeout(function() { @@ -16246,7 +13880,7 @@ var waitForTick = function() { }); }; -// ../../../node_modules/pdf-lib/es/utils/unicode.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/utils/unicode.js var utf16Encode = function(input, byteOrderMark) { if (byteOrderMark === void 0) { byteOrderMark = true; @@ -16344,7 +13978,7 @@ var hasUtf16BOM = function(bytes) { return hasUtf16BigEndianBOM(bytes) || hasUtf16LittleEndianBOM(bytes); }; -// ../../../node_modules/pdf-lib/es/utils/numbers.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/utils/numbers.js var numberToString = function(num) { var numStr = String(num); if (Math.abs(num) < 1) { @@ -16379,12 +14013,12 @@ var bytesFor = function(n) { return bytes; }; -// ../../../node_modules/pdf-lib/es/utils/errors.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/utils/errors.js var error = function(msg) { throw new Error(msg); }; -// ../../../node_modules/@pdf-lib/standard-fonts/es/utils.js +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/utils.js var import_pako = __toESM(require_pako()); var chars2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var lookup2 = new Uint8Array(256); @@ -16437,49 +14071,49 @@ var padStart2 = function(value2, length, padChar) { return padding + value2; }; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Courier-Bold.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Courier-Bold.compressed.json var Courier_Bold_compressed_default = "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"; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Courier-BoldOblique.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Courier-BoldOblique.compressed.json var Courier_BoldOblique_compressed_default = "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"; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Courier-Oblique.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Courier-Oblique.compressed.json var Courier_Oblique_compressed_default = "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"; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Courier.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Courier.compressed.json var Courier_compressed_default = "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"; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Helvetica-Bold.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Helvetica-Bold.compressed.json var Helvetica_Bold_compressed_default = "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"; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Helvetica-BoldOblique.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Helvetica-BoldOblique.compressed.json var Helvetica_BoldOblique_compressed_default = "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"; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Helvetica-Oblique.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Helvetica-Oblique.compressed.json var Helvetica_Oblique_compressed_default = "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"; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Helvetica.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Helvetica.compressed.json var Helvetica_compressed_default = "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"; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Times-Bold.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Times-Bold.compressed.json var Times_Bold_compressed_default = "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"; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Times-BoldItalic.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Times-BoldItalic.compressed.json var Times_BoldItalic_compressed_default = "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"; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Times-Italic.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Times-Italic.compressed.json var Times_Italic_compressed_default = "eJyNnV1320aWtf+KF6/mXcvpsWTJsnPnTtLdsdNx7ESGMb36gpZgmSNKcEhRCjNr/vsLgqhz9tlnFz03XsaziwDqVNWuDxSg/5l919/cdLd3s29n7/+5Wc+vukcnZ2fHZ49On5+dHs8ez/7W3979PL/phgS/LW669Tc/3s2Xi4udslkuUXnkyvxmsdyiNsCmW1x93l3nn93lYnMzkH36l7dXyyHdN0enfzkd2Ppviz+6y18WdxefZ9/erTbd49l3n+er+cVdt/q12/3+hz/uutvL7vJdfzO/ne7wr3/t/5h9+69vjp69ePzN8dHZ46MnR08eP3/+9N+PZ+dD4tVycdv90q8Xd4v+dnexJ09A+O3z4uL6tluvZ9+eDvx9t1qPyWZPnhz/5cmTJ8NFfu7vFhe77HzXf9mudjl59B8X/+/R0Yvnp493/56N/77Y/fviyfjv0/Hfs0cvL/uP3aNft+u77maI0e1Fv/rSr+Z33eVfHj16uVw+erc72/rRu27dre4Hug/mYv1o/uhuNb/sbuar60f9p0c/LW77u+2X7pt/dMOvXv790fz28j/71aPF8OP15uN6cbmYrxbd+i/D7f4wXOZycXv168XnbiyF8S5+vRt+Ml9dFnVI+N38yz+mgnl2+vTx7EM5Ojk5ejx7ub7YhXo1iM8H8fvOjscgz369u/xHM/v26fH43/fDf8+e7cvrn93danExBPRf/zNrPsy+Pd4F9ufhRtZf5kMc//fxHj99+nSPuz8ulvMb4yfHU/LfN/0QqY9LU06fTMrt5ubjrqCubrN22S+X85Xx5+UqX7rVxa6yF+Hs7PlemN8M0nqITr6z8Q7GEs/al/mqu112n2pS/Jnd3ny9O+P62pRnZ6fTr5abtVGL2cXQRuf5Ep+3Xz53tzn5kJVF7zk5LplcL+frz/lu/uxWfab9bZfh3YNIefd51Ym0n/rNStDFvUi7XvwhYHffibLtdExvF7eiWl30y/4243V3s4iSlcByZwOJdr9v5suMr1bd0JBFNn/fdOvRaoryolToud/7s6OjPXuZ0V8dPTvbo++82h4f79H3+Yc/ZPS3/MO/Z/SPHKYfvT2enOzRq3xfrz37p8/26Kfc9P6Zf/hzvok3+e5/yane5lTvchn8mu/rt3yu83yu9/num5zqQz59m9F/eVSH3mFEH4fO7Lq7C7ZhbfTjoMV2yr+LnnJS8jFfXywWF4vVxeYmh2KzM+310POIJjL6W7gZ96mMPuYqcSH8N6fqcl4/5R9eZfQ5/3CR0X/nK17nVMtc/iJawnSE7X0RrT4X2iqjdb4vEftNztB9bkIPOdUfGW3zTfzpqaxoh/rVUa08LbVyVUlPPdzJEdTGu8XyssuX3nf1l/2DiHPonb0nuBvHaV45jkr+P+0Ghuiz9put6js+LfvVQvB1VznLxWY1dOMXHsDjoxNoNuvFOHhNrb6MWnSzutosBuWmv9Mjh508nvgrcmVw8Wmh8i360WEoqIYDl/OrK9Wl7TkOxWjAsSu7btV52z899rHQ/Go1/wKmVn76cZhEdCKXHt6P8/WBCB9WKyGyAoj6c6uhy+Xiy3rhDXWYLnhW7z73mzBUTL1+qNtecKv5vfDf+cXmTo1cRiv/tOz+yBo1rIJv5hcrNdr5uOrUhS/7u/lFaHAuLYaCxACYssJm6Dc7TOmGEbcYom5ur+arzc1yvhGX6a+GUea1ON0c8+HFchNqrPGXPuY5PptqQL+6/DQM8sKo0IcnsYf10UfkL4p/vvELPD16Yhe4GVxus8QrmC/PRXd3uWvw67XovJaVkXkfuZ29F0PooW0O0+GhzotC+zGVp3fLsfp51x8rjXdLskT9dLHofGSU7sDG0JeL+8WlKKQ23pkPlkXL8NuOP/JRnviRd4/UBK2jHudd1EYgq/mUfr3QThynMPidU2Pw31RKaEM/8BlAuojPFwaDgAlInGBSRs+emTiteIhLkeX4mJDqgeUyxMVnAuoGvHnU6mh0VB/lq7P5NKp2tuiqEM7sk15DQjaBkyH60DVe/eRsusqy/7O7vRKXfxcv4TM4lUmvHAcbiRC9eXEvYiPZeCNQ1JRXn/vkyNllfvvcr0Su3tDVPQyVUvuVeLmry0rYzukCHrHYs4XFjfVmHOGsxP3GKuhRrPFoq2aCN5vl3eLLcivuizLolTwWR+n4hrHW3WK+vFx8+pTLaptt2JpgvI5X2EOV5YeD1exAr1OXLioFfVuzQa4x7ilzORr6kfoVXHobBgy4/mbTn1V/3d3iJMjMcdVdLdZx2OtNtDLw+lG0C5uJbIZWHeYiHmwaQFrDrESm56pu7bJSpf6LTPvkRRm4jqtccQ3McvnDnRihfFc1wKXyLW9uFZPpqr1jrRd8WRs+HKiVlQD/WWsatZt6UyuRWtdT89x17cr1Lv7NwWEJ21IZF3TLO7HYcxdM2gvpoT/giPUhzs1G5IT6cAuVHGd6W6DQ+yw1jnDOTtHHhwq8GiqyuLVf0wymKMtYI33VU/a/NsOIBffiebmN8kBHeWJ9PvZjZe74Y627/Im6vxKGIWif50tYeCttfDcziQ3ci+KQyd/GUZPXtK+UHw2DLAi17vkqeilmaCpVVah6EPqrHO5aBdYzHKtgg0uoxx09NS13Qn0Tm5j+5LRMsIdu80L57PeVsebq4Gj351g+fruV0e67w9VaXsustXLOl1WP1rOkN5WFwz8PjCd/qPX2dG1fHZZZsfFYGAj42Q42hXgLvrh78ErL/mpX3re9GMX3dS/dZKk05eFUlZZ8dXDO0N2Jhw5/Vqrv7cFufAh56iHc8mtt/IfN7kHkvx/PXner21/mi9Xu8fG/Zi93j6lnj795+uTfj6ejvXsEtL/PiCZPR/j33dGpHe1dJSDMGApvhqMTO8+bcguAoHIEbkUV6L79BxScJyhTyALbLw4FtG84iN6Go992OTqzI4sZoJh7E86Ho1M7z3nJPaCQe+CQe6Al94Ao96BY7oFN7Tqw0U6QvB+Ojp5YETbD4Qs7andJ/ciy5Ahv3SjsB8AAbYajY7vwppwNUAgQcLgK0BIgQBQgUCxAwCxAwKYAObkPWXsIR9t4lOOzzfGZEmF7NUSN1ji1XOfcfIsCbdgQNWTjsjUXFZq0IWrXxlXjNjG3cJOomRvXbd1kbvAmUKs3Tk2/8LcZgQkYIidwruygqOAJhsgYjCt3MDFbhEnkE8a1WZjMjmEC24YJ0TsKRgMpDFykoDa3APYT4/VGo5ylaGAvhshjjCujMTG7jUlkOca175jM5mMCO5AJ0YYKvs8RechoK1Al1MKfJptAfzJE/mSc/Mk5+1NRwJ8MkT8Zl/5UVPAnQ+RPxpU/mZj9ySTyJ+Pan0xmfzKB/Mk4+VPhbzMCfzJE/uRc+VNRwZ8MkT8ZV/5kYvYnk8ifjGt/Mpn9yQT2JxOiPxWM/lQY+FNBbW4B7E/G641G+VPRwJ8MkT8ZV/5kYvYnk8ifjGt/Mpn9yQT2JxOiPxV8nyPykNFWoEqohT9haNCkIieniiLZFYnsWUEG44qc3CuK0sJCEvCxyMnMoqgcLabIthZ18rYoaoOLadjlokpWF0XyuyC+rXBwvsjJ/khUHhiSgBFGTm4YRWWJMUX2xaiTOUZRO2RMwzYZVfbKqEbDDBq6ZhDAOgNvKy2UTTSKX2neyk5DAvDUyMlYo6jcNabIFht18tkoarONadhxo8q2G9XovUG7rwTyocK3NX6o1IQpO0FLRkqGjBLZcZDYjEEEK0ZKRoyStGFIACaMlCwYJWXAqGf7RZXMFyVtvZiCjRc1sl2UyHRBeispGC5SstsgKbOFBGC1SMloUVI2i3o2WVTJYlHSBosp2F5RY3NFLVorKGisgMFWgbayhbGlonSwaSo7BRnMFClZKUrKSFHPNooqmShK2kIxBRsoamyfqEXzBOVehuxB0q2m9XIRljnlHv3SEJmlcXJK52yTRQGPNEQGaVy6Y1HBGg2RLxpXpmhidkSTyA6Nay80mY3QBHJB42SBhb/NCMzPEDmfc2V7RQXPM0SGZ1y5nYnZ6kwinzOuTc5kdjgT2N5MiN5WMBpbYeBqBbW5BbCfGa83GuVkRQMbM0QeZlwZmInZvUwi6zKufctkNi0T2LFMiHZV8H2OyENGW4EqoRb+VO4VDcoZOZQLZFEgsEeZBCbljFzKBWlTJoNPOSOjckE5lavZqlwjr3JBm5Xr7FaukF25QH5lwlvBwLGckWWBoDzLZDAtZ+RaLijbcjX7lmtkXC5o53KdrcsV9i5XonkZR/cyCPZlrBUthA3MhQPNSlmYieBhzsjEXFAu5mq2MdfIx1zQRuY6O5krbGWuRC8zfi+C8yDYVrFa5IWhlRtDQ3NGhuYCGRoIbGgmgaE5I0NzQRqayWBozsjQXFCG5mo2NNfI0FzQhuY6G5orZGgukKGZ8FYwMDRnZGggKEMzGQzNGRmaC8rQXM2G5hoZmgva0FxnQ3OFDc2VaGjG0dAMgqEZa0ULYUNz4UCzUoZmIhiaMzI0F5ShuZoNzTUyNBe0obnOhuYKG5or0dCM34vgPAi2VawWeWFoq+n7JO5AhZCZFUxWZpiNbBLAxgohEytYWtgkgoEVQvZVsDKvomXrKgoZV8HatorKplU4WVbBZFgTfpsImFUhZFWGlVFNIthUIWRSBSuLKlo2qKKQPRWszamobE2FszEVHm1pomhKEwJLmkibajjbUcHVJqGsaJLAiAohGypYmVDRsgUVhQyoYG0/RWXzKZytp/BoPBO9T2F4SGSbiY6tsJupEaDfGCLDMU6O45wtpyjgOYbIdIxL1ykq2I4h8h3jynhMzM5jElmPce09JrP5mEDuY5zsp/C3GYEBGSIHcq4sqKjgQYbIhIwrFzIx25BJ5EPGtRGZzE5kAluRCdGLCkYzKgzcqKA2twD2I+P1RqMcqWhgSYbIk4wrUzIxu5JJZEvGtS+ZzMZkAjuTCdGaCr7PEXnIaCtQJdTZn/460Je7K/uRBdFR8RJAMaTOMZpOLZCOPEjOPD7OSmiclIbt6HyslHZUcgAo3C5wuF2g5XYBUZGDYhkBZhkBNmVkT76f4r733+8x7oCih3+f4g4cMgK0ZASQ3S4wu11g0+0CKXF39N689PvJBvyojUexF/me2v1EJ9PFyBii8BinGBlXgTIxR8skCplxjpsJHDwTYgQNUxgLf5/D0GTUCkShNS7iO77DGONbEMe3cI5v4TK+RRTxLRLHt/AU3yKk+BaB4lswx3fi73MYmoxagTi+haf4/m0K7dHRqR2aFwErIUUWDQoEdCjAZlHA3IkAuhUBLF4EqIQN2G6keeZHJSuASk4AhYwAh3wALdkAZLkAZpkANuUBSMmCo/0HLodMPTUUE3Q5U10Z+iHSmepkpuCF24BzXjuR107kdbGrYn5kFdJRHIw7xzrq1Ibgjnx47czuxFnvw7/x0LtaZ9TXuhA6W8fe2zpL3a1L0N86LJMAZFajnU1fMA0VYmWDofEoDp1GVCoEojAN2Auvpua/N4NX2PoBlSYDSMykXlHTBxrnT69CwwfmhedsajJA4iTp1dTon1p+5rFbeIWNHpDoDF5Rowcau4BXodEDI+N/BY0eSLT7V9Doj4108SiOcF9hm0eUR7ivqM0jhTYPOA58X4U2D4wGvq+mlgZH+Z77yg328gb7fCfcyEAR92hNDFAcib/CBuZoEwpnkyvUplJ7NrL2bHLt4fkYKKJebUS92oR69Xq2XwnZT33HoziLH5GYwI88zd1HGqftI5Iz9lGhyfrISvgBlfA76kIeuhjr11jREeXwv6aKjhQqOuBYKq9DRQdGsX89VfQTy0EfLfN1qujAkz++xooOSC4tvQ4VHVhcUHqNFd3RJh7lu95U7noj73qT75prNSjirjfk96+hVjvZxqN819t8d6Grw3ZBAjURUlVroSS54VACakOk6uZEibhlkUyNjFRqb1GFyk8CtUJSqUGyKtomJcnNlBPkFkspqPGSyu2YZG7SUe5rFYkbOqmq9VCSr1VVdgJSdfOiRNzSSCarIJVcI6qbqnAwMNJWKMnXAsNmQ+r/JTDJgkhmNyI5GlMUt1XhYGCyc/002y/tH/uRDfMAhZG8C7v1gv24fnfUhKM2pGzjsvOI0qLyjorl7J+mDD+1RJZLQNjE9xTfuT8mRJmsvHNPKmQX30cn1OYfcu7V++gkqTjga9iUR46Ieg17kmKVgOCQQCFiVQUqpoFwRaGpCW3tVBxAUnMYYwIVzNygZHw4sPUGNSWY7A4Da4hC6lwFs6gQxoKajNr8Qw6a8RyuIqlAFW2b88jBMZ7C8vNseoZyZkd2d47sGYqjOIFzjnlwahM4Rz5Nc+ZTSWflGYoTm7ntUWlSLwWivBinDBlXuTIxZ80kyp9xzqQJnFMTYnYNU57xYQMjynN62MBc5Vk9bGCJ8pwfNrDAeeaHDYw5z6GFv6wKnP+ochSiKmMRk4iIxAQcl6im6EQ5xSjKFKkoUrzKg9OXAlGMjFN0jKu4mJgjYhLFwjhHwQTOvwkx54Zjnt9M2d178BvMKaCSSUBxhuc8PXN+g7kC5HMzZ747wVnZmODEJmaGfrNR4BvsnBCFfsmFsUuyoyYcfQgp26D59gZHaUb7Bo12uttktMwp1tpoWcxRT0bLnOOfjZaFWBLJaIlDmaSxauKqdMJYNaImow/5h21OxcWmhq+TFF7nhgKMnEoxilSUUVTlGVPkQo06lWwUuXijymUc1VjQUaPSTh+eOBHR43I/9OEJleR9pVSaCv9QOU9bSc+1ov79hb0OL61CxUBK1QIlqhQoqSqBeq4QqFJ1QIkrA2pcFVCLFQEVqgb0MvxJihNXgfrL8DnBexn5RtIP8gytTMvFXntHfK+W1wChxA1RcRunsjauCtrEXMomUREb5/I1gQvXhFiyhqlY8R3fkxgGLtDKO76kvs/xbDL6kH/Y5lRcfPKV2L0U17iwCFmhkmSZCpRlVa6cJhcvp6BSZpkLm3Uuc9Zj0bNKNYBkqAisUH1IsqoWlOh9tcSaqvKhera2+huuOSznCmTvzEHVcUaVxgWqLi6oiuJqriKuUeVwgauFK1whXIlVwTlVgvDm7AlFhAu+9uYsy+9FdBvBPojftiIdF6p+wXSvldUdKE1DVJjGqSyNq6I0MZekSVSQxrkcTeBiNCGWomEqRFzNO4lh4CKsrOaR+j7Hs8noQ/5hm1Nx4akFvknCSfqUtTRJZ05lpyfpLOayS5N05lx2eZLOQiy7NEknDmWXXl1IXJUd7uuneDYZfcg/bHMqLju503+UfpmK7YUfld8CKoUFKJQTcLgC0FI6gKxggFmZAJuKA0gpCUe7zUbP/ajkAFDJAaCQA+CQA6AlB4AsB8AsB8CmHAApOXBE+yR3KCbocqbsyTUinalOZio8mAac89qJvHYir308yvfcV26wlzfY5zvhp8agiHu058OAcvB5U+LbGb7RMB7FNxpGJN5oGHl6o2Gk8Y2GEck3GkaF3mgYGb3RMLLwRsO7Gb4+Nh7F57UjEk+vR54e3o40PqcekXw4PSr0RHpk8fn8iOJD+XdTrOEo3/V55a7P5V2f57vmWIMi7vqcHp6/g1g7GV/Eel6OmnDUxiOrPY6wluxpWfiCMjREITGu4mJiDo5JFCHjOkwmc6xMoGI2TmVd+LlAlSzKojexnkWuBMYPZzFVBxO4TpgQKwYukVLBNhm1AlFlUeuhk1QeMkGNMUThNK7CaWIOp0kUTuM6nCZzOE2gGmOcakzh5wJVsihrjIn1LHKNMX44i6nGmMA1xoRYY/D9IyrYJqNWIKox6v2jIqWthOUm9FZCrcoAV7cS6gQc7INbCXWiFHi9lVCrXM+Cel4VDgZG17yY5GuBSbUwqv+XwOQaGeVUL6NMtTPtupFVqakJbVXgWlvddbNPMEy09hPMJ3YUZzkjsmmlI7HxdeRpLjTSuMV1RLRldWT00vbIwvvaI4n7VX+bmpzn502MwW+pcQGXAbFmBIiHla74sNKZvbfjyF7bMbSbmbw4tiObITqyGaKjOEN0jjNEpzZDdOQzRGc+Q3RWZohObIZo6KJfwirAnuxnXGcnhcRfdDmXNuFCFGqXc6xdQGHCBSexSufIK50zkfnP2y+fu9uQjUXIpr2rBoiWPnasD2ftc977SnH2sjj7XJw8cQNFFLRN3ADlUrWJm+d+FbK1yrmnl8n2SLxMthPW3c2i1JxnRjchzSZfYiMWsUae1q9GGpeuRsRb6V2h9ayRifLchFWsHXkIYdrGo5IHQLjLbk9xv9bkaGm/FnPyY71fi8XszGm/FnP26Lxfi4Xo1mm/FnHw7TTEZq4cXA2xWSIvrw2xWWZXT0Ns5uTvhYPJGyIfME52b1yZhInZKUwiuzDOzmACW6EJsTMwTN5ROHULjkPfULA4AfcSxqmrcC76CxNzp+FS7jlMo+7DOPchJtSix71J4YscIu5XjLMZFaHPl+NuxvihaiQ6HJMq1ajS9Zhcq2XcCRmv1Cbujgpf5Whwx2SceifnqosqquinirTJqbnHMq66LRNz32USdWDGdS9mMndlJtSqEHVqBT/kiG8Foj7OuOjo0ibd0hvoTbpa5a7vwCZdnUR0g3qTrlZTl1jZpKtl6h71Jl2pYlepVxW0KrvN6qqCTsBd6MFVBZ0odad6VUGr3LUGFTvYKLAPRpU726hKr4xJhGPGBOybUU32GOXUmUSZOuQospEGlTtnEmMXnV4FladM3bV+FbSiqq67+ipoJYHoxvWroPr3qUuvvAoqz52696AuaqFOXX1Uk1vHdzBrN5M6/6h+vVqrgUBMcLBa1wYFMdHhup8GCFE9WLvTYCGoq1o808Ahqjx8IFUOIkIaNZSIr47WfpmGFVGVg4uYRAwxYgIeaES1MtyIidKgI8qHKzMPQIL4UCvLbVXgIUn99b8xwfk0GtkvzZ7jEARQ/L7NeRpsAE+L0ec4rABEK8rnYQABLKwdn+NQwVFx7v0HSs5n6ZslZZEd85re0WBOudbvaLCY85/e0WDOkcjvaLAQY5Le0SBO0SmYQ5RehZhOo1+FkCJF7MCrEDJFjp1+FUKKHMXKqxBSjfHUr0IokSIbNA4vvU4wnU69TiAkCmz1dQKh56Cq1wmExAGVrxMILQZTvU6QJQokKBxG3KA/nSdt0GdO0dMb9FnMcUsb9JlzxPIGfRZirNIGfeIUpYI5RGIf/HSi2j74ikxxO7gPvpImR7G2D74ic0yr++AreoxwbR+8linepHLYw+7x6YR593gSKMiV3eNJzYHNu8eTwMEUu8eTEgOYd4+zQEEzzuGyv+cA4XJG4XKBwuWCCperOVyuUbhc4HC5wuFyJYbLOYXLBAqXcQ7X9DV6CFYhFKqCKVAFqzAVLQepKBSigjlAhXN4Co/BKZRCM2EKzEQpLO+nkDx7YkclHIBKKACFMACHEAAt2QdkWQdm2QY2ZRlIya6j3fLWUz8qOQAUPxnlPH23YqT26SdH/DU9V/xLUM7KHBSQfZLR0Li3+OjIDm0pDph/FdcZfRXXBVyKA+xfxXUGX8V1CF/FdWhfxXXkX8U1Fqen76H6HR2/KIh+04kM23JPYJUMhy/NAoX1HExtn5p15J+adaaiYKs0p5a/3dLMfo44HsVp44hinXOe5pAjtTrnyGuWM/8QrrE+3msvwtrXQtjrOtOLOpM+PwuSqk7++Vlgour4Tm+vKbji4RndxKMc8rigARwrilOrEI4oj6B4VXEmCqMsR+xJE+y1yfbaZHttKvbaSHttsr02wl4bYa9Nstcm22sz2eu+u2jQXgGJr642ZK9A41dXG2GvoNBXVxu0V0Dxq6vNDJf2m1laz29maRG/Sd4KPK1rNrO0Rt/M8sJ8M8ur8c2Ml+CbWVp3b5KpNmCqnib+osu5pAX0Jhkq8LRU3rCfQuK4KN7M8kp4M8vL3w266f6DU80MF7qbWVrdbmZ5SbuZ4Tp2M0uL102yPeCyOPtcnHpBupnlVehmlpaem1lab27Q7xzlBd5mhqu6zSwt5TbJ7oCnRdtmllZqG2F3oNCabDPLC7HNjFdfd2RcWTXr8OVUR2jGI21n+ES3RZcEFJ/dtsklgaentC26JCB6HtsGlwQWnry26JKOxmesp3ZkvbCj2Ak7xz7YqXXBjrgHdsU7YGfW/zqy7teQu0mbXbLNLtlWXLKVLtlml2yFS7bCJdvkkm12yTa5ZJtcsg0u2WaXbLNLthWXbKVLttol2+ySrXDJVrhkO0tPBtsZjjnbWRpzjkiMOUeexpwjjWPOEdGYs53lMWcbrLfN1ttWrLeV1ttm622r1tsK622z9bbZettsva203nayXk+zydnbVLK3kdnb5Oyx9YIisrcR9WMTGwc+oJlMKT2gYU6Wqh/QsJjNNT2gYc42mx/QsBANNz2gIQ7Wm17PY65MWL2exxLZce31PJbZmNPreczJoguf55JmszZOjm1c1VkTc8U1iWqvca6oJnBtNUFXWTZ1f+4W2iU/jqPU4gRs9MbJ7Z0fiJDwfZey+ZtGPYBx7gZMqEWPO4TCFwJR12Bc9Q8m5k7CJOopjHN3YQL3GUXoc7649zB+qDREP2JSpb5WehSTa9WZ+xbjlWrLvUzhoqsp0ian5k7H+KGoiO7HpEpUKh2RybWopC7JhNjI+StwTxKl3kl+BS5Lqo+qfQUuq9RT6a/AZY37K/UVuKxQrwUSdFxIqe9CSXVfqOceDFXqxFDS/Rim4K4MNerNUKIODaS5rCXcraFEPRtKqlmgnlsGqtQ4UOIGgBq3AdSqzYC7u/AYP9iDeMCff6PPxF0fStT7BelwFEUfGNTcDaJMPSFK3BmidiDI3CWCtNCUOkaUVN+Ieu4eUaUeEiXuJFHjfhK0XmaZe0uUvlJ6os9Etd4GKj0npjjQSrj/RKneFLgXBUl0pKBu5G+4O0XpK2ETnSqq9bBVulZMcSBsqYNFLZjL4Asz/+bMeGTPDR3FjaaTUDrtK4HoHMbliabEeCJDdCLj8kRhD9hVjdMpoyjPC9G70pTOiZI8Y9k+dCUQncu4PJFt8bhSjE7lgjyX7X+4UozO5YI817Rl4CoTOk/B8izlQ2dXAtF5jKsTfURTODHkf/L8IzZzQPHhlHN8OOXUHk45kn/Z/GNovsDo75l/hOa6Jxe7jssGRLuj66Bdx9xPgs0C/ZcFXedU+hz2TqGfo6DrnKpyjmEMsFzO6SwGr1VKfab9iGb/J0guPy7LXyE5OskyabgKcGTEd8aEugUo3oYL/gj6tKD7cPQQjrwe7Y78z6SMR3HzyYjSJpMyOONMoBufEKLsVNyYVM5Y4fcZPWQE+Sxom/PAOTaes83v8h5FDNk2RNk2LrOdXvqcMlT4fUYPGUG28d1FygNnW767OElqy/OR0DAAsruTog6F3EpdcorifYU/VDiGB/m2kuEUqCDmaIlJz1FSIFKqCxeSjJIab055Bule0gdJITpAtzJ7HBmURFx8cpUCAxJGBjGHBjUdG0iRggPavcYPGmN8AG91PlOEUMsh4n3eRxFDaNJAjbkMSdowPmWw8PuMHjKCEBS0zXngrBvP2U5bh4+IQ8bzuDIJMut5G/KUKxPuBXsQDLJvbCsywwFwIUcg7QY+Ig4RyKPhJMgI5J3FU85MuBfsQTCIgLGtyAxHwIUUgU8p7zsyNJdlt17vlkKeGfw0K+9C744Wdi/jEQ1eP+XsfqIx2X4KepWuvyNdPLJlTUe23RNQ/obryHFlEyhu9nQcP+06IvqA68joA65xtiNmOtVZzlUOVPkpx6XgTiCKkHEKk3MRKxNzwFzKUTONQmec42cCBzEvBVxVlgKuDi4FmMqB1W+dTz/Kb51rgUJdeeu8ooqw1986ryTIRVB561yrXBy1t86lfFUVqIBIlcVUeYd6X1jXoRCuc+Svc7ivKzG+loG91tG8ziG8FnG7FsHasT4e5XvuKzfYyxvs852k/dSuiHv03dSO7MmKoW08yne9zXdXazAs0MkONpikilh9rcGkBLmIDzYYVjmohxsMyX1VOBgWWUnqn0zQCQ5mq1KLap9M0DLVrconE6S6rQoHA5PrYRlC7kdbt7hSMSGcxRcUTgpCWUl01Afb67PX9TWD68vQbn+Ul8z7tEjDXJ42LMbsUWXxuz+0+N1/ffG7zxP+PZeL4r2aUQtJXomnzXual8r7ylJ5f3CpvA8zrT2it0qv6gpdiWV5QUoE1xWr9n1t1b4/vGrfx0nUnpU/7nIlEJ3duDx5UeHceU2+r6zJ9wfX5HtsZ3tU+v/aum7USRzZsvt0V/T9/8vrQviTmb/EGPEQyfmd1uIlxTlX+nf2gRellZ5PanHdO6dYmz9FXC6otHJBqZU1d62KeW1M8WV+0VVis/vJ0/yTu3hSkcLrxhDe/VuPp3YUt7qMyCqgI7HrZeRpt8tI4y6XEdHelZF5j++svO3oJG5f2aGLWXlzZTyySbqjUkKIrGAAlpnLPtqrqVJ7AqvLjuKVunzxLl88Dr+A4zICUBhoAbYNDo58Y4Mzi6qzq3hUyhcQ1SETbH/HsdWf3UjsxMrChl+A4hvaziG3QO3NbEf8QXdX/H1tZ/ZNe0f2QrYhnxV5Wf8esuojoRUaAKA4xF7F5o5QGHVxMGx+aR8xc2qIeh8xi7lJpn3EzLlx5n3ELMRmmvYRE4cGa4gajnFqPc65/aZHeFPBFn6Zk3Jzxp3LjCr3x61b71xmMbdzuXOZNWrxeecyC9z2cajMiFygMlQmlf0AdxWfxEJnZ9C7ilnMHpF2FTPXbpF3FbNAvpF2FRNPDlKE33OYwEsMkaEYJ1dxztbiivIX/GL11PzSF6uZk7/oL1azmP0lfbGaOftL/mI1C9Ff0heriYO/GKL2a5zar3P2l/SsfCr2wi9zUvYX/EY2o8r9sb/ob2SzmP1FfiObNfKX/I1sFthfcOMAI/KXysYBUtlf8EPZJ7HQ2V/0h7JZzP6SPpTNXPtL/lA2C+Qv6UPZxJO/FOH3HCbwF0PkL8bJX5yzv7gi/SWs9KDLRIG9JqrsOFGVvhOTCPeJCdiDopqcKMrJj6JMrhRF9qb4jATKMArsA1FlNyA1eZZ+MFMqVFAvaz9LLpbWp7VwMCfJ1w6sT+skwuPq69M6BftdZX1ay8n70gMdLbAPHnqgI9MkT0wL4yeqyiV/PLAwrpMIr9QL41qt+GZlYVzL7KF6YVyq2U+D/Hst3OitUWCHjSr7LKnJbUkXnjstBo2vbe03DBixW4nY7DVi8RV509BQoxK/G2+YvgVv3L0z8mKakcaPwhf8WyYWVsIxXkHc/UG2/R+tLWT3l9hOQkx3f4LtLKSxv71GGAK0V+7BWvcvjdxjddujh5ToISfaQqL9Bzy2mGhCPNElzMnF9r2s4I/+/b//H63X5Vs="; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Times-Roman.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Times-Roman.compressed.json var Times_Roman_compressed_default = "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"; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Symbol.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Symbol.compressed.json var Symbol_compressed_default = "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"; -// ../../../node_modules/@pdf-lib/standard-fonts/es/ZapfDingbats.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/ZapfDingbats.compressed.json var ZapfDingbats_compressed_default = "eJxtmNtu20YQhl+F4FULyMGeD7pz3AY1ChtG7NpFA18w1NomIlECSRcxgrx7SVk7+wOdG8H5OJydf2Z2d5gf9cV+t0v9VK/r+6vXsXlOlbHe28paq229qj/t++m62aXZ4J/m8PRb1z9/baZxefK63Z6eXN5dVMvTCh83u277xr/6kLrnl2XNq7TpXnczuZyabdee98/b2VzM/x4/dd/T5qab2pd6PQ2vaVVfvDRD005puE3Lu7eH1HbN9hTjx4/77/X6y5lcnUmjVzHIVVDicVX/1W/SsO36dLMfu6nb9/X6TAoBD+5euvZbn8axXtuZ36dhPJrVQqgPQoh5hev91LWLkIv94W1Ygq9+aX+tZAx2tfz64284/sblN/rqfLP/mqrbt3FKu7G67Nv9cNgPzZQ2H6rz7bb6vLgZq89pTMO/M/xfEqturJpqSM/d7GJIm2oamk3aNcO3av80O5xh3yyKmm1193ZIT02bqovTKjP+MAf++7zsZvZ3276kYyWWXB0z99S18/PbafPHQ71W4fjn/fxnFO+ZvkrT0LVzTr78qB/+nk38bHM9exgP8zr1z9U7jt6840YW5uSJKcZOCaBBnKgm5mU8MVNYyMwWFvO7Ukagkmgg6sDWQ5yFFqjzUrLEaQ3BEmiwNsMSaZS0vgWfOkPHWQowNeTUc0kumnxZvsgPxlGai6VTGUqAVCTQ6QkWnc77DKEiLktSUBJKqHIQZ86d8gCpHYoiEzMsb1ubYy8vW50DChB5ZhGqrijD0EqUIeiaEHIfCg5Kpuu0ApiToaGPSY0uaQsyr65L2oKi1yFt1PLaQ3lzfXTgXodGoJYzglndSLDMPg1sTPJpQJHJigw0QrGERqD9YhyTOgONQDUyuF1zaxuokc/BW2ztXCMrGZ9WMW1oQZHIXWNBkSCfRZEL5BMUiZw6CzVSFCfUSGZFNjIldoKDkonTKQiJIGzWmFd3BizJJ9SINoLDriOfUCOZS+zg+KGD1qGiLNMLxtJD1/ns00ON6EzyUCM6vbxhoBKaqbG3DFQCNiL1iHccBPV0DHhQH/JW8EW90dkyFKGywCJU0WkVSvSGeiSUODWFFD0HYdPQVoiRgfPMA+/nnRgiAyNYSjpWNQcNSMrtFCUH4ZIRpSCWocFCSuhCEY6hoUClc0WC52BJlCYYLQdhN+hygRRRlo5BKRRLS6oihSqh+ZzzRGG1Mo4Iz1LoP0qsxDGFzk0JE42ji0jCPejomJKCuwil4m5CiRMEUMVSzVLDUstSx1Juc0oVWMpqY295qVltmtWmWW2a1aZZbZrVplltmtWmWW2G1WZYbYbVZlhthtVmWG2G1WZYbYbVZlhtltVmWW2W1WZZbZbVZlltltVmWW2W1QYjQCh7E2aAQHeGhCFgPoNoy8KNb2wxBhmGKBxoUZXlLGsLI6AsftEDHV0wIURVbANLcTKlGGBIKPOAxCmhePCKUwFzAmpDFRQvjA9R06Hq8TONvshgKDCuRAZTXigUxjxNFfKRo3CLhnIJBMFRvMZpqpNBMlQJzGT5WFQMVQI/AikPMIhEU1aDjqJvQwmjSHB05cC9jbYwc5UtAHNLhDw41ha+lEqF4JaH3gmB61SYcqInxTDmQK8v08vjqv4zDf1N0w3Lf4A8/vwPpfK11w=="; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Font.js +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Font.js var compressedJsonForFontName = { "Courier": Courier_compressed_default, "Courier-Bold": Courier_Bold_compressed_default, @@ -16550,10 +14184,10 @@ var Font = ( })() ); -// ../../../node_modules/@pdf-lib/standard-fonts/es/all-encodings.compressed.json +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/all-encodings.compressed.json var all_encodings_compressed_default = "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"; -// ../../../node_modules/@pdf-lib/standard-fonts/es/Encoding.js +// node_modules/.pnpm/@pdf-lib+standard-fonts@1.0.0/node_modules/@pdf-lib/standard-fonts/es/Encoding.js var decompressedEncodings = decompressJson(all_encodings_compressed_default); var allUnicodeMappings = JSON.parse(decompressedEncodings); var Encoding = ( @@ -16589,7 +14223,7 @@ var Encodings = { WinAnsi: new Encoding("WinAnsi", allUnicodeMappings.win1252) }; -// ../../../node_modules/pdf-lib/es/utils/objects.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/utils/objects.js var values = function(obj) { return Object.keys(obj).map(function(k) { return obj[k]; @@ -16603,7 +14237,7 @@ var rectanglesAreEqual = function(a, b) { return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height; }; -// ../../../node_modules/pdf-lib/es/utils/validators.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/utils/validators.js var backtick = function(val2) { return "`" + val2 + "`"; }; @@ -16780,7 +14414,7 @@ var assertPositive = function(value2, valueName) { } }; -// ../../../node_modules/pdf-lib/es/utils/pdfDocEncoding.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/utils/pdfDocEncoding.js var pdfDocEncodingToUnicode = new Uint16Array(256); for (idx = 0; idx < 256; idx++) { pdfDocEncodingToUnicode[idx] = idx; @@ -16838,7 +14472,7 @@ var pdfDocEncodingDecode = function(bytes) { return String.fromCodePoint.apply(String, codePoints); }; -// ../../../node_modules/pdf-lib/es/utils/Cache.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/utils/Cache.js var Cache = ( /** @class */ (function() { @@ -16865,7 +14499,7 @@ var Cache = ( ); var Cache_default = Cache; -// ../../../node_modules/pdf-lib/es/core/errors.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/errors.js var MethodNotImplementedError = ( /** @class */ (function(_super) { @@ -17238,7 +14872,7 @@ var MissingKeywordError = ( })(PDFParsingError) ); -// ../../../node_modules/pdf-lib/es/core/syntax/CharCodes.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/syntax/CharCodes.js var CharCodes; (function(CharCodes2) { CharCodes2[CharCodes2["Null"] = 0] = "Null"; @@ -17302,10 +14936,10 @@ var CharCodes; })(CharCodes || (CharCodes = {})); var CharCodes_default = CharCodes; -// ../../../node_modules/pdf-lib/es/core/PDFContext.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/PDFContext.js var import_pako3 = __toESM(require_pako()); -// ../../../node_modules/pdf-lib/es/core/document/PDFHeader.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/document/PDFHeader.js var PDFHeader = ( /** @class */ (function() { @@ -17346,7 +14980,7 @@ var PDFHeader = ( ); var PDFHeader_default = PDFHeader; -// ../../../node_modules/pdf-lib/es/core/objects/PDFObject.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/objects/PDFObject.js var PDFObject = ( /** @class */ (function() { @@ -17369,7 +15003,7 @@ var PDFObject = ( ); var PDFObject_default = PDFObject; -// ../../../node_modules/pdf-lib/es/core/objects/PDFNumber.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/objects/PDFNumber.js var PDFNumber = ( /** @class */ (function(_super) { @@ -17407,7 +15041,7 @@ var PDFNumber = ( ); var PDFNumber_default = PDFNumber; -// ../../../node_modules/pdf-lib/es/core/objects/PDFArray.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/objects/PDFArray.js var PDFArray = ( /** @class */ (function(_super) { @@ -17523,7 +15157,7 @@ var PDFArray = ( ); var PDFArray_default = PDFArray; -// ../../../node_modules/pdf-lib/es/core/objects/PDFBool.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/objects/PDFBool.js var ENFORCER = {}; var PDFBool = ( /** @class */ @@ -17572,7 +15206,7 @@ var PDFBool = ( ); var PDFBool_default = PDFBool; -// ../../../node_modules/pdf-lib/es/core/syntax/Delimiters.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/syntax/Delimiters.js var IsDelimiter = new Uint8Array(256); IsDelimiter[CharCodes_default.LeftParen] = 1; IsDelimiter[CharCodes_default.RightParen] = 1; @@ -17585,7 +15219,7 @@ IsDelimiter[CharCodes_default.RightCurly] = 1; IsDelimiter[CharCodes_default.ForwardSlash] = 1; IsDelimiter[CharCodes_default.Percent] = 1; -// ../../../node_modules/pdf-lib/es/core/syntax/Whitespace.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/syntax/Whitespace.js var IsWhitespace = new Uint8Array(256); IsWhitespace[CharCodes_default.Null] = 1; IsWhitespace[CharCodes_default.Tab] = 1; @@ -17594,7 +15228,7 @@ IsWhitespace[CharCodes_default.FormFeed] = 1; IsWhitespace[CharCodes_default.CarriageReturn] = 1; IsWhitespace[CharCodes_default.Space] = 1; -// ../../../node_modules/pdf-lib/es/core/syntax/Irregular.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/syntax/Irregular.js var IsIrregular = new Uint8Array(256); for (idx = 0, len = 256; idx < len; idx++) { IsIrregular[idx] = IsWhitespace[idx] || IsDelimiter[idx] ? 1 : 0; @@ -17603,7 +15237,7 @@ var idx; var len; IsIrregular[CharCodes_default.Hash] = 1; -// ../../../node_modules/pdf-lib/es/core/objects/PDFName.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/objects/PDFName.js var decodeName = function(name) { return name.replace(/#([\dABCDEF]{2})/g, function(_, hex2) { return charFromHexCode(hex2); @@ -17726,7 +15360,7 @@ var PDFName = ( ); var PDFName_default = PDFName; -// ../../../node_modules/pdf-lib/es/core/objects/PDFNull.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/objects/PDFNull.js var PDFNull = ( /** @class */ (function(_super) { @@ -17758,7 +15392,7 @@ var PDFNull = ( ); var PDFNull_default = new PDFNull(); -// ../../../node_modules/pdf-lib/es/core/objects/PDFDict.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/objects/PDFDict.js var PDFDict = ( /** @class */ (function(_super) { @@ -17891,7 +15525,7 @@ var PDFDict = ( ); var PDFDict_default = PDFDict; -// ../../../node_modules/pdf-lib/es/core/objects/PDFStream.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/objects/PDFStream.js var PDFStream = ( /** @class */ (function(_super) { @@ -17962,7 +15596,7 @@ var PDFStream = ( ); var PDFStream_default = PDFStream; -// ../../../node_modules/pdf-lib/es/core/objects/PDFRawStream.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/objects/PDFRawStream.js var PDFRawStream = ( /** @class */ (function(_super) { @@ -17995,7 +15629,7 @@ var PDFRawStream = ( ); var PDFRawStream_default = PDFRawStream; -// ../../../node_modules/pdf-lib/es/core/objects/PDFRef.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/objects/PDFRef.js var ENFORCER3 = {}; var pool2 = /* @__PURE__ */ new Map(); var PDFRef = ( @@ -18042,7 +15676,7 @@ var PDFRef = ( ); var PDFRef_default = PDFRef; -// ../../../node_modules/pdf-lib/es/core/operators/PDFOperator.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/operators/PDFOperator.js var PDFOperator = ( /** @class */ (function() { @@ -18097,7 +15731,7 @@ var PDFOperator = ( ); var PDFOperator_default = PDFOperator; -// ../../../node_modules/pdf-lib/es/core/operators/PDFOperatorNames.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/operators/PDFOperatorNames.js var PDFOperatorNames; (function(PDFOperatorNames2) { PDFOperatorNames2["NonStrokingColor"] = "sc"; @@ -18176,7 +15810,7 @@ var PDFOperatorNames; })(PDFOperatorNames || (PDFOperatorNames = {})); var PDFOperatorNames_default = PDFOperatorNames; -// ../../../node_modules/pdf-lib/es/core/structures/PDFFlateStream.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/structures/PDFFlateStream.js var import_pako2 = __toESM(require_pako()); var PDFFlateStream = ( /** @class */ @@ -18208,7 +15842,7 @@ var PDFFlateStream = ( ); var PDFFlateStream_default = PDFFlateStream; -// ../../../node_modules/pdf-lib/es/core/structures/PDFContentStream.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/structures/PDFContentStream.js var PDFContentStream = ( /** @class */ (function(_super) { @@ -18271,7 +15905,7 @@ var PDFContentStream = ( ); var PDFContentStream_default = PDFContentStream; -// ../../../node_modules/pdf-lib/es/utils/rng.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/utils/rng.js var SimpleRNG = ( /** @class */ (function() { @@ -18289,7 +15923,7 @@ var SimpleRNG = ( })() ); -// ../../../node_modules/pdf-lib/es/core/PDFContext.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/PDFContext.js var byAscendingObjectNumber = function(_a, _b) { var a = _a[0]; var b = _b[0]; @@ -18464,7 +16098,7 @@ var PDFContext = ( ); var PDFContext_default = PDFContext; -// ../../../node_modules/pdf-lib/es/core/structures/PDFPageLeaf.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/structures/PDFPageLeaf.js var PDFPageLeaf = ( /** @class */ (function(_super) { @@ -18666,7 +16300,7 @@ var PDFPageLeaf = ( ); var PDFPageLeaf_default = PDFPageLeaf; -// ../../../node_modules/pdf-lib/es/core/PDFObjectCopier.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/PDFObjectCopier.js var PDFObjectCopier = ( /** @class */ (function() { @@ -18750,7 +16384,7 @@ var PDFObjectCopier = ( ); var PDFObjectCopier_default = PDFObjectCopier; -// ../../../node_modules/pdf-lib/es/core/document/PDFCrossRefSection.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/document/PDFCrossRefSection.js var PDFCrossRefSection = ( /** @class */ (function() { @@ -18869,7 +16503,7 @@ var PDFCrossRefSection = ( ); var PDFCrossRefSection_default = PDFCrossRefSection; -// ../../../node_modules/pdf-lib/es/core/document/PDFTrailer.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/document/PDFTrailer.js var PDFTrailer = ( /** @class */ (function() { @@ -18911,7 +16545,7 @@ var PDFTrailer = ( ); var PDFTrailer_default = PDFTrailer; -// ../../../node_modules/pdf-lib/es/core/document/PDFTrailerDict.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/document/PDFTrailerDict.js var PDFTrailerDict = ( /** @class */ (function() { @@ -18945,7 +16579,7 @@ var PDFTrailerDict = ( ); var PDFTrailerDict_default = PDFTrailerDict; -// ../../../node_modules/pdf-lib/es/core/structures/PDFObjectStream.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/structures/PDFObjectStream.js var PDFObjectStream = ( /** @class */ (function(_super) { @@ -19019,7 +16653,7 @@ var PDFObjectStream = ( ); var PDFObjectStream_default = PDFObjectStream; -// ../../../node_modules/pdf-lib/es/core/writers/PDFWriter.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/writers/PDFWriter.js var PDFWriter = ( /** @class */ (function() { @@ -19158,7 +16792,7 @@ var PDFWriter = ( ); var PDFWriter_default = PDFWriter; -// ../../../node_modules/pdf-lib/es/core/objects/PDFInvalidObject.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/objects/PDFInvalidObject.js var PDFInvalidObject = ( /** @class */ (function(_super) { @@ -19192,7 +16826,7 @@ var PDFInvalidObject = ( ); var PDFInvalidObject_default = PDFInvalidObject; -// ../../../node_modules/pdf-lib/es/core/structures/PDFCrossRefStream.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/structures/PDFCrossRefStream.js var EntryType; (function(EntryType2) { EntryType2[EntryType2["Deleted"] = 0] = "Deleted"; @@ -19372,7 +17006,7 @@ var PDFCrossRefStream = ( ); var PDFCrossRefStream_default = PDFCrossRefStream; -// ../../../node_modules/pdf-lib/es/core/writers/PDFStreamWriter.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/writers/PDFStreamWriter.js var PDFStreamWriter = ( /** @class */ (function(_super) { @@ -19477,7 +17111,7 @@ var PDFStreamWriter = ( ); var PDFStreamWriter_default = PDFStreamWriter; -// ../../../node_modules/pdf-lib/es/core/objects/PDFHexString.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/objects/PDFHexString.js var PDFHexString = ( /** @class */ (function(_super) { @@ -19548,7 +17182,7 @@ var PDFHexString = ( ); var PDFHexString_default = PDFHexString; -// ../../../node_modules/pdf-lib/es/core/embedders/StandardFontEmbedder.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/embedders/StandardFontEmbedder.js var StandardFontEmbedder = ( /** @class */ (function() { @@ -19631,7 +17265,7 @@ var StandardFontEmbedder = ( ); var StandardFontEmbedder_default = StandardFontEmbedder; -// ../../../node_modules/pdf-lib/es/core/embedders/CMap.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/embedders/CMap.js var createCmap = function(glyphs, glyphId) { var bfChars = new Array(glyphs.length); for (var idx = 0, len = glyphs.length; idx < len; idx++) { @@ -19671,7 +17305,7 @@ var cmapCodePointFormat = function(codePoint) { throw new Error(msg); }; -// ../../../node_modules/pdf-lib/es/core/embedders/FontFlags.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/embedders/FontFlags.js var makeFontFlags = function(options) { var flags = 0; var flipBit = function(bit) { @@ -19709,7 +17343,7 @@ var deriveFontFlags = function(font) { return flags; }; -// ../../../node_modules/pdf-lib/es/core/objects/PDFString.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/objects/PDFString.js var PDFString = ( /** @class */ (function(_super) { @@ -19819,7 +17453,7 @@ var PDFString = ( ); var PDFString_default = PDFString; -// ../../../node_modules/pdf-lib/es/core/embedders/CustomFontEmbedder.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/embedders/CustomFontEmbedder.js var CustomFontEmbedder = ( /** @class */ (function() { @@ -20050,7 +17684,7 @@ var CustomFontEmbedder = ( ); var CustomFontEmbedder_default = CustomFontEmbedder; -// ../../../node_modules/pdf-lib/es/core/embedders/CustomFontSubsetEmbedder.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/embedders/CustomFontSubsetEmbedder.js var CustomFontSubsetEmbedder = ( /** @class */ (function(_super) { @@ -20116,7 +17750,7 @@ var CustomFontSubsetEmbedder = ( ); var CustomFontSubsetEmbedder_default = CustomFontSubsetEmbedder; -// ../../../node_modules/pdf-lib/es/core/embedders/FileEmbedder.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/embedders/FileEmbedder.js var AFRelationship; (function(AFRelationship2) { AFRelationship2["Source"] = "Source"; @@ -20186,7 +17820,7 @@ var FileEmbedder = ( ); var FileEmbedder_default = FileEmbedder; -// ../../../node_modules/pdf-lib/es/core/embedders/JpegEmbedder.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/embedders/JpegEmbedder.js var MARKERS = [ 65472, 65473, @@ -20298,7 +17932,7 @@ var JpegEmbedder = ( ); var JpegEmbedder_default = JpegEmbedder; -// ../../../node_modules/@pdf-lib/upng/UPNG.js +// node_modules/.pnpm/@pdf-lib+upng@1.0.1/node_modules/@pdf-lib/upng/UPNG.js var import_pako4 = __toESM(require_pako()); var UPNG = {}; UPNG.toRGBA8 = function(out) { @@ -21654,7 +19288,7 @@ UPNG.encode.concatRGBA = function(bufs) { }; var UPNG_default = UPNG; -// ../../../node_modules/pdf-lib/es/utils/png.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/utils/png.js var getImageType = function(ctype) { if (ctype === 0) return PngType.Greyscale; @@ -21719,7 +19353,7 @@ var PNG = ( })() ); -// ../../../node_modules/pdf-lib/es/core/embedders/PngEmbedder.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/embedders/PngEmbedder.js var PngEmbedder = ( /** @class */ (function() { @@ -21785,7 +19419,7 @@ var PngEmbedder = ( ); var PngEmbedder_default = PngEmbedder; -// ../../../node_modules/pdf-lib/es/core/streams/Stream.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/streams/Stream.js var Stream = ( /** @class */ (function() { @@ -21886,7 +19520,7 @@ var Stream = ( ); var Stream_default = Stream; -// ../../../node_modules/pdf-lib/es/core/streams/DecodeStream.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/streams/DecodeStream.js var emptyBuffer = new Uint8Array(0); var DecodeStream = ( /** @class */ @@ -22024,7 +19658,7 @@ var DecodeStream = ( ); var DecodeStream_default = DecodeStream; -// ../../../node_modules/pdf-lib/es/core/streams/Ascii85Stream.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/streams/Ascii85Stream.js var isSpace = function(ch) { return ch === 32 || ch === 9 || ch === 13 || ch === 10; }; @@ -22099,7 +19733,7 @@ var Ascii85Stream = ( ); var Ascii85Stream_default = Ascii85Stream; -// ../../../node_modules/pdf-lib/es/core/streams/AsciiHexStream.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/streams/AsciiHexStream.js var AsciiHexStream = ( /** @class */ (function(_super) { @@ -22156,7 +19790,7 @@ var AsciiHexStream = ( ); var AsciiHexStream_default = AsciiHexStream; -// ../../../node_modules/pdf-lib/es/core/streams/FlateStream.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/streams/FlateStream.js var codeLenCodeMap = new Int32Array([ 16, 17, @@ -23035,7 +20669,7 @@ var FlateStream = ( ); var FlateStream_default = FlateStream; -// ../../../node_modules/pdf-lib/es/core/streams/LZWStream.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/streams/LZWStream.js var LZWStream = ( /** @class */ (function(_super) { @@ -23158,7 +20792,7 @@ var LZWStream = ( ); var LZWStream_default = LZWStream; -// ../../../node_modules/pdf-lib/es/core/streams/RunLengthStream.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/streams/RunLengthStream.js var RunLengthStream = ( /** @class */ (function(_super) { @@ -23200,7 +20834,7 @@ var RunLengthStream = ( ); var RunLengthStream_default = RunLengthStream; -// ../../../node_modules/pdf-lib/es/core/streams/decode.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/streams/decode.js var decodeStream = function(stream2, encoding, params) { if (encoding === PDFName_default.of("FlateDecode")) { return new FlateStream_default(stream2); @@ -23243,7 +20877,7 @@ var decodePDFRawStream = function(_a) { return stream2; }; -// ../../../node_modules/pdf-lib/es/core/embedders/PDFPageEmbedder.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/embedders/PDFPageEmbedder.js var fullPageBoundingBox = function(page) { var mediaBox = page.MediaBox(); var width = mediaBox.lookup(2, PDFNumber_default).asNumber() - mediaBox.lookup(0, PDFNumber_default).asNumber(); @@ -23323,7 +20957,7 @@ var PDFPageEmbedder = ( ); var PDFPageEmbedder_default = PDFPageEmbedder; -// ../../../node_modules/pdf-lib/es/core/interactive/ViewerPreferences.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/interactive/ViewerPreferences.js var asEnum = function(rawValue, enumType) { if (rawValue === void 0) return void 0; @@ -23557,7 +21191,7 @@ var ViewerPreferences = ( ); var ViewerPreferences_default = ViewerPreferences; -// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroField.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/PDFAcroField.js var tfRegex = /\/([^\0\t\n\f\r\ ]+)[\0\t\n\f\r\ ]*(\d*\.\d+|\d+)?[\0\t\n\f\r\ ]+Tf/; var PDFAcroField = ( /** @class */ @@ -23688,7 +21322,7 @@ var PDFAcroField = ( ); var PDFAcroField_default = PDFAcroField; -// ../../../node_modules/pdf-lib/es/core/annotation/BorderStyle.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/annotation/BorderStyle.js var BorderStyle = ( /** @class */ (function() { @@ -23717,7 +21351,7 @@ var BorderStyle = ( ); var BorderStyle_default = BorderStyle; -// ../../../node_modules/pdf-lib/es/core/annotation/PDFAnnotation.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/annotation/PDFAnnotation.js var PDFAnnotation = ( /** @class */ (function() { @@ -23833,7 +21467,7 @@ var PDFAnnotation = ( ); var PDFAnnotation_default = PDFAnnotation; -// ../../../node_modules/pdf-lib/es/core/annotation/AppearanceCharacteristics.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/annotation/AppearanceCharacteristics.js var AppearanceCharacteristics = ( /** @class */ (function() { @@ -23950,7 +21584,7 @@ var AppearanceCharacteristics = ( ); var AppearanceCharacteristics_default = AppearanceCharacteristics; -// ../../../node_modules/pdf-lib/es/core/annotation/PDFWidgetAnnotation.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/annotation/PDFWidgetAnnotation.js var PDFWidgetAnnotation = ( /** @class */ (function(_super) { @@ -24053,7 +21687,7 @@ var PDFWidgetAnnotation = ( ); var PDFWidgetAnnotation_default = PDFWidgetAnnotation; -// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroTerminal.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/PDFAcroTerminal.js var PDFAcroTerminal = ( /** @class */ (function(_super) { @@ -24109,7 +21743,7 @@ var PDFAcroTerminal = ( ); var PDFAcroTerminal_default = PDFAcroTerminal; -// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroButton.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/PDFAcroButton.js var PDFAcroButton = ( /** @class */ (function(_super) { @@ -24194,7 +21828,7 @@ var PDFAcroButton = ( ); var PDFAcroButton_default = PDFAcroButton; -// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroCheckBox.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/PDFAcroCheckBox.js var PDFAcroCheckBox = ( /** @class */ (function(_super) { @@ -24242,7 +21876,7 @@ var PDFAcroCheckBox = ( ); var PDFAcroCheckBox_default = PDFAcroCheckBox; -// ../../../node_modules/pdf-lib/es/core/acroform/flags.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/flags.js var flag = function(bitIndex) { return 1 << bitIndex; }; @@ -24279,7 +21913,7 @@ var AcroChoiceFlags; AcroChoiceFlags2[AcroChoiceFlags2["CommitOnSelChange"] = flag(27 - 1)] = "CommitOnSelChange"; })(AcroChoiceFlags || (AcroChoiceFlags = {})); -// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroChoice.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/PDFAcroChoice.js var PDFAcroChoice = ( /** @class */ (function(_super) { @@ -24396,7 +22030,7 @@ var PDFAcroChoice = ( ); var PDFAcroChoice_default = PDFAcroChoice; -// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroComboBox.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/PDFAcroComboBox.js var PDFAcroComboBox = ( /** @class */ (function(_super) { @@ -24421,7 +22055,7 @@ var PDFAcroComboBox = ( ); var PDFAcroComboBox_default = PDFAcroComboBox; -// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroNonTerminal.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/PDFAcroNonTerminal.js var PDFAcroNonTerminal = ( /** @class */ (function(_super) { @@ -24454,7 +22088,7 @@ var PDFAcroNonTerminal = ( ); var PDFAcroNonTerminal_default = PDFAcroNonTerminal; -// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroSignature.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/PDFAcroSignature.js var PDFAcroSignature = ( /** @class */ (function(_super) { @@ -24470,7 +22104,7 @@ var PDFAcroSignature = ( ); var PDFAcroSignature_default = PDFAcroSignature; -// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroText.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/PDFAcroText.js var PDFAcroText = ( /** @class */ (function(_super) { @@ -24535,7 +22169,7 @@ var PDFAcroText = ( ); var PDFAcroText_default = PDFAcroText; -// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroPushButton.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/PDFAcroPushButton.js var PDFAcroPushButton = ( /** @class */ (function(_super) { @@ -24560,7 +22194,7 @@ var PDFAcroPushButton = ( ); var PDFAcroPushButton_default = PDFAcroPushButton; -// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroRadioButton.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/PDFAcroRadioButton.js var PDFAcroRadioButton = ( /** @class */ (function(_super) { @@ -24614,7 +22248,7 @@ var PDFAcroRadioButton = ( ); var PDFAcroRadioButton_default = PDFAcroRadioButton; -// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroListBox.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/PDFAcroListBox.js var PDFAcroListBox = ( /** @class */ (function(_super) { @@ -24638,7 +22272,7 @@ var PDFAcroListBox = ( ); var PDFAcroListBox_default = PDFAcroListBox; -// ../../../node_modules/pdf-lib/es/core/acroform/utils.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/utils.js var createPDFAcroFields = function(kidDicts) { if (!kidDicts) return []; @@ -24725,7 +22359,7 @@ var ascend = function(startNode, visitor) { ascend(Parent, visitor); }; -// ../../../node_modules/pdf-lib/es/core/acroform/PDFAcroForm.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/acroform/PDFAcroForm.js var PDFAcroForm = ( /** @class */ (function() { @@ -24801,7 +22435,7 @@ var PDFAcroForm = ( ); var PDFAcroForm_default = PDFAcroForm; -// ../../../node_modules/pdf-lib/es/core/structures/PDFCatalog.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/structures/PDFCatalog.js var PDFCatalog = ( /** @class */ (function(_super) { @@ -24870,7 +22504,7 @@ var PDFCatalog = ( ); var PDFCatalog_default = PDFCatalog; -// ../../../node_modules/pdf-lib/es/core/structures/PDFPageTree.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/structures/PDFPageTree.js var PDFPageTree = ( /** @class */ (function(_super) { @@ -25012,7 +22646,7 @@ var PDFPageTree = ( ); var PDFPageTree_default = PDFPageTree; -// ../../../node_modules/pdf-lib/es/core/syntax/Numeric.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/syntax/Numeric.js var IsDigit = new Uint8Array(256); IsDigit[CharCodes_default.Zero] = 1; IsDigit[CharCodes_default.One] = 1; @@ -25035,7 +22669,7 @@ for (idx = 0, len = 256; idx < len; idx++) { var idx; var len; -// ../../../node_modules/pdf-lib/es/core/parser/BaseParser.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/parser/BaseParser.js var Newline = CharCodes_default.Newline; var CarriageReturn = CharCodes_default.CarriageReturn; var BaseParser = ( @@ -25138,7 +22772,7 @@ var BaseParser = ( ); var BaseParser_default = BaseParser; -// ../../../node_modules/pdf-lib/es/core/parser/ByteStream.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/parser/ByteStream.js var ByteStream = ( /** @class */ (function() { @@ -25200,7 +22834,7 @@ var ByteStream = ( ); var ByteStream_default = ByteStream; -// ../../../node_modules/pdf-lib/es/core/syntax/Keywords.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/syntax/Keywords.js var Space = CharCodes_default.Space; var CarriageReturn2 = CharCodes_default.CarriageReturn; var Newline2 = CharCodes_default.Newline; @@ -25282,7 +22916,7 @@ var Keywords = { EOF3endstream: __spreadArrays([Newline2], endstream) }; -// ../../../node_modules/pdf-lib/es/core/parser/PDFObjectParser.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/parser/PDFObjectParser.js var PDFObjectParser = ( /** @class */ (function(_super) { @@ -25473,7 +23107,7 @@ var PDFObjectParser = ( ); var PDFObjectParser_default = PDFObjectParser; -// ../../../node_modules/pdf-lib/es/core/parser/PDFObjectStreamParser.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/parser/PDFObjectStreamParser.js var PDFObjectStreamParser = ( /** @class */ (function(_super) { @@ -25545,7 +23179,7 @@ var PDFObjectStreamParser = ( ); var PDFObjectStreamParser_default = PDFObjectStreamParser; -// ../../../node_modules/pdf-lib/es/core/parser/PDFXRefStreamParser.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/parser/PDFXRefStreamParser.js var PDFXRefStreamParser = ( /** @class */ (function() { @@ -25626,7 +23260,7 @@ var PDFXRefStreamParser = ( ); var PDFXRefStreamParser_default = PDFXRefStreamParser; -// ../../../node_modules/pdf-lib/es/core/parser/PDFParser.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/parser/PDFParser.js var PDFParser = ( /** @class */ (function(_super) { @@ -25942,7 +23576,7 @@ var PDFParser = ( ); var PDFParser_default = PDFParser; -// ../../../node_modules/pdf-lib/es/core/annotation/flags.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/annotation/flags.js var flag2 = function(bitIndex) { return 1 << bitIndex; }; @@ -25960,7 +23594,7 @@ var AnnotationFlags; AnnotationFlags2[AnnotationFlags2["LockedContents"] = flag2(10 - 1)] = "LockedContents"; })(AnnotationFlags || (AnnotationFlags = {})); -// ../../../node_modules/pdf-lib/es/api/objects.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/objects.js var asPDFName = function(name) { return name instanceof PDFName_default ? name : PDFName_default.of(name); }; @@ -25971,7 +23605,7 @@ var asNumber = function(num) { return num instanceof PDFNumber_default ? num.asNumber() : num; }; -// ../../../node_modules/pdf-lib/es/api/rotations.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/rotations.js var RotationTypes; (function(RotationTypes2) { RotationTypes2["Degrees"] = "degrees"; @@ -26039,7 +23673,7 @@ var rotateRectangle = function(rectangle, borderWidth, degreeAngle) { return { x: x - b, y: y - b, width: w, height: h }; }; -// ../../../node_modules/pdf-lib/es/api/operators.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/operators.js var clip = function() { return PDFOperator_default.of(PDFOperatorNames_default.ClipNonZero); }; @@ -26231,7 +23865,7 @@ var endMarkedContent = function() { return PDFOperator_default.of(PDFOperatorNames_default.EndMarkedContent); }; -// ../../../node_modules/pdf-lib/es/api/colors.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/colors.js var ColorTypes; (function(ColorTypes2) { ColorTypes2["Grayscale"] = "Grayscale"; @@ -26274,7 +23908,7 @@ var colorToComponents = function(color) { return color.type === Grayscale ? [color.gray] : color.type === RGB ? [color.red, color.green, color.blue] : color.type === CMYK ? [color.cyan, color.magenta, color.yellow, color.key] : error("Invalid color: " + JSON.stringify(color)); }; -// ../../../node_modules/pdf-lib/es/api/svgPath.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/svgPath.js var cx = 0; var cy = 0; var px = 0; @@ -26628,7 +24262,7 @@ var svgPathToOperators = function(path) { return apply(parse(path)); }; -// ../../../node_modules/pdf-lib/es/api/operations.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/operations.js var drawLinesOfText = function(lines, options) { var operators = [ pushGraphicsState(), @@ -27054,7 +24688,7 @@ var drawOptionList = function(options) { ]); }; -// ../../../node_modules/pdf-lib/es/api/errors.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/errors.js var EncryptedPDFError = ( /** @class */ (function(_super) { @@ -27241,7 +24875,7 @@ var InvalidMaxLengthError = ( })(Error) ); -// ../../../node_modules/pdf-lib/es/api/text/alignment.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/text/alignment.js var TextAlignment; (function(TextAlignment2) { TextAlignment2[TextAlignment2["Left"] = 0] = "Left"; @@ -27249,7 +24883,7 @@ var TextAlignment; TextAlignment2[TextAlignment2["Right"] = 2] = "Right"; })(TextAlignment || (TextAlignment = {})); -// ../../../node_modules/pdf-lib/es/api/text/layout.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/text/layout.js var MIN_FONT_SIZE = 4; var MAX_FONT_SIZE = 500; var computeFontSize = function(lines, font, bounds, multiline) { @@ -27442,7 +25076,7 @@ var layoutSinglelineText = function(text2, _a) { }; }; -// ../../../node_modules/pdf-lib/es/api/form/appearances.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/form/appearances.js var normalizeAppearance = function(appearance) { if ("normal" in appearance) return appearance; @@ -27827,7 +25461,7 @@ var defaultOptionListAppearanceProvider = function(optionList, widget, font) { })); }; -// ../../../node_modules/pdf-lib/es/api/PDFEmbeddedPage.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/PDFEmbeddedPage.js var PDFEmbeddedPage = ( /** @class */ (function() { @@ -27877,7 +25511,7 @@ var PDFEmbeddedPage = ( ); var PDFEmbeddedPage_default = PDFEmbeddedPage; -// ../../../node_modules/pdf-lib/es/api/PDFFont.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/PDFFont.js var PDFFont = ( /** @class */ (function() { @@ -27951,7 +25585,7 @@ var PDFFont = ( ); var PDFFont_default = PDFFont; -// ../../../node_modules/pdf-lib/es/api/PDFImage.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/PDFImage.js var PDFImage = ( /** @class */ (function() { @@ -28018,7 +25652,7 @@ var PDFImage = ( ); var PDFImage_default = PDFImage; -// ../../../node_modules/pdf-lib/es/api/image/alignment.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/image/alignment.js var ImageAlignment; (function(ImageAlignment2) { ImageAlignment2[ImageAlignment2["Left"] = 0] = "Left"; @@ -28026,7 +25660,7 @@ var ImageAlignment; ImageAlignment2[ImageAlignment2["Right"] = 2] = "Right"; })(ImageAlignment || (ImageAlignment = {})); -// ../../../node_modules/pdf-lib/es/api/form/PDFField.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/form/PDFField.js var assertFieldAppearanceOptions = function(options) { assertOrUndefined(options === null || options === void 0 ? void 0 : options.x, "options.x", ["number"]); assertOrUndefined(options === null || options === void 0 ? void 0 : options.y, "options.y", ["number"]); @@ -28239,7 +25873,7 @@ var PDFField = ( ); var PDFField_default = PDFField; -// ../../../node_modules/pdf-lib/es/api/form/PDFCheckBox.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/form/PDFCheckBox.js var PDFCheckBox = ( /** @class */ (function(_super) { @@ -28342,7 +25976,7 @@ var PDFCheckBox = ( ); var PDFCheckBox_default = PDFCheckBox; -// ../../../node_modules/pdf-lib/es/api/form/PDFDropdown.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/form/PDFDropdown.js var PDFDropdown = ( /** @class */ (function(_super) { @@ -28545,7 +26179,7 @@ var PDFDropdown = ( ); var PDFDropdown_default = PDFDropdown; -// ../../../node_modules/pdf-lib/es/api/form/PDFOptionList.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/form/PDFOptionList.js var PDFOptionList = ( /** @class */ (function(_super) { @@ -28726,7 +26360,7 @@ var PDFOptionList = ( ); var PDFOptionList_default = PDFOptionList; -// ../../../node_modules/pdf-lib/es/api/form/PDFRadioGroup.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/form/PDFRadioGroup.js var PDFRadioGroup = ( /** @class */ (function(_super) { @@ -28877,7 +26511,7 @@ var PDFRadioGroup = ( ); var PDFRadioGroup_default = PDFRadioGroup; -// ../../../node_modules/pdf-lib/es/api/form/PDFSignature.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/form/PDFSignature.js var PDFSignature = ( /** @class */ (function(_super) { @@ -28901,7 +26535,7 @@ var PDFSignature = ( ); var PDFSignature_default = PDFSignature; -// ../../../node_modules/pdf-lib/es/api/form/PDFTextField.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/form/PDFTextField.js var PDFTextField = ( /** @class */ (function(_super) { @@ -29125,7 +26759,7 @@ var PDFTextField = ( ); var PDFTextField_default = PDFTextField; -// ../../../node_modules/pdf-lib/es/api/StandardFonts.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/StandardFonts.js var StandardFonts; (function(StandardFonts2) { StandardFonts2["Courier"] = "Courier"; @@ -29144,7 +26778,7 @@ var StandardFonts; StandardFonts2["ZapfDingbats"] = "ZapfDingbats"; })(StandardFonts || (StandardFonts = {})); -// ../../../node_modules/pdf-lib/es/api/form/PDFForm.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/form/PDFForm.js var PDFForm = ( /** @class */ (function() { @@ -29501,7 +27135,7 @@ var addFieldToParent = function(_a, _b, partialName) { field.setParent(parentRef); }; -// ../../../node_modules/pdf-lib/es/api/sizes.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/sizes.js var PageSizes = { "4A0": [4767.87, 6740.79], "2A0": [3370.39, 4767.87], @@ -29555,7 +27189,7 @@ var PageSizes = { Tabloid: [792, 1224] }; -// ../../../node_modules/pdf-lib/es/api/PDFDocumentOptions.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/PDFDocumentOptions.js var ParseSpeeds; (function(ParseSpeeds2) { ParseSpeeds2[ParseSpeeds2["Fastest"] = Infinity] = "Fastest"; @@ -29564,7 +27198,7 @@ var ParseSpeeds; ParseSpeeds2[ParseSpeeds2["Slow"] = 100] = "Slow"; })(ParseSpeeds || (ParseSpeeds = {})); -// ../../../node_modules/pdf-lib/es/api/PDFEmbeddedFile.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/PDFEmbeddedFile.js var PDFEmbeddedFile = ( /** @class */ (function() { @@ -29622,7 +27256,7 @@ var PDFEmbeddedFile = ( ); var PDFEmbeddedFile_default = PDFEmbeddedFile; -// ../../../node_modules/pdf-lib/es/api/PDFJavaScript.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/PDFJavaScript.js var PDFJavaScript = ( /** @class */ (function() { @@ -29676,7 +27310,7 @@ var PDFJavaScript = ( ); var PDFJavaScript_default = PDFJavaScript; -// ../../../node_modules/pdf-lib/es/core/embedders/JavaScriptEmbedder.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/core/embedders/JavaScriptEmbedder.js var JavaScriptEmbedder = ( /** @class */ (function() { @@ -29714,7 +27348,7 @@ var JavaScriptEmbedder = ( ); var JavaScriptEmbedder_default = JavaScriptEmbedder; -// ../../../node_modules/pdf-lib/es/api/PDFDocument.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/PDFDocument.js var PDFDocument = ( /** @class */ (function() { @@ -30400,7 +28034,7 @@ function assertIsLiteralOrHexString(pdfObject) { } } -// ../../../node_modules/pdf-lib/es/api/PDFPageOptions.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/PDFPageOptions.js var BlendMode; (function(BlendMode2) { BlendMode2["Normal"] = "Normal"; @@ -30417,7 +28051,7 @@ var BlendMode; BlendMode2["Exclusion"] = "Exclusion"; })(BlendMode || (BlendMode = {})); -// ../../../node_modules/pdf-lib/es/api/PDFPage.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/PDFPage.js var PDFPage = ( /** @class */ (function() { @@ -31069,7 +28703,7 @@ var PDFPage = ( ); var PDFPage_default = PDFPage; -// ../../../node_modules/pdf-lib/es/api/form/PDFButton.js +// node_modules/.pnpm/pdf-lib@1.17.1/node_modules/pdf-lib/es/api/form/PDFButton.js var PDFButton = ( /** @class */ (function(_super) { @@ -31167,7 +28801,7 @@ var PDFButton_default = PDFButton; var import_jszip2 = __toESM(require_jszip_min(), 1); // node_modules/.pnpm/pptxgenjs@4.0.1/node_modules/pptxgenjs/dist/pptxgen.es.js -var import_jszip = __toESM(require_jszip_min2()); +var import_jszip = __toESM(require_jszip_min()); function __awaiter2(thisArg, _arguments, P, generator) { function adopt(value2) { return value2 instanceof P ? value2 : new P(function(resolve) { diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/meta.json b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/meta.json index 3865589f77..157246aec8 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/meta.json +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/meta.json @@ -10,7 +10,7 @@ "ppt", "ai" ], - "version": 216, + "version": 217, "created_at": 0, "updated_at": 0, "permissions": { diff --git a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/flat-select.js b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/flat-select.js index 8cef403aa9..e56eaf678a 100644 --- a/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/flat-select.js +++ b/src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src/flat-select.js @@ -207,7 +207,7 @@ export function refreshFlatSelectLabels() { }); } -if (!window.__pptLiveFlatSelectBound) { +if (typeof window !== 'undefined' && typeof document !== 'undefined' && !window.__pptLiveFlatSelectBound) { window.__pptLiveFlatSelectBound = true; document.addEventListener('click', handleOutsideClick); document.addEventListener('keydown', (event) => {