@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
package/dist/0~7614.js
ADDED
|
@@ -0,0 +1,1037 @@
|
|
|
1
|
+
import jszip from "jszip";
|
|
2
|
+
import { workSpreadsheetChartSupportsErrorBars, workSpreadsheetChartSupportsGrouping, parseXml, firstDescendant, normalizeWorkSpreadsheetChartSmoothLines, workSpreadsheetChartSupportsSeriesAnalysis, descendants, normalizeWorkSpreadsheetChartSeriesStyle, attribute, directChildren, xmlNamespacePrefix, normalizeWorkSpreadsheetChartOverlap, normalizeWorkSpreadsheetErrorBars, normalizeWorkSpreadsheetChartLegendOverlay, normalizeWorkSpreadsheetChartGapWidth, workSpreadsheetChartSupportsBarSpacing, directChild, normalizeWorkSpreadsheetChartGrouping, workSpreadsheetChartSupportsSmoothLines, normalizeWorkSpreadsheetTrendline, workSpreadsheetChartUsesNumericXAxis, workSpreadsheetChartSupportsTrendlines } from "./8715.js";
|
|
3
|
+
import { normalizePresentationChartDataLabelPosition, normalizePresentationChartDataLabels, normalizePresentationChartSeriesStyle } from "./0~work-presentation-charts.js";
|
|
4
|
+
import { parseXlsxChartSeriesStyle, xlsxChartSeriesMarkerXml, parseXlsxTrendline, isSupportedXlsxChartLegend, isSupportedXlsxChartPlotLayout, isSupportedXlsxChartSeriesFormatting, parseXlsxChartPlotLayout, parseXlsxChartLegend, xlsxChartSeriesShapePropertiesXml, parseXlsxErrorBars } from "./4104.js";
|
|
5
|
+
import { createWorkSlideTransition } from "./0~work-presentation-transition.js";
|
|
6
|
+
const PRESENTATION_NAMESPACE = 'http://schemas.openxmlformats.org/presentationml/2006/main';
|
|
7
|
+
const DRAWING_NAMESPACE = 'http://schemas.openxmlformats.org/drawingml/2006/main';
|
|
8
|
+
const OFFICE_RELATIONSHIPS_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';
|
|
9
|
+
const PACKAGE_RELATIONSHIPS_NAMESPACE = 'http://schemas.openxmlformats.org/package/2006/relationships';
|
|
10
|
+
const CONTENT_TYPES_NAMESPACE = 'http://schemas.openxmlformats.org/package/2006/content-types';
|
|
11
|
+
const COMMENTS_RELATIONSHIP = `${OFFICE_RELATIONSHIPS_NAMESPACE}/comments`;
|
|
12
|
+
const COMMENT_AUTHORS_RELATIONSHIP = `${OFFICE_RELATIONSHIPS_NAMESPACE}/commentAuthors`;
|
|
13
|
+
const COMMENTS_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.presentationml.comments+xml';
|
|
14
|
+
const COMMENT_AUTHORS_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml';
|
|
15
|
+
async function loadPptxCommentAuthors(archive, presentationRelationships) {
|
|
16
|
+
const relationship = Array.from(presentationRelationships.values()).find((item)=>item.type.endsWith('/commentAuthors'));
|
|
17
|
+
if (!relationship || !archive.has(relationship.target)) return new Map();
|
|
18
|
+
const document = await archive.xml(relationship.target);
|
|
19
|
+
return new Map(descendants(document, 'cmAuthor').map((author)=>{
|
|
20
|
+
const id = attribute(author, 'id')?.trim() ?? '';
|
|
21
|
+
return [
|
|
22
|
+
id,
|
|
23
|
+
{
|
|
24
|
+
id,
|
|
25
|
+
name: attribute(author, 'name')?.trim() || '未知审阅者',
|
|
26
|
+
initials: attribute(author, 'initials')?.trim() || ''
|
|
27
|
+
}
|
|
28
|
+
];
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
async function readPptxSlideComments(archive, relationships, authors, slideNumber, slideWidthEmu, slideHeightEmu) {
|
|
32
|
+
const result = {
|
|
33
|
+
comments: [],
|
|
34
|
+
hasLegacyComments: false,
|
|
35
|
+
hasUnsupportedThreadedComments: false,
|
|
36
|
+
hasUnreadableComments: false,
|
|
37
|
+
hasMalformedMetadata: false
|
|
38
|
+
};
|
|
39
|
+
const commentRelationships = Array.from(relationships.values()).filter((item)=>item.type.endsWith('/comments'));
|
|
40
|
+
for (const relationship of commentRelationships){
|
|
41
|
+
if (!archive.has(relationship.target)) {
|
|
42
|
+
result.hasUnreadableComments = true;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const document = await archive.xml(relationship.target);
|
|
46
|
+
const root = document.documentElement;
|
|
47
|
+
if (root.namespaceURI !== PRESENTATION_NAMESPACE || 'cmLst' !== root.localName) {
|
|
48
|
+
result.hasUnsupportedThreadedComments = true;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
result.hasLegacyComments = true;
|
|
52
|
+
for (const [index, element] of directChildren(root, 'cm').entries()){
|
|
53
|
+
const authorId = attribute(element, 'authorId')?.trim() ?? '';
|
|
54
|
+
const author = authors.get(authorId);
|
|
55
|
+
const sourceIndex = attribute(element, 'idx')?.trim() || String(index + 1);
|
|
56
|
+
const position = firstDescendant(element, 'pos');
|
|
57
|
+
const sourceDate = attribute(element, 'dt');
|
|
58
|
+
if (!author || !normalizeDate(sourceDate) || !position || !validCoordinate(attribute(position ?? element, 'x'), slideWidthEmu) || !validCoordinate(attribute(position ?? element, 'y'), slideHeightEmu)) result.hasMalformedMetadata = true;
|
|
59
|
+
result.comments.push({
|
|
60
|
+
id: `pptx-comment-${slideNumber}-${safeIdPart(sourceIndex)}-${index + 1}`,
|
|
61
|
+
author: author?.name ?? '未知审阅者',
|
|
62
|
+
initials: author?.initials || void 0,
|
|
63
|
+
date: normalizeDate(sourceDate),
|
|
64
|
+
text: firstDescendant(element, 'text')?.textContent ?? '',
|
|
65
|
+
x: coordinatePercent(attribute(position ?? element, 'x'), slideWidthEmu),
|
|
66
|
+
y: coordinatePercent(attribute(position ?? element, 'y'), slideHeightEmu)
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
async function patchPptxComments(buffer, slides, slideWidth, slideHeight) {
|
|
73
|
+
if (!slides.some((slide)=>slide.comments?.length)) return buffer;
|
|
74
|
+
const archive = await jszip.loadAsync(buffer);
|
|
75
|
+
const authors = collectExportAuthors(slides);
|
|
76
|
+
const slideWidthEmu = Math.round(914400 * slideWidth);
|
|
77
|
+
const slideHeightEmu = Math.round(914400 * slideHeight);
|
|
78
|
+
const commentParts = [];
|
|
79
|
+
for (const [slideIndex, slide] of slides.entries()){
|
|
80
|
+
if (!slide.comments?.length) continue;
|
|
81
|
+
const partPath = `ppt/comments/comment${slideIndex + 1}.xml`;
|
|
82
|
+
commentParts.push(partPath);
|
|
83
|
+
archive.file(partPath, serializeSlideComments(slide.comments, authors, slideWidthEmu, slideHeightEmu));
|
|
84
|
+
await upsertRelationship(archive, `ppt/slides/slide${slideIndex + 1}.xml`, COMMENTS_RELATIONSHIP, `../comments/comment${slideIndex + 1}.xml`);
|
|
85
|
+
}
|
|
86
|
+
archive.file('ppt/commentAuthors.xml', serializeCommentAuthors(authors));
|
|
87
|
+
await upsertRelationship(archive, 'ppt/presentation.xml', COMMENT_AUTHORS_RELATIONSHIP, 'commentAuthors.xml');
|
|
88
|
+
await upsertContentTypes(archive, commentParts);
|
|
89
|
+
return archive.generateAsync({
|
|
90
|
+
type: 'arraybuffer',
|
|
91
|
+
compression: 'DEFLATE'
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function collectExportAuthors(slides) {
|
|
95
|
+
const authors = new Map();
|
|
96
|
+
for (const comment of slides.flatMap((slide)=>slide.comments ?? [])){
|
|
97
|
+
const name = comment.author.trim() || 'A3S Work';
|
|
98
|
+
const initials = comment.initials?.trim() || commentInitials(name);
|
|
99
|
+
const key = authorKey(name, initials);
|
|
100
|
+
if (!authors.has(key)) authors.set(key, {
|
|
101
|
+
id: String(authors.size),
|
|
102
|
+
name,
|
|
103
|
+
initials,
|
|
104
|
+
nextIndex: 1,
|
|
105
|
+
lastIndex: 0,
|
|
106
|
+
colorIndex: authors.size % 8
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return authors;
|
|
110
|
+
}
|
|
111
|
+
function serializeSlideComments(comments, authors, slideWidthEmu, slideHeightEmu) {
|
|
112
|
+
const document = presentationDocument('cmLst');
|
|
113
|
+
for (const comment of comments){
|
|
114
|
+
const name = comment.author.trim() || 'A3S Work';
|
|
115
|
+
const initials = comment.initials?.trim() || commentInitials(name);
|
|
116
|
+
const author = authors.get(authorKey(name, initials));
|
|
117
|
+
if (!author) continue;
|
|
118
|
+
const index = author.nextIndex;
|
|
119
|
+
author.nextIndex += 1;
|
|
120
|
+
author.lastIndex = Math.max(author.lastIndex, index);
|
|
121
|
+
const element = document.createElementNS(PRESENTATION_NAMESPACE, 'p:cm');
|
|
122
|
+
element.setAttribute('authorId', author.id);
|
|
123
|
+
element.setAttribute('dt', commentDate(comment.date));
|
|
124
|
+
element.setAttribute('idx', String(index));
|
|
125
|
+
const position = document.createElementNS(PRESENTATION_NAMESPACE, 'p:pos');
|
|
126
|
+
position.setAttribute('x', String(percentCoordinate(comment.x, slideWidthEmu)));
|
|
127
|
+
position.setAttribute('y', String(percentCoordinate(comment.y, slideHeightEmu)));
|
|
128
|
+
const text = document.createElementNS(PRESENTATION_NAMESPACE, 'p:text');
|
|
129
|
+
text.textContent = comment.text;
|
|
130
|
+
element.append(position, text);
|
|
131
|
+
document.documentElement.append(element);
|
|
132
|
+
}
|
|
133
|
+
return new XMLSerializer().serializeToString(document);
|
|
134
|
+
}
|
|
135
|
+
function serializeCommentAuthors(authors) {
|
|
136
|
+
const document = presentationDocument('cmAuthorLst');
|
|
137
|
+
for (const author of authors.values()){
|
|
138
|
+
const element = document.createElementNS(PRESENTATION_NAMESPACE, 'p:cmAuthor');
|
|
139
|
+
element.setAttribute('id', author.id);
|
|
140
|
+
element.setAttribute('name', author.name);
|
|
141
|
+
element.setAttribute('initials', author.initials);
|
|
142
|
+
element.setAttribute('lastIdx', String(author.lastIndex));
|
|
143
|
+
element.setAttribute('clrIdx', String(author.colorIndex));
|
|
144
|
+
document.documentElement.append(element);
|
|
145
|
+
}
|
|
146
|
+
return new XMLSerializer().serializeToString(document);
|
|
147
|
+
}
|
|
148
|
+
async function upsertRelationship(archive, sourcePart, type, target) {
|
|
149
|
+
const path = relationshipPartPath(sourcePart);
|
|
150
|
+
const entry = archive.file(path);
|
|
151
|
+
const document = entry ? parseXml(await entry.async('text'), path) : parseXml(`<Relationships xmlns="${PACKAGE_RELATIONSHIPS_NAMESPACE}"/>`, path);
|
|
152
|
+
const root = document.documentElement;
|
|
153
|
+
const existing = directChildren(root, 'Relationship').find((item)=>attribute(item, 'Type') === type);
|
|
154
|
+
if (existing) existing.setAttribute('Target', target);
|
|
155
|
+
else {
|
|
156
|
+
const relationship = document.createElementNS(PACKAGE_RELATIONSHIPS_NAMESPACE, 'Relationship');
|
|
157
|
+
relationship.setAttribute('Id', nextRelationshipId(root));
|
|
158
|
+
relationship.setAttribute('Type', type);
|
|
159
|
+
relationship.setAttribute('Target', target);
|
|
160
|
+
root.append(relationship);
|
|
161
|
+
}
|
|
162
|
+
archive.file(path, new XMLSerializer().serializeToString(document));
|
|
163
|
+
}
|
|
164
|
+
async function upsertContentTypes(archive, commentParts) {
|
|
165
|
+
const path = '[Content_Types].xml';
|
|
166
|
+
const entry = archive.file(path);
|
|
167
|
+
if (!entry) throw new Error('PPTX content types part is missing.');
|
|
168
|
+
const document = parseXml(await entry.async('text'), path);
|
|
169
|
+
upsertContentType(document, '/ppt/commentAuthors.xml', COMMENT_AUTHORS_CONTENT_TYPE);
|
|
170
|
+
for (const part of commentParts)upsertContentType(document, `/${part}`, COMMENTS_CONTENT_TYPE);
|
|
171
|
+
archive.file(path, new XMLSerializer().serializeToString(document));
|
|
172
|
+
}
|
|
173
|
+
function upsertContentType(document, partName, contentType) {
|
|
174
|
+
const root = document.documentElement;
|
|
175
|
+
const existing = directChildren(root, 'Override').find((item)=>attribute(item, 'PartName') === partName);
|
|
176
|
+
if (existing) return void existing.setAttribute('ContentType', contentType);
|
|
177
|
+
const override = document.createElementNS(CONTENT_TYPES_NAMESPACE, 'Override');
|
|
178
|
+
override.setAttribute('PartName', partName);
|
|
179
|
+
override.setAttribute('ContentType', contentType);
|
|
180
|
+
root.append(override);
|
|
181
|
+
}
|
|
182
|
+
function presentationDocument(rootName) {
|
|
183
|
+
return parseXml(`<p:${rootName} xmlns:a="${DRAWING_NAMESPACE}" xmlns:r="${OFFICE_RELATIONSHIPS_NAMESPACE}" xmlns:p="${PRESENTATION_NAMESPACE}"/>`, `PPTX ${rootName}`);
|
|
184
|
+
}
|
|
185
|
+
function relationshipPartPath(sourcePart) {
|
|
186
|
+
const separator = sourcePart.lastIndexOf('/');
|
|
187
|
+
const directory = separator >= 0 ? sourcePart.slice(0, separator + 1) : '';
|
|
188
|
+
const fileName = separator >= 0 ? sourcePart.slice(separator + 1) : sourcePart;
|
|
189
|
+
return `${directory}_rels/${fileName}.rels`;
|
|
190
|
+
}
|
|
191
|
+
function nextRelationshipId(root) {
|
|
192
|
+
const used = new Set(directChildren(root, 'Relationship').map((item)=>attribute(item, 'Id') ?? ''));
|
|
193
|
+
let index = 1;
|
|
194
|
+
while(used.has(`rId${index}`))index += 1;
|
|
195
|
+
return `rId${index}`;
|
|
196
|
+
}
|
|
197
|
+
function coordinatePercent(value, size) {
|
|
198
|
+
const coordinate = Number(value);
|
|
199
|
+
if (!Number.isFinite(coordinate) || coordinate < 0 || size <= 0) return 50;
|
|
200
|
+
return Math.round(10000 * clamp(coordinate / size * 100, 0, 100)) / 10000;
|
|
201
|
+
}
|
|
202
|
+
function validCoordinate(value, size) {
|
|
203
|
+
const coordinate = Number(value);
|
|
204
|
+
return null !== value && Number.isFinite(coordinate) && coordinate >= 0 && coordinate <= size;
|
|
205
|
+
}
|
|
206
|
+
function percentCoordinate(value, size) {
|
|
207
|
+
return Math.round(clamp(Number.isFinite(value) ? value : 50, 0, 100) / 100 * size);
|
|
208
|
+
}
|
|
209
|
+
function commentDate(value) {
|
|
210
|
+
const time = Date.parse(value);
|
|
211
|
+
return Number.isFinite(time) ? new Date(time).toISOString() : new Date().toISOString();
|
|
212
|
+
}
|
|
213
|
+
function normalizeDate(value) {
|
|
214
|
+
if (!value) return '';
|
|
215
|
+
const time = Date.parse(value);
|
|
216
|
+
return Number.isFinite(time) ? new Date(time).toISOString() : '';
|
|
217
|
+
}
|
|
218
|
+
function commentInitials(author) {
|
|
219
|
+
const parts = author.trim().split(/\s+/).filter(Boolean);
|
|
220
|
+
if (!parts.length) return 'AW';
|
|
221
|
+
return parts.slice(0, 2).map((part)=>Array.from(part)[0] ?? '').join('').toUpperCase();
|
|
222
|
+
}
|
|
223
|
+
function authorKey(author, initials) {
|
|
224
|
+
return `${author}\u0000${initials}`;
|
|
225
|
+
}
|
|
226
|
+
function safeIdPart(value) {
|
|
227
|
+
const normalized = value.replace(/[^a-z0-9_-]/gi, '-').replace(/-+/g, '-');
|
|
228
|
+
return normalized || 'comment';
|
|
229
|
+
}
|
|
230
|
+
function clamp(value, minimum, maximum) {
|
|
231
|
+
return Math.min(Math.max(value, minimum), maximum);
|
|
232
|
+
}
|
|
233
|
+
const CHART_TYPES = [
|
|
234
|
+
'barChart',
|
|
235
|
+
'lineChart',
|
|
236
|
+
'pieChart',
|
|
237
|
+
'doughnutChart',
|
|
238
|
+
'areaChart',
|
|
239
|
+
'radarChart',
|
|
240
|
+
'scatterChart',
|
|
241
|
+
'bubbleChart'
|
|
242
|
+
];
|
|
243
|
+
const DATA_LABEL_ANCHORS = new Set([
|
|
244
|
+
'dropLines',
|
|
245
|
+
'hiLowLines',
|
|
246
|
+
'upDownBars',
|
|
247
|
+
'marker',
|
|
248
|
+
'smooth',
|
|
249
|
+
'gapWidth',
|
|
250
|
+
'overlap',
|
|
251
|
+
'firstSliceAng',
|
|
252
|
+
'holeSize',
|
|
253
|
+
'bubble3D',
|
|
254
|
+
'bubbleScale',
|
|
255
|
+
'showNegBubbles',
|
|
256
|
+
'sizeRepresents',
|
|
257
|
+
'axId',
|
|
258
|
+
'extLst'
|
|
259
|
+
]);
|
|
260
|
+
function readPptxChartDataLabels(chartNode, chartType) {
|
|
261
|
+
if (!chartNode) return {
|
|
262
|
+
diagnostics: []
|
|
263
|
+
};
|
|
264
|
+
const diagnostics = [];
|
|
265
|
+
const series = directChildren(chartNode, 'ser');
|
|
266
|
+
const chartLabels = directChild(chartNode, 'dLbls');
|
|
267
|
+
const seriesLabels = series.flatMap((item)=>directChildren(item, 'dLbls'));
|
|
268
|
+
const source = chartLabels ?? seriesLabels[0];
|
|
269
|
+
if (!source || pptxBooleanElement(source, 'delete')) return {
|
|
270
|
+
diagnostics
|
|
271
|
+
};
|
|
272
|
+
if (chartLabels && seriesLabels.length) diagnostics.push({
|
|
273
|
+
code: 'pptx.chart.data-label-overrides',
|
|
274
|
+
message: 'Per-series data-label overrides were normalized to the chart-level editable settings.'
|
|
275
|
+
});
|
|
276
|
+
else if (!chartLabels && (seriesLabels.length !== series.length || new Set(seriesLabels.map(dataLabelSignature)).size > 1)) diagnostics.push({
|
|
277
|
+
code: 'pptx.chart.data-label-overrides',
|
|
278
|
+
message: 'Different per-series data-label settings were normalized to one editable chart-level setting.'
|
|
279
|
+
});
|
|
280
|
+
const allLabelNodes = [
|
|
281
|
+
...chartLabels ? [
|
|
282
|
+
chartLabels
|
|
283
|
+
] : [],
|
|
284
|
+
...seriesLabels
|
|
285
|
+
];
|
|
286
|
+
if (allLabelNodes.some((labels)=>directChildren(labels, 'dLbl').length > 0)) diagnostics.push({
|
|
287
|
+
code: 'pptx.chart.data-label-overrides',
|
|
288
|
+
message: 'Per-point data-label overrides were normalized to the chart-level editable settings.'
|
|
289
|
+
});
|
|
290
|
+
const rawPosition = attribute(directChild(source, 'dLblPos') ?? source, 'val');
|
|
291
|
+
const parsedPosition = pptxDataLabelPosition(rawPosition);
|
|
292
|
+
const normalizedPosition = normalizePresentationChartDataLabelPosition(parsedPosition, chartType);
|
|
293
|
+
if (rawPosition && (!parsedPosition || normalizedPosition !== parsedPosition)) diagnostics.push({
|
|
294
|
+
code: 'pptx.chart.data-label-position',
|
|
295
|
+
message: `The data-label position “${rawPosition}” was normalized for this editable chart type.`
|
|
296
|
+
});
|
|
297
|
+
const separatorElement = directChild(source, 'separator');
|
|
298
|
+
const separator = separatorElement?.textContent ?? void 0;
|
|
299
|
+
if (separator && separator.length > 64) diagnostics.push({
|
|
300
|
+
code: 'pptx.chart.data-label-separator',
|
|
301
|
+
message: 'The data-label separator exceeded 64 characters and was truncated.'
|
|
302
|
+
});
|
|
303
|
+
const showPercentage = pptxBooleanElement(source, 'showPercent');
|
|
304
|
+
const showBubbleSize = pptxBooleanElement(source, 'showBubbleSize');
|
|
305
|
+
if (showPercentage && 'pie' !== chartType && 'doughnut' !== chartType) diagnostics.push({
|
|
306
|
+
code: 'pptx.chart.data-label-content',
|
|
307
|
+
message: 'Percentage data labels are supported only for editable pie and doughnut charts.'
|
|
308
|
+
});
|
|
309
|
+
if (showBubbleSize && 'bubble' !== chartType) diagnostics.push({
|
|
310
|
+
code: 'pptx.chart.data-label-content',
|
|
311
|
+
message: 'Bubble-size data labels are supported only for editable bubble charts.'
|
|
312
|
+
});
|
|
313
|
+
if (pptxBooleanElement(source, 'showLegendKey') || pptxBooleanElement(source, 'showLeaderLines')) diagnostics.push({
|
|
314
|
+
code: 'pptx.chart.data-label-content',
|
|
315
|
+
message: 'Legend-key or leader-line data-label options were normalized.'
|
|
316
|
+
});
|
|
317
|
+
if ([
|
|
318
|
+
'numFmt',
|
|
319
|
+
'spPr',
|
|
320
|
+
'txPr',
|
|
321
|
+
'extLst'
|
|
322
|
+
].some((name)=>directChildren(source, name).length > 0)) diagnostics.push({
|
|
323
|
+
code: 'pptx.chart.data-label-format',
|
|
324
|
+
message: 'Advanced data-label number and text formatting is normalized by the editable chart model.'
|
|
325
|
+
});
|
|
326
|
+
return {
|
|
327
|
+
dataLabels: normalizePresentationChartDataLabels({
|
|
328
|
+
...pptxBooleanElement(source, 'showVal') ? {
|
|
329
|
+
showValue: true
|
|
330
|
+
} : {},
|
|
331
|
+
...pptxBooleanElement(source, 'showCatName') ? {
|
|
332
|
+
showCategoryName: true
|
|
333
|
+
} : {},
|
|
334
|
+
...pptxBooleanElement(source, 'showSerName') ? {
|
|
335
|
+
showSeriesName: true
|
|
336
|
+
} : {},
|
|
337
|
+
...showPercentage ? {
|
|
338
|
+
showPercentage: true
|
|
339
|
+
} : {},
|
|
340
|
+
...showBubbleSize ? {
|
|
341
|
+
showBubbleSize: true
|
|
342
|
+
} : {},
|
|
343
|
+
...void 0 !== separator ? {
|
|
344
|
+
separator
|
|
345
|
+
} : {},
|
|
346
|
+
position: normalizedPosition
|
|
347
|
+
}, chartType),
|
|
348
|
+
diagnostics
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
async function patchPptxChartDataLabels(buffer, slides) {
|
|
352
|
+
const charts = slides.flatMap((slide)=>slide.elements.flatMap((element)=>'chart' === element.type && element.chart ? [
|
|
353
|
+
element.chart
|
|
354
|
+
] : []));
|
|
355
|
+
if (!charts.length) return buffer;
|
|
356
|
+
const archive = await jszip.loadAsync(buffer);
|
|
357
|
+
const chartPaths = Object.keys(archive.files).filter((path)=>/^ppt\/charts\/chart\d+\.xml$/.test(path)).sort((left, right)=>chartPartNumber(left) - chartPartNumber(right));
|
|
358
|
+
if (chartPaths.length !== charts.length) throw new Error(`PPTX chart export produced ${chartPaths.length} chart part(s) for ${charts.length} chart element(s).`);
|
|
359
|
+
for (const [index, path] of chartPaths.entries()){
|
|
360
|
+
const entry = archive.file(path);
|
|
361
|
+
if (!entry) continue;
|
|
362
|
+
const document = parseXml(await entry.async('text'), path);
|
|
363
|
+
const chartNode = CHART_TYPES.map((name)=>firstDescendant(document, name)).find(Boolean);
|
|
364
|
+
if (!chartNode) throw new Error(`PPTX chart part is missing a supported chart node: ${path}`);
|
|
365
|
+
writePptxChartDataLabels(document, chartNode, charts[index]);
|
|
366
|
+
archive.file(path, new XMLSerializer().serializeToString(document));
|
|
367
|
+
}
|
|
368
|
+
return archive.generateAsync({
|
|
369
|
+
type: 'arraybuffer',
|
|
370
|
+
compression: 'DEFLATE'
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
function writePptxChartDataLabels(document, chartNode, chart) {
|
|
374
|
+
for (const element of directChildren(chartNode, 'dLbls'))element.remove();
|
|
375
|
+
for (const series of directChildren(chartNode, 'ser'))for (const element of directChildren(series, 'dLbls'))element.remove();
|
|
376
|
+
if (!chart.dataLabels) return;
|
|
377
|
+
const labels = normalizePresentationChartDataLabels(chart.dataLabels, chart.type);
|
|
378
|
+
const namespace = chartNode.namespaceURI;
|
|
379
|
+
const prefix = xmlNamespacePrefix(chartNode, namespace) ?? chartNode.prefix ?? 'c';
|
|
380
|
+
const container = document.createElementNS(namespace, `${prefix}:dLbls`);
|
|
381
|
+
appendChartElement(document, container, prefix, 'dLblPos', {
|
|
382
|
+
val: pptxDataLabelPositionValue(normalizePresentationChartDataLabelPosition(labels.position, chart.type))
|
|
383
|
+
});
|
|
384
|
+
appendChartElement(document, container, prefix, 'showLegendKey', {
|
|
385
|
+
val: '0'
|
|
386
|
+
});
|
|
387
|
+
appendChartElement(document, container, prefix, 'showVal', {
|
|
388
|
+
val: labels.showValue ? '1' : '0'
|
|
389
|
+
});
|
|
390
|
+
appendChartElement(document, container, prefix, 'showCatName', {
|
|
391
|
+
val: labels.showCategoryName ? '1' : '0'
|
|
392
|
+
});
|
|
393
|
+
appendChartElement(document, container, prefix, 'showSerName', {
|
|
394
|
+
val: labels.showSeriesName ? '1' : '0'
|
|
395
|
+
});
|
|
396
|
+
appendChartElement(document, container, prefix, 'showPercent', {
|
|
397
|
+
val: labels.showPercentage ? '1' : '0'
|
|
398
|
+
});
|
|
399
|
+
appendChartElement(document, container, prefix, 'showBubbleSize', {
|
|
400
|
+
val: labels.showBubbleSize ? '1' : '0'
|
|
401
|
+
});
|
|
402
|
+
if (void 0 !== labels.separator) {
|
|
403
|
+
const separator = appendChartElement(document, container, prefix, 'separator');
|
|
404
|
+
separator.textContent = labels.separator;
|
|
405
|
+
}
|
|
406
|
+
appendChartElement(document, container, prefix, 'showLeaderLines', {
|
|
407
|
+
val: '0'
|
|
408
|
+
});
|
|
409
|
+
const anchor = directChildren(chartNode).find((child)=>DATA_LABEL_ANCHORS.has(child.localName)) ?? null;
|
|
410
|
+
chartNode.insertBefore(container, anchor);
|
|
411
|
+
}
|
|
412
|
+
function appendChartElement(document, parent, prefix, localName, attributes = {}) {
|
|
413
|
+
const element = document.createElementNS(parent.namespaceURI, `${prefix}:${localName}`);
|
|
414
|
+
for (const [name, value] of Object.entries(attributes))element.setAttribute(name, value);
|
|
415
|
+
parent.append(element);
|
|
416
|
+
return element;
|
|
417
|
+
}
|
|
418
|
+
function pptxDataLabelPosition(value) {
|
|
419
|
+
if ('ctr' === value) return 'center';
|
|
420
|
+
if ('inBase' === value) return 'insideBase';
|
|
421
|
+
if ('inEnd' === value) return 'insideEnd';
|
|
422
|
+
if ('outEnd' === value) return 'outsideEnd';
|
|
423
|
+
if ('l' === value) return 'left';
|
|
424
|
+
if ('r' === value) return 'right';
|
|
425
|
+
if ('t' === value) return 'above';
|
|
426
|
+
if ('b' === value) return 'below';
|
|
427
|
+
if ('bestFit' === value) return 'bestFit';
|
|
428
|
+
}
|
|
429
|
+
function pptxDataLabelPositionValue(position) {
|
|
430
|
+
if ('center' === position) return 'ctr';
|
|
431
|
+
if ('insideBase' === position) return 'inBase';
|
|
432
|
+
if ('insideEnd' === position) return 'inEnd';
|
|
433
|
+
if ('outsideEnd' === position) return 'outEnd';
|
|
434
|
+
if ('left' === position) return 'l';
|
|
435
|
+
if ('right' === position) return 'r';
|
|
436
|
+
if ('above' === position) return 't';
|
|
437
|
+
if ('below' === position) return 'b';
|
|
438
|
+
return 'bestFit';
|
|
439
|
+
}
|
|
440
|
+
function pptxBooleanElement(parent, localName) {
|
|
441
|
+
const element = directChild(parent, localName);
|
|
442
|
+
if (!element) return false;
|
|
443
|
+
const value = attribute(element, 'val');
|
|
444
|
+
return null === value || '1' === value || 'true' === value.toLocaleLowerCase();
|
|
445
|
+
}
|
|
446
|
+
function dataLabelSignature(element) {
|
|
447
|
+
return [
|
|
448
|
+
attribute(directChild(element, 'dLblPos') ?? element, 'val') ?? '',
|
|
449
|
+
String(pptxBooleanElement(element, 'showVal')),
|
|
450
|
+
String(pptxBooleanElement(element, 'showCatName')),
|
|
451
|
+
String(pptxBooleanElement(element, 'showSerName')),
|
|
452
|
+
String(pptxBooleanElement(element, 'showPercent')),
|
|
453
|
+
String(pptxBooleanElement(element, 'showBubbleSize')),
|
|
454
|
+
directChild(element, 'separator')?.textContent ?? ''
|
|
455
|
+
].join('|');
|
|
456
|
+
}
|
|
457
|
+
function chartPartNumber(path) {
|
|
458
|
+
return Number(/chart(\d+)\.xml$/.exec(path)?.[1] ?? Number.MAX_SAFE_INTEGER);
|
|
459
|
+
}
|
|
460
|
+
const work_pptx_chart_layout_style_CHART_TYPES = [
|
|
461
|
+
'barChart',
|
|
462
|
+
'lineChart',
|
|
463
|
+
'pieChart',
|
|
464
|
+
'doughnutChart',
|
|
465
|
+
'areaChart',
|
|
466
|
+
'radarChart',
|
|
467
|
+
'scatterChart',
|
|
468
|
+
'bubbleChart'
|
|
469
|
+
];
|
|
470
|
+
const work_pptx_chart_layout_style_DRAWING_NAMESPACE = 'http://schemas.openxmlformats.org/drawingml/2006/main';
|
|
471
|
+
function readPptxChartLayoutAndSeriesStyles(document, chartNode, chartType, seriesNodes) {
|
|
472
|
+
const diagnostics = [];
|
|
473
|
+
const legend = firstDescendant(document, 'legend');
|
|
474
|
+
const parsedLegend = parseXlsxChartLegend(document);
|
|
475
|
+
if (legend && !isSupportedXlsxChartLegend(document)) diagnostics.push({
|
|
476
|
+
code: 'pptx.chart.format.legend',
|
|
477
|
+
message: 'Manual legend layout, entry overrides, or advanced legend formatting was normalized.'
|
|
478
|
+
});
|
|
479
|
+
const hasLayout = Boolean(chartNode && chartHasEditableLayoutElements(chartNode));
|
|
480
|
+
const layout = chartNode && hasLayout ? parseXlsxChartPlotLayout(chartNode, chartType) : {};
|
|
481
|
+
if (chartNode && hasLayout && !isSupportedXlsxChartPlotLayout(chartNode)) diagnostics.push({
|
|
482
|
+
code: 'pptx.chart.format.layout',
|
|
483
|
+
message: 'Invalid grouping, spacing, overlap, or mixed smoothing settings were normalized.'
|
|
484
|
+
});
|
|
485
|
+
const seriesStyles = seriesNodes.map((series)=>parseXlsxChartSeriesStyle(series));
|
|
486
|
+
if (chartNode && seriesNodes.some((series)=>!isSupportedXlsxChartSeriesFormatting(series, chartNode.localName) || directChildren(series, 'dPt').length > 0)) diagnostics.push({
|
|
487
|
+
code: 'pptx.chart.format.series',
|
|
488
|
+
message: 'Theme, gradient, pattern, effect, custom dash, or per-point series formatting was normalized to portable series appearance.'
|
|
489
|
+
});
|
|
490
|
+
if (!workSpreadsheetChartSupportsSeriesAnalysis({
|
|
491
|
+
type: chartType,
|
|
492
|
+
...layout
|
|
493
|
+
}) && seriesNodes.some((series)=>directChild(series, 'trendline') || directChild(series, 'errBars'))) diagnostics.push({
|
|
494
|
+
code: 'pptx.chart.format.series-analysis',
|
|
495
|
+
message: 'Trendlines and error bars were removed because stacked chart layouts do not support series analysis.'
|
|
496
|
+
});
|
|
497
|
+
return {
|
|
498
|
+
...legend ? {
|
|
499
|
+
legendOverlay: normalizeWorkSpreadsheetChartLegendOverlay(parsedLegend.legendOverlay)
|
|
500
|
+
} : {},
|
|
501
|
+
layout,
|
|
502
|
+
seriesStyles,
|
|
503
|
+
diagnostics
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
async function patchPptxChartLayoutAndSeriesStyles(buffer, slides) {
|
|
507
|
+
const charts = slides.flatMap((slide)=>slide.elements.flatMap((element)=>'chart' === element.type && element.chart ? [
|
|
508
|
+
element.chart
|
|
509
|
+
] : []));
|
|
510
|
+
if (!charts.length) return buffer;
|
|
511
|
+
const archive = await jszip.loadAsync(buffer);
|
|
512
|
+
const chartPaths = Object.keys(archive.files).filter((path)=>/^ppt\/charts\/chart\d+\.xml$/.test(path)).sort((left, right)=>work_pptx_chart_layout_style_chartPartNumber(left) - work_pptx_chart_layout_style_chartPartNumber(right));
|
|
513
|
+
if (chartPaths.length !== charts.length) throw new Error(`PPTX chart export produced ${chartPaths.length} chart part(s) for ${charts.length} chart element(s).`);
|
|
514
|
+
for (const [index, chart] of charts.entries()){
|
|
515
|
+
const path = chartPaths[index];
|
|
516
|
+
const entry = archive.file(path);
|
|
517
|
+
if (!entry) throw new Error(`PPTX chart export is missing chart part: ${path}`);
|
|
518
|
+
const document = parseXml(await entry.async('text'), path);
|
|
519
|
+
const chartNode = work_pptx_chart_layout_style_CHART_TYPES.map((name)=>firstDescendant(document, name)).find(Boolean);
|
|
520
|
+
if (!chartNode) throw new Error(`PPTX chart part is missing a supported chart node: ${path}`);
|
|
521
|
+
writePptxChartLayoutAndSeriesStyles(document, chartNode, chart);
|
|
522
|
+
archive.file(path, new XMLSerializer().serializeToString(document));
|
|
523
|
+
}
|
|
524
|
+
return archive.generateAsync({
|
|
525
|
+
type: 'arraybuffer',
|
|
526
|
+
compression: 'DEFLATE'
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
function writePptxChartLayoutAndSeriesStyles(document, chartNode, chart) {
|
|
530
|
+
writeLegendOverlay(document, chart);
|
|
531
|
+
writePlotLayout(document, chartNode, chart);
|
|
532
|
+
const seriesNodes = directChildren(chartNode, 'ser');
|
|
533
|
+
if (seriesNodes.length !== chart.series.length) throw new Error(`PPTX chart export produced ${seriesNodes.length} native series for ${chart.series.length} editable series.`);
|
|
534
|
+
for (const [seriesIndex, seriesNode] of seriesNodes.entries())writeSeriesStyle(document, seriesNode, chart.series[seriesIndex].style, chart.type);
|
|
535
|
+
}
|
|
536
|
+
function writeLegendOverlay(document, chart) {
|
|
537
|
+
if (!chart.showLegend) return;
|
|
538
|
+
const chartRoot = firstDescendant(document, 'chart');
|
|
539
|
+
const legend = chartRoot ? directChild(chartRoot, 'legend') : void 0;
|
|
540
|
+
if (!legend) return;
|
|
541
|
+
for (const overlay of directChildren(legend, 'overlay'))overlay.remove();
|
|
542
|
+
const anchor = directChildren(legend).find((child)=>[
|
|
543
|
+
'spPr',
|
|
544
|
+
'txPr',
|
|
545
|
+
'extLst'
|
|
546
|
+
].includes(child.localName)) ?? null;
|
|
547
|
+
insertChartSetting(document, legend, 'overlay', normalizeWorkSpreadsheetChartLegendOverlay(chart.legendOverlay) ? '1' : '0', anchor);
|
|
548
|
+
}
|
|
549
|
+
function writePlotLayout(document, chartNode, chart) {
|
|
550
|
+
if (workSpreadsheetChartSupportsGrouping(chart.type)) replaceChartSetting(document, chartNode, 'grouping', normalizeWorkSpreadsheetChartGrouping(chart.grouping, chart.type), directChildren(chartNode).find((child)=>[
|
|
551
|
+
'varyColors',
|
|
552
|
+
'ser'
|
|
553
|
+
].includes(child.localName)) ?? null);
|
|
554
|
+
if (workSpreadsheetChartSupportsBarSpacing(chart.type)) {
|
|
555
|
+
const grouping = normalizeWorkSpreadsheetChartGrouping(chart.grouping, chart.type);
|
|
556
|
+
for (const name of [
|
|
557
|
+
'gapWidth',
|
|
558
|
+
'overlap'
|
|
559
|
+
])for (const child of directChildren(chartNode, name))child.remove();
|
|
560
|
+
const anchor = directChildren(chartNode).find((child)=>[
|
|
561
|
+
'axId',
|
|
562
|
+
'extLst'
|
|
563
|
+
].includes(child.localName)) ?? null;
|
|
564
|
+
insertChartSetting(document, chartNode, 'gapWidth', String(normalizeWorkSpreadsheetChartGapWidth(chart.gapWidth)), anchor);
|
|
565
|
+
insertChartSetting(document, chartNode, 'overlap', String(normalizeWorkSpreadsheetChartOverlap(chart.overlap, grouping)), anchor);
|
|
566
|
+
}
|
|
567
|
+
if (workSpreadsheetChartSupportsSmoothLines(chart.type)) {
|
|
568
|
+
for (const child of directChildren(chartNode, 'smooth'))child.remove();
|
|
569
|
+
for (const series of directChildren(chartNode, 'ser'))for (const child of directChildren(series, 'smooth'))child.remove();
|
|
570
|
+
const anchor = directChildren(chartNode).find((child)=>[
|
|
571
|
+
'axId',
|
|
572
|
+
'extLst'
|
|
573
|
+
].includes(child.localName)) ?? null;
|
|
574
|
+
insertChartSetting(document, chartNode, 'smooth', normalizeWorkSpreadsheetChartSmoothLines(chart.smoothLines) ? '1' : '0', anchor);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
function writeSeriesStyle(document, seriesNode, source, chartType) {
|
|
578
|
+
const style = normalizePresentationChartSeriesStyle(source, chartType);
|
|
579
|
+
for (const shape of directChildren(seriesNode, 'spPr'))shape.remove();
|
|
580
|
+
for (const marker of directChildren(seriesNode, 'marker'))marker.remove();
|
|
581
|
+
if (!style) return;
|
|
582
|
+
const shapeXml = xlsxChartSeriesShapePropertiesXml(style);
|
|
583
|
+
if (shapeXml) {
|
|
584
|
+
const anchor = directChildren(seriesNode).find((child)=>[
|
|
585
|
+
'marker',
|
|
586
|
+
'dPt',
|
|
587
|
+
'dLbls',
|
|
588
|
+
'trendline',
|
|
589
|
+
'errBars',
|
|
590
|
+
'cat',
|
|
591
|
+
'xVal',
|
|
592
|
+
'val',
|
|
593
|
+
'yVal',
|
|
594
|
+
'bubbleSize',
|
|
595
|
+
'smooth',
|
|
596
|
+
'extLst'
|
|
597
|
+
].includes(child.localName));
|
|
598
|
+
seriesNode.insertBefore(chartFragmentElement(document, seriesNode, shapeXml), anchor ?? null);
|
|
599
|
+
}
|
|
600
|
+
const normalized = normalizeWorkSpreadsheetChartSeriesStyle(style);
|
|
601
|
+
if (!normalized?.marker) return;
|
|
602
|
+
const markerXml = xlsxChartSeriesMarkerXml(style, true);
|
|
603
|
+
const anchor = directChildren(seriesNode).find((child)=>[
|
|
604
|
+
'dPt',
|
|
605
|
+
'dLbls',
|
|
606
|
+
'trendline',
|
|
607
|
+
'errBars',
|
|
608
|
+
'cat',
|
|
609
|
+
'xVal',
|
|
610
|
+
'val',
|
|
611
|
+
'yVal',
|
|
612
|
+
'bubbleSize',
|
|
613
|
+
'smooth',
|
|
614
|
+
'extLst'
|
|
615
|
+
].includes(child.localName));
|
|
616
|
+
seriesNode.insertBefore(chartFragmentElement(document, seriesNode, markerXml), anchor ?? null);
|
|
617
|
+
}
|
|
618
|
+
function chartFragmentElement(document, parent, xml) {
|
|
619
|
+
const namespace = parent.namespaceURI ?? 'http://schemas.openxmlformats.org/drawingml/2006/chart';
|
|
620
|
+
const parsed = parseXml(`<c:root xmlns:c="${namespace}" xmlns:a="${work_pptx_chart_layout_style_DRAWING_NAMESPACE}">${xml}</c:root>`, 'PPTX chart formatting fragment');
|
|
621
|
+
const element = parsed.documentElement.firstElementChild;
|
|
622
|
+
if (!element) throw new Error('PPTX chart formatting fragment did not contain an element.');
|
|
623
|
+
return document.importNode(element, true);
|
|
624
|
+
}
|
|
625
|
+
function replaceChartSetting(document, parent, localName, value, anchor) {
|
|
626
|
+
for (const child of directChildren(parent, localName))child.remove();
|
|
627
|
+
insertChartSetting(document, parent, localName, value, anchor);
|
|
628
|
+
}
|
|
629
|
+
function insertChartSetting(document, parent, localName, value, anchor) {
|
|
630
|
+
const prefix = xmlNamespacePrefix(parent, parent.namespaceURI) ?? parent.prefix ?? 'c';
|
|
631
|
+
const element = document.createElementNS(parent.namespaceURI, `${prefix}:${localName}`);
|
|
632
|
+
element.setAttribute('val', value);
|
|
633
|
+
parent.insertBefore(element, anchor);
|
|
634
|
+
return element;
|
|
635
|
+
}
|
|
636
|
+
function chartHasEditableLayoutElements(chartNode) {
|
|
637
|
+
return [
|
|
638
|
+
'grouping',
|
|
639
|
+
'gapWidth',
|
|
640
|
+
'overlap'
|
|
641
|
+
].some((name)=>directChildren(chartNode, name).length > 0) || 'lineChart' === chartNode.localName && (directChildren(chartNode, 'smooth').length > 0 || directChildren(chartNode, 'ser').some((series)=>directChildren(series, 'smooth').length > 0));
|
|
642
|
+
}
|
|
643
|
+
function work_pptx_chart_layout_style_chartPartNumber(path) {
|
|
644
|
+
return Number(/chart(\d+)\.xml$/.exec(path)?.[1] ?? Number.MAX_SAFE_INTEGER);
|
|
645
|
+
}
|
|
646
|
+
const work_pptx_chart_series_analysis_CHART_TYPES = [
|
|
647
|
+
'barChart',
|
|
648
|
+
'lineChart',
|
|
649
|
+
'pieChart',
|
|
650
|
+
'doughnutChart',
|
|
651
|
+
'areaChart',
|
|
652
|
+
'radarChart',
|
|
653
|
+
'scatterChart',
|
|
654
|
+
'bubbleChart'
|
|
655
|
+
];
|
|
656
|
+
function readPptxChartSeriesAnalysis(seriesNode, chartType) {
|
|
657
|
+
const diagnostics = [];
|
|
658
|
+
const trendlineNodes = directChildren(seriesNode, 'trendline');
|
|
659
|
+
const errorBarNodes = directChildren(seriesNode, 'errBars');
|
|
660
|
+
if (!workSpreadsheetChartSupportsTrendlines(chartType) && trendlineNodes.length || !workSpreadsheetChartSupportsErrorBars(chartType) && errorBarNodes.length) diagnostics.push({
|
|
661
|
+
code: 'pptx.chart.series-analysis-type',
|
|
662
|
+
message: 'Trendlines or error bars on this chart type were omitted because the editable chart type does not support them.'
|
|
663
|
+
});
|
|
664
|
+
const trendlines = workSpreadsheetChartSupportsTrendlines(chartType) ? trendlineNodes.flatMap((node)=>{
|
|
665
|
+
const trendline = parseXlsxTrendline(node);
|
|
666
|
+
if (!trendline) {
|
|
667
|
+
diagnostics.push({
|
|
668
|
+
code: 'pptx.chart.trendline-type',
|
|
669
|
+
message: 'An unsupported or incomplete trendline was omitted from the editable chart.'
|
|
670
|
+
});
|
|
671
|
+
return [];
|
|
672
|
+
}
|
|
673
|
+
readTrendlineDiagnostics(node, diagnostics);
|
|
674
|
+
return [
|
|
675
|
+
trendline
|
|
676
|
+
];
|
|
677
|
+
}) : [];
|
|
678
|
+
const directions = new Set();
|
|
679
|
+
const errorBars = workSpreadsheetChartSupportsErrorBars(chartType) ? errorBarNodes.flatMap((node)=>{
|
|
680
|
+
const errorBar = parseXlsxErrorBars(node, chartType);
|
|
681
|
+
if (!errorBar) {
|
|
682
|
+
diagnostics.push({
|
|
683
|
+
code: 'pptx.chart.error-bars-type',
|
|
684
|
+
message: 'Unsupported or incomplete error-bar settings were omitted from the editable chart.'
|
|
685
|
+
});
|
|
686
|
+
return [];
|
|
687
|
+
}
|
|
688
|
+
if (directions.has(errorBar.direction)) {
|
|
689
|
+
diagnostics.push({
|
|
690
|
+
code: 'pptx.chart.error-bars-duplicate',
|
|
691
|
+
message: `Multiple ${errorBar.direction.toUpperCase()} error bars on one series were normalized to the first editable setting.`
|
|
692
|
+
});
|
|
693
|
+
return [];
|
|
694
|
+
}
|
|
695
|
+
directions.add(errorBar.direction);
|
|
696
|
+
readErrorBarDiagnostics(node, errorBar, diagnostics);
|
|
697
|
+
return [
|
|
698
|
+
errorBar
|
|
699
|
+
];
|
|
700
|
+
}) : [];
|
|
701
|
+
return {
|
|
702
|
+
...trendlines.length ? {
|
|
703
|
+
trendlines
|
|
704
|
+
} : {},
|
|
705
|
+
...errorBars.length ? {
|
|
706
|
+
errorBars
|
|
707
|
+
} : {},
|
|
708
|
+
diagnostics
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
async function patchPptxChartSeriesAnalysis(buffer, slides) {
|
|
712
|
+
const charts = slides.flatMap((slide)=>slide.elements.flatMap((element)=>'chart' === element.type && element.chart ? [
|
|
713
|
+
element.chart
|
|
714
|
+
] : []));
|
|
715
|
+
if (!charts.some(chartHasSeriesAnalysis)) return buffer;
|
|
716
|
+
const archive = await jszip.loadAsync(buffer);
|
|
717
|
+
const chartPaths = Object.keys(archive.files).filter((path)=>/^ppt\/charts\/chart\d+\.xml$/.test(path)).sort((left, right)=>work_pptx_chart_series_analysis_chartPartNumber(left) - work_pptx_chart_series_analysis_chartPartNumber(right));
|
|
718
|
+
if (chartPaths.length !== charts.length) throw new Error(`PPTX chart export produced ${chartPaths.length} chart part(s) for ${charts.length} chart element(s).`);
|
|
719
|
+
for (const [index, chart] of charts.entries()){
|
|
720
|
+
const path = chartPaths[index];
|
|
721
|
+
const entry = archive.file(path);
|
|
722
|
+
if (!entry) throw new Error(`PPTX chart export is missing chart part: ${path}`);
|
|
723
|
+
const document = parseXml(await entry.async('text'), path);
|
|
724
|
+
const chartNode = work_pptx_chart_series_analysis_CHART_TYPES.map((name)=>firstDescendant(document, name)).find(Boolean);
|
|
725
|
+
if (!chartNode) throw new Error(`PPTX chart part is missing a supported chart node: ${path}`);
|
|
726
|
+
writePptxChartSeriesAnalysis(document, chartNode, chart);
|
|
727
|
+
archive.file(path, new XMLSerializer().serializeToString(document));
|
|
728
|
+
}
|
|
729
|
+
return archive.generateAsync({
|
|
730
|
+
type: 'arraybuffer',
|
|
731
|
+
compression: 'DEFLATE'
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
function writePptxChartSeriesAnalysis(document, chartNode, chart) {
|
|
735
|
+
const seriesNodes = directChildren(chartNode, 'ser');
|
|
736
|
+
if (seriesNodes.length !== chart.series.length) throw new Error(`PPTX chart export produced ${seriesNodes.length} native series for ${chart.series.length} editable series.`);
|
|
737
|
+
for (const [seriesIndex, seriesNode] of seriesNodes.entries()){
|
|
738
|
+
for (const name of [
|
|
739
|
+
'trendline',
|
|
740
|
+
'errBars'
|
|
741
|
+
])for (const child of directChildren(seriesNode, name))child.remove();
|
|
742
|
+
const series = chart.series[seriesIndex];
|
|
743
|
+
const anchor = directChildren(seriesNode).find((child)=>[
|
|
744
|
+
'cat',
|
|
745
|
+
'val',
|
|
746
|
+
'xVal',
|
|
747
|
+
'yVal',
|
|
748
|
+
'bubbleSize',
|
|
749
|
+
'smooth',
|
|
750
|
+
'extLst'
|
|
751
|
+
].includes(child.localName)) ?? null;
|
|
752
|
+
if (workSpreadsheetChartSupportsSeriesAnalysis(chart) && workSpreadsheetChartSupportsTrendlines(chart.type)) for (const source of series.trendlines ?? [])seriesNode.insertBefore(createTrendlineElement(document, seriesNode, source), anchor);
|
|
753
|
+
if (workSpreadsheetChartSupportsSeriesAnalysis(chart) && workSpreadsheetChartSupportsErrorBars(chart.type)) {
|
|
754
|
+
const directions = new Set();
|
|
755
|
+
for (const source of series.errorBars ?? []){
|
|
756
|
+
const errorBars = normalizeWorkSpreadsheetErrorBars(source, chart.type);
|
|
757
|
+
if ('x' !== errorBars.direction || workSpreadsheetChartUsesNumericXAxis(chart.type)) {
|
|
758
|
+
if (!directions.has(errorBars.direction)) {
|
|
759
|
+
directions.add(errorBars.direction);
|
|
760
|
+
seriesNode.insertBefore(createErrorBarsElement(document, seriesNode, errorBars), anchor);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
function readTrendlineDiagnostics(node, diagnostics) {
|
|
768
|
+
if (directChild(node, 'trendlineLbl')) diagnostics.push({
|
|
769
|
+
code: 'pptx.chart.trendline-label',
|
|
770
|
+
message: 'Manual trendline-label positioning and formatting were normalized to the editable equation and R-squared display.'
|
|
771
|
+
});
|
|
772
|
+
if ([
|
|
773
|
+
'spPr',
|
|
774
|
+
'extLst'
|
|
775
|
+
].some((name)=>directChildren(node, name).length > 0)) diagnostics.push({
|
|
776
|
+
code: 'pptx.chart.trendline-format',
|
|
777
|
+
message: 'Advanced trendline styling and extensions are normalized by the editable chart model.'
|
|
778
|
+
});
|
|
779
|
+
const type = attribute(directChild(node, 'trendlineType') ?? node, 'val');
|
|
780
|
+
const parameter = 'poly' === type ? numericSetting(node, 'order') : 'movingAvg' === type ? numericSetting(node, 'period') : void 0;
|
|
781
|
+
const parameterInvalid = 'poly' === type && (void 0 === parameter || parameter < 2 || parameter > 6 || !Number.isInteger(parameter)) || 'movingAvg' === type && (void 0 === parameter || parameter < 2 || parameter > 255 || !Number.isInteger(parameter));
|
|
782
|
+
const forecastInvalid = [
|
|
783
|
+
'forward',
|
|
784
|
+
'backward'
|
|
785
|
+
].some((name)=>{
|
|
786
|
+
const value = numericSetting(node, name);
|
|
787
|
+
return void 0 !== directChild(node, name) && (void 0 === value || value < 0);
|
|
788
|
+
});
|
|
789
|
+
if (parameterInvalid || forecastInvalid) diagnostics.push({
|
|
790
|
+
code: 'pptx.chart.trendline-parameter',
|
|
791
|
+
message: 'Trendline order, period, or forecast values were normalized to the editable range.'
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
function readErrorBarDiagnostics(node, errorBars, diagnostics) {
|
|
795
|
+
if ([
|
|
796
|
+
'spPr',
|
|
797
|
+
'extLst'
|
|
798
|
+
].some((name)=>directChildren(node, name).length > 0)) diagnostics.push({
|
|
799
|
+
code: 'pptx.chart.error-bars-format',
|
|
800
|
+
message: 'Advanced error-bar styling and extensions are normalized by the editable chart model.'
|
|
801
|
+
});
|
|
802
|
+
const incompatibleCustomSource = 'custom' === errorBars.valueType && ('plus' === errorBars.barType && directChild(node, 'minus') || 'minus' === errorBars.barType && directChild(node, 'plus'));
|
|
803
|
+
const value = numericSetting(node, 'val');
|
|
804
|
+
const invalidValue = void 0 !== directChild(node, 'val') && (void 0 === value || value < 0) && 'standardError' !== errorBars.valueType && 'custom' !== errorBars.valueType;
|
|
805
|
+
if (incompatibleCustomSource || invalidValue) diagnostics.push({
|
|
806
|
+
code: 'pptx.chart.error-bars-value',
|
|
807
|
+
message: 'Error-bar values or custom sources were normalized to the editable direction and non-negative range.'
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
function createTrendlineElement(document, parent, source) {
|
|
811
|
+
const trendline = normalizeWorkSpreadsheetTrendline(source);
|
|
812
|
+
const container = createChartElement(document, parent, 'trendline');
|
|
813
|
+
if (trendline.name) appendTextElement(document, container, 'name', trendline.name);
|
|
814
|
+
appendSetting(document, container, 'trendlineType', trendlineTypeValue(trendline.type));
|
|
815
|
+
if ('polynomial' === trendline.type) appendSetting(document, container, 'order', trendline.order ?? 2);
|
|
816
|
+
if ('movingAverage' === trendline.type) appendSetting(document, container, 'period', trendline.period ?? 2);
|
|
817
|
+
if (trendline.forward) appendSetting(document, container, 'forward', trendline.forward);
|
|
818
|
+
if (trendline.backward) appendSetting(document, container, 'backward', trendline.backward);
|
|
819
|
+
if (void 0 !== trendline.intercept) appendSetting(document, container, 'intercept', trendline.intercept);
|
|
820
|
+
if (trendline.displayRSquared) appendSetting(document, container, 'dispRSq', 1);
|
|
821
|
+
if (trendline.displayEquation) appendSetting(document, container, 'dispEq', 1);
|
|
822
|
+
return container;
|
|
823
|
+
}
|
|
824
|
+
function createErrorBarsElement(document, parent, errorBars) {
|
|
825
|
+
const container = createChartElement(document, parent, 'errBars');
|
|
826
|
+
appendSetting(document, container, 'errDir', errorBars.direction);
|
|
827
|
+
appendSetting(document, container, 'errBarType', errorBars.barType);
|
|
828
|
+
appendSetting(document, container, 'errValType', errorBarValueType(errorBars.valueType));
|
|
829
|
+
if (false === errorBars.showEndCaps) appendSetting(document, container, 'noEndCap', 1);
|
|
830
|
+
if ('custom' === errorBars.valueType) {
|
|
831
|
+
if ('minus' !== errorBars.barType) appendCustomErrorSource(document, container, 'plus', errorBars.plusReference, errorBars.plusValues);
|
|
832
|
+
if ('plus' !== errorBars.barType) appendCustomErrorSource(document, container, 'minus', errorBars.minusReference, errorBars.minusValues);
|
|
833
|
+
} else if ('fixedValue' === errorBars.valueType || 'percentage' === errorBars.valueType || 'standardDeviation' === errorBars.valueType) appendSetting(document, container, 'val', errorBars.value ?? ('percentage' === errorBars.valueType ? 5 : 1));
|
|
834
|
+
return container;
|
|
835
|
+
}
|
|
836
|
+
function appendCustomErrorSource(document, parent, localName, reference, values) {
|
|
837
|
+
if (!reference?.trim() && !values?.length) return;
|
|
838
|
+
const container = work_pptx_chart_series_analysis_appendChartElement(document, parent, localName);
|
|
839
|
+
if (reference?.trim()) {
|
|
840
|
+
const numberReference = work_pptx_chart_series_analysis_appendChartElement(document, container, 'numRef');
|
|
841
|
+
appendTextElement(document, numberReference, 'f', reference.trim().replace(/^=/, ''));
|
|
842
|
+
if (values?.length) appendNumberCollection(document, numberReference, 'numCache', values);
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
appendNumberCollection(document, container, 'numLit', values ?? []);
|
|
846
|
+
}
|
|
847
|
+
function appendNumberCollection(document, parent, localName, values) {
|
|
848
|
+
const collection = work_pptx_chart_series_analysis_appendChartElement(document, parent, localName);
|
|
849
|
+
appendTextElement(document, collection, 'formatCode', 'General');
|
|
850
|
+
appendSetting(document, collection, 'ptCount', values.length);
|
|
851
|
+
for (const [index, value] of values.entries()){
|
|
852
|
+
const point = appendSetting(document, collection, 'pt', index, 'idx');
|
|
853
|
+
appendTextElement(document, point, 'v', String(finiteNumber(value)));
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
function appendSetting(document, parent, localName, value, attributeName = 'val') {
|
|
857
|
+
const element = work_pptx_chart_series_analysis_appendChartElement(document, parent, localName);
|
|
858
|
+
element.setAttribute(attributeName, String(value));
|
|
859
|
+
return element;
|
|
860
|
+
}
|
|
861
|
+
function appendTextElement(document, parent, localName, value) {
|
|
862
|
+
const element = work_pptx_chart_series_analysis_appendChartElement(document, parent, localName);
|
|
863
|
+
element.textContent = value;
|
|
864
|
+
return element;
|
|
865
|
+
}
|
|
866
|
+
function work_pptx_chart_series_analysis_appendChartElement(document, parent, localName) {
|
|
867
|
+
const prefix = xmlNamespacePrefix(parent, parent.namespaceURI) ?? parent.prefix ?? 'c';
|
|
868
|
+
const element = document.createElementNS(parent.namespaceURI, `${prefix}:${localName}`);
|
|
869
|
+
parent.append(element);
|
|
870
|
+
return element;
|
|
871
|
+
}
|
|
872
|
+
function createChartElement(document, parent, localName) {
|
|
873
|
+
const prefix = xmlNamespacePrefix(parent, parent.namespaceURI) ?? parent.prefix ?? 'c';
|
|
874
|
+
return document.createElementNS(parent.namespaceURI, `${prefix}:${localName}`);
|
|
875
|
+
}
|
|
876
|
+
function trendlineTypeValue(type) {
|
|
877
|
+
if ('exponential' === type) return 'exp';
|
|
878
|
+
if ('logarithmic' === type) return 'log';
|
|
879
|
+
if ('polynomial' === type) return 'poly';
|
|
880
|
+
if ('movingAverage' === type) return 'movingAvg';
|
|
881
|
+
return type;
|
|
882
|
+
}
|
|
883
|
+
function errorBarValueType(type) {
|
|
884
|
+
if ('fixedValue' === type) return 'fixedVal';
|
|
885
|
+
if ('standardDeviation' === type) return 'stdDev';
|
|
886
|
+
if ('standardError' === type) return 'stdErr';
|
|
887
|
+
if ('custom' === type) return 'cust';
|
|
888
|
+
return 'percentage';
|
|
889
|
+
}
|
|
890
|
+
function chartHasSeriesAnalysis(chart) {
|
|
891
|
+
return workSpreadsheetChartSupportsSeriesAnalysis(chart) && chart.series.some((series)=>series.trendlines?.length || series.errorBars?.length);
|
|
892
|
+
}
|
|
893
|
+
function numericSetting(parent, localName) {
|
|
894
|
+
const element = directChild(parent, localName);
|
|
895
|
+
if (!element) return;
|
|
896
|
+
const value = Number(attribute(element, 'val'));
|
|
897
|
+
return Number.isFinite(value) ? value : void 0;
|
|
898
|
+
}
|
|
899
|
+
function finiteNumber(value) {
|
|
900
|
+
const number = Number(value);
|
|
901
|
+
return Number.isFinite(number) ? number : 0;
|
|
902
|
+
}
|
|
903
|
+
function work_pptx_chart_series_analysis_chartPartNumber(path) {
|
|
904
|
+
return Number(/chart(\d+)\.xml$/.exec(path)?.[1] ?? Number.MAX_SAFE_INTEGER);
|
|
905
|
+
}
|
|
906
|
+
const EFFECT_TYPES = new Set([
|
|
907
|
+
'fade',
|
|
908
|
+
'push',
|
|
909
|
+
'wipe',
|
|
910
|
+
'split',
|
|
911
|
+
'cut'
|
|
912
|
+
]);
|
|
913
|
+
const CARDINAL_DIRECTIONS = {
|
|
914
|
+
l: 'left',
|
|
915
|
+
r: 'right',
|
|
916
|
+
u: 'up',
|
|
917
|
+
d: 'down'
|
|
918
|
+
};
|
|
919
|
+
const OOXML_DIRECTIONS = {
|
|
920
|
+
left: 'l',
|
|
921
|
+
right: 'r',
|
|
922
|
+
up: 'u',
|
|
923
|
+
down: 'd',
|
|
924
|
+
in: 'in',
|
|
925
|
+
out: 'out'
|
|
926
|
+
};
|
|
927
|
+
function readPptxTransition(document) {
|
|
928
|
+
const element = directChild(document.documentElement, 'transition');
|
|
929
|
+
if (!element) return {
|
|
930
|
+
present: false,
|
|
931
|
+
diagnostics: []
|
|
932
|
+
};
|
|
933
|
+
const diagnostics = [];
|
|
934
|
+
if (directChild(element, 'sndAc')) diagnostics.push({
|
|
935
|
+
code: 'pptx.transition.sound',
|
|
936
|
+
message: 'Transition sounds remain in the original PPTX only.'
|
|
937
|
+
});
|
|
938
|
+
const effect = directChildren(element).find((child)=>![
|
|
939
|
+
'sndAc',
|
|
940
|
+
'extLst'
|
|
941
|
+
].includes(child.localName));
|
|
942
|
+
if (!effect || !EFFECT_TYPES.has(effect.localName)) {
|
|
943
|
+
diagnostics.push({
|
|
944
|
+
code: 'pptx.transition.type',
|
|
945
|
+
message: effect ? `The “${effect.localName}” slide transition remains in the original PPTX only.` : 'The source slide has a transition container without a supported effect.'
|
|
946
|
+
});
|
|
947
|
+
return {
|
|
948
|
+
present: true,
|
|
949
|
+
diagnostics
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
const base = createWorkSlideTransition(effect.localName);
|
|
953
|
+
const transition = {
|
|
954
|
+
...base,
|
|
955
|
+
speed: readSpeed(element, diagnostics),
|
|
956
|
+
advanceOnClick: readBoolean(attribute(element, 'advClick'), true)
|
|
957
|
+
};
|
|
958
|
+
const advanceAfterMs = nonnegativeInteger(attribute(element, 'advTm'));
|
|
959
|
+
if (void 0 !== advanceAfterMs) transition.advanceAfterMs = advanceAfterMs;
|
|
960
|
+
else if (null !== attribute(element, 'advTm')) diagnostics.push({
|
|
961
|
+
code: 'pptx.transition.timing',
|
|
962
|
+
message: 'An invalid automatic-advance delay was ignored.'
|
|
963
|
+
});
|
|
964
|
+
if ('push' === transition.type || 'wipe' === transition.type) transition.direction = CARDINAL_DIRECTIONS[attribute(effect, 'dir') ?? ''] ?? 'left';
|
|
965
|
+
if ('split' === transition.type) {
|
|
966
|
+
transition.direction = 'in' === attribute(effect, 'dir') ? 'in' : 'out';
|
|
967
|
+
transition.orientation = 'vert' === attribute(effect, 'orient') ? 'vertical' : 'horizontal';
|
|
968
|
+
}
|
|
969
|
+
if (readBoolean(attribute(effect, 'thruBlk'), false)) diagnostics.push({
|
|
970
|
+
code: 'pptx.transition.through-black',
|
|
971
|
+
message: 'The through-black transition option is normalized to the basic effect.'
|
|
972
|
+
});
|
|
973
|
+
return {
|
|
974
|
+
present: true,
|
|
975
|
+
transition,
|
|
976
|
+
diagnostics
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
async function patchPptxTransitions(buffer, slides) {
|
|
980
|
+
if (!slides.some((slide)=>slide.transition)) return buffer;
|
|
981
|
+
const archive = await jszip.loadAsync(buffer);
|
|
982
|
+
for (const [index, slide] of slides.entries()){
|
|
983
|
+
const path = `ppt/slides/slide${index + 1}.xml`;
|
|
984
|
+
const entry = archive.file(path);
|
|
985
|
+
if (!entry) continue;
|
|
986
|
+
const document = parseXml(await entry.async('text'), path);
|
|
987
|
+
writePptxTransition(document, slide.transition);
|
|
988
|
+
archive.file(path, new XMLSerializer().serializeToString(document));
|
|
989
|
+
}
|
|
990
|
+
return archive.generateAsync({
|
|
991
|
+
type: 'arraybuffer',
|
|
992
|
+
compression: 'DEFLATE'
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
function writePptxTransition(document, transition) {
|
|
996
|
+
const root = document.documentElement;
|
|
997
|
+
directChild(root, 'transition')?.remove();
|
|
998
|
+
if (!transition) return;
|
|
999
|
+
const namespace = root.namespaceURI;
|
|
1000
|
+
const prefix = xmlNamespacePrefix(root, namespace) ?? root.prefix ?? 'p';
|
|
1001
|
+
const element = document.createElementNS(namespace, `${prefix}:transition`);
|
|
1002
|
+
element.setAttribute('spd', 'medium' === transition.speed ? 'med' : transition.speed);
|
|
1003
|
+
element.setAttribute('advClick', transition.advanceOnClick ? '1' : '0');
|
|
1004
|
+
if (void 0 !== transition.advanceAfterMs) element.setAttribute('advTm', String(Math.max(0, Math.trunc(transition.advanceAfterMs))));
|
|
1005
|
+
const effect = document.createElementNS(namespace, `${prefix}:${transition.type}`);
|
|
1006
|
+
if ('push' === transition.type || 'wipe' === transition.type) effect.setAttribute('dir', OOXML_DIRECTIONS[transition.direction ?? 'left'] ?? 'l');
|
|
1007
|
+
if ('split' === transition.type) {
|
|
1008
|
+
effect.setAttribute('orient', 'vertical' === transition.orientation ? 'vert' : 'horz');
|
|
1009
|
+
effect.setAttribute('dir', 'in' === transition.direction ? 'in' : 'out');
|
|
1010
|
+
}
|
|
1011
|
+
element.append(effect);
|
|
1012
|
+
const anchor = directChildren(root).find((child)=>[
|
|
1013
|
+
'timing',
|
|
1014
|
+
'extLst'
|
|
1015
|
+
].includes(child.localName)) ?? null;
|
|
1016
|
+
root.insertBefore(element, anchor);
|
|
1017
|
+
}
|
|
1018
|
+
function readSpeed(element, diagnostics) {
|
|
1019
|
+
const value = attribute(element, 'spd');
|
|
1020
|
+
if ('fast' === value || 'slow' === value) return value;
|
|
1021
|
+
if (null === value || 'med' === value) return 'medium';
|
|
1022
|
+
diagnostics.push({
|
|
1023
|
+
code: 'pptx.transition.speed',
|
|
1024
|
+
message: `The transition speed “${value}” was normalized to medium.`
|
|
1025
|
+
});
|
|
1026
|
+
return 'medium';
|
|
1027
|
+
}
|
|
1028
|
+
function readBoolean(value, fallback) {
|
|
1029
|
+
if (null === value) return fallback;
|
|
1030
|
+
return '1' === value || 'true' === value.toLowerCase();
|
|
1031
|
+
}
|
|
1032
|
+
function nonnegativeInteger(value) {
|
|
1033
|
+
if (null === value) return;
|
|
1034
|
+
const number = Number(value);
|
|
1035
|
+
return Number.isSafeInteger(number) && number >= 0 ? number : void 0;
|
|
1036
|
+
}
|
|
1037
|
+
export { loadPptxCommentAuthors, patchPptxChartDataLabels, patchPptxChartLayoutAndSeriesStyles, patchPptxChartSeriesAnalysis, patchPptxComments, patchPptxTransitions, readPptxChartDataLabels, readPptxChartLayoutAndSeriesStyles, readPptxChartSeriesAnalysis, readPptxSlideComments, readPptxTransition };
|