@a3s-lab/office 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +470 -0
- package/THIRD_PARTY_NOTICES.md +33 -0
- package/dist/0~1403.js +245 -0
- package/dist/0~152.js +94 -0
- package/dist/0~3539.js +1856 -0
- package/dist/0~3557.js +179 -0
- package/dist/0~3635.js +302 -0
- package/dist/0~4595.js +1162 -0
- package/dist/0~5050.js +308 -0
- package/dist/0~6552.js +787 -0
- package/dist/0~7048.js +2110 -0
- package/dist/0~7614.js +1037 -0
- package/dist/0~8155.js +299 -0
- package/dist/0~9445.js +283 -0
- package/dist/0~9512.js +743 -0
- package/dist/0~document-editor.js +10967 -0
- package/dist/0~markdown-editor.js +2260 -0
- package/dist/0~pdf-viewer.js +2156 -0
- package/dist/0~presentation-editor.js +8359 -0
- package/dist/0~rslib-runtime.js +27 -0
- package/dist/0~spreadsheet-editor.js +10388 -0
- package/dist/0~use-office-draft.js +46 -0
- package/dist/0~work-document-extensions.js +2470 -0
- package/dist/0~work-document-links.js +14 -0
- package/dist/0~work-document-model-codec.js +42 -0
- package/dist/0~work-document-page-color.js +11 -0
- package/dist/0~work-document-paragraph-formatting.js +425 -0
- package/dist/0~work-docx-bibliography.js +347 -0
- package/dist/0~work-docx-export.js +1151 -0
- package/dist/0~work-docx-import.js +3116 -0
- package/dist/0~work-docx-page-color.js +42 -0
- package/dist/0~work-office-diagnostics.js +1377 -0
- package/dist/0~work-pptx-export.js +1009 -0
- package/dist/0~work-pptx-import.js +1138 -0
- package/dist/0~work-presentation-charts.js +442 -0
- package/dist/0~work-presentation-transition.js +38 -0
- package/dist/0~work-presentation-visual-scale.js +38 -0
- package/dist/0~work-spreadsheet-formula-support.js +9 -0
- package/dist/1134.js +445 -0
- package/dist/4104.js +5786 -0
- package/dist/432.js +211 -0
- package/dist/4704.js +1364 -0
- package/dist/6489.js +182 -0
- package/dist/8715.js +3959 -0
- package/dist/8728.js +723 -0
- package/dist/9356.js +10 -0
- package/dist/core.d.ts +15 -0
- package/dist/core.js +4 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/internal/design-system/primitives/button/button.d.ts +9 -0
- package/dist/internal/design-system/primitives/button/icon-button.d.ts +7 -0
- package/dist/internal/design-system/primitives/dialog/dialog.d.ts +12 -0
- package/dist/internal/design-system/primitives/feedback/collection-state.d.ts +9 -0
- package/dist/internal/design-system/primitives/feedback/inline-notice.d.ts +10 -0
- package/dist/internal/design-system/primitives/feedback/state-view.d.ts +13 -0
- package/dist/internal/design-system/primitives/form/field.d.ts +19 -0
- package/dist/internal/design-system/primitives/index.d.ts +14 -0
- package/dist/internal/design-system/primitives/layout/split-handle.d.ts +17 -0
- package/dist/internal/design-system/primitives/navigation/segmented-control.d.ts +19 -0
- package/dist/internal/design-system/primitives/navigation/tab-navigation.d.ts +13 -0
- package/dist/internal/design-system/primitives/navigation/tabs.d.ts +21 -0
- package/dist/internal/design-system/primitives/overlay/dialog-focus-scope.d.ts +17 -0
- package/dist/internal/design-system/primitives/overlay/popover.d.ts +34 -0
- package/dist/internal/design-system/primitives/overlay/portal-root.d.ts +1 -0
- package/dist/internal/design-system/primitives/status/status-badge.d.ts +6 -0
- package/dist/internal/features/work/components/work-document-pages.d.ts +4 -0
- package/dist/internal/features/work/components/work-editor-agent-menus.d.ts +12 -0
- package/dist/internal/features/work/components/work-editor-loading-state.d.ts +3 -0
- package/dist/internal/features/work/editors/document-changes-panel.d.ts +9 -0
- package/dist/internal/features/work/editors/document-citation-source-form.d.ts +33 -0
- package/dist/internal/features/work/editors/document-citations-panel.d.ts +8 -0
- package/dist/internal/features/work/editors/document-columns-panel.d.ts +5 -0
- package/dist/internal/features/work/editors/document-comment-composer.d.ts +13 -0
- package/dist/internal/features/work/editors/document-comments-panel.d.ts +17 -0
- package/dist/internal/features/work/editors/document-editor-focus.d.ts +1 -0
- package/dist/internal/features/work/editors/document-editor-pagination.d.ts +3 -0
- package/dist/internal/features/work/editors/document-editor-support.d.ts +34 -0
- package/dist/internal/features/work/editors/document-editor.d.ts +20 -0
- package/dist/internal/features/work/editors/document-find-highlight.d.ts +8 -0
- package/dist/internal/features/work/editors/document-find-replace-panel.d.ts +10 -0
- package/dist/internal/features/work/editors/document-formatting-options.d.ts +113 -0
- package/dist/internal/features/work/editors/document-home-ribbon.d.ts +9 -0
- package/dist/internal/features/work/editors/document-layout-panel.d.ts +10 -0
- package/dist/internal/features/work/editors/document-list-gallery.d.ts +4 -0
- package/dist/internal/features/work/editors/document-navigation-panel.d.ts +9 -0
- package/dist/internal/features/work/editors/document-page-chrome-editor.d.ts +39 -0
- package/dist/internal/features/work/editors/document-page-chrome-panel.d.ts +5 -0
- package/dist/internal/features/work/editors/document-page-chrome-ribbon.d.ts +10 -0
- package/dist/internal/features/work/editors/document-page-navigation.d.ts +14 -0
- package/dist/internal/features/work/editors/document-page-stack.d.ts +8 -0
- package/dist/internal/features/work/editors/document-pagination-popover.d.ts +4 -0
- package/dist/internal/features/work/editors/document-paragraph-spacing-popover.d.ts +4 -0
- package/dist/internal/features/work/editors/document-picture-ribbon.d.ts +4 -0
- package/dist/internal/features/work/editors/document-ruler-tab-stops.d.ts +12 -0
- package/dist/internal/features/work/editors/document-ruler.d.ts +15 -0
- package/dist/internal/features/work/editors/document-selection-context-menu.d.ts +22 -0
- package/dist/internal/features/work/editors/document-selection-toolbar.d.ts +8 -0
- package/dist/internal/features/work/editors/document-status-bar.d.ts +19 -0
- package/dist/internal/features/work/editors/document-style-gallery.d.ts +4 -0
- package/dist/internal/features/work/editors/document-table-insert-popover.d.ts +4 -0
- package/dist/internal/features/work/editors/document-table-ribbon.d.ts +7 -0
- package/dist/internal/features/work/editors/document-task-pane.d.ts +11 -0
- package/dist/internal/features/work/editors/document-toolbar.d.ts +100 -0
- package/dist/internal/features/work/editors/document-vertical-ruler.d.ts +6 -0
- package/dist/internal/features/work/editors/markdown-editor-focus.d.ts +2 -0
- package/dist/internal/features/work/editors/markdown-editor.d.ts +16 -0
- package/dist/internal/features/work/editors/markdown-insert-dialog.d.ts +19 -0
- package/dist/internal/features/work/editors/markdown-selection-context-menu.d.ts +14 -0
- package/dist/internal/features/work/editors/markdown-source-commands.d.ts +41 -0
- package/dist/internal/features/work/editors/markdown-status.d.ts +7 -0
- package/dist/internal/features/work/editors/markdown-toolbar.d.ts +22 -0
- package/dist/internal/features/work/editors/markdown-workspace.d.ts +26 -0
- package/dist/internal/features/work/editors/office-checkbox.d.ts +9 -0
- package/dist/internal/features/work/editors/office-color-picker.d.ts +11 -0
- package/dist/internal/features/work/editors/office-controls.d.ts +7 -0
- package/dist/internal/features/work/editors/office-dialog.d.ts +35 -0
- package/dist/internal/features/work/editors/office-editor-extension.d.ts +86 -0
- package/dist/internal/features/work/editors/office-file-data.d.ts +1 -0
- package/dist/internal/features/work/editors/office-font-families.d.ts +187 -0
- package/dist/internal/features/work/editors/office-menu-keyboard.d.ts +2 -0
- package/dist/internal/features/work/editors/office-number-field.d.ts +21 -0
- package/dist/internal/features/work/editors/office-number-normalization.d.ts +9 -0
- package/dist/internal/features/work/editors/office-select.d.ts +19 -0
- package/dist/internal/features/work/editors/office-shortcuts.d.ts +1 -0
- package/dist/internal/features/work/editors/office-slider.d.ts +10 -0
- package/dist/internal/features/work/editors/office-table-dimensions.d.ts +4 -0
- package/dist/internal/features/work/editors/office-table-insert-popover.d.ts +7 -0
- package/dist/internal/features/work/editors/office-task-pane.d.ts +7 -0
- package/dist/internal/features/work/editors/office-text-field.d.ts +20 -0
- package/dist/internal/features/work/editors/office-tiptap-extensions.d.ts +2 -0
- package/dist/internal/features/work/editors/pdf-annotation-controller.d.ts +23 -0
- package/dist/internal/features/work/editors/pdf-editor-extensions.d.ts +36 -0
- package/dist/internal/features/work/editors/pdf-thumbnail-rail.d.ts +26 -0
- package/dist/internal/features/work/editors/pdf-toolbar.d.ts +23 -0
- package/dist/internal/features/work/editors/pdf-viewer-controller.d.ts +48 -0
- package/dist/internal/features/work/editors/pdf-viewer.d.ts +11 -0
- package/dist/internal/features/work/editors/presentation-arrangement-controller.d.ts +19 -0
- package/dist/internal/features/work/editors/presentation-chart-analysis-canvas.d.ts +21 -0
- package/dist/internal/features/work/editors/presentation-chart-axis-canvas.d.ts +33 -0
- package/dist/internal/features/work/editors/presentation-chart-axis-editor.d.ts +5 -0
- package/dist/internal/features/work/editors/presentation-chart-canvas.d.ts +5 -0
- package/dist/internal/features/work/editors/presentation-chart-cartesian-canvas.d.ts +3 -0
- package/dist/internal/features/work/editors/presentation-chart-data-label-editor.d.ts +6 -0
- package/dist/internal/features/work/editors/presentation-chart-data-labels.d.ts +26 -0
- package/dist/internal/features/work/editors/presentation-chart-layout-editor.d.ts +5 -0
- package/dist/internal/features/work/editors/presentation-chart-legend-canvas.d.ts +15 -0
- package/dist/internal/features/work/editors/presentation-chart-panel.d.ts +7 -0
- package/dist/internal/features/work/editors/presentation-chart-series-analysis-editor.d.ts +6 -0
- package/dist/internal/features/work/editors/presentation-chart-series-canvas.d.ts +15 -0
- package/dist/internal/features/work/editors/presentation-command-controller.d.ts +3 -0
- package/dist/internal/features/work/editors/presentation-command-types.d.ts +206 -0
- package/dist/internal/features/work/editors/presentation-comments-panel.d.ts +9 -0
- package/dist/internal/features/work/editors/presentation-context-menu.d.ts +11 -0
- package/dist/internal/features/work/editors/presentation-design-panel.d.ts +13 -0
- package/dist/internal/features/work/editors/presentation-editor-focus.d.ts +12 -0
- package/dist/internal/features/work/editors/presentation-editor-operations.d.ts +10 -0
- package/dist/internal/features/work/editors/presentation-editor-types.d.ts +22 -0
- package/dist/internal/features/work/editors/presentation-editor.d.ts +3 -0
- package/dist/internal/features/work/editors/presentation-keyboard-extension.d.ts +3 -0
- package/dist/internal/features/work/editors/presentation-player.d.ts +7 -0
- package/dist/internal/features/work/editors/presentation-presenter-view.d.ts +15 -0
- package/dist/internal/features/work/editors/presentation-selection.d.ts +21 -0
- package/dist/internal/features/work/editors/presentation-slide-canvas.d.ts +26 -0
- package/dist/internal/features/work/editors/presentation-slide-thumbnail.d.ts +18 -0
- package/dist/internal/features/work/editors/presentation-status-bar.d.ts +10 -0
- package/dist/internal/features/work/editors/presentation-text-editor.d.ts +22 -0
- package/dist/internal/features/work/editors/presentation-text-formatting.d.ts +3 -0
- package/dist/internal/features/work/editors/presentation-thumbnail-rail.d.ts +20 -0
- package/dist/internal/features/work/editors/presentation-toolbar.d.ts +19 -0
- package/dist/internal/features/work/editors/presentation-transition-panel.d.ts +9 -0
- package/dist/internal/features/work/editors/presentation-workspace.d.ts +38 -0
- package/dist/internal/features/work/editors/spreadsheet-calculation-model.d.ts +8 -0
- package/dist/internal/features/work/editors/spreadsheet-calculation-projection.d.ts +32 -0
- package/dist/internal/features/work/editors/spreadsheet-chart-axis-editor.d.ts +9 -0
- package/dist/internal/features/work/editors/spreadsheet-chart-draft.d.ts +17 -0
- package/dist/internal/features/work/editors/spreadsheet-chart-layout-editor.d.ts +13 -0
- package/dist/internal/features/work/editors/spreadsheet-chart-panel.d.ts +10 -0
- package/dist/internal/features/work/editors/spreadsheet-chart-series-style-editor.d.ts +9 -0
- package/dist/internal/features/work/editors/spreadsheet-clipboard-shortcuts.d.ts +9 -0
- package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +121 -0
- package/dist/internal/features/work/editors/spreadsheet-conditional-comparison-fields.d.ts +7 -0
- package/dist/internal/features/work/editors/spreadsheet-conditional-format-model.d.ts +72 -0
- package/dist/internal/features/work/editors/spreadsheet-conditional-format-panel.d.ts +7 -0
- package/dist/internal/features/work/editors/spreadsheet-conditional-threshold-fields.d.ts +10 -0
- package/dist/internal/features/work/editors/spreadsheet-context-menu.d.ts +36 -0
- package/dist/internal/features/work/editors/spreadsheet-data-label-editor.d.ts +9 -0
- package/dist/internal/features/work/editors/spreadsheet-editor-ribbon.d.ts +46 -0
- package/dist/internal/features/work/editors/spreadsheet-editor-support.d.ts +31 -0
- package/dist/internal/features/work/editors/spreadsheet-editor.d.ts +16 -0
- package/dist/internal/features/work/editors/spreadsheet-error-bar-editor.d.ts +10 -0
- package/dist/internal/features/work/editors/spreadsheet-find-bar.d.ts +8 -0
- package/dist/internal/features/work/editors/spreadsheet-find.d.ts +9 -0
- package/dist/internal/features/work/editors/spreadsheet-formula-panel.d.ts +10 -0
- package/dist/internal/features/work/editors/spreadsheet-header-footer-fields.d.ts +5 -0
- package/dist/internal/features/work/editors/spreadsheet-keyboard-navigation.d.ts +18 -0
- package/dist/internal/features/work/editors/spreadsheet-number-format.d.ts +11 -0
- package/dist/internal/features/work/editors/spreadsheet-pivot-panel.d.ts +10 -0
- package/dist/internal/features/work/editors/spreadsheet-print-settings-panel.d.ts +6 -0
- package/dist/internal/features/work/editors/spreadsheet-protection-panel.d.ts +7 -0
- package/dist/internal/features/work/editors/spreadsheet-sheet-bar.d.ts +17 -0
- package/dist/internal/features/work/editors/spreadsheet-sheet-model.d.ts +13 -0
- package/dist/internal/features/work/editors/spreadsheet-trendline-editor.d.ts +8 -0
- package/dist/internal/features/work/editors/spreadsheet-workbook-panel.d.ts +16 -0
- package/dist/internal/features/work/editors/use-document-comments.d.ts +26 -0
- package/dist/internal/features/work/editors/use-document-insert-commands.d.ts +19 -0
- package/dist/internal/features/work/editors/use-document-layout-fonts.d.ts +2 -0
- package/dist/internal/features/work/editors/use-document-page-chrome.d.ts +33 -0
- package/dist/internal/features/work/editors/use-document-pagination.d.ts +46 -0
- package/dist/internal/features/work/editors/use-markdown-source-history.d.ts +16 -0
- package/dist/internal/features/work/editors/use-office-draft.d.ts +10 -0
- package/dist/internal/features/work/editors/use-office-editor-keyboard-shortcuts.d.ts +9 -0
- package/dist/internal/features/work/editors/use-office-editor-runtime.d.ts +6 -0
- package/dist/internal/features/work/editors/use-office-editor-wheel-zoom.d.ts +19 -0
- package/dist/internal/features/work/editors/use-office-history.d.ts +10 -0
- package/dist/internal/features/work/editors/use-presentation-clipboard.d.ts +22 -0
- package/dist/internal/features/work/editors/use-presentation-design-commands.d.ts +33 -0
- package/dist/internal/features/work/editors/use-presentation-element-commands.d.ts +29 -0
- package/dist/internal/features/work/editors/use-presentation-geometry.d.ts +17 -0
- package/dist/internal/features/work/editors/use-presentation-history.d.ts +12 -0
- package/dist/internal/features/work/editors/use-presentation-review-commands.d.ts +22 -0
- package/dist/internal/features/work/editors/use-presentation-selection.d.ts +11 -0
- package/dist/internal/features/work/editors/use-presentation-slide-commands.d.ts +18 -0
- package/dist/internal/features/work/editors/use-presentation-thumbnail-visibility.d.ts +4 -0
- package/dist/internal/features/work/editors/use-presentation-thumbnail-window.d.ts +17 -0
- package/dist/internal/features/work/editors/use-presentation-transform.d.ts +53 -0
- package/dist/internal/features/work/editors/use-spreadsheet-calculation.d.ts +17 -0
- package/dist/internal/features/work/editors/use-spreadsheet-workbook-sync.d.ts +10 -0
- package/dist/internal/features/work/editors/work-office-chrome.d.ts +61 -0
- package/dist/internal/features/work/editors/work-office-ribbon-overflow.d.ts +18 -0
- package/dist/internal/features/work/work-agent-proposal-apply.d.ts +8 -0
- package/dist/internal/features/work/work-agent-proposal.d.ts +55 -0
- package/dist/internal/features/work/work-agent-request.d.ts +6 -0
- package/dist/internal/features/work/work-chart-series-analysis-context.d.ts +3 -0
- package/dist/internal/features/work/work-document-caption-nodes.d.ts +13 -0
- package/dist/internal/features/work/work-document-captions.d.ts +14 -0
- package/dist/internal/features/work/work-document-changes.d.ts +35 -0
- package/dist/internal/features/work/work-document-character-formatting.d.ts +13 -0
- package/dist/internal/features/work/work-document-citation-nodes.d.ts +25 -0
- package/dist/internal/features/work/work-document-citations.d.ts +21 -0
- package/dist/internal/features/work/work-document-columns.d.ts +15 -0
- package/dist/internal/features/work/work-document-comments.d.ts +48 -0
- package/dist/internal/features/work/work-document-extensions.d.ts +11 -0
- package/dist/internal/features/work/work-document-field-node.d.ts +12 -0
- package/dist/internal/features/work/work-document-fields.d.ts +15 -0
- package/dist/internal/features/work/work-document-file-io.d.ts +4 -0
- package/dist/internal/features/work/work-document-fonts.d.ts +16 -0
- package/dist/internal/features/work/work-document-image-layout.d.ts +29 -0
- package/dist/internal/features/work/work-document-incremental-layout.d.ts +17 -0
- package/dist/internal/features/work/work-document-layout.d.ts +5 -0
- package/dist/internal/features/work/work-document-line-measurement.d.ts +24 -0
- package/dist/internal/features/work/work-document-links.d.ts +2 -0
- package/dist/internal/features/work/work-document-lists.d.ts +25 -0
- package/dist/internal/features/work/work-document-model-codec.d.ts +3 -0
- package/dist/internal/features/work/work-document-model.d.ts +12 -0
- package/dist/internal/features/work/work-document-note-nodes.d.ts +11 -0
- package/dist/internal/features/work/work-document-notes.d.ts +18 -0
- package/dist/internal/features/work/work-document-outline.d.ts +14 -0
- package/dist/internal/features/work/work-document-page-break.d.ts +2 -0
- package/dist/internal/features/work/work-document-page-chrome-commands.d.ts +15 -0
- package/dist/internal/features/work/work-document-page-chrome.d.ts +19 -0
- package/dist/internal/features/work/work-document-page-color.d.ts +3 -0
- package/dist/internal/features/work/work-document-pages.d.ts +19 -0
- package/dist/internal/features/work/work-document-pagination-decorations.d.ts +3 -0
- package/dist/internal/features/work/work-document-pagination-dom.d.ts +35 -0
- package/dist/internal/features/work/work-document-pagination-measurement.d.ts +9 -0
- package/dist/internal/features/work/work-document-pagination-types.d.ts +88 -0
- package/dist/internal/features/work/work-document-pagination.d.ts +17 -0
- package/dist/internal/features/work/work-document-paragraph-formatting.d.ts +61 -0
- package/dist/internal/features/work/work-document-search.d.ts +11 -0
- package/dist/internal/features/work/work-document-section-editor.d.ts +20 -0
- package/dist/internal/features/work/work-document-section-node.d.ts +13 -0
- package/dist/internal/features/work/work-document-section.d.ts +34 -0
- package/dist/internal/features/work/work-document-selection-menu.d.ts +54 -0
- package/dist/internal/features/work/work-document-tab-node.d.ts +6 -0
- package/dist/internal/features/work/work-document-tab-stops.d.ts +29 -0
- package/dist/internal/features/work/work-document-table-cell-formatting.d.ts +46 -0
- package/dist/internal/features/work/work-document-table-commands.d.ts +17 -0
- package/dist/internal/features/work/work-document-table-pagination.d.ts +5 -0
- package/dist/internal/features/work/work-document-table-row.d.ts +37 -0
- package/dist/internal/features/work/work-document-table-sizing.d.ts +27 -0
- package/dist/internal/features/work/work-document-text-layout.d.ts +14 -0
- package/dist/internal/features/work/work-docx-bibliography.d.ts +12 -0
- package/dist/internal/features/work/work-docx-caption-diagnostics.d.ts +6 -0
- package/dist/internal/features/work/work-docx-caption-export.d.ts +4 -0
- package/dist/internal/features/work/work-docx-caption-fields.d.ts +5 -0
- package/dist/internal/features/work/work-docx-caption-import.d.ts +20 -0
- package/dist/internal/features/work/work-docx-change-import.d.ts +12 -0
- package/dist/internal/features/work/work-docx-citation-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-citation-export.d.ts +3 -0
- package/dist/internal/features/work/work-docx-citation-import.d.ts +23 -0
- package/dist/internal/features/work/work-docx-column-export.d.ts +14 -0
- package/dist/internal/features/work/work-docx-column-import.d.ts +2 -0
- package/dist/internal/features/work/work-docx-comment-import.d.ts +14 -0
- package/dist/internal/features/work/work-docx-export-formatting.d.ts +30 -0
- package/dist/internal/features/work/work-docx-export-image.d.ts +2 -0
- package/dist/internal/features/work/work-docx-export.d.ts +2 -0
- package/dist/internal/features/work/work-docx-field-export.d.ts +2 -0
- package/dist/internal/features/work/work-docx-field-import.d.ts +16 -0
- package/dist/internal/features/work/work-docx-field-instructions.d.ts +8 -0
- package/dist/internal/features/work/work-docx-image-layout-import.d.ts +12 -0
- package/dist/internal/features/work/work-docx-import.d.ts +50 -0
- package/dist/internal/features/work/work-docx-list-import.d.ts +14 -0
- package/dist/internal/features/work/work-docx-note-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-note-import.d.ts +3 -0
- package/dist/internal/features/work/work-docx-page-chrome-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-page-chrome-import.d.ts +11 -0
- package/dist/internal/features/work/work-docx-page-color.d.ts +2 -0
- package/dist/internal/features/work/work-docx-paragraph-alignment-import.d.ts +12 -0
- package/dist/internal/features/work/work-docx-paragraph-direction-import.d.ts +12 -0
- package/dist/internal/features/work/work-docx-paragraph-indent-import.d.ts +12 -0
- package/dist/internal/features/work/work-docx-paragraph-pagination-import.d.ts +12 -0
- package/dist/internal/features/work/work-docx-paragraph-spacing-import.d.ts +12 -0
- package/dist/internal/features/work/work-docx-paragraph-styles.d.ts +18 -0
- package/dist/internal/features/work/work-docx-run-formatting-import.d.ts +19 -0
- package/dist/internal/features/work/work-docx-tab-stop-import.d.ts +13 -0
- package/dist/internal/features/work/work-docx-table-cell-export.d.ts +4 -0
- package/dist/internal/features/work/work-docx-table-cell-import.d.ts +16 -0
- package/dist/internal/features/work/work-docx-table-row-import.d.ts +13 -0
- package/dist/internal/features/work/work-docx-table-sizing-export.d.ts +8 -0
- package/dist/internal/features/work/work-docx-table-sizing-import.d.ts +12 -0
- package/dist/internal/features/work/work-docx-theme.d.ts +9 -0
- package/dist/internal/features/work/work-file-data.d.ts +1 -0
- package/dist/internal/features/work/work-file-download.d.ts +3 -0
- package/dist/internal/features/work/work-file-io.d.ts +8 -0
- package/dist/internal/features/work/work-markdown-extensions.d.ts +19 -0
- package/dist/internal/features/work/work-markdown-file-io.d.ts +3 -0
- package/dist/internal/features/work/work-markdown-selection-menu.d.ts +57 -0
- package/dist/internal/features/work/work-office-diagnostics.d.ts +9 -0
- package/dist/internal/features/work/work-ooxml-package.d.ts +28 -0
- package/dist/internal/features/work/work-pdf-export.d.ts +23 -0
- package/dist/internal/features/work/work-pptx-chart-axes.d.ts +3 -0
- package/dist/internal/features/work/work-pptx-chart-axis-diagnostics.d.ts +5 -0
- package/dist/internal/features/work/work-pptx-chart-data-labels.d.ts +12 -0
- package/dist/internal/features/work/work-pptx-chart-import.d.ts +11 -0
- package/dist/internal/features/work/work-pptx-chart-layout-style.d.ts +15 -0
- package/dist/internal/features/work/work-pptx-chart-series-analysis.d.ts +13 -0
- package/dist/internal/features/work/work-pptx-chart-xy.d.ts +3 -0
- package/dist/internal/features/work/work-pptx-comments.d.ts +17 -0
- package/dist/internal/features/work/work-pptx-export.d.ts +4 -0
- package/dist/internal/features/work/work-pptx-groups.d.ts +19 -0
- package/dist/internal/features/work/work-pptx-import.d.ts +6 -0
- package/dist/internal/features/work/work-pptx-layout-export.d.ts +13 -0
- package/dist/internal/features/work/work-pptx-layout-import.d.ts +30 -0
- package/dist/internal/features/work/work-pptx-style.d.ts +13 -0
- package/dist/internal/features/work/work-pptx-transition.d.ts +13 -0
- package/dist/internal/features/work/work-presentation-agent-context.d.ts +6 -0
- package/dist/internal/features/work/work-presentation-chart-axes.d.ts +14 -0
- package/dist/internal/features/work/work-presentation-charts.d.ts +37 -0
- package/dist/internal/features/work/work-presentation-clipboard.d.ts +26 -0
- package/dist/internal/features/work/work-presentation-file-io.d.ts +15 -0
- package/dist/internal/features/work/work-presentation-groups.d.ts +17 -0
- package/dist/internal/features/work/work-presentation-layouts.d.ts +13 -0
- package/dist/internal/features/work/work-presentation-transition.d.ts +4 -0
- package/dist/internal/features/work/work-presentation-visual-scale.d.ts +2 -0
- package/dist/internal/features/work/work-repository.d.ts +4 -0
- package/dist/internal/features/work/work-spreadsheet-agent-context.d.ts +15 -0
- package/dist/internal/features/work/work-spreadsheet-chart-axis.d.ts +42 -0
- package/dist/internal/features/work/work-spreadsheet-chart-layout.d.ts +29 -0
- package/dist/internal/features/work/work-spreadsheet-chart-legend-svg.d.ts +18 -0
- package/dist/internal/features/work/work-spreadsheet-chart-series-layout.d.ts +24 -0
- package/dist/internal/features/work/work-spreadsheet-chart-series-style.d.ts +29 -0
- package/dist/internal/features/work/work-spreadsheet-chart-svg-utils.d.ts +7 -0
- package/dist/internal/features/work/work-spreadsheet-chart-svg.d.ts +3 -0
- package/dist/internal/features/work/work-spreadsheet-chart-types.d.ts +147 -0
- package/dist/internal/features/work/work-spreadsheet-chart-validation.d.ts +2 -0
- package/dist/internal/features/work/work-spreadsheet-charts.d.ts +17 -0
- package/dist/internal/features/work/work-spreadsheet-combination-chart-svg.d.ts +9 -0
- package/dist/internal/features/work/work-spreadsheet-comments.d.ts +7 -0
- package/dist/internal/features/work/work-spreadsheet-conditional-canvas.d.ts +5 -0
- package/dist/internal/features/work/work-spreadsheet-conditional-colors.d.ts +9 -0
- package/dist/internal/features/work/work-spreadsheet-conditional-comparisons.d.ts +4 -0
- package/dist/internal/features/work/work-spreadsheet-conditional-data-bar.d.ts +8 -0
- package/dist/internal/features/work/work-spreadsheet-conditional-format.d.ts +10 -0
- package/dist/internal/features/work/work-spreadsheet-conditional-icons.d.ts +107 -0
- package/dist/internal/features/work/work-spreadsheet-conditional-values.d.ts +19 -0
- package/dist/internal/features/work/work-spreadsheet-data-label-svg.d.ts +27 -0
- package/dist/internal/features/work/work-spreadsheet-error-bar-svg.d.ts +5 -0
- package/dist/internal/features/work/work-spreadsheet-error-bars.d.ts +8 -0
- package/dist/internal/features/work/work-spreadsheet-formula-analysis.d.ts +30 -0
- package/dist/internal/features/work/work-spreadsheet-formula-support.d.ts +1 -0
- package/dist/internal/features/work/work-spreadsheet-formulas.d.ts +19 -0
- package/dist/internal/features/work/work-spreadsheet-header-footer.d.ts +14 -0
- package/dist/internal/features/work/work-spreadsheet-line-chart-svg.d.ts +10 -0
- package/dist/internal/features/work/work-spreadsheet-page-breaks.d.ts +4 -0
- package/dist/internal/features/work/work-spreadsheet-page-setup.d.ts +26 -0
- package/dist/internal/features/work/work-spreadsheet-pivot-engine.d.ts +21 -0
- package/dist/internal/features/work/work-spreadsheet-pivot-values.d.ts +7 -0
- package/dist/internal/features/work/work-spreadsheet-pivots.d.ts +27 -0
- package/dist/internal/features/work/work-spreadsheet-protection.d.ts +55 -0
- package/dist/internal/features/work/work-spreadsheet-ranges.d.ts +25 -0
- package/dist/internal/features/work/work-spreadsheet-trendline-svg.d.ts +9 -0
- package/dist/internal/features/work/work-spreadsheet-trendlines.d.ts +11 -0
- package/dist/internal/features/work/work-spreadsheet-xy-chart-axes-svg.d.ts +10 -0
- package/dist/internal/features/work/work-templates.d.ts +4 -0
- package/dist/internal/features/work/work-types.d.ts +513 -0
- package/dist/internal/features/work/work-xlsx-chart-axes.d.ts +4 -0
- package/dist/internal/features/work/work-xlsx-chart-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-xlsx-chart-layout.d.ts +16 -0
- package/dist/internal/features/work/work-xlsx-chart-series-style.d.ts +6 -0
- package/dist/internal/features/work/work-xlsx-chart-values.d.ts +10 -0
- package/dist/internal/features/work/work-xlsx-charts.d.ts +32 -0
- package/dist/internal/features/work/work-xlsx-conditional-format-diagnostics.d.ts +6 -0
- package/dist/internal/features/work/work-xlsx-conditional-format-write.d.ts +11 -0
- package/dist/internal/features/work/work-xlsx-conditional-format.d.ts +29 -0
- package/dist/internal/features/work/work-xlsx-defined-names.d.ts +4 -0
- package/dist/internal/features/work/work-xlsx-drawing-geometry.d.ts +27 -0
- package/dist/internal/features/work/work-xlsx-formula-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-xlsx-formulas.d.ts +40 -0
- package/dist/internal/features/work/work-xlsx-header-footer.d.ts +12 -0
- package/dist/internal/features/work/work-xlsx-images.d.ts +17 -0
- package/dist/internal/features/work/work-xlsx-interop.d.ts +39 -0
- package/dist/internal/features/work/work-xlsx-page-breaks.d.ts +7 -0
- package/dist/internal/features/work/work-xlsx-page-setup-diagnostics.d.ts +2 -0
- package/dist/internal/features/work/work-xlsx-page-setup.d.ts +5 -0
- package/dist/internal/features/work/work-xlsx-pivot-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-xlsx-pivot-xml.d.ts +9 -0
- package/dist/internal/features/work/work-xlsx-pivots.d.ts +32 -0
- package/dist/internal/features/work/work-xlsx-protection.d.ts +24 -0
- package/dist/internal/features/workspace/components/workspace-context-menu.d.ts +29 -0
- package/dist/internal/features/workspace/components/workspace-text-control-selection.d.ts +7 -0
- package/dist/internal/kernel/office-kernel-client-types.d.ts +40 -0
- package/dist/internal/kernel/office-kernel-client.d.ts +4 -0
- package/dist/internal/kernel/office-kernel-fallback.d.ts +2 -0
- package/dist/internal/kernel/office-kernel-presentation-fallback.d.ts +2 -0
- package/dist/internal/kernel/office-kernel-protocol.d.ts +229 -0
- package/dist/internal/kernel/office-kernel-spreadsheet-fallback-formula.d.ts +3 -0
- package/dist/internal/kernel/office-kernel-spreadsheet-fallback-validation.d.ts +5 -0
- package/dist/internal/kernel/office-kernel-spreadsheet-fallback-value.d.ts +6 -0
- package/dist/internal/kernel/office-kernel-spreadsheet-fallback.d.ts +2 -0
- package/dist/internal/kernel/office-kernel-spreadsheet-protocol.d.ts +112 -0
- package/dist/internal/kernel/office-kernel-spreadsheet-session-fallback.d.ts +8 -0
- package/dist/internal/kernel/office-kernel-text-fallback.d.ts +10 -0
- package/dist/internal/kernel/office-kernel-version.d.ts +1 -0
- package/dist/internal/kernel/office-kernel.worker.d.ts +1 -0
- package/dist/internal/keyboard-shortcuts.d.ts +2 -0
- package/dist/internal/state/app-state.d.ts +8 -0
- package/dist/noto-naskh-arabic-regular.ttf +0 -0
- package/dist/noto-naskh-arabic.LICENSE.txt +94 -0
- package/dist/noto-sans-hans-regular.otf +0 -0
- package/dist/noto-sans-hans.LICENSE.txt +94 -0
- package/dist/noto-sans-hebrew-regular.ttf +0 -0
- package/dist/noto-sans-hebrew.LICENSE.txt +94 -0
- package/dist/noto-sans-regular.ttf +0 -0
- package/dist/noto-sans.LICENSE.txt +94 -0
- package/dist/office-kernel.wasm +0 -0
- package/dist/office-kernel.worker.js +14605 -0
- package/dist/office-surface.d.ts +10 -0
- package/dist/pdfium.LICENSE.txt +196 -0
- package/dist/pdfium.wasm +0 -0
- package/dist/pptxgen.LICENSE.txt +21 -0
- package/dist/pptxgen.bundle.js +11244 -0
- package/dist/react.d.ts +51 -0
- package/dist/react.js +1 -0
- package/dist/styles.css +17435 -0
- package/dist/styles.js +0 -0
- package/dist/vue.d.ts +282 -0
- package/dist/vue.js +231 -0
- package/dist/web-component.d.ts +98 -0
- package/dist/web-component.js +335 -0
- package/docs/browser-editor-architecture.md +947 -0
- package/package.json +165 -0
|
@@ -0,0 +1,1138 @@
|
|
|
1
|
+
import { contentTypeForPart, directChildren, bytesToDataUrl, OoxmlPackage, firstDescendant, descendants, directChild, childPath, attribute } from "./8715.js";
|
|
2
|
+
import { normalizeRadarStyle, normalizePresentationChartLegendPosition, presentationChartUsesNumericXAxis, normalizePresentationBubbleScale, normalizePresentationBubbleSizeRepresents, withPresentationChartLayout, normalizeDoughnutHoleSize, normalizePresentationScatterStyle } from "./0~work-presentation-charts.js";
|
|
3
|
+
import { loadPptxCommentAuthors, readPptxSlideComments, readPptxChartLayoutAndSeriesStyles, readPptxTransition, readPptxChartSeriesAnalysis, readPptxChartDataLabels } from "./0~7614.js";
|
|
4
|
+
import { parseXlsxChartAxes } from "./4104.js";
|
|
5
|
+
import { createOfficeId as createWorkId } from "./1134.js";
|
|
6
|
+
import { scaledPresentationVisuals } from "./0~work-presentation-visual-scale.js";
|
|
7
|
+
async function loadPptxTheme(archive, presentationRelationships) {
|
|
8
|
+
const defaults = {
|
|
9
|
+
dk1: '#000000',
|
|
10
|
+
lt1: '#ffffff',
|
|
11
|
+
dk2: '#1f497d',
|
|
12
|
+
lt2: '#eeece1',
|
|
13
|
+
accent1: '#4472c4',
|
|
14
|
+
accent2: '#ed7d31',
|
|
15
|
+
accent3: '#a5a5a5',
|
|
16
|
+
accent4: '#ffc000',
|
|
17
|
+
accent5: '#5b9bd5',
|
|
18
|
+
accent6: '#70ad47',
|
|
19
|
+
hlink: '#0563c1',
|
|
20
|
+
folHlink: '#954f72',
|
|
21
|
+
tx1: '#000000',
|
|
22
|
+
tx2: '#1f497d',
|
|
23
|
+
bg1: '#ffffff',
|
|
24
|
+
bg2: '#eeece1'
|
|
25
|
+
};
|
|
26
|
+
const masterRelationship = Array.from(presentationRelationships.values()).find((item)=>item.type.endsWith('/slideMaster'));
|
|
27
|
+
if (!masterRelationship || !archive.has(masterRelationship.target)) return defaults;
|
|
28
|
+
const masterRelationships = await archive.relationships(masterRelationship.target);
|
|
29
|
+
const themeRelationship = Array.from(masterRelationships.values()).find((item)=>item.type.endsWith('/theme'));
|
|
30
|
+
if (!themeRelationship || !archive.has(themeRelationship.target)) return defaults;
|
|
31
|
+
const document1 = await archive.xml(themeRelationship.target);
|
|
32
|
+
const colorScheme = firstDescendant(document1, 'clrScheme');
|
|
33
|
+
if (!colorScheme) return defaults;
|
|
34
|
+
for (const slot of directChildren(colorScheme)){
|
|
35
|
+
const color = drawingColor(slot, defaults);
|
|
36
|
+
if (color) defaults[slot.localName] = color.color;
|
|
37
|
+
}
|
|
38
|
+
return defaults;
|
|
39
|
+
}
|
|
40
|
+
function readPptxBackground(document1, theme) {
|
|
41
|
+
const background = firstDescendant(document1, 'bg');
|
|
42
|
+
if (!background) return;
|
|
43
|
+
return readPptxFill(background, theme, '#ffffff').color;
|
|
44
|
+
}
|
|
45
|
+
function readPptxFill(container, theme, fallback) {
|
|
46
|
+
if (!container) return {
|
|
47
|
+
color: fallback
|
|
48
|
+
};
|
|
49
|
+
if (firstDescendant(container, 'noFill')) return {
|
|
50
|
+
color: 'transparent'
|
|
51
|
+
};
|
|
52
|
+
const solidFill = firstDescendant(container, 'solidFill');
|
|
53
|
+
const color = drawingColor(solidFill ?? container, theme);
|
|
54
|
+
return color ?? {
|
|
55
|
+
color: fallback
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function supportedPptxShapeType(value) {
|
|
59
|
+
const shapes = {
|
|
60
|
+
rect: 'rect',
|
|
61
|
+
roundRect: 'roundRect',
|
|
62
|
+
ellipse: 'ellipse',
|
|
63
|
+
triangle: 'triangle',
|
|
64
|
+
rtTriangle: 'triangle',
|
|
65
|
+
diamond: 'diamond',
|
|
66
|
+
line: 'line'
|
|
67
|
+
};
|
|
68
|
+
return shapes[value];
|
|
69
|
+
}
|
|
70
|
+
function pptxTextAlignment(value) {
|
|
71
|
+
if ('ctr' === value) return 'center';
|
|
72
|
+
if ('r' === value) return 'right';
|
|
73
|
+
return 'left';
|
|
74
|
+
}
|
|
75
|
+
function pptxVerticalAlignment(value) {
|
|
76
|
+
if ('ctr' === value) return 'middle';
|
|
77
|
+
if ('b' === value) return 'bottom';
|
|
78
|
+
return 'top';
|
|
79
|
+
}
|
|
80
|
+
function drawingColor(container, theme) {
|
|
81
|
+
const colorNames = [
|
|
82
|
+
'srgbClr',
|
|
83
|
+
'scrgbClr',
|
|
84
|
+
'sysClr',
|
|
85
|
+
'schemeClr',
|
|
86
|
+
'prstClr'
|
|
87
|
+
];
|
|
88
|
+
const colorNode = directChildren(container).find((node)=>colorNames.includes(node.localName)) ?? colorNames.map((name)=>firstDescendant(container, name)).find(Boolean);
|
|
89
|
+
if (!colorNode) return;
|
|
90
|
+
let color;
|
|
91
|
+
if ('srgbClr' === colorNode.localName) color = normalizeColor(attribute(colorNode, 'val'));
|
|
92
|
+
else if ('sysClr' === colorNode.localName) color = normalizeColor(attribute(colorNode, 'lastClr'));
|
|
93
|
+
else if ('schemeClr' === colorNode.localName) color = theme[attribute(colorNode, 'val') ?? ''];
|
|
94
|
+
else if ('prstClr' === colorNode.localName) color = presetColor(attribute(colorNode, 'val'));
|
|
95
|
+
else {
|
|
96
|
+
const red = numberAttribute(colorNode, 'r', 0) / 100000 * 255;
|
|
97
|
+
const green = numberAttribute(colorNode, 'g', 0) / 100000 * 255;
|
|
98
|
+
const blue = numberAttribute(colorNode, 'b', 0) / 100000 * 255;
|
|
99
|
+
color = rgbToHex(red, green, blue);
|
|
100
|
+
}
|
|
101
|
+
if (!color) return;
|
|
102
|
+
const tint = numberAttribute(firstDescendant(colorNode, 'tint'), 'val', 0) / 100000;
|
|
103
|
+
const shadeNode = firstDescendant(colorNode, 'shade');
|
|
104
|
+
const shade = shadeNode ? numberAttribute(shadeNode, 'val', 100000) / 100000 : 1;
|
|
105
|
+
color = modifyColor(color, tint, shade);
|
|
106
|
+
const alphaNode = firstDescendant(colorNode, 'alpha');
|
|
107
|
+
return {
|
|
108
|
+
color,
|
|
109
|
+
opacity: alphaNode ? numberAttribute(alphaNode, 'val', 100000) / 100000 : void 0
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function normalizeColor(value) {
|
|
113
|
+
if (!value) return;
|
|
114
|
+
const normalized = value.replace(/^#/, '');
|
|
115
|
+
return /^[0-9a-f]{6}$/i.test(normalized) ? `#${normalized.toLowerCase()}` : void 0;
|
|
116
|
+
}
|
|
117
|
+
function presetColor(value) {
|
|
118
|
+
const colors = {
|
|
119
|
+
black: '#000000',
|
|
120
|
+
white: '#ffffff',
|
|
121
|
+
red: '#ff0000',
|
|
122
|
+
green: '#008000',
|
|
123
|
+
blue: '#0000ff',
|
|
124
|
+
yellow: '#ffff00',
|
|
125
|
+
orange: '#ffa500',
|
|
126
|
+
purple: '#800080',
|
|
127
|
+
gray: '#808080',
|
|
128
|
+
grey: '#808080'
|
|
129
|
+
};
|
|
130
|
+
return value ? colors[value] : void 0;
|
|
131
|
+
}
|
|
132
|
+
function modifyColor(color, tint, shade) {
|
|
133
|
+
const red = Number.parseInt(color.slice(1, 3), 16);
|
|
134
|
+
const green = Number.parseInt(color.slice(3, 5), 16);
|
|
135
|
+
const blue = Number.parseInt(color.slice(5, 7), 16);
|
|
136
|
+
return rgbToHex((red + (255 - red) * tint) * shade, (green + (255 - green) * tint) * shade, (blue + (255 - blue) * tint) * shade);
|
|
137
|
+
}
|
|
138
|
+
function rgbToHex(red, green, blue) {
|
|
139
|
+
return `#${[
|
|
140
|
+
red,
|
|
141
|
+
green,
|
|
142
|
+
blue
|
|
143
|
+
].map((value)=>Math.max(0, Math.min(255, Math.round(value))).toString(16).padStart(2, '0')).join('')}`;
|
|
144
|
+
}
|
|
145
|
+
function numberAttribute(element, name, fallback) {
|
|
146
|
+
if (!element) return fallback;
|
|
147
|
+
const value = Number(attribute(element, name));
|
|
148
|
+
return Number.isFinite(value) ? value : fallback;
|
|
149
|
+
}
|
|
150
|
+
async function loadPptxSlideInheritance(archive, slideRelationships, theme) {
|
|
151
|
+
const layoutRelationship = Array.from(slideRelationships.values()).find((item)=>item.type.endsWith('/slideLayout'));
|
|
152
|
+
const layout = layoutRelationship ? await loadPptxDesignPart(archive, layoutRelationship.target, theme, 'Slide layout') : void 0;
|
|
153
|
+
const masterRelationship = layout ? Array.from(layout.relationships.values()).find((item)=>item.type.endsWith('/slideMaster')) : void 0;
|
|
154
|
+
const master = masterRelationship ? await loadPptxDesignPart(archive, masterRelationship.target, theme, 'Slide master') : void 0;
|
|
155
|
+
const placeholders = new Map();
|
|
156
|
+
for (const part of [
|
|
157
|
+
master,
|
|
158
|
+
layout
|
|
159
|
+
])if (part) for (const shape of descendants(part.document, 'sp')){
|
|
160
|
+
const box = pptxRawElementBox(shape);
|
|
161
|
+
const placeholder = pptxPlaceholder(shape);
|
|
162
|
+
if (box && placeholder) {
|
|
163
|
+
placeholders.set(placeholder.key, box);
|
|
164
|
+
placeholders.set(`type:${placeholder.type}`, box);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
layout,
|
|
169
|
+
master,
|
|
170
|
+
placeholders
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function pptxRawElementBox(node) {
|
|
174
|
+
const xfrm = 'graphicFrame' === node.localName ? directChild(node, 'xfrm') : 'grpSp' === node.localName ? childPath(node, 'grpSpPr', 'xfrm') : childPath(node, 'spPr', 'xfrm');
|
|
175
|
+
if (!xfrm) return;
|
|
176
|
+
const offset = directChild(xfrm, 'off');
|
|
177
|
+
const extent = directChild(xfrm, 'ext');
|
|
178
|
+
if (!offset || !extent) return;
|
|
179
|
+
return {
|
|
180
|
+
x: work_pptx_layout_import_numberAttribute(offset, 'x', 0),
|
|
181
|
+
y: work_pptx_layout_import_numberAttribute(offset, 'y', 0),
|
|
182
|
+
width: Math.abs(work_pptx_layout_import_numberAttribute(extent, 'cx', 0)),
|
|
183
|
+
height: Math.abs(work_pptx_layout_import_numberAttribute(extent, 'cy', 0)),
|
|
184
|
+
rotation: work_pptx_layout_import_numberAttribute(xfrm, 'rot', 0) / 60000 || void 0
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function pptxPlaceholderBox(node, placeholders) {
|
|
188
|
+
const placeholder = pptxPlaceholder(node);
|
|
189
|
+
if (!placeholder) return;
|
|
190
|
+
return placeholders.get(placeholder.key) ?? placeholders.get(`type:${placeholder.type}`);
|
|
191
|
+
}
|
|
192
|
+
function pptxPlaceholder(node) {
|
|
193
|
+
const placeholder = firstDescendant(node, 'ph');
|
|
194
|
+
if (!placeholder) return;
|
|
195
|
+
const index = attribute(placeholder, 'idx')?.trim();
|
|
196
|
+
const type = attribute(placeholder, 'type')?.trim() || 'body';
|
|
197
|
+
return {
|
|
198
|
+
key: index ? `idx:${index}` : `type:${type}`,
|
|
199
|
+
type
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function pptxShowsMasterElements(document1) {
|
|
203
|
+
const value = attribute(document1.documentElement, 'showMasterSp');
|
|
204
|
+
return '0' !== value && 'false' !== value;
|
|
205
|
+
}
|
|
206
|
+
async function loadPptxDesignPart(archive, path, theme, fallbackName) {
|
|
207
|
+
if (!archive.has(path)) return;
|
|
208
|
+
const document1 = await archive.xml(path);
|
|
209
|
+
const commonSlideData = directChild(document1.documentElement, 'cSld');
|
|
210
|
+
return {
|
|
211
|
+
path,
|
|
212
|
+
document: document1,
|
|
213
|
+
relationships: await archive.relationships(path),
|
|
214
|
+
name: attribute(commonSlideData ?? document1.documentElement, 'name')?.trim() || `${fallbackName} ${partNumber(path)}`,
|
|
215
|
+
background: readPptxBackground(document1, theme),
|
|
216
|
+
showMasterElements: pptxShowsMasterElements(document1),
|
|
217
|
+
sourceType: attribute(document1.documentElement, 'type')?.trim() || void 0
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function partNumber(path) {
|
|
221
|
+
return /(\d+)(?:\.xml)?$/i.exec(path)?.[1] ?? '1';
|
|
222
|
+
}
|
|
223
|
+
function work_pptx_layout_import_numberAttribute(element, name, fallback) {
|
|
224
|
+
if (!element) return fallback;
|
|
225
|
+
const value = Number(attribute(element, name));
|
|
226
|
+
return Number.isFinite(value) ? value : fallback;
|
|
227
|
+
}
|
|
228
|
+
function readPptxChartAxisDiagnostics(document1) {
|
|
229
|
+
const plotArea = firstDescendant(document1, 'plotArea');
|
|
230
|
+
if (!plotArea) return [];
|
|
231
|
+
const axes = directChildren(plotArea).filter((child)=>'catAx' === child.localName || 'valAx' === child.localName || 'dateAx' === child.localName);
|
|
232
|
+
const diagnostics = [];
|
|
233
|
+
if (axes.length > 2 || axes.some((axis)=>[
|
|
234
|
+
't',
|
|
235
|
+
'r'
|
|
236
|
+
].includes(attribute(directChild(axis, 'axPos') ?? axis, 'val') ?? ''))) diagnostics.push({
|
|
237
|
+
code: 'pptx.chart.axis-secondary',
|
|
238
|
+
message: 'Secondary or additional chart axes were normalized to the editable primary horizontal and vertical axes.'
|
|
239
|
+
});
|
|
240
|
+
if (axes.some((axis)=>'dateAx' === axis.localName)) diagnostics.push({
|
|
241
|
+
code: 'pptx.chart.axis-date',
|
|
242
|
+
message: 'Date-axis units and calendar behavior were normalized to an editable category axis.'
|
|
243
|
+
});
|
|
244
|
+
if (axes.some((axis)=>directChild(directChild(axis, 'scaling') ?? axis, 'logBase'))) diagnostics.push({
|
|
245
|
+
code: 'pptx.chart.axis-logarithmic',
|
|
246
|
+
message: 'Logarithmic chart-axis scaling was normalized to the editable linear scale.'
|
|
247
|
+
});
|
|
248
|
+
if (axes.some((axis)=>directChild(axis, 'minorUnit'))) diagnostics.push({
|
|
249
|
+
code: 'pptx.chart.axis-minor-unit',
|
|
250
|
+
message: 'Minor chart-axis units were normalized because only the primary unit is editable.'
|
|
251
|
+
});
|
|
252
|
+
if (axes.some((axis)=>directChild(axis, 'dispUnits'))) diagnostics.push({
|
|
253
|
+
code: 'pptx.chart.axis-display-units',
|
|
254
|
+
message: 'Chart-axis display units were flattened into the editable number format.'
|
|
255
|
+
});
|
|
256
|
+
if (axes.some((axis)=>directChild(axis, 'minorGridlines') || directChild(axis, 'minorTickMark') || directChild(axis, 'tickMarkSkip'))) diagnostics.push({
|
|
257
|
+
code: 'pptx.chart.axis-minor-display',
|
|
258
|
+
message: 'Minor gridlines, minor tick marks, or tick-mark intervals were normalized to primary-axis settings.'
|
|
259
|
+
});
|
|
260
|
+
if (axes.some((axis)=>directChild(axis, 'crossesAt'))) diagnostics.push({
|
|
261
|
+
code: 'pptx.chart.axis-crossing',
|
|
262
|
+
message: 'Custom chart-axis crossing points were normalized to automatic crossing.'
|
|
263
|
+
});
|
|
264
|
+
return diagnostics;
|
|
265
|
+
}
|
|
266
|
+
function readPptxChart(document1) {
|
|
267
|
+
const diagnostics = [];
|
|
268
|
+
const chartTypes = [
|
|
269
|
+
'barChart',
|
|
270
|
+
'lineChart',
|
|
271
|
+
'pieChart',
|
|
272
|
+
'doughnutChart',
|
|
273
|
+
'areaChart',
|
|
274
|
+
'radarChart',
|
|
275
|
+
'scatterChart',
|
|
276
|
+
'bubbleChart'
|
|
277
|
+
];
|
|
278
|
+
const chartNode = chartTypes.map((name)=>firstDescendant(document1, name)).find(Boolean);
|
|
279
|
+
if (!chartNode) diagnostics.push({
|
|
280
|
+
code: 'pptx.chart.type',
|
|
281
|
+
feature: 'Charts',
|
|
282
|
+
message: 'This chart type is shown as a basic column chart and will be normalized on export.'
|
|
283
|
+
});
|
|
284
|
+
const localName = chartNode?.localName;
|
|
285
|
+
const barDirection = attribute(firstDescendant(chartNode, 'barDir') ?? document1.documentElement, 'val');
|
|
286
|
+
const type = 'scatterChart' === localName ? 'scatter' : 'bubbleChart' === localName ? 'bubble' : 'lineChart' === localName ? 'line' : 'pieChart' === localName ? 'pie' : 'doughnutChart' === localName ? 'doughnut' : 'radarChart' === localName ? 'radar' : 'areaChart' === localName ? 'area' : 'bar' === barDirection ? 'bar' : 'column';
|
|
287
|
+
const numericXAxis = presentationChartUsesNumericXAxis(type);
|
|
288
|
+
const seriesNodes = chartNode ? directChildren(chartNode, 'ser') : descendants(document1, 'ser');
|
|
289
|
+
const formatting = readPptxChartLayoutAndSeriesStyles(document1, chartNode, type, seriesNodes);
|
|
290
|
+
const xValues = seriesNodes.map((node)=>cachedValues(directChild(node, 'xVal')).map(finiteNumber));
|
|
291
|
+
const seriesAnalysis = seriesNodes.map((node)=>readPptxChartSeriesAnalysis(node, type));
|
|
292
|
+
const series = seriesNodes.map((node, index)=>({
|
|
293
|
+
name: cachedValues(directChild(node, 'tx'))[0] ?? `Series ${index + 1}`,
|
|
294
|
+
values: cachedValues(directChild(node, numericXAxis ? 'yVal' : 'val')).map(finiteNumber),
|
|
295
|
+
...'bubble' === type ? {
|
|
296
|
+
bubbleSizes: cachedValues(directChild(node, 'bubbleSize')).map(finiteNumber)
|
|
297
|
+
} : {},
|
|
298
|
+
...seriesAnalysis[index]?.trendlines ? {
|
|
299
|
+
trendlines: seriesAnalysis[index].trendlines
|
|
300
|
+
} : {},
|
|
301
|
+
...seriesAnalysis[index]?.errorBars ? {
|
|
302
|
+
errorBars: seriesAnalysis[index].errorBars
|
|
303
|
+
} : {},
|
|
304
|
+
...formatting.seriesStyles[index] ? {
|
|
305
|
+
style: formatting.seriesStyles[index]
|
|
306
|
+
} : {}
|
|
307
|
+
}));
|
|
308
|
+
diagnostics.push(...seriesAnalysis.flatMap((result)=>result.diagnostics.map((diagnostic)=>({
|
|
309
|
+
...diagnostic,
|
|
310
|
+
feature: 'Chart series analysis'
|
|
311
|
+
}))));
|
|
312
|
+
const categories = numericXAxis ? (xValues[0] ?? []).map((value)=>String(value)) : cachedValues(directChild(seriesNodes[0] ?? document1.documentElement, 'cat'));
|
|
313
|
+
if (numericXAxis && new Set(xValues.map((values)=>values.join('|'))).size > 1) diagnostics.push({
|
|
314
|
+
code: 'pptx.chart.xy-values',
|
|
315
|
+
feature: 'XY chart data',
|
|
316
|
+
message: 'Different per-series X values were normalized to the first series shared X-value list.'
|
|
317
|
+
});
|
|
318
|
+
const chartRoot = firstDescendant(document1, 'chart');
|
|
319
|
+
const legend = directChild(chartRoot ?? document1.documentElement, 'legend');
|
|
320
|
+
const title = chartText(directChild(chartRoot ?? document1.documentElement, 'title'));
|
|
321
|
+
const axes = parseXlsxChartAxes(document1, type, false, true);
|
|
322
|
+
diagnostics.push(...readPptxChartAxisDiagnostics(document1).map((diagnostic)=>({
|
|
323
|
+
...diagnostic,
|
|
324
|
+
feature: 'Chart axes'
|
|
325
|
+
})));
|
|
326
|
+
diagnostics.push(...formatting.diagnostics.map((diagnostic)=>({
|
|
327
|
+
...diagnostic,
|
|
328
|
+
feature: 'Chart formatting'
|
|
329
|
+
})));
|
|
330
|
+
const chart = {
|
|
331
|
+
type,
|
|
332
|
+
title,
|
|
333
|
+
categories,
|
|
334
|
+
series,
|
|
335
|
+
showLegend: Boolean(legend),
|
|
336
|
+
...legend ? {
|
|
337
|
+
legendPosition: pptxLegendPosition(legend)
|
|
338
|
+
} : {},
|
|
339
|
+
...void 0 !== formatting.legendOverlay ? {
|
|
340
|
+
legendOverlay: formatting.legendOverlay
|
|
341
|
+
} : {},
|
|
342
|
+
...formatting.layout,
|
|
343
|
+
...axes ? {
|
|
344
|
+
axes
|
|
345
|
+
} : {}
|
|
346
|
+
};
|
|
347
|
+
const dataLabelResult = readPptxChartDataLabels(chartNode, type);
|
|
348
|
+
if (dataLabelResult.dataLabels) chart.dataLabels = dataLabelResult.dataLabels;
|
|
349
|
+
diagnostics.push(...dataLabelResult.diagnostics.map((diagnostic)=>({
|
|
350
|
+
...diagnostic,
|
|
351
|
+
feature: 'Chart data labels'
|
|
352
|
+
})));
|
|
353
|
+
if ('doughnut' === type) readDoughnutSettings(chartNode, document1, chart, diagnostics);
|
|
354
|
+
if ('radar' === type) readRadarSettings(chartNode, document1, chart, diagnostics);
|
|
355
|
+
if ('scatter' === type) readScatterSettings(chartNode, chart, diagnostics);
|
|
356
|
+
if ('bubble' === type) readBubbleSettings(chartNode, chart, diagnostics);
|
|
357
|
+
return {
|
|
358
|
+
chart: withPresentationChartLayout(chart),
|
|
359
|
+
diagnostics
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
function pptxLegendPosition(legend) {
|
|
363
|
+
const value = attribute(directChild(legend, 'legendPos') ?? legend, 'val');
|
|
364
|
+
const position = 'l' === value ? 'left' : 't' === value ? 'top' : 'b' === value ? 'bottom' : 'tr' === value ? 'topRight' : 'right';
|
|
365
|
+
return normalizePresentationChartLegendPosition(position);
|
|
366
|
+
}
|
|
367
|
+
function chartText(node) {
|
|
368
|
+
if (!node) return;
|
|
369
|
+
const richText = descendants(node, 't').map((part)=>part.textContent ?? '').join('').trim();
|
|
370
|
+
if (richText) return richText;
|
|
371
|
+
const cachedText = descendants(node, 'v').map((part)=>part.textContent ?? '').join('').trim();
|
|
372
|
+
return cachedText || void 0;
|
|
373
|
+
}
|
|
374
|
+
function readDoughnutSettings(chartNode, document1, chart, diagnostics) {
|
|
375
|
+
const holeSize = firstDescendant(chartNode ?? document1.documentElement, 'holeSize');
|
|
376
|
+
const holeSizeValue = attribute(holeSize ?? document1.documentElement, 'val');
|
|
377
|
+
const rawHoleSize = null === holeSizeValue ? void 0 : Number(holeSizeValue);
|
|
378
|
+
chart.doughnutHoleSize = normalizeDoughnutHoleSize(rawHoleSize);
|
|
379
|
+
if (holeSize && (void 0 === rawHoleSize || !Number.isFinite(rawHoleSize) || rawHoleSize < 10 || rawHoleSize > 90)) diagnostics.push({
|
|
380
|
+
code: 'pptx.chart.doughnut-hole',
|
|
381
|
+
feature: 'Chart formatting',
|
|
382
|
+
message: 'The doughnut hole size was outside the editable 10–90% range and was normalized.'
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
function readRadarSettings(chartNode, document1, chart, diagnostics) {
|
|
386
|
+
const radarStyle = attribute(firstDescendant(chartNode ?? document1.documentElement, 'radarStyle') ?? chartNode ?? document1.documentElement, 'val');
|
|
387
|
+
chart.radarStyle = normalizeRadarStyle('standard' === radarStyle || 'marker' === radarStyle || 'filled' === radarStyle ? radarStyle : void 0);
|
|
388
|
+
if (radarStyle && ![
|
|
389
|
+
'standard',
|
|
390
|
+
'marker',
|
|
391
|
+
'filled'
|
|
392
|
+
].includes(radarStyle)) diagnostics.push({
|
|
393
|
+
code: 'pptx.chart.radar-style',
|
|
394
|
+
feature: 'Chart formatting',
|
|
395
|
+
message: `The radar style “${radarStyle}” was normalized to the standard editable style.`
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
function readScatterSettings(chartNode, chart, diagnostics) {
|
|
399
|
+
if (!chartNode) return;
|
|
400
|
+
const rawStyle = attribute(directChild(chartNode, 'scatterStyle') ?? chartNode, 'val');
|
|
401
|
+
chart.scatterStyle = normalizePresentationScatterStyle(rawStyle);
|
|
402
|
+
if (rawStyle && ![
|
|
403
|
+
'marker',
|
|
404
|
+
'line',
|
|
405
|
+
'lineMarker',
|
|
406
|
+
'smooth',
|
|
407
|
+
'smoothMarker'
|
|
408
|
+
].includes(rawStyle)) diagnostics.push({
|
|
409
|
+
code: 'pptx.chart.scatter-style',
|
|
410
|
+
feature: 'Chart formatting',
|
|
411
|
+
message: `The scatter style “${rawStyle}” was normalized to the editable line-and-marker style.`
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
function readBubbleSettings(chartNode, chart, diagnostics) {
|
|
415
|
+
if (!chartNode) return;
|
|
416
|
+
const source = chartNode;
|
|
417
|
+
const scaleElement = directChild(source, 'bubbleScale');
|
|
418
|
+
const rawScale = scaleElement ? Number(attribute(scaleElement, 'val')) : void 0;
|
|
419
|
+
chart.bubbleScale = normalizePresentationBubbleScale(rawScale);
|
|
420
|
+
if (scaleElement && (void 0 === rawScale || !Number.isFinite(rawScale) || rawScale < 5 || rawScale > 300)) diagnostics.push({
|
|
421
|
+
code: 'pptx.chart.bubble-scale',
|
|
422
|
+
feature: 'Chart formatting',
|
|
423
|
+
message: 'The bubble scale was outside the editable 5–300% range and was normalized.'
|
|
424
|
+
});
|
|
425
|
+
chart.showNegativeBubbles = pptxBooleanElement(source, 'showNegBubbles');
|
|
426
|
+
const rawSizeRepresents = attribute(directChild(source, 'sizeRepresents') ?? source, 'val');
|
|
427
|
+
chart.bubbleSizeRepresents = normalizePresentationBubbleSizeRepresents('w' === rawSizeRepresents ? 'width' : rawSizeRepresents);
|
|
428
|
+
if (rawSizeRepresents && 'area' !== rawSizeRepresents && 'w' !== rawSizeRepresents) diagnostics.push({
|
|
429
|
+
code: 'pptx.chart.bubble-size',
|
|
430
|
+
feature: 'Chart formatting',
|
|
431
|
+
message: `The bubble-size representation “${rawSizeRepresents}” was normalized to area.`
|
|
432
|
+
});
|
|
433
|
+
if (descendants(source, 'bubble3D').some((element)=>pptxBooleanValue(element))) diagnostics.push({
|
|
434
|
+
code: 'pptx.chart.bubble-3d',
|
|
435
|
+
feature: 'Chart formatting',
|
|
436
|
+
message: '3D bubble effects were normalized to editable 2D bubbles.'
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
function cachedValues(parent) {
|
|
440
|
+
if (!parent) return [];
|
|
441
|
+
const multiLevelCache = firstDescendant(parent, 'multiLvlStrCache');
|
|
442
|
+
if (multiLevelCache) {
|
|
443
|
+
const levels = directChildren(multiLevelCache, 'lvl').map((level)=>cachedPoints(level));
|
|
444
|
+
const length = Math.max(0, ...levels.map((level)=>level.length));
|
|
445
|
+
return Array.from({
|
|
446
|
+
length
|
|
447
|
+
}, (_, index)=>levels.map((level)=>level[index]?.trim()).filter(Boolean).join(' / '));
|
|
448
|
+
}
|
|
449
|
+
const cache = firstDescendant(parent, 'strCache') ?? firstDescendant(parent, 'numCache') ?? firstDescendant(parent, 'strLit') ?? firstDescendant(parent, 'numLit');
|
|
450
|
+
if (!cache) {
|
|
451
|
+
const value = firstDescendant(parent, 'v')?.textContent;
|
|
452
|
+
return null == value ? [] : [
|
|
453
|
+
value
|
|
454
|
+
];
|
|
455
|
+
}
|
|
456
|
+
return cachedPoints(cache);
|
|
457
|
+
}
|
|
458
|
+
function cachedPoints(cache) {
|
|
459
|
+
return descendants(cache, 'pt').sort((left, right)=>work_pptx_chart_import_numberAttribute(left, 'idx', 0) - work_pptx_chart_import_numberAttribute(right, 'idx', 0)).map((point)=>firstDescendant(point, 'v')?.textContent ?? '');
|
|
460
|
+
}
|
|
461
|
+
function work_pptx_chart_import_numberAttribute(element, name, fallback) {
|
|
462
|
+
if (!element) return fallback;
|
|
463
|
+
const value = Number(attribute(element, name));
|
|
464
|
+
return Number.isFinite(value) ? value : fallback;
|
|
465
|
+
}
|
|
466
|
+
function finiteNumber(value) {
|
|
467
|
+
const number = Number(value);
|
|
468
|
+
return Number.isFinite(number) ? number : 0;
|
|
469
|
+
}
|
|
470
|
+
function pptxBooleanElement(parent, localName) {
|
|
471
|
+
const element = directChild(parent, localName);
|
|
472
|
+
return element ? pptxBooleanValue(element) : false;
|
|
473
|
+
}
|
|
474
|
+
function pptxBooleanValue(element) {
|
|
475
|
+
const value = attribute(element, 'val');
|
|
476
|
+
return null === value || '1' === value || 'true' === value.toLocaleLowerCase();
|
|
477
|
+
}
|
|
478
|
+
const EMU_PER_INCH = 914400;
|
|
479
|
+
const DEFAULT_SLIDE_WIDTH = 13.333;
|
|
480
|
+
const DEFAULT_SLIDE_HEIGHT = 7.5;
|
|
481
|
+
const MAX_EMBEDDED_IMAGE_BYTES = 11534336;
|
|
482
|
+
async function importPptxPresentation(file) {
|
|
483
|
+
const archive = await OoxmlPackage.load(await file.arrayBuffer());
|
|
484
|
+
if (!archive.has('ppt/presentation.xml')) throw new Error('The selected file is not a valid PPTX presentation.');
|
|
485
|
+
const presentation = await archive.xml('ppt/presentation.xml');
|
|
486
|
+
const presentationRelationships = await archive.relationships('ppt/presentation.xml');
|
|
487
|
+
const size = firstDescendant(presentation, 'sldSz');
|
|
488
|
+
const slideWidthEmu = positiveNumber(attribute(size ?? presentation.documentElement, 'cx')) ?? 12192000;
|
|
489
|
+
const slideHeightEmu = positiveNumber(attribute(size ?? presentation.documentElement, 'cy')) ?? 6858000;
|
|
490
|
+
const theme = await loadPptxTheme(archive, presentationRelationships);
|
|
491
|
+
const commentAuthors = await loadPptxCommentAuthors(archive, presentationRelationships);
|
|
492
|
+
const issues = [];
|
|
493
|
+
const imageBudget = {
|
|
494
|
+
bytes: 0
|
|
495
|
+
};
|
|
496
|
+
const designs = {
|
|
497
|
+
masterByPath: new Map(),
|
|
498
|
+
layoutByPath: new Map(),
|
|
499
|
+
masters: [],
|
|
500
|
+
layouts: []
|
|
501
|
+
};
|
|
502
|
+
await loadPptxPresentationDesigns(archive, presentationRelationships, slideWidthEmu, slideHeightEmu, theme, issues, imageBudget, designs);
|
|
503
|
+
const slideParts = orderedSlideParts(presentation, presentationRelationships);
|
|
504
|
+
if (!slideParts.length) throw new Error('The PPTX presentation does not contain any slides.');
|
|
505
|
+
const slides = [];
|
|
506
|
+
for (const [index, slidePart] of slideParts.entries())slides.push(await parseSlide(archive, slidePart, index + 1, slideWidthEmu, slideHeightEmu, theme, commentAuthors, issues, imageBudget, designs));
|
|
507
|
+
if (designs.layouts.length || designs.masters.length) issues.push({
|
|
508
|
+
code: 'pptx.layouts',
|
|
509
|
+
severity: 'info',
|
|
510
|
+
feature: 'Slide layouts and masters',
|
|
511
|
+
message: `${designs.layouts.length} slide layout(s) and ${designs.masters.length} slide master(s) retain inherited backgrounds, artwork, placeholder geometry, and native layout assignments.`
|
|
512
|
+
});
|
|
513
|
+
if (designs.masters.length > 1) issues.push({
|
|
514
|
+
code: 'pptx.masters.multiple',
|
|
515
|
+
severity: 'warning',
|
|
516
|
+
feature: 'Slide layouts and masters',
|
|
517
|
+
message: `${designs.masters.length} source master trees remain separately editable in Work. PPTX export preserves their visual inheritance per layout while normalizing them into the generated master hierarchy.`
|
|
518
|
+
});
|
|
519
|
+
addFontDiagnostics(slides, issues);
|
|
520
|
+
return {
|
|
521
|
+
content: {
|
|
522
|
+
type: 'presentation',
|
|
523
|
+
slides,
|
|
524
|
+
width: slideWidthEmu / EMU_PER_INCH || DEFAULT_SLIDE_WIDTH,
|
|
525
|
+
height: slideHeightEmu / EMU_PER_INCH || DEFAULT_SLIDE_HEIGHT,
|
|
526
|
+
masters: designs.masters.length ? designs.masters : void 0,
|
|
527
|
+
layouts: designs.layouts.length ? designs.layouts : void 0
|
|
528
|
+
},
|
|
529
|
+
compatibility: {
|
|
530
|
+
sourceFormat: 'PPTX',
|
|
531
|
+
sourceName: file.name,
|
|
532
|
+
assessedAt: Date.now(),
|
|
533
|
+
issues: deduplicateIssues(issues)
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
async function parseSlide(archive, slidePart, slideNumber, slideWidthEmu, slideHeightEmu, theme, commentAuthors, issues, imageBudget, designs) {
|
|
538
|
+
const document1 = await archive.xml(slidePart);
|
|
539
|
+
const relationships = await archive.relationships(slidePart);
|
|
540
|
+
const inheritance = await loadPptxSlideInheritance(archive, relationships, theme);
|
|
541
|
+
const context = {
|
|
542
|
+
archive,
|
|
543
|
+
slideNumber,
|
|
544
|
+
slideWidthEmu,
|
|
545
|
+
slideHeightEmu,
|
|
546
|
+
relationships,
|
|
547
|
+
placeholders: inheritance.placeholders,
|
|
548
|
+
theme,
|
|
549
|
+
issues,
|
|
550
|
+
imageBudget,
|
|
551
|
+
location: `幻灯片 ${slideNumber}`
|
|
552
|
+
};
|
|
553
|
+
const design = await ensurePptxDesignDefinitions(archive, inheritance.layout, inheritance.master, context, designs);
|
|
554
|
+
const elements = [];
|
|
555
|
+
const shapeTree = firstDescendant(document1, 'spTree');
|
|
556
|
+
for (const child of shapeTree ? directChildren(shapeTree) : [])elements.push(...await parseSlideNode(child, context));
|
|
557
|
+
const resolvedElements = inheritPptxPlaceholderStyles(elements, design.master, design.layout);
|
|
558
|
+
const transition = readPptxTransition(document1);
|
|
559
|
+
const commentResult = await readPptxSlideComments(archive, relationships, commentAuthors, slideNumber, slideWidthEmu, slideHeightEmu);
|
|
560
|
+
if (commentResult.comments.length) addIssue(context, 'pptx.comments', 'Comments', `${commentResult.comments.length} traditional slide comment(s), authors, dates, and positions are preserved and editable.`, 'info');
|
|
561
|
+
if (commentResult.hasUnsupportedThreadedComments) addIssue(context, 'pptx.comments.threaded', 'Modern comments', 'Modern threaded replies, mentions, and resolved state remain in the original PPTX only.');
|
|
562
|
+
if (commentResult.hasUnreadableComments) addIssue(context, 'pptx.comments.unreadable', 'Comments', 'One or more slide comment parts could not be read and remain in the original PPTX only.');
|
|
563
|
+
if (commentResult.hasMalformedMetadata) addIssue(context, 'pptx.comments.metadata', 'Comment metadata', 'One or more traditional comments had a missing author, date, or position; unavailable metadata was normalized.');
|
|
564
|
+
if (transition.present) {
|
|
565
|
+
addIssue(context, 'pptx.transition', 'Slide transitions', transition.transition ? 'Basic slide transitions and advance timing are preserved, editable, and replayed in presentation preview.' : 'This slide transition is not editable and remains in the original PPTX only.', transition.transition ? 'info' : 'warning');
|
|
566
|
+
for (const diagnostic of transition.diagnostics)addIssue(context, diagnostic.code, 'Slide transitions', diagnostic.message);
|
|
567
|
+
}
|
|
568
|
+
if (firstDescendant(document1, 'timing')) addIssue(context, 'pptx.animation', 'Animations', 'Object animations are not replayed and will be omitted on export.');
|
|
569
|
+
for (const relationship of relationships.values())if (relationship.type.includes('/audio') || relationship.type.includes('/video') || relationship.type.includes('/media')) addIssue(context, 'pptx.media', 'Embedded media', 'Audio and video remain in the original file but are not playable yet.');
|
|
570
|
+
else if (relationship.type.endsWith('/oleObject') || relationship.type.endsWith('/package')) addIssue(context, 'pptx.ole', 'Embedded objects', 'Embedded Office or OLE objects remain in the original file only.');
|
|
571
|
+
const slideBackground = readPptxBackground(document1, theme);
|
|
572
|
+
return {
|
|
573
|
+
id: createWorkId('slide'),
|
|
574
|
+
name: readSlideName(document1, slideNumber),
|
|
575
|
+
layoutId: design.layout?.id,
|
|
576
|
+
background: slideBackground ?? inheritance.layout?.background ?? inheritance.master?.background ?? '#ffffff',
|
|
577
|
+
useLayoutBackground: !slideBackground,
|
|
578
|
+
showMasterElements: pptxShowsMasterElements(document1) ? void 0 : false,
|
|
579
|
+
elements: resolvedElements,
|
|
580
|
+
notes: await readSpeakerNotes(archive, relationships, context),
|
|
581
|
+
comments: commentResult.comments.length ? commentResult.comments : void 0,
|
|
582
|
+
transition: transition.transition
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
async function loadPptxPresentationDesigns(archive, relationships, slideWidthEmu, slideHeightEmu, theme, issues, imageBudget, registry) {
|
|
586
|
+
const context = {
|
|
587
|
+
archive,
|
|
588
|
+
slideNumber: 0,
|
|
589
|
+
slideWidthEmu,
|
|
590
|
+
slideHeightEmu,
|
|
591
|
+
relationships,
|
|
592
|
+
placeholders: new Map(),
|
|
593
|
+
theme,
|
|
594
|
+
issues,
|
|
595
|
+
imageBudget,
|
|
596
|
+
location: '母版与布局'
|
|
597
|
+
};
|
|
598
|
+
for (const relationship of relationships.values()){
|
|
599
|
+
if (!relationship.type.endsWith('/slideMaster')) continue;
|
|
600
|
+
const part = await loadPptxDesignPart(archive, relationship.target, theme, 'Slide master');
|
|
601
|
+
if (part) await ensurePptxMaster(archive, part, context, registry);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
async function ensurePptxDesignDefinitions(archive, layoutPart, masterPart, context, registry) {
|
|
605
|
+
const master = masterPart ? await ensurePptxMaster(archive, masterPart, context, registry) : layoutPart ? ensureFallbackPptxMaster(registry) : void 0;
|
|
606
|
+
const layout = layoutPart && master ? await ensurePptxLayout(layoutPart, master.id, context, registry) : void 0;
|
|
607
|
+
return {
|
|
608
|
+
master,
|
|
609
|
+
layout
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
async function ensurePptxMaster(archive, part, context, registry) {
|
|
613
|
+
const existing = registry.masterByPath.get(part.path);
|
|
614
|
+
if (existing) return existing;
|
|
615
|
+
const master = {
|
|
616
|
+
id: `pptx-master-${registry.masters.length + 1}`,
|
|
617
|
+
name: part.name,
|
|
618
|
+
background: part.background ?? '#ffffff',
|
|
619
|
+
elements: await parsePptxDesignElements(part, context)
|
|
620
|
+
};
|
|
621
|
+
registry.masterByPath.set(part.path, master);
|
|
622
|
+
registry.masters.push(master);
|
|
623
|
+
for (const relationship of part.relationships.values()){
|
|
624
|
+
if (!relationship.type.endsWith('/slideLayout')) continue;
|
|
625
|
+
const layoutPart = await loadPptxDesignPart(archive, relationship.target, context.theme, 'Slide layout');
|
|
626
|
+
if (layoutPart) await ensurePptxLayout(layoutPart, master.id, context, registry);
|
|
627
|
+
}
|
|
628
|
+
return master;
|
|
629
|
+
}
|
|
630
|
+
async function ensurePptxLayout(part, masterId, context, registry) {
|
|
631
|
+
const existing = registry.layoutByPath.get(part.path);
|
|
632
|
+
if (existing) return existing;
|
|
633
|
+
const layout = {
|
|
634
|
+
id: `pptx-layout-${registry.layouts.length + 1}`,
|
|
635
|
+
name: part.name,
|
|
636
|
+
masterId,
|
|
637
|
+
background: part.background,
|
|
638
|
+
elements: await parsePptxDesignElements(part, context),
|
|
639
|
+
showMasterElements: part.showMasterElements ? void 0 : false,
|
|
640
|
+
sourceType: part.sourceType
|
|
641
|
+
};
|
|
642
|
+
registry.layoutByPath.set(part.path, layout);
|
|
643
|
+
registry.layouts.push(layout);
|
|
644
|
+
return layout;
|
|
645
|
+
}
|
|
646
|
+
function ensureFallbackPptxMaster(registry) {
|
|
647
|
+
const path = 'pptx:fallback-master';
|
|
648
|
+
const existing = registry.masterByPath.get(path);
|
|
649
|
+
if (existing) return existing;
|
|
650
|
+
const master = {
|
|
651
|
+
id: `pptx-master-${registry.masters.length + 1}`,
|
|
652
|
+
name: 'Imported master',
|
|
653
|
+
background: '#ffffff',
|
|
654
|
+
elements: []
|
|
655
|
+
};
|
|
656
|
+
registry.masterByPath.set(path, master);
|
|
657
|
+
registry.masters.push(master);
|
|
658
|
+
return master;
|
|
659
|
+
}
|
|
660
|
+
async function parsePptxDesignElements(part, context) {
|
|
661
|
+
const partContext = {
|
|
662
|
+
...context,
|
|
663
|
+
relationships: part.relationships,
|
|
664
|
+
placeholders: new Map()
|
|
665
|
+
};
|
|
666
|
+
const elements = [];
|
|
667
|
+
const shapeTree = firstDescendant(part.document, 'spTree');
|
|
668
|
+
for (const child of shapeTree ? directChildren(shapeTree) : [])elements.push(...await parseSlideNode(child, partContext));
|
|
669
|
+
return elements;
|
|
670
|
+
}
|
|
671
|
+
function inheritPptxPlaceholderStyles(elements, master, layout) {
|
|
672
|
+
const definitions = new Map();
|
|
673
|
+
const addDefinitions = (candidates)=>{
|
|
674
|
+
for (const candidate of candidates){
|
|
675
|
+
const placeholder = candidate.placeholder;
|
|
676
|
+
if (!placeholder) continue;
|
|
677
|
+
const inheritedDefinition = placeholder.inheritsStyle ? definitions.get(placeholder.key) ?? definitions.get(`type:${placeholder.type}`) : void 0;
|
|
678
|
+
const definition = inheritedDefinition ? inheritPptxPlaceholderStyle(candidate, inheritedDefinition) : candidate;
|
|
679
|
+
definitions.set(placeholder.key, definition);
|
|
680
|
+
definitions.set(`type:${placeholder.type}`, definition);
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
if (layout?.showMasterElements !== false) addDefinitions(master?.elements ?? []);
|
|
684
|
+
addDefinitions(layout?.elements ?? []);
|
|
685
|
+
return elements.map((element)=>{
|
|
686
|
+
const placeholder = element.placeholder;
|
|
687
|
+
if (!placeholder?.inheritsStyle) return element;
|
|
688
|
+
const definition = definitions.get(placeholder.key) ?? definitions.get(`type:${placeholder.type}`);
|
|
689
|
+
return definition ? inheritPptxPlaceholderStyle(element, definition) : element;
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
function inheritPptxPlaceholderStyle(element, definition) {
|
|
693
|
+
return {
|
|
694
|
+
...element,
|
|
695
|
+
fontSize: definition.fontSize,
|
|
696
|
+
color: definition.color,
|
|
697
|
+
fill: definition.fill,
|
|
698
|
+
bold: definition.bold,
|
|
699
|
+
align: definition.align,
|
|
700
|
+
fontFamily: definition.fontFamily,
|
|
701
|
+
italic: definition.italic,
|
|
702
|
+
underline: definition.underline,
|
|
703
|
+
verticalAlign: definition.verticalAlign,
|
|
704
|
+
textRuns: element.textRuns?.map((run)=>({
|
|
705
|
+
...run,
|
|
706
|
+
fontSize: run.fontSize ?? definition.fontSize,
|
|
707
|
+
color: run.color ?? definition.color,
|
|
708
|
+
bold: run.bold ?? definition.bold,
|
|
709
|
+
italic: run.italic ?? definition.italic,
|
|
710
|
+
underline: run.underline ?? definition.underline,
|
|
711
|
+
fontFamily: run.fontFamily ?? definition.fontFamily
|
|
712
|
+
}))
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
async function parseSlideNode(node, context, transform) {
|
|
716
|
+
if ('sp' === node.localName) return [
|
|
717
|
+
withImportedGroupTransform(parseShape(node, context, transform), transform)
|
|
718
|
+
];
|
|
719
|
+
if ('pic' === node.localName) return [
|
|
720
|
+
withImportedGroupTransform(await parsePicture(node, context, transform), transform)
|
|
721
|
+
];
|
|
722
|
+
if ('graphicFrame' === node.localName) return [
|
|
723
|
+
withImportedGroupTransform(await parseGraphicFrame(node, context, transform), transform)
|
|
724
|
+
];
|
|
725
|
+
if ('cxnSp' === node.localName) return [
|
|
726
|
+
withImportedGroupTransform(parseConnector(node, context, transform), transform)
|
|
727
|
+
];
|
|
728
|
+
if ('grpSp' === node.localName) return parseGroup(node, context, transform);
|
|
729
|
+
if ([
|
|
730
|
+
'contentPart',
|
|
731
|
+
'oleObj'
|
|
732
|
+
].includes(node.localName)) addIssue(context, 'pptx.content-part', 'Embedded content', 'An embedded slide object remains available in the original PPTX only.');
|
|
733
|
+
return [];
|
|
734
|
+
}
|
|
735
|
+
function parseShape(node, context, transform) {
|
|
736
|
+
const box = elementBox(node, context, transform);
|
|
737
|
+
const text = parseText(firstDescendant(node, 'txBody'), context);
|
|
738
|
+
const placeholder = pptxPlaceholder(node);
|
|
739
|
+
const ownBox = pptxRawElementBox(node);
|
|
740
|
+
const properties = directChild(node, 'spPr');
|
|
741
|
+
const fill = readPptxFill(properties, context.theme, text.text ? 'transparent' : '#dce6fb');
|
|
742
|
+
const geometry = attribute(firstDescendant(properties, 'prstGeom') ?? node, 'prst') ?? 'rect';
|
|
743
|
+
const shapeType = supportedPptxShapeType(geometry);
|
|
744
|
+
if (!shapeType) addIssue(context, `pptx.shape.${geometry}`, 'Shape geometry', `The “${geometry}” shape is shown as a rectangle and will be normalized on export.`);
|
|
745
|
+
const line = firstDescendant(properties, 'ln');
|
|
746
|
+
const border = readPptxFill(line, context.theme, 'transparent' === fill.color ? '#657087' : fill.color);
|
|
747
|
+
const isTextBox = '1' === attribute(firstDescendant(node, 'cNvSpPr') ?? node, 'txBox');
|
|
748
|
+
const isTextPlaceholder = placeholder && ![
|
|
749
|
+
'pic',
|
|
750
|
+
'chart',
|
|
751
|
+
'tbl',
|
|
752
|
+
'media',
|
|
753
|
+
'obj'
|
|
754
|
+
].includes(placeholder.type);
|
|
755
|
+
const altText = readAlternativeText(node);
|
|
756
|
+
return {
|
|
757
|
+
id: createWorkId('element'),
|
|
758
|
+
type: 'line' === shapeType ? 'line' : isTextPlaceholder || isTextBox || text.text && 'transparent' === fill.color ? 'text' : 'shape',
|
|
759
|
+
...box,
|
|
760
|
+
text: text.text,
|
|
761
|
+
fontSize: text.fontSize,
|
|
762
|
+
color: text.color,
|
|
763
|
+
fill: fill.color,
|
|
764
|
+
bold: text.bold,
|
|
765
|
+
align: text.align,
|
|
766
|
+
shapeType: shapeType ?? 'rect',
|
|
767
|
+
radius: 'roundRect' === shapeType ? 5 : void 0,
|
|
768
|
+
opacity: fill.opacity,
|
|
769
|
+
borderColor: border.color,
|
|
770
|
+
borderWidth: work_pptx_import_numberAttribute(line, 'w', 0) / 12700 || void 0,
|
|
771
|
+
fontFamily: text.fontFamily,
|
|
772
|
+
italic: text.italic,
|
|
773
|
+
underline: text.underline,
|
|
774
|
+
verticalAlign: text.verticalAlign,
|
|
775
|
+
textRuns: text.runs.length ? text.runs : void 0,
|
|
776
|
+
href: text.href,
|
|
777
|
+
altText,
|
|
778
|
+
placeholder: placeholder ? {
|
|
779
|
+
...placeholder,
|
|
780
|
+
prompt: text.text.trim() || void 0,
|
|
781
|
+
inheritsGeometry: ownBox ? void 0 : true,
|
|
782
|
+
inheritsStyle: text.explicitStyle ? void 0 : true
|
|
783
|
+
} : void 0
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
async function parsePicture(node, context, transform) {
|
|
787
|
+
const box = elementBox(node, context, transform);
|
|
788
|
+
const properties = firstDescendant(node, 'blip');
|
|
789
|
+
const relationshipId = attribute(properties ?? node, 'r:embed') ?? attribute(properties ?? node, 'embed');
|
|
790
|
+
const relationship = relationshipId ? context.relationships.get(relationshipId) : void 0;
|
|
791
|
+
const name = attribute(firstDescendant(node, 'cNvPr') ?? node, 'name') ?? 'Imported picture';
|
|
792
|
+
const placeholder = pptxPlaceholder(node);
|
|
793
|
+
const base = {
|
|
794
|
+
id: createWorkId('element'),
|
|
795
|
+
type: 'image',
|
|
796
|
+
...box,
|
|
797
|
+
text: '',
|
|
798
|
+
fontSize: 12,
|
|
799
|
+
color: '#536078',
|
|
800
|
+
fill: '#eef1f6',
|
|
801
|
+
bold: false,
|
|
802
|
+
align: 'center',
|
|
803
|
+
altText: readAlternativeText(node) || name,
|
|
804
|
+
placeholder
|
|
805
|
+
};
|
|
806
|
+
if (!relationship || 'External' === relationship.targetMode || !context.archive.has(relationship.target)) {
|
|
807
|
+
addIssue(context, 'pptx.image.linked', 'Linked pictures', `The linked picture “${name}” could not be embedded.`);
|
|
808
|
+
return {
|
|
809
|
+
...base,
|
|
810
|
+
type: 'shape',
|
|
811
|
+
text: `图片:${name}`
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
const bytes = await context.archive.bytes(relationship.target);
|
|
815
|
+
if (context.imageBudget.bytes + bytes.byteLength > MAX_EMBEDDED_IMAGE_BYTES) {
|
|
816
|
+
addIssue(context, 'pptx.image.limit', 'Large pictures', `The picture “${name}” exceeds the safe native-artifact image budget and remains in the original file only.`);
|
|
817
|
+
return {
|
|
818
|
+
...base,
|
|
819
|
+
type: 'shape',
|
|
820
|
+
text: `大型图片:${name}`
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
context.imageBudget.bytes += bytes.byteLength;
|
|
824
|
+
const contentType = contentTypeForPart(relationship.target);
|
|
825
|
+
const sourceRectangle = firstDescendant(node, 'srcRect');
|
|
826
|
+
if (sourceRectangle && Array.from(sourceRectangle.attributes).some((item)=>0 !== Number(item.value))) addIssue(context, 'pptx.image.crop', 'Picture cropping', `Crop settings for “${name}” will be normalized on export.`);
|
|
827
|
+
return {
|
|
828
|
+
...base,
|
|
829
|
+
fill: 'transparent',
|
|
830
|
+
image: {
|
|
831
|
+
dataUrl: bytesToDataUrl(bytes, contentType),
|
|
832
|
+
contentType,
|
|
833
|
+
name
|
|
834
|
+
}
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
async function parseGraphicFrame(node, context, transform) {
|
|
838
|
+
const box = elementBox(node, context, transform);
|
|
839
|
+
const table = firstDescendant(node, 'tbl');
|
|
840
|
+
if (table) {
|
|
841
|
+
const rows = directChildren(table, 'tr').map((row)=>directChildren(row, 'tc').map((cell)=>directChildren(firstDescendant(cell, 'txBody') ?? cell, 'p').map((paragraph)=>descendants(paragraph, 't').map((text)=>text.textContent ?? '').join('')).join('\n')));
|
|
842
|
+
if (descendants(table, 'tc').some((cell)=>[
|
|
843
|
+
'gridSpan',
|
|
844
|
+
'rowSpan',
|
|
845
|
+
'hMerge',
|
|
846
|
+
'vMerge'
|
|
847
|
+
].some((name)=>attribute(cell, name)))) addIssue(context, 'pptx.table.merge', 'Merged table cells', 'Merged table cells are flattened for editing and export.');
|
|
848
|
+
return {
|
|
849
|
+
id: createWorkId('element'),
|
|
850
|
+
type: 'table',
|
|
851
|
+
...box,
|
|
852
|
+
text: '',
|
|
853
|
+
fontSize: 12,
|
|
854
|
+
color: '#172033',
|
|
855
|
+
fill: '#ffffff',
|
|
856
|
+
bold: false,
|
|
857
|
+
align: 'left',
|
|
858
|
+
borderColor: '#cbd2de',
|
|
859
|
+
borderWidth: 1,
|
|
860
|
+
table: {
|
|
861
|
+
rows,
|
|
862
|
+
headerRows: rows.length > 1 ? 1 : 0
|
|
863
|
+
},
|
|
864
|
+
altText: readAlternativeText(node)
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
const chartReference = firstDescendant(node, 'chart');
|
|
868
|
+
const relationshipId = attribute(chartReference ?? node, 'r:id') ?? attribute(chartReference ?? node, 'id');
|
|
869
|
+
const relationship = relationshipId ? context.relationships.get(relationshipId) : void 0;
|
|
870
|
+
if (relationship?.type.endsWith('/chart') && context.archive.has(relationship.target)) {
|
|
871
|
+
const result = readPptxChart(await context.archive.xml(relationship.target));
|
|
872
|
+
for (const diagnostic of result.diagnostics)addIssue(context, diagnostic.code, diagnostic.feature, diagnostic.message);
|
|
873
|
+
const chart = result.chart;
|
|
874
|
+
return {
|
|
875
|
+
id: createWorkId('element'),
|
|
876
|
+
type: 'chart',
|
|
877
|
+
...box,
|
|
878
|
+
text: chart.title ?? '',
|
|
879
|
+
fontSize: 12,
|
|
880
|
+
color: '#172033',
|
|
881
|
+
fill: '#ffffff',
|
|
882
|
+
bold: false,
|
|
883
|
+
align: 'center',
|
|
884
|
+
borderColor: '#d9dee8',
|
|
885
|
+
borderWidth: 1,
|
|
886
|
+
chart,
|
|
887
|
+
altText: readAlternativeText(node)
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
addIssue(context, 'pptx.graphic-frame', 'SmartArt and diagrams', 'A SmartArt or diagram object remains in the original PPTX only.');
|
|
891
|
+
return {
|
|
892
|
+
id: createWorkId('element'),
|
|
893
|
+
type: 'shape',
|
|
894
|
+
...box,
|
|
895
|
+
text: 'SmartArt / 图示',
|
|
896
|
+
fontSize: 14,
|
|
897
|
+
color: '#536078',
|
|
898
|
+
fill: '#eef1f6',
|
|
899
|
+
bold: true,
|
|
900
|
+
align: 'center',
|
|
901
|
+
shapeType: 'rect'
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
function parseConnector(node, context, transform) {
|
|
905
|
+
const box = elementBox(node, context, transform);
|
|
906
|
+
const properties = directChild(node, 'spPr');
|
|
907
|
+
const line = firstDescendant(properties, 'ln');
|
|
908
|
+
const color = readPptxFill(line, context.theme, '#657087');
|
|
909
|
+
return {
|
|
910
|
+
id: createWorkId('element'),
|
|
911
|
+
type: 'line',
|
|
912
|
+
...box,
|
|
913
|
+
text: '',
|
|
914
|
+
fontSize: 12,
|
|
915
|
+
color: color.color,
|
|
916
|
+
fill: 'transparent',
|
|
917
|
+
bold: false,
|
|
918
|
+
align: 'left',
|
|
919
|
+
shapeType: 'line',
|
|
920
|
+
borderColor: color.color,
|
|
921
|
+
borderWidth: work_pptx_import_numberAttribute(line, 'w', 12700) / 12700
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
async function parseGroup(node, context, parentTransform) {
|
|
925
|
+
const xfrm = childPath(node, 'grpSpPr', 'xfrm');
|
|
926
|
+
if (0 !== work_pptx_import_numberAttribute(xfrm, 'rot', 0) || booleanAttribute(xfrm, 'flipH') || booleanAttribute(xfrm, 'flipV')) addIssue(context, 'pptx.group.transform', 'Group transform', 'Group rotation or reflection is retained in the original PPTX but is not applied to browser editing geometry.');
|
|
927
|
+
const offset = directChild(xfrm ?? node, 'off');
|
|
928
|
+
const extent = directChild(xfrm ?? node, 'ext');
|
|
929
|
+
const childOffset = directChild(xfrm ?? node, 'chOff');
|
|
930
|
+
const childExtent = directChild(xfrm ?? node, 'chExt');
|
|
931
|
+
const group = {
|
|
932
|
+
x: work_pptx_import_numberAttribute(offset, 'x', 0),
|
|
933
|
+
y: work_pptx_import_numberAttribute(offset, 'y', 0),
|
|
934
|
+
width: work_pptx_import_numberAttribute(extent, 'cx', context.slideWidthEmu),
|
|
935
|
+
height: work_pptx_import_numberAttribute(extent, 'cy', context.slideHeightEmu)
|
|
936
|
+
};
|
|
937
|
+
const viewport = {
|
|
938
|
+
x: work_pptx_import_numberAttribute(childOffset, 'x', 0),
|
|
939
|
+
y: work_pptx_import_numberAttribute(childOffset, 'y', 0),
|
|
940
|
+
width: work_pptx_import_numberAttribute(childExtent, 'cx', group.width),
|
|
941
|
+
height: work_pptx_import_numberAttribute(childExtent, 'cy', group.height)
|
|
942
|
+
};
|
|
943
|
+
const localVisualScale = pptxGroupVisualScale(group, viewport);
|
|
944
|
+
const transform = {
|
|
945
|
+
groupIds: [
|
|
946
|
+
...parentTransform?.groupIds ?? [],
|
|
947
|
+
createWorkId('element-group')
|
|
948
|
+
],
|
|
949
|
+
visualScale: (parentTransform?.visualScale ?? 1) * localVisualScale,
|
|
950
|
+
map: (box)=>{
|
|
951
|
+
const mapped = {
|
|
952
|
+
...box,
|
|
953
|
+
x: group.x + (box.x - viewport.x) * group.width / Math.max(1, viewport.width),
|
|
954
|
+
y: group.y + (box.y - viewport.y) * group.height / Math.max(1, viewport.height),
|
|
955
|
+
width: box.width * group.width / Math.max(1, viewport.width),
|
|
956
|
+
height: box.height * group.height / Math.max(1, viewport.height)
|
|
957
|
+
};
|
|
958
|
+
return parentTransform ? parentTransform.map(mapped) : mapped;
|
|
959
|
+
}
|
|
960
|
+
};
|
|
961
|
+
const elements = [];
|
|
962
|
+
for (const child of directChildren(node))elements.push(...await parseSlideNode(child, context, transform));
|
|
963
|
+
return elements;
|
|
964
|
+
}
|
|
965
|
+
function withImportedGroupTransform(element, transform) {
|
|
966
|
+
if (!transform?.groupIds.length) return element;
|
|
967
|
+
return {
|
|
968
|
+
...element,
|
|
969
|
+
...scaledPresentationVisuals(element, transform.visualScale),
|
|
970
|
+
groupIds: [
|
|
971
|
+
...transform.groupIds
|
|
972
|
+
]
|
|
973
|
+
};
|
|
974
|
+
}
|
|
975
|
+
function pptxGroupVisualScale(group, viewport) {
|
|
976
|
+
const scaleX = Math.abs(group.width) / Math.max(1, Math.abs(viewport.width));
|
|
977
|
+
const scaleY = Math.abs(group.height) / Math.max(1, Math.abs(viewport.height));
|
|
978
|
+
const scale = Math.min(scaleX, scaleY);
|
|
979
|
+
return Number.isFinite(scale) && scale > 0 ? scale : 1;
|
|
980
|
+
}
|
|
981
|
+
function parseText(body, context) {
|
|
982
|
+
const runs = [];
|
|
983
|
+
const paragraphs = body ? directChildren(body, 'p') : [];
|
|
984
|
+
let align = 'left';
|
|
985
|
+
let explicitStyle = false;
|
|
986
|
+
for (const [paragraphIndex, paragraph] of paragraphs.entries()){
|
|
987
|
+
const paragraphProperties = directChild(paragraph, 'pPr');
|
|
988
|
+
if (paragraphProperties && (paragraphProperties.attributes.length || paragraphProperties.children.length)) explicitStyle = true;
|
|
989
|
+
if (0 === paragraphIndex) align = pptxTextAlignment(attribute(paragraphProperties ?? paragraph, 'algn'));
|
|
990
|
+
const bullet = directChild(paragraphProperties ?? paragraph, 'buChar');
|
|
991
|
+
const autoNumber = directChild(paragraphProperties ?? paragraph, 'buAutoNum');
|
|
992
|
+
if (bullet || autoNumber) {
|
|
993
|
+
explicitStyle = true;
|
|
994
|
+
runs.push({
|
|
995
|
+
text: bullet ? `${attribute(bullet, 'char') ?? '•'} ` : `${paragraphIndex + 1}. `
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
for (const child of directChildren(paragraph)){
|
|
999
|
+
if ('br' === child.localName) {
|
|
1000
|
+
runs.push({
|
|
1001
|
+
text: '\n'
|
|
1002
|
+
});
|
|
1003
|
+
continue;
|
|
1004
|
+
}
|
|
1005
|
+
if ('r' !== child.localName && 'fld' !== child.localName) continue;
|
|
1006
|
+
const text = directChild(child, 't')?.textContent ?? '';
|
|
1007
|
+
if (!text) continue;
|
|
1008
|
+
const runProperties = directChild(child, 'rPr') ?? directChild(paragraphProperties ?? paragraph, 'defRPr');
|
|
1009
|
+
if (runProperties) explicitStyle = true;
|
|
1010
|
+
const color = runProperties ? readPptxFill(runProperties, context.theme, '#172033').color : void 0;
|
|
1011
|
+
const hyperlink = firstDescendant(runProperties, 'hlinkClick');
|
|
1012
|
+
const relationshipId = attribute(hyperlink ?? child, 'r:id') ?? attribute(hyperlink ?? child, 'id');
|
|
1013
|
+
const relationship = relationshipId ? context.relationships.get(relationshipId) : void 0;
|
|
1014
|
+
const fontSize = runProperties ? positiveNumber(attribute(runProperties, 'sz')) : void 0;
|
|
1015
|
+
runs.push({
|
|
1016
|
+
text,
|
|
1017
|
+
fontSize: fontSize ? fontSize / 100 : void 0,
|
|
1018
|
+
color,
|
|
1019
|
+
bold: runProperties ? booleanAttribute(runProperties, 'b') : void 0,
|
|
1020
|
+
italic: runProperties ? booleanAttribute(runProperties, 'i') : void 0,
|
|
1021
|
+
underline: runProperties ? Boolean(attribute(runProperties, 'u') && 'none' !== attribute(runProperties, 'u')) : void 0,
|
|
1022
|
+
fontFamily: runProperties ? attribute(directChild(runProperties, 'latin') ?? runProperties, 'typeface') ?? attribute(directChild(runProperties, 'ea') ?? runProperties, 'typeface') ?? void 0 : void 0,
|
|
1023
|
+
href: relationship?.targetMode === 'External' ? relationship.target : void 0
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
if (paragraphIndex < paragraphs.length - 1) runs.push({
|
|
1027
|
+
text: '\n'
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
const first = runs.find((run)=>'\n' !== run.text);
|
|
1031
|
+
const bodyProperties = body ? directChild(body, 'bodyPr') : void 0;
|
|
1032
|
+
if (bodyProperties?.attributes.length) explicitStyle = true;
|
|
1033
|
+
return {
|
|
1034
|
+
text: runs.map((run)=>run.text).join(''),
|
|
1035
|
+
runs,
|
|
1036
|
+
align,
|
|
1037
|
+
verticalAlign: pptxVerticalAlignment(bodyProperties ? attribute(bodyProperties, 'anchor') : null),
|
|
1038
|
+
fontSize: first?.fontSize ?? 18,
|
|
1039
|
+
color: first?.color ?? '#172033',
|
|
1040
|
+
bold: first?.bold ?? false,
|
|
1041
|
+
italic: first?.italic ?? false,
|
|
1042
|
+
underline: first?.underline ?? false,
|
|
1043
|
+
fontFamily: first?.fontFamily,
|
|
1044
|
+
href: runs.find((run)=>run.href)?.href,
|
|
1045
|
+
explicitStyle
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
function elementBox(node, context, transform) {
|
|
1049
|
+
const raw = pptxRawElementBox(node) ?? pptxPlaceholderBox(node, context.placeholders) ?? {
|
|
1050
|
+
x: 0.1 * context.slideWidthEmu,
|
|
1051
|
+
y: 0.1 * context.slideHeightEmu,
|
|
1052
|
+
width: 0.4 * context.slideWidthEmu,
|
|
1053
|
+
height: 0.15 * context.slideHeightEmu
|
|
1054
|
+
};
|
|
1055
|
+
const mapped = transform ? transform.map(raw) : raw;
|
|
1056
|
+
return {
|
|
1057
|
+
x: mapped.x / context.slideWidthEmu * 100,
|
|
1058
|
+
y: mapped.y / context.slideHeightEmu * 100,
|
|
1059
|
+
width: Math.max(0.5, mapped.width / context.slideWidthEmu * 100),
|
|
1060
|
+
height: Math.max(0.5, mapped.height / context.slideHeightEmu * 100),
|
|
1061
|
+
rotation: mapped.rotation
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
async function readSpeakerNotes(archive, relationships, context) {
|
|
1065
|
+
const relationship = Array.from(relationships.values()).find((item)=>item.type.endsWith('/notesSlide'));
|
|
1066
|
+
if (!relationship || !archive.has(relationship.target)) return;
|
|
1067
|
+
const document1 = await archive.xml(relationship.target);
|
|
1068
|
+
const bodies = descendants(document1, 'sp').filter((shape)=>'body' === attribute(firstDescendant(directChild(shape, 'nvSpPr'), 'ph') ?? shape, 'type')).map((shape)=>parseText(firstDescendant(shape, 'txBody'), context).text.trim()).filter(Boolean);
|
|
1069
|
+
return bodies.join('\n\n') || void 0;
|
|
1070
|
+
}
|
|
1071
|
+
function orderedSlideParts(presentation, relationships) {
|
|
1072
|
+
return descendants(presentation, 'sldId').map((node)=>{
|
|
1073
|
+
const id = attribute(node, 'r:id') ?? attribute(node, 'id');
|
|
1074
|
+
return id ? relationships.get(id) : void 0;
|
|
1075
|
+
}).filter((relationship)=>Boolean(relationship?.type.endsWith('/slide'))).map((relationship)=>relationship.target);
|
|
1076
|
+
}
|
|
1077
|
+
function readSlideName(document1, slideNumber) {
|
|
1078
|
+
const titleShape = descendants(document1, 'sp').find((shape)=>{
|
|
1079
|
+
const type = attribute(firstDescendant(directChild(shape, 'nvSpPr'), 'ph') ?? shape, 'type');
|
|
1080
|
+
return 'title' === type || 'ctrTitle' === type;
|
|
1081
|
+
});
|
|
1082
|
+
const title = titleShape ? descendants(titleShape, 't').map((node)=>node.textContent ?? '').join('').trim() : '';
|
|
1083
|
+
return title || `幻灯片 ${slideNumber}`;
|
|
1084
|
+
}
|
|
1085
|
+
function readAlternativeText(node) {
|
|
1086
|
+
const properties = firstDescendant(node, 'cNvPr');
|
|
1087
|
+
return attribute(properties ?? node, 'descr')?.trim() || attribute(properties ?? node, 'title')?.trim() || void 0;
|
|
1088
|
+
}
|
|
1089
|
+
function addIssue(context, code, feature, message, severity = 'warning') {
|
|
1090
|
+
context.issues.push({
|
|
1091
|
+
code,
|
|
1092
|
+
severity,
|
|
1093
|
+
feature,
|
|
1094
|
+
message,
|
|
1095
|
+
location: context.location ?? `幻灯片 ${context.slideNumber}`
|
|
1096
|
+
});
|
|
1097
|
+
}
|
|
1098
|
+
function addFontDiagnostics(slides, issues) {
|
|
1099
|
+
const fonts = new Set();
|
|
1100
|
+
for (const slide of slides)for (const element of slide.elements){
|
|
1101
|
+
if (element.fontFamily) fonts.add(element.fontFamily);
|
|
1102
|
+
for (const run of element.textRuns ?? [])if (run.fontFamily) fonts.add(run.fontFamily);
|
|
1103
|
+
}
|
|
1104
|
+
for (const font of fonts){
|
|
1105
|
+
if (font.startsWith('+m') || font.startsWith('+mj') || font.startsWith('+mn')) continue;
|
|
1106
|
+
const available = 'function' == typeof document.fonts?.check ? document.fonts.check(`12px "${font}"`) : true;
|
|
1107
|
+
if (!available) issues.push({
|
|
1108
|
+
code: `pptx.font.${font.toLowerCase()}`,
|
|
1109
|
+
severity: 'warning',
|
|
1110
|
+
feature: 'Font substitution',
|
|
1111
|
+
message: `The font “${font}” is unavailable in this browser and may be substituted in preview and export.`
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
function deduplicateIssues(issues) {
|
|
1116
|
+
const seen = new Set();
|
|
1117
|
+
return issues.filter((issue)=>{
|
|
1118
|
+
const key = `${issue.code}:${issue.location ?? ''}:${issue.message}`;
|
|
1119
|
+
if (seen.has(key)) return false;
|
|
1120
|
+
seen.add(key);
|
|
1121
|
+
return true;
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
function booleanAttribute(element, name) {
|
|
1125
|
+
if (!element) return false;
|
|
1126
|
+
const value = attribute(element, name);
|
|
1127
|
+
return '1' === value || 'true' === value;
|
|
1128
|
+
}
|
|
1129
|
+
function work_pptx_import_numberAttribute(element, name, fallback) {
|
|
1130
|
+
if (!element) return fallback;
|
|
1131
|
+
const value = Number(attribute(element, name));
|
|
1132
|
+
return Number.isFinite(value) ? value : fallback;
|
|
1133
|
+
}
|
|
1134
|
+
function positiveNumber(value) {
|
|
1135
|
+
const number = Number(value);
|
|
1136
|
+
return Number.isFinite(number) && number > 0 ? number : void 0;
|
|
1137
|
+
}
|
|
1138
|
+
export { importPptxPresentation };
|