ooxml-core 1.12.2 → 1.14.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/dist/PptxHandler-5YP75BPO.cjs +12 -0
- package/dist/PptxHandler-GT5Q66TG.mjs +3 -0
- package/dist/{PptxHandler-FIN6XDTI.mjs → PptxHandler-KNBFECUE.mjs} +3 -3
- package/dist/PresentationBuilder-5DCCFHWJ.mjs +7 -0
- package/dist/PresentationBuilder-CVM6LJ7L.mjs +3 -0
- package/dist/PresentationBuilder-II7C4A3R.cjs +20 -0
- package/dist/automation/docx.d.ts +18 -0
- package/dist/automation/docx.d.ts.map +1 -1
- package/dist/automation/index.cjs +22549 -8585
- package/dist/automation/index.d.ts +1 -0
- package/dist/automation/index.d.ts.map +1 -1
- package/dist/automation/index.mjs +22546 -8586
- package/dist/automation/node.cjs +66 -6
- package/dist/automation/node.d.ts +10 -0
- package/dist/automation/node.d.ts.map +1 -1
- package/dist/automation/node.mjs +67 -7
- package/dist/automation/outline.d.ts +29 -0
- package/dist/automation/outline.d.ts.map +1 -0
- package/dist/automation/xlsx.d.ts +21 -0
- package/dist/automation/xlsx.d.ts.map +1 -1
- package/dist/chart/auto-title.d.ts +31 -0
- package/dist/chart/auto-title.d.ts.map +1 -0
- package/dist/chart/axis-format.d.ts +13 -0
- package/dist/chart/axis-format.d.ts.map +1 -0
- package/dist/chart/bubble-radius.d.ts +30 -0
- package/dist/chart/bubble-radius.d.ts.map +1 -0
- package/dist/chart/error-bar-amount.d.ts +22 -0
- package/dist/chart/error-bar-amount.d.ts.map +1 -0
- package/dist/chart/hierarchy.d.ts +69 -0
- package/dist/chart/hierarchy.d.ts.map +1 -0
- package/dist/chart/index.cjs +2377 -527
- package/dist/chart/index.d.ts +12 -0
- package/dist/chart/index.d.ts.map +1 -1
- package/dist/chart/index.mjs +2338 -528
- package/dist/chart/model-analysis.d.ts +66 -0
- package/dist/chart/model-analysis.d.ts.map +1 -0
- package/dist/chart/model-series.d.ts +5 -0
- package/dist/chart/model-series.d.ts.map +1 -1
- package/dist/chart/number-format-pattern.d.ts +35 -0
- package/dist/chart/number-format-pattern.d.ts.map +1 -0
- package/dist/chart/number-format.d.ts +21 -0
- package/dist/chart/number-format.d.ts.map +1 -0
- package/dist/chart/parse-analysis.d.ts +13 -0
- package/dist/chart/parse-analysis.d.ts.map +1 -0
- package/dist/chart/parse-series.d.ts +1 -1
- package/dist/chart/parse-series.d.ts.map +1 -1
- package/dist/chart/parse-util.d.ts +2 -0
- package/dist/chart/parse-util.d.ts.map +1 -1
- package/dist/chart/render/chart-svg-analysis.d.ts +7 -0
- package/dist/chart/render/chart-svg-analysis.d.ts.map +1 -0
- package/dist/chart/render/chart-svg-bars.d.ts +5 -0
- package/dist/chart/render/chart-svg-bars.d.ts.map +1 -1
- package/dist/chart/render/chart-svg-cartesian.d.ts +7 -2
- package/dist/chart/render/chart-svg-cartesian.d.ts.map +1 -1
- package/dist/chart/render/chart-svg-hierarchy.d.ts +5 -0
- package/dist/chart/render/chart-svg-hierarchy.d.ts.map +1 -0
- package/dist/chart/render/chart-svg-plots.d.ts +5 -0
- package/dist/chart/render/chart-svg-plots.d.ts.map +1 -0
- package/dist/chart/render/chart-svg-stock.d.ts +4 -0
- package/dist/chart/render/chart-svg-stock.d.ts.map +1 -0
- package/dist/chart/render/chart-svg-waterfall.d.ts +4 -0
- package/dist/chart/render/chart-svg-waterfall.d.ts.map +1 -0
- package/dist/chart/render/chart-svg-xy.d.ts +4 -0
- package/dist/chart/render/chart-svg-xy.d.ts.map +1 -0
- package/dist/chart/render/chart-svg.d.ts +1 -1
- package/dist/chart/render/chart-svg.d.ts.map +1 -1
- package/dist/chart/render/chart-value-axis.d.ts +6 -1
- package/dist/chart/render/chart-value-axis.d.ts.map +1 -1
- package/dist/chart/render/chart-view-analysis.d.ts +30 -0
- package/dist/chart/render/chart-view-analysis.d.ts.map +1 -0
- package/dist/chart/render/chart-view-ex.d.ts +24 -0
- package/dist/chart/render/chart-view-ex.d.ts.map +1 -0
- package/dist/chart/render/chart-view-families.d.ts +10 -0
- package/dist/chart/render/chart-view-families.d.ts.map +1 -0
- package/dist/chart/render/chart-view-series.d.ts +36 -0
- package/dist/chart/render/chart-view-series.d.ts.map +1 -0
- package/dist/chart/render/chart-view-stock.d.ts +23 -0
- package/dist/chart/render/chart-view-stock.d.ts.map +1 -0
- package/dist/chart/render/chart-view.d.ts +49 -18
- package/dist/chart/render/chart-view.d.ts.map +1 -1
- package/dist/chart/render/index.d.ts +2 -0
- package/dist/chart/render/index.d.ts.map +1 -1
- package/dist/chart/render/render-space.d.ts +6 -1
- package/dist/chart/render/render-space.d.ts.map +1 -1
- package/dist/chart/render/summary-analysis.d.ts +11 -0
- package/dist/chart/render/summary-analysis.d.ts.map +1 -0
- package/dist/chart/render/summary-from-chartex.d.ts +11 -0
- package/dist/chart/render/summary-from-chartex.d.ts.map +1 -0
- package/dist/chart/render/summary-from-space.d.ts.map +1 -1
- package/dist/chart/render/summary.d.ts +86 -3
- package/dist/chart/render/summary.d.ts.map +1 -1
- package/dist/chart/stock-candles.d.ts +72 -0
- package/dist/chart/stock-candles.d.ts.map +1 -0
- package/dist/chart/style-palette.d.ts +29 -0
- package/dist/chart/style-palette.d.ts.map +1 -0
- package/dist/chart/sunburst-arcs.d.ts +41 -0
- package/dist/chart/sunburst-arcs.d.ts.map +1 -0
- package/dist/chart/trendline-fit.d.ts +39 -0
- package/dist/chart/trendline-fit.d.ts.map +1 -0
- package/dist/chart/waterfall.d.ts +31 -0
- package/dist/chart/waterfall.d.ts.map +1 -0
- package/dist/chart/write-analysis.d.ts +12 -0
- package/dist/chart/write-analysis.d.ts.map +1 -0
- package/dist/chart/write-series.d.ts.map +1 -1
- package/dist/{chunk-G5PQKHCG.mjs → chunk-2D4IFQ5M.mjs} +1 -1
- package/dist/{chunk-UAY26XOI.mjs → chunk-2EBMHIGJ.mjs} +1303 -994
- package/dist/{chunk-TVE6UIJF.mjs → chunk-4WZLFUUA.mjs} +54 -13
- package/dist/{chunk-H2FRDUNV.mjs → chunk-54ASP65T.mjs} +868 -585
- package/dist/chunk-M4XLF4R7.mjs +387 -0
- package/dist/{chunk-O6NIA4NG.mjs → chunk-ORH32TO3.mjs} +5798 -5742
- package/dist/{chunk-B2JBBAEQ.mjs → chunk-TNNXOW2O.mjs} +1 -1
- package/dist/{chunk-IT3U6QD6.cjs → chunk-TQE7FFNT.cjs} +6754 -6695
- package/dist/{chunk-7QZGRB3T.cjs → chunk-X7MGZQ6C.cjs} +1321 -995
- package/dist/{chunk-6DELVMYB.mjs → chunk-XGXIS4PN.mjs} +12316 -12260
- package/dist/crypto/decrypt.d.ts +17 -3
- package/dist/crypto/decrypt.d.ts.map +1 -1
- package/dist/crypto/encryption-info.d.ts.map +1 -1
- package/dist/crypto/index.cjs +252 -78
- package/dist/crypto/index.d.ts +19 -4
- package/dist/crypto/index.d.ts.map +1 -1
- package/dist/crypto/index.mjs +252 -79
- package/dist/crypto/key-derivation.d.ts +2 -3
- package/dist/crypto/key-derivation.d.ts.map +1 -1
- package/dist/crypto/validate.d.ts +22 -0
- package/dist/crypto/validate.d.ts.map +1 -0
- package/dist/diagram/engine/layout-def-parse.d.ts.map +1 -1
- package/dist/diagram/engine/pres-tree.d.ts.map +1 -1
- package/dist/diagram/index.cjs +102 -52
- package/dist/diagram/index.mjs +102 -52
- package/dist/digest/index.cjs +23 -11
- package/dist/digest/index.d.ts +2 -1
- package/dist/digest/index.d.ts.map +1 -1
- package/dist/digest/index.mjs +21 -12
- package/dist/digest/password-hash.d.ts +19 -5
- package/dist/digest/password-hash.d.ts.map +1 -1
- package/dist/digest/timing-safe.d.ts +7 -0
- package/dist/digest/timing-safe.d.ts.map +1 -0
- package/dist/docx/block-parser.d.ts.map +1 -1
- package/dist/docx/chart-paint.d.ts.map +1 -1
- package/dist/docx/chart.d.ts +10 -2
- package/dist/docx/chart.d.ts.map +1 -1
- package/dist/docx/content-control-edit.d.ts +26 -0
- package/dist/docx/content-control-edit.d.ts.map +1 -0
- package/dist/docx/content-control-model.d.ts +51 -0
- package/dist/docx/content-control-model.d.ts.map +1 -0
- package/dist/docx/content-control.d.ts +9 -0
- package/dist/docx/content-control.d.ts.map +1 -0
- package/dist/docx/default-styles.d.ts.map +1 -1
- package/dist/docx/drawing.d.ts.map +1 -1
- package/dist/docx/embedded.cjs +9932 -935
- package/dist/docx/embedded.mjs +9932 -935
- package/dist/docx/equation.d.ts +7 -3
- package/dist/docx/equation.d.ts.map +1 -1
- package/dist/docx/index.cjs +14117 -1513
- package/dist/docx/index.d.ts +6 -0
- package/dist/docx/index.d.ts.map +1 -1
- package/dist/docx/index.mjs +14093 -1514
- package/dist/docx/inline-model.d.ts +3 -0
- package/dist/docx/inline-model.d.ts.map +1 -1
- package/dist/docx/layout/adapt-floats.d.ts +3 -3
- package/dist/docx/layout/adapt-floats.d.ts.map +1 -1
- package/dist/docx/layout/adapter.d.ts.map +1 -1
- package/dist/docx/layout/equation-object.d.ts +7 -0
- package/dist/docx/layout/equation-object.d.ts.map +1 -0
- package/dist/docx/layout/floats.d.ts +8 -0
- package/dist/docx/layout/floats.d.ts.map +1 -1
- package/dist/docx/layout/incremental-layout.d.ts +39 -0
- package/dist/docx/layout/incremental-layout.d.ts.map +1 -0
- package/dist/docx/layout/index.cjs +14177 -1707
- package/dist/docx/layout/index.d.ts +2 -2
- package/dist/docx/layout/index.d.ts.map +1 -1
- package/dist/docx/layout/index.mjs +14176 -1708
- package/dist/docx/layout/input.d.ts +4 -0
- package/dist/docx/layout/input.d.ts.map +1 -1
- package/dist/docx/layout/layout-session.d.ts +13 -2
- package/dist/docx/layout/layout-session.d.ts.map +1 -1
- package/dist/docx/layout/layout.d.ts +1 -1
- package/dist/docx/layout/layout.d.ts.map +1 -1
- package/dist/docx/layout/line-metrics.d.ts.map +1 -1
- package/dist/docx/layout/page-cursor.d.ts +1 -1
- package/dist/docx/layout/page-cursor.d.ts.map +1 -1
- package/dist/docx/layout/page-fields.d.ts +3 -1
- package/dist/docx/layout/page-fields.d.ts.map +1 -1
- package/dist/docx/layout/result.d.ts +14 -1
- package/dist/docx/layout/result.d.ts.map +1 -1
- package/dist/docx/layout/section-flow.d.ts +11 -1
- package/dist/docx/layout/section-flow.d.ts.map +1 -1
- package/dist/docx/ligatures.d.ts +2 -0
- package/dist/docx/ligatures.d.ts.map +1 -1
- package/dist/docx/load/index.cjs +12709 -3590
- package/dist/docx/load/index.mjs +12709 -3590
- package/dist/docx/model-paragraph.d.ts +3 -0
- package/dist/docx/model-paragraph.d.ts.map +1 -1
- package/dist/docx/model-run.d.ts +3 -0
- package/dist/docx/model-run.d.ts.map +1 -1
- package/dist/docx/model.d.ts +3 -0
- package/dist/docx/model.d.ts.map +1 -1
- package/dist/docx/numbering-parse.d.ts.map +1 -1
- package/dist/docx/numbering-text.d.ts.map +1 -1
- package/dist/docx/package-limits.d.ts +6 -0
- package/dist/docx/package-limits.d.ts.map +1 -0
- package/dist/docx/parse-content-control.d.ts +28 -0
- package/dist/docx/parse-content-control.d.ts.map +1 -0
- package/dist/docx/parse-table.d.ts.map +1 -1
- package/dist/docx/parse.d.ts.map +1 -1
- package/dist/docx/save.d.ts.map +1 -1
- package/dist/docx/shape-model.d.ts +31 -0
- package/dist/docx/shape-model.d.ts.map +1 -0
- package/dist/docx/shape-palette.d.ts +19 -0
- package/dist/docx/shape-palette.d.ts.map +1 -0
- package/dist/docx/shape-parse.d.ts +16 -0
- package/dist/docx/shape-parse.d.ts.map +1 -0
- package/dist/docx/shape-svg.d.ts +20 -0
- package/dist/docx/shape-svg.d.ts.map +1 -0
- package/dist/docx/table-model.d.ts +4 -0
- package/dist/docx/table-model.d.ts.map +1 -1
- package/dist/docx/ui/content-control-commands.d.ts +37 -0
- package/dist/docx/ui/content-control-commands.d.ts.map +1 -0
- package/dist/docx/ui/content-control-guard.d.ts +8 -0
- package/dist/docx/ui/content-control-guard.d.ts.map +1 -0
- package/dist/docx/ui/content-control-spans.d.ts +19 -0
- package/dist/docx/ui/content-control-spans.d.ts.map +1 -0
- package/dist/docx/ui/index.cjs +3132 -506
- package/dist/docx/ui/index.d.ts +3 -0
- package/dist/docx/ui/index.d.ts.map +1 -1
- package/dist/docx/ui/index.mjs +3117 -507
- package/dist/docx/ui/inline-content-schema.d.ts.map +1 -1
- package/dist/docx/ui/paragraph-attributes.d.ts.map +1 -1
- package/dist/docx/ui/ribbon-action-ids.d.ts +1 -1
- package/dist/docx/ui/ribbon-action-ids.d.ts.map +1 -1
- package/dist/docx/ui/run-adapter.d.ts.map +1 -1
- package/dist/docx/ui/run-compare.d.ts.map +1 -1
- package/dist/docx/ui/run-mark-properties.d.ts.map +1 -1
- package/dist/docx/ui/run-marks.d.ts.map +1 -1
- package/dist/docx/ui/schema-marks.d.ts +16 -1
- package/dist/docx/ui/schema-marks.d.ts.map +1 -1
- package/dist/docx/ui/table-structure-guard.d.ts.map +1 -1
- package/dist/docx/write-block-placement.d.ts +9 -0
- package/dist/docx/write-block-placement.d.ts.map +1 -0
- package/dist/docx/write-content-control.d.ts +12 -0
- package/dist/docx/write-content-control.d.ts.map +1 -0
- package/dist/docx/write-drawing.d.ts +2 -0
- package/dist/docx/write-drawing.d.ts.map +1 -1
- package/dist/docx/write-inline.d.ts.map +1 -1
- package/dist/docx/write-paragraph.d.ts.map +1 -1
- package/dist/docx/write-shape.d.ts +16 -0
- package/dist/docx/write-shape.d.ts.map +1 -0
- package/dist/docx/write-table.d.ts.map +1 -1
- package/dist/docx/write.d.ts.map +1 -1
- package/dist/drawingml/index.cjs +24 -0
- package/dist/drawingml/index.mjs +24 -0
- package/dist/geometry/index.cjs +63 -48
- package/dist/geometry/index.mjs +63 -48
- package/dist/geometry/preset-shape-definitions-table.d.ts.map +1 -1
- package/dist/i18n/index.cjs +266 -0
- package/dist/i18n/index.d.ts +1 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.mjs +265 -1
- package/dist/i18n/option-strings.d.ts +17 -0
- package/dist/i18n/option-strings.d.ts.map +1 -0
- package/dist/index.cjs +4558 -1579
- package/dist/index.mjs +4558 -1579
- package/dist/math/equation-gallery.d.ts +10 -0
- package/dist/math/equation-gallery.d.ts.map +1 -0
- package/dist/math/index.cjs +777 -139
- package/dist/math/index.d.ts +3 -0
- package/dist/math/index.d.ts.map +1 -1
- package/dist/math/index.mjs +772 -140
- package/dist/math/latex-omml-siblings.d.ts.map +1 -1
- package/dist/math/latex-to-omml.d.ts.map +1 -1
- package/dist/math/omml-box-grouped.d.ts +9 -0
- package/dist/math/omml-box-grouped.d.ts.map +1 -0
- package/dist/math/omml-box-layout.d.ts +15 -0
- package/dist/math/omml-box-layout.d.ts.map +1 -0
- package/dist/math/omml-box-structures.d.ts +7 -0
- package/dist/math/omml-box-structures.d.ts.map +1 -0
- package/dist/math/omml-box.d.ts +85 -0
- package/dist/math/omml-box.d.ts.map +1 -0
- package/dist/math/omml-dom.d.ts.map +1 -1
- package/dist/math/omml-mathml-converters.d.ts.map +1 -1
- package/dist/math/omml-svg.d.ts +14 -0
- package/dist/math/omml-svg.d.ts.map +1 -0
- package/dist/math/omml-to-xml.d.ts +10 -0
- package/dist/math/omml-to-xml.d.ts.map +1 -0
- package/dist/opc/embedded-packages.d.ts.map +1 -1
- package/dist/opc/index.cjs +257 -22
- package/dist/opc/index.d.ts +1 -0
- package/dist/opc/index.d.ts.map +1 -1
- package/dist/opc/index.mjs +251 -23
- package/dist/opc/package.d.ts.map +1 -1
- package/dist/opc/signature/detection.d.ts +22 -6
- package/dist/opc/signature/detection.d.ts.map +1 -1
- package/dist/opc/signature/index.d.ts +1 -1
- package/dist/opc/signature/index.d.ts.map +1 -1
- package/dist/opc/signature/xml-utils.d.ts.map +1 -1
- package/dist/opc/zip-limits.d.ts +52 -0
- package/dist/opc/zip-limits.d.ts.map +1 -0
- package/dist/pptx/automation/index.cjs +1848 -1320
- package/dist/pptx/automation/index.d.ts +4 -4
- package/dist/pptx/automation/index.mjs +6 -6
- package/dist/pptx/chunks/{elements-DmbzOhFu.d.ts → elements-tK7xnWeS.d.ts} +20 -9
- package/dist/pptx/chunks/elements-tK7xnWeS.d.ts.map +1 -0
- package/dist/pptx/chunks/{index-Cija6Dih.d.ts → index-BSpNQuvz.d.ts} +30 -5
- package/dist/pptx/chunks/{index-Cija6Dih.d.ts.map → index-BSpNQuvz.d.ts.map} +1 -1
- package/dist/pptx/chunks/{index-BmvOxbsh.d.ts → index-DS9Y4Ne3.d.ts} +25 -9
- package/dist/pptx/chunks/index-DS9Y4Ne3.d.ts.map +1 -0
- package/dist/pptx/chunks/inspection-status-DjiWd_Aa.d.ts.map +1 -1
- package/dist/pptx/chunks/{text-operations-sXxhsKDd.d.ts → text-operations-BdD_UQ11.d.ts} +2 -2
- package/dist/pptx/chunks/{text-operations-sXxhsKDd.d.ts.map → text-operations-BdD_UQ11.d.ts.map} +1 -1
- package/dist/pptx/cli/index.cjs +1795 -1275
- package/dist/pptx/cli/index.d.ts +1 -1
- package/dist/pptx/cli/index.mjs +5 -5
- package/dist/pptx/converter/index.cjs +80 -54
- package/dist/pptx/converter/index.d.ts +1 -1
- package/dist/pptx/converter/index.mjs +3 -3
- package/dist/pptx/editor/render/find-replace.cjs +14 -14
- package/dist/pptx/editor/render/find-replace.d.ts +2 -2
- package/dist/pptx/editor/render/find-replace.mjs +1 -1
- package/dist/pptx/editor/render/slide-operations.cjs +8 -8
- package/dist/pptx/editor/render/slide-operations.mjs +2 -2
- package/dist/pptx/editor/render/text-runs-style-patch.d.ts +1 -1
- package/dist/pptx/editor/render/text-style-scope.d.ts +1 -1
- package/dist/pptx/index.cjs +1117 -351
- package/dist/pptx/index.d.ts +5 -5
- package/dist/pptx/index.mjs +6 -6
- package/dist/pptx/signature-node/index.cjs +342 -65
- package/dist/pptx/signature-node/index.d.ts +12 -1
- package/dist/pptx/signature-node/index.d.ts.map +1 -1
- package/dist/pptx/signature-node/index.mjs +112 -52
- package/dist/teams/activity-feed.d.ts +19 -0
- package/dist/teams/activity-feed.d.ts.map +1 -0
- package/dist/teams/activity-state.d.ts +12 -0
- package/dist/teams/activity-state.d.ts.map +1 -0
- package/dist/teams/activity.d.ts +52 -0
- package/dist/teams/activity.d.ts.map +1 -0
- package/dist/teams/calendar.d.ts +57 -0
- package/dist/teams/calendar.d.ts.map +1 -0
- package/dist/teams/chat-actions.d.ts +20 -0
- package/dist/teams/chat-actions.d.ts.map +1 -0
- package/dist/teams/chat-rooms.d.ts +42 -0
- package/dist/teams/chat-rooms.d.ts.map +1 -0
- package/dist/teams/chat-view.d.ts +56 -0
- package/dist/teams/chat-view.d.ts.map +1 -0
- package/dist/teams/chat.d.ts +25 -3
- package/dist/teams/chat.d.ts.map +1 -1
- package/dist/teams/chats.d.ts +52 -0
- package/dist/teams/chats.d.ts.map +1 -0
- package/dist/teams/ics-timezone.d.ts +17 -0
- package/dist/teams/ics-timezone.d.ts.map +1 -0
- package/dist/teams/ics.d.ts +20 -0
- package/dist/teams/ics.d.ts.map +1 -0
- package/dist/teams/index.cjs +12462 -7011
- package/dist/teams/index.d.ts +25 -0
- package/dist/teams/index.d.ts.map +1 -1
- package/dist/teams/index.mjs +12349 -7012
- package/dist/teams/meeting-actions.d.ts +31 -0
- package/dist/teams/meeting-actions.d.ts.map +1 -0
- package/dist/teams/meeting-exceptions.d.ts +28 -0
- package/dist/teams/meeting-exceptions.d.ts.map +1 -0
- package/dist/teams/meeting-reminders.d.ts +13 -0
- package/dist/teams/meeting-reminders.d.ts.map +1 -0
- package/dist/teams/meetings.d.ts +71 -0
- package/dist/teams/meetings.d.ts.map +1 -0
- package/dist/teams/mention-text.d.ts +11 -0
- package/dist/teams/mention-text.d.ts.map +1 -0
- package/dist/teams/mentions.d.ts +68 -0
- package/dist/teams/mentions.d.ts.map +1 -0
- package/dist/teams/model.d.ts +7 -0
- package/dist/teams/model.d.ts.map +1 -1
- package/dist/teams/notifications.d.ts +21 -0
- package/dist/teams/notifications.d.ts.map +1 -0
- package/dist/teams/pins.d.ts +22 -0
- package/dist/teams/pins.d.ts.map +1 -0
- package/dist/teams/presence-controller.d.ts +39 -0
- package/dist/teams/presence-controller.d.ts.map +1 -0
- package/dist/teams/presence.d.ts +55 -0
- package/dist/teams/presence.d.ts.map +1 -0
- package/dist/teams/recurrence.d.ts +18 -0
- package/dist/teams/recurrence.d.ts.map +1 -0
- package/dist/teams/roster.d.ts +12 -0
- package/dist/teams/roster.d.ts.map +1 -0
- package/dist/teams/server-config.d.ts +23 -2
- package/dist/teams/server-config.d.ts.map +1 -1
- package/dist/teams/server-session.d.ts +19 -0
- package/dist/teams/server-session.d.ts.map +1 -0
- package/dist/teams/shared-chat.d.ts +83 -0
- package/dist/teams/shared-chat.d.ts.map +1 -0
- package/dist/teams/store.d.ts +79 -5
- package/dist/teams/store.d.ts.map +1 -1
- package/dist/teams/sync-transport.d.ts +12 -0
- package/dist/teams/sync-transport.d.ts.map +1 -0
- package/dist/teams/time-zone.d.ts +32 -0
- package/dist/teams/time-zone.d.ts.map +1 -0
- package/dist/teams/view.d.ts +8 -0
- package/dist/teams/view.d.ts.map +1 -1
- package/dist/teams/workspace.d.ts +23 -4
- package/dist/teams/workspace.d.ts.map +1 -1
- package/dist/visio/edit-connector-follow.d.ts +15 -0
- package/dist/visio/edit-connector-follow.d.ts.map +1 -0
- package/dist/visio/edit-connector-obstacles.d.ts +9 -3
- package/dist/visio/edit-connector-obstacles.d.ts.map +1 -1
- package/dist/visio/edit-connector-reroute.d.ts.map +1 -1
- package/dist/visio/edit-connector.d.ts.map +1 -1
- package/dist/visio/edit-master-add.d.ts +37 -0
- package/dist/visio/edit-master-add.d.ts.map +1 -0
- package/dist/visio/edit-master-drop.d.ts +6 -0
- package/dist/visio/edit-master-drop.d.ts.map +1 -1
- package/dist/visio/edit-recalculate-index.d.ts +5 -0
- package/dist/visio/edit-recalculate-index.d.ts.map +1 -1
- package/dist/visio/edit-recalculate-values.d.ts.map +1 -1
- package/dist/visio/edit-stencil-connector-layout.d.ts +2 -0
- package/dist/visio/edit-stencil-connector-layout.d.ts.map +1 -1
- package/dist/visio/edit-stencil-connector.d.ts +1 -0
- package/dist/visio/edit-stencil-connector.d.ts.map +1 -1
- package/dist/visio/edit-stencil-import.d.ts +10 -0
- package/dist/visio/edit-stencil-import.d.ts.map +1 -0
- package/dist/visio/edit-stencil-line.d.ts +29 -0
- package/dist/visio/edit-stencil-line.d.ts.map +1 -0
- package/dist/visio/edit-stencil-master.d.ts +3 -8
- package/dist/visio/edit-stencil-master.d.ts.map +1 -1
- package/dist/visio/edit.d.ts.map +1 -1
- package/dist/visio/formula-evaluate.d.ts.map +1 -1
- package/dist/visio/formula-math-functions.d.ts +11 -0
- package/dist/visio/formula-math-functions.d.ts.map +1 -0
- package/dist/visio/formula-text-functions.d.ts +23 -0
- package/dist/visio/formula-text-functions.d.ts.map +1 -0
- package/dist/visio/formula.d.ts.map +1 -1
- package/dist/visio/index.cjs +2552 -1833
- package/dist/visio/index.d.ts +1 -0
- package/dist/visio/index.d.ts.map +1 -1
- package/dist/visio/index.mjs +2552 -1834
- package/dist/visio/parser.d.ts +6 -0
- package/dist/visio/parser.d.ts.map +1 -1
- package/dist/visio/stencil-file.d.ts +14 -0
- package/dist/visio/stencil-file.d.ts.map +1 -0
- package/dist/visio/ui/index.cjs +2398 -1679
- package/dist/visio/ui/index.mjs +2398 -1680
- package/dist/visio/ui/master-drop.d.ts +10 -0
- package/dist/visio/ui/master-drop.d.ts.map +1 -1
- package/dist/xlsx/edit/cell-values.d.ts.map +1 -1
- package/dist/xlsx/edit/clipboard-html-parse.d.ts +4 -0
- package/dist/xlsx/edit/clipboard-html-parse.d.ts.map +1 -1
- package/dist/xlsx/edit/data-table.d.ts +38 -0
- package/dist/xlsx/edit/data-table.d.ts.map +1 -0
- package/dist/xlsx/edit/drawings.d.ts.map +1 -1
- package/dist/xlsx/edit/goal-seek.d.ts +30 -0
- package/dist/xlsx/edit/goal-seek.d.ts.map +1 -0
- package/dist/xlsx/edit/goal-solver.d.ts +20 -0
- package/dist/xlsx/edit/goal-solver.d.ts.map +1 -0
- package/dist/xlsx/edit/history.d.ts +1 -1
- package/dist/xlsx/edit/history.d.ts.map +1 -1
- package/dist/xlsx/edit/index.d.ts +5 -0
- package/dist/xlsx/edit/index.d.ts.map +1 -1
- package/dist/xlsx/edit/input-text.d.ts.map +1 -1
- package/dist/xlsx/edit/pivots.d.ts +2 -1
- package/dist/xlsx/edit/pivots.d.ts.map +1 -1
- package/dist/xlsx/edit/scenarios.d.ts +41 -0
- package/dist/xlsx/edit/scenarios.d.ts.map +1 -0
- package/dist/xlsx/edit/session.d.ts.map +1 -1
- package/dist/xlsx/edit/slicers.d.ts +34 -0
- package/dist/xlsx/edit/slicers.d.ts.map +1 -0
- package/dist/xlsx/edit/table-edits.d.ts.map +1 -1
- package/dist/xlsx/edit/timelines.d.ts +26 -0
- package/dist/xlsx/edit/timelines.d.ts.map +1 -0
- package/dist/xlsx/edit/types.d.ts +39 -0
- package/dist/xlsx/edit/types.d.ts.map +1 -1
- package/dist/xlsx/formula/context.d.ts +13 -0
- package/dist/xlsx/formula/context.d.ts.map +1 -1
- package/dist/xlsx/formula/engine.d.ts.map +1 -1
- package/dist/xlsx/formula/evaluator.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/amordegrc.d.ts +6 -0
- package/dist/xlsx/formula/functions/amordegrc.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/bahttext.d.ts +4 -0
- package/dist/xlsx/formula/functions/bahttext.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/bessel.d.ts +7 -0
- package/dist/xlsx/formula/functions/bessel.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/bonds.d.ts +3 -0
- package/dist/xlsx/formula/functions/bonds.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/engineering.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/financial.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/getpivotdata.d.ts +2 -0
- package/dist/xlsx/formula/functions/getpivotdata.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/groupby.d.ts +3 -0
- package/dist/xlsx/formula/functions/groupby.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/helpers.d.ts +3 -2
- package/dist/xlsx/formula/functions/helpers.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/logical.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/modern.d.ts +3 -0
- package/dist/xlsx/formula/functions/modern.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/odd-securities.d.ts +3 -0
- package/dist/xlsx/formula/functions/odd-securities.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/registry.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/text-regex.d.ts +8 -0
- package/dist/xlsx/formula/functions/text-regex.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/text.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/wildcard.d.ts +8 -0
- package/dist/xlsx/formula/functions/wildcard.d.ts.map +1 -0
- package/dist/xlsx/formula/values.d.ts +11 -0
- package/dist/xlsx/formula/values.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +11696 -4994
- package/dist/xlsx/index.d.ts +1 -0
- package/dist/xlsx/index.d.ts.map +1 -1
- package/dist/xlsx/index.mjs +11612 -4994
- package/dist/xlsx/layout/chart-view.d.ts.map +1 -1
- package/dist/xlsx/layout/header-footer-edit.d.ts +16 -0
- package/dist/xlsx/layout/header-footer-edit.d.ts.map +1 -0
- package/dist/xlsx/layout/index.d.ts +3 -0
- package/dist/xlsx/layout/index.d.ts.map +1 -1
- package/dist/xlsx/layout/page-break-view.d.ts +39 -0
- package/dist/xlsx/layout/page-break-view.d.ts.map +1 -0
- package/dist/xlsx/layout/page-view.d.ts +69 -0
- package/dist/xlsx/layout/page-view.d.ts.map +1 -0
- package/dist/xlsx/layout/ref-evaluator.d.ts.map +1 -1
- package/dist/xlsx/load/index.cjs +5718 -2191
- package/dist/xlsx/load/index.mjs +5717 -2190
- package/dist/xlsx/model-pivots.d.ts +88 -2
- package/dist/xlsx/model-pivots.d.ts.map +1 -1
- package/dist/xlsx/model-slicers.d.ts +146 -0
- package/dist/xlsx/model-slicers.d.ts.map +1 -0
- package/dist/xlsx/model-whatif.d.ts +51 -0
- package/dist/xlsx/model-whatif.d.ts.map +1 -0
- package/dist/xlsx/model.d.ts +26 -1
- package/dist/xlsx/model.d.ts.map +1 -1
- package/dist/xlsx/pivot/admission.d.ts.map +1 -1
- package/dist/xlsx/pivot/aggregate.d.ts +15 -6
- package/dist/xlsx/pivot/aggregate.d.ts.map +1 -1
- package/dist/xlsx/pivot/axes.d.ts +6 -0
- package/dist/xlsx/pivot/axes.d.ts.map +1 -0
- package/dist/xlsx/pivot/cache-xml.d.ts.map +1 -1
- package/dist/xlsx/pivot/columns.d.ts +48 -0
- package/dist/xlsx/pivot/columns.d.ts.map +1 -0
- package/dist/xlsx/pivot/data.d.ts +9 -3
- package/dist/xlsx/pivot/data.d.ts.map +1 -1
- package/dist/xlsx/pivot/date-axes.d.ts +12 -0
- package/dist/xlsx/pivot/date-axes.d.ts.map +1 -0
- package/dist/xlsx/pivot/date-group-read.d.ts +11 -0
- package/dist/xlsx/pivot/date-group-read.d.ts.map +1 -0
- package/dist/xlsx/pivot/date-groups.d.ts +60 -0
- package/dist/xlsx/pivot/date-groups.d.ts.map +1 -0
- package/dist/xlsx/pivot/date-read.d.ts +10 -0
- package/dist/xlsx/pivot/date-read.d.ts.map +1 -0
- package/dist/xlsx/pivot/dates.d.ts +17 -0
- package/dist/xlsx/pivot/dates.d.ts.map +1 -0
- package/dist/xlsx/pivot/group-read.d.ts +9 -0
- package/dist/xlsx/pivot/group-read.d.ts.map +1 -0
- package/dist/xlsx/pivot/groups.d.ts +31 -0
- package/dist/xlsx/pivot/groups.d.ts.map +1 -0
- package/dist/xlsx/pivot/hierarchy.d.ts +4 -1
- package/dist/xlsx/pivot/hierarchy.d.ts.map +1 -1
- package/dist/xlsx/pivot/index.d.ts +7 -0
- package/dist/xlsx/pivot/index.d.ts.map +1 -1
- package/dist/xlsx/pivot/item-filters-read.d.ts +7 -0
- package/dist/xlsx/pivot/item-filters-read.d.ts.map +1 -0
- package/dist/xlsx/pivot/item-filters.d.ts +23 -0
- package/dist/xlsx/pivot/item-filters.d.ts.map +1 -0
- package/dist/xlsx/pivot/measures.d.ts +6 -4
- package/dist/xlsx/pivot/measures.d.ts.map +1 -1
- package/dist/xlsx/pivot/nested.d.ts +8 -0
- package/dist/xlsx/pivot/nested.d.ts.map +1 -0
- package/dist/xlsx/pivot/page-filter-admission.d.ts.map +1 -1
- package/dist/xlsx/pivot/page-filter.d.ts.map +1 -1
- package/dist/xlsx/pivot/read.d.ts +2 -1
- package/dist/xlsx/pivot/read.d.ts.map +1 -1
- package/dist/xlsx/pivot/subtotal-read.d.ts +9 -0
- package/dist/xlsx/pivot/subtotal-read.d.ts.map +1 -0
- package/dist/xlsx/pivot/subtotals.d.ts +23 -0
- package/dist/xlsx/pivot/subtotals.d.ts.map +1 -0
- package/dist/xlsx/pivot/table-xml.d.ts +1 -1
- package/dist/xlsx/pivot/table-xml.d.ts.map +1 -1
- package/dist/xlsx/pivot/values-axis.d.ts +2 -2
- package/dist/xlsx/pivot/values-axis.d.ts.map +1 -1
- package/dist/xlsx/read/chart-ex.d.ts +9 -0
- package/dist/xlsx/read/chart-ex.d.ts.map +1 -0
- package/dist/xlsx/read/chart.d.ts.map +1 -1
- package/dist/xlsx/read/drawing.d.ts.map +1 -1
- package/dist/xlsx/read/load.d.ts.map +1 -1
- package/dist/xlsx/read/package.d.ts +2 -1
- package/dist/xlsx/read/package.d.ts.map +1 -1
- package/dist/xlsx/read/scenarios.d.ts +4 -0
- package/dist/xlsx/read/scenarios.d.ts.map +1 -0
- package/dist/xlsx/read/sheet-data.d.ts.map +1 -1
- package/dist/xlsx/read/sheet-props.d.ts.map +1 -1
- package/dist/xlsx/read/tables.d.ts +3 -0
- package/dist/xlsx/read/tables.d.ts.map +1 -1
- package/dist/xlsx/read/worksheet.d.ts.map +1 -1
- package/dist/xlsx/slicer/book.d.ts +16 -0
- package/dist/xlsx/slicer/book.d.ts.map +1 -0
- package/dist/xlsx/slicer/frame.d.ts +14 -0
- package/dist/xlsx/slicer/frame.d.ts.map +1 -0
- package/dist/xlsx/slicer/index.d.ts +10 -0
- package/dist/xlsx/slicer/index.d.ts.map +1 -0
- package/dist/xlsx/slicer/items.d.ts +30 -0
- package/dist/xlsx/slicer/items.d.ts.map +1 -0
- package/dist/xlsx/slicer/layout.d.ts +67 -0
- package/dist/xlsx/slicer/layout.d.ts.map +1 -0
- package/dist/xlsx/slicer/read-slicers.d.ts +11 -0
- package/dist/xlsx/slicer/read-slicers.d.ts.map +1 -0
- package/dist/xlsx/slicer/read-timelines.d.ts +5 -0
- package/dist/xlsx/slicer/read-timelines.d.ts.map +1 -0
- package/dist/xlsx/slicer/read.d.ts +26 -0
- package/dist/xlsx/slicer/read.d.ts.map +1 -0
- package/dist/xlsx/slicer/select.d.ts +10 -0
- package/dist/xlsx/slicer/select.d.ts.map +1 -0
- package/dist/xlsx/slicer/styles.d.ts +36 -0
- package/dist/xlsx/slicer/styles.d.ts.map +1 -0
- package/dist/xlsx/slicer/table-filter.d.ts +28 -0
- package/dist/xlsx/slicer/table-filter.d.ts.map +1 -0
- package/dist/xlsx/slicer/timeline-periods.d.ts +35 -0
- package/dist/xlsx/slicer/timeline-periods.d.ts.map +1 -0
- package/dist/xlsx/slicer/timeline-view.d.ts +60 -0
- package/dist/xlsx/slicer/timeline-view.d.ts.map +1 -0
- package/dist/xlsx/slicer/write-plan.d.ts +31 -0
- package/dist/xlsx/slicer/write-plan.d.ts.map +1 -0
- package/dist/xlsx/slicer/write-timeline.d.ts +7 -0
- package/dist/xlsx/slicer/write-timeline.d.ts.map +1 -0
- package/dist/xlsx/slicer/write-xml.d.ts +17 -0
- package/dist/xlsx/slicer/write-xml.d.ts.map +1 -0
- package/dist/xlsx/ui/commands/i18n/index.d.ts.map +1 -1
- package/dist/xlsx/ui/commands/i18n/pivots.d.ts.map +1 -1
- package/dist/xlsx/ui/commands/i18n/print-layout.d.ts.map +1 -1
- package/dist/xlsx/ui/commands/i18n/slicers.d.ts +3 -0
- package/dist/xlsx/ui/commands/i18n/slicers.d.ts.map +1 -0
- package/dist/xlsx/ui/commands/i18n/what-if.d.ts +3 -0
- package/dist/xlsx/ui/commands/i18n/what-if.d.ts.map +1 -0
- package/dist/xlsx/ui/commands/icons.d.ts.map +1 -1
- package/dist/xlsx/ui/commands/slicers.d.ts +37 -0
- package/dist/xlsx/ui/commands/slicers.d.ts.map +1 -0
- package/dist/xlsx/ui/commands/what-if.d.ts +4 -0
- package/dist/xlsx/ui/commands/what-if.d.ts.map +1 -0
- package/dist/xlsx/ui/commands.d.ts +2 -0
- package/dist/xlsx/ui/commands.d.ts.map +1 -1
- package/dist/xlsx/ui/index.cjs +6999 -3052
- package/dist/xlsx/ui/index.d.ts +2 -0
- package/dist/xlsx/ui/index.d.ts.map +1 -1
- package/dist/xlsx/ui/index.mjs +6994 -3053
- package/dist/xlsx/ui/locales/de/index.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/de/options.d.ts +2 -0
- package/dist/xlsx/ui/locales/de/options.d.ts.map +1 -0
- package/dist/xlsx/ui/locales/de/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/en/index.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/en/options.d.ts +2 -0
- package/dist/xlsx/ui/locales/en/options.d.ts.map +1 -0
- package/dist/xlsx/ui/locales/en/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/es/index.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/es/options.d.ts +2 -0
- package/dist/xlsx/ui/locales/es/options.d.ts.map +1 -0
- package/dist/xlsx/ui/locales/es/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/fr/index.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/fr/options.d.ts +2 -0
- package/dist/xlsx/ui/locales/fr/options.d.ts.map +1 -0
- package/dist/xlsx/ui/locales/fr/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/zh-CN/index.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/zh-CN/options.d.ts +2 -0
- package/dist/xlsx/ui/locales/zh-CN/options.d.ts.map +1 -0
- package/dist/xlsx/ui/locales/zh-CN/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/ribbon/tabs/review-view.d.ts.map +1 -1
- package/dist/xlsx/write/carried-refs.d.ts.map +1 -1
- package/dist/xlsx/write/drawing.d.ts.map +1 -1
- package/dist/xlsx/write/package-writer.d.ts +2 -0
- package/dist/xlsx/write/package-writer.d.ts.map +1 -1
- package/dist/xlsx/write/save.d.ts.map +1 -1
- package/dist/xlsx/write/scenarios.d.ts +4 -0
- package/dist/xlsx/write/scenarios.d.ts.map +1 -0
- package/dist/xlsx/write/sheet-data.d.ts.map +1 -1
- package/dist/xlsx/write/sheet-parts.d.ts +1 -0
- package/dist/xlsx/write/sheet-parts.d.ts.map +1 -1
- package/dist/xlsx/write/sheet-props.d.ts.map +1 -1
- package/dist/xlsx/write/table-patch.d.ts.map +1 -1
- package/dist/xlsx/write/tables.d.ts.map +1 -1
- package/dist/xlsx/write/worksheet.d.ts.map +1 -1
- package/dist/xml/index.cjs +28 -0
- package/dist/xml/index.mjs +27 -1
- package/dist/xml/namespaces.d.ts +2 -0
- package/dist/xml/namespaces.d.ts.map +1 -1
- package/dist/xml/xml.d.ts +15 -0
- package/dist/xml/xml.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/PptxHandler-RWTOUCLC.mjs +0 -3
- package/dist/PptxHandler-UU4ZCT6H.cjs +0 -12
- package/dist/chunk-KBIJI6P5.mjs +0 -166
- package/dist/pptx/chunks/elements-DmbzOhFu.d.ts.map +0 -1
- package/dist/pptx/chunks/index-BmvOxbsh.d.ts.map +0 -1
package/dist/docx/ui/index.mjs
CHANGED
|
@@ -179,13 +179,13 @@ function updatedInlineRunAttributes(node, format) {
|
|
|
179
179
|
if (Object.hasOwn(desired, key)) metadata[key] = desired[key];
|
|
180
180
|
else delete metadata[key];
|
|
181
181
|
}
|
|
182
|
-
const
|
|
182
|
+
const attrs2 = {
|
|
183
183
|
...node.attrs,
|
|
184
184
|
format: Object.keys(metadata).length ? JSON.stringify(metadata) : null
|
|
185
185
|
};
|
|
186
186
|
for (const key of DIRECT_RUN_PROPERTY_KEYS)
|
|
187
|
-
|
|
188
|
-
return
|
|
187
|
+
attrs2[attributeName(key)] = JSON.stringify(base[key]) === JSON.stringify(desired[key]) ? null : JSON.stringify(desired[key] ?? null);
|
|
188
|
+
return attrs2;
|
|
189
189
|
}
|
|
190
190
|
function wordInlinePropertyCodec(schema) {
|
|
191
191
|
return Object.values(schema.nodes).some((type) => type.spec.attrs?.[attributeName("bold")]) ? schema.marks.inlineCommentAnchors ? "word-yjs-v3" : "word-yjs-v2" : "word-yjs-v1";
|
|
@@ -202,7 +202,7 @@ var hardBreakNodeSpec = {
|
|
|
202
202
|
parseDOM: [
|
|
203
203
|
{
|
|
204
204
|
tag: "br",
|
|
205
|
-
getAttrs: (
|
|
205
|
+
getAttrs: (el4) => ({ format: el4.dataset.runProperties ?? null })
|
|
206
206
|
}
|
|
207
207
|
],
|
|
208
208
|
toDOM: (node) => ["br", inlineRunPropertiesDomAttrs(node)]
|
|
@@ -217,9 +217,9 @@ var pageBreakNodeSpec = {
|
|
|
217
217
|
parseDOM: [
|
|
218
218
|
{
|
|
219
219
|
tag: "span[data-docx-break]",
|
|
220
|
-
getAttrs: (
|
|
221
|
-
kind:
|
|
222
|
-
format:
|
|
220
|
+
getAttrs: (el4) => ({
|
|
221
|
+
kind: el4.dataset.docxBreak === "column" ? "column" : "page",
|
|
222
|
+
format: el4.dataset.runProperties ?? null
|
|
223
223
|
})
|
|
224
224
|
}
|
|
225
225
|
],
|
|
@@ -255,11 +255,11 @@ var noteReferenceNodeSpec = {
|
|
|
255
255
|
{
|
|
256
256
|
tag: "sup[data-docx-note-kind]",
|
|
257
257
|
priority: 60,
|
|
258
|
-
getAttrs: (
|
|
259
|
-
kind:
|
|
260
|
-
format:
|
|
261
|
-
id:
|
|
262
|
-
number: Number(
|
|
258
|
+
getAttrs: (el4) => ({
|
|
259
|
+
kind: el4.dataset.docxNoteKind === "endnote" ? "endnote" : "footnote",
|
|
260
|
+
format: el4.dataset.runProperties ?? null,
|
|
261
|
+
id: el4.dataset.docxNoteId || "",
|
|
262
|
+
number: Number(el4.textContent) || 1
|
|
263
263
|
})
|
|
264
264
|
}
|
|
265
265
|
],
|
|
@@ -290,10 +290,10 @@ var fieldMarkerNodeSpec = {
|
|
|
290
290
|
parseDOM: [
|
|
291
291
|
{
|
|
292
292
|
tag: "span[data-field-marker]",
|
|
293
|
-
getAttrs: (
|
|
294
|
-
kind:
|
|
295
|
-
format:
|
|
296
|
-
code:
|
|
293
|
+
getAttrs: (el4) => ({
|
|
294
|
+
kind: el4.dataset.fieldMarker || "begin",
|
|
295
|
+
format: el4.dataset.runProperties ?? null,
|
|
296
|
+
code: el4.dataset.fieldCode ?? null
|
|
297
297
|
})
|
|
298
298
|
}
|
|
299
299
|
],
|
|
@@ -628,14 +628,14 @@ function repairCollaborativeDocumentIds(state, clientId, idGenerator = createCol
|
|
|
628
628
|
seen.add(id);
|
|
629
629
|
return;
|
|
630
630
|
}
|
|
631
|
-
let
|
|
631
|
+
let generated2 = "";
|
|
632
632
|
const kind = node.type.name === "table" ? "table" : "paragraph";
|
|
633
633
|
do
|
|
634
|
-
|
|
635
|
-
while (reserved.has(
|
|
636
|
-
reserved.add(
|
|
637
|
-
seen.add(
|
|
638
|
-
transaction = transaction.setNodeMarkup(pos, void 0, { ...node.attrs, id:
|
|
634
|
+
generated2 = idGenerator(kind);
|
|
635
|
+
while (reserved.has(generated2));
|
|
636
|
+
reserved.add(generated2);
|
|
637
|
+
seen.add(generated2);
|
|
638
|
+
transaction = transaction.setNodeMarkup(pos, void 0, { ...node.attrs, id: generated2 });
|
|
639
639
|
});
|
|
640
640
|
return transaction.docChanged ? transaction : null;
|
|
641
641
|
}
|
|
@@ -754,10 +754,34 @@ var NS = {
|
|
|
754
754
|
w: "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
|
|
755
755
|
/** DrawingML main. */
|
|
756
756
|
a: "http://schemas.openxmlformats.org/drawingml/2006/main"};
|
|
757
|
+
var DEFAULT_XML_LIMITS = {
|
|
758
|
+
maxDepth: 512,
|
|
759
|
+
maxNodes: 5e6
|
|
760
|
+
};
|
|
761
|
+
var MARKUP_RE = /<!--[\s\S]*?-->|<!\[CDATA\[[\s\S]*?\]\]>|<\?[\s\S]*?\?>|<(\/?)([^\s\/>]+)(?:\s+[^\s=\/>]+\s*=\s*(?:"[^"]*"|'[^']*'))*\s*(\/?)>/g;
|
|
762
|
+
function checkXmlLimits(xml, label, limits = {}) {
|
|
763
|
+
const maxDepth = limits.maxDepth ?? DEFAULT_XML_LIMITS.maxDepth;
|
|
764
|
+
const maxNodes = limits.maxNodes ?? DEFAULT_XML_LIMITS.maxNodes;
|
|
765
|
+
let depth = 0;
|
|
766
|
+
let nodes = 0;
|
|
767
|
+
for (const match of xml.matchAll(MARKUP_RE)) {
|
|
768
|
+
const [, closing, name, selfClosing] = match;
|
|
769
|
+
if (name === void 0) continue;
|
|
770
|
+
if (closing) {
|
|
771
|
+
depth--;
|
|
772
|
+
continue;
|
|
773
|
+
}
|
|
774
|
+
nodes++;
|
|
775
|
+
if (nodes > maxNodes) throw new Error(`${label} XML exceeds the limit of ${maxNodes} elements`);
|
|
776
|
+
if (!selfClosing && ++depth > maxDepth)
|
|
777
|
+
throw new Error(`${label} XML exceeds the nesting depth limit of ${maxDepth}`);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
757
780
|
function parseXml(xml, options = {}) {
|
|
758
781
|
const label = options.label ?? "OOXML";
|
|
759
782
|
if (/<!DOCTYPE|<!ENTITY/i.test(xml))
|
|
760
783
|
throw new Error(`${label} XML with DTD or entity declarations is not supported`);
|
|
784
|
+
checkXmlLimits(xml, label, options.limits);
|
|
761
785
|
let parseError = "";
|
|
762
786
|
let parsed;
|
|
763
787
|
try {
|
|
@@ -1012,16 +1036,20 @@ function extensionPrefix(doc, ns, preferred) {
|
|
|
1012
1036
|
root.setAttributeNS(XMLNS, `xmlns:${prefix}`, ns);
|
|
1013
1037
|
return prefix;
|
|
1014
1038
|
}
|
|
1015
|
-
function
|
|
1016
|
-
|
|
1017
|
-
if (value === void 0) return;
|
|
1018
|
-
const prefix = extensionPrefix(doc, WORD_2010_NS, "w14");
|
|
1039
|
+
function declareIgnorableExtension(doc, ns, preferred) {
|
|
1040
|
+
const prefix = extensionPrefix(doc, ns, preferred);
|
|
1019
1041
|
const mc = extensionPrefix(doc, MC, "mc");
|
|
1020
1042
|
const ignored = new Set(
|
|
1021
1043
|
(doc.documentElement.getAttributeNS(MC, "Ignorable") ?? "").split(/\s+/).filter(Boolean)
|
|
1022
1044
|
);
|
|
1023
1045
|
ignored.add(prefix);
|
|
1024
1046
|
doc.documentElement.setAttributeNS(MC, `${mc}:Ignorable`, [...ignored].join(" "));
|
|
1047
|
+
return prefix;
|
|
1048
|
+
}
|
|
1049
|
+
function writeLigatures(doc, props, value) {
|
|
1050
|
+
for (const element2 of ligatureElements(props)) props.removeChild(element2);
|
|
1051
|
+
if (value === void 0) return;
|
|
1052
|
+
const prefix = declareIgnorableExtension(doc, WORD_2010_NS, "w14");
|
|
1025
1053
|
const element = doc.createElementNS(WORD_2010_NS, `${prefix}:ligatures`);
|
|
1026
1054
|
element.setAttributeNS(WORD_2010_NS, `${prefix}:val`, value);
|
|
1027
1055
|
props.appendChild(element);
|
|
@@ -1130,8 +1158,8 @@ function parseRunProperties(props) {
|
|
|
1130
1158
|
if (scale !== void 0) result.textScalePercent = scale;
|
|
1131
1159
|
const kerning = parseHalfPoints(getW(first2(props, "kern"), "val"));
|
|
1132
1160
|
if (kerning !== void 0) result.kerningHalfPoints = kerning;
|
|
1133
|
-
const
|
|
1134
|
-
if (
|
|
1161
|
+
const position2 = parseSignedHalfPoints(getW(first2(props, "position"), "val"));
|
|
1162
|
+
if (position2 !== void 0) result.positionHalfPoints = position2;
|
|
1135
1163
|
const shd = first2(props, "shd");
|
|
1136
1164
|
const fill = parseRgbColor(getW(shd, "fill"));
|
|
1137
1165
|
if (fill) result.shadingFill = fill;
|
|
@@ -1506,7 +1534,7 @@ var W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
|
1506
1534
|
var heading = (id, name, level, before, size, color) => `<w:style w:type="paragraph" w:styleId="${id}"><w:name w:val="${name}"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:uiPriority w:val="9"/><w:qFormat/><w:pPr><w:keepNext/><w:keepLines/><w:spacing w:before="${before}" w:after="0"/><w:outlineLvl w:val="${level}"/></w:pPr><w:rPr><w:rFonts w:ascii="Calibri Light" w:hAnsi="Calibri Light" w:eastAsia="Calibri Light" w:cs="Times New Roman"/><w:color w:val="${color}"/><w:sz w:val="${size}"/><w:szCs w:val="${size}"/></w:rPr></w:style>`;
|
|
1507
1535
|
var toc = (level) => `<w:style w:type="paragraph" w:styleId="TOC${level}"><w:name w:val="toc ${level}"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:uiPriority w:val="39"/><w:unhideWhenUsed/><w:pPr><w:spacing w:after="100"/>${level > 1 ? `<w:ind w:left="${(level - 1) * 220}"/>` : ""}</w:pPr></w:style>`;
|
|
1508
1536
|
var noteStyles = (id, name) => `<w:style w:type="paragraph" w:styleId="${id}Text"><w:name w:val="${name} text"/><w:basedOn w:val="Normal"/><w:link w:val="${id}TextChar"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr><w:rPr><w:sz w:val="20"/><w:szCs w:val="20"/></w:rPr></w:style><w:style w:type="character" w:styleId="${id}TextChar"><w:name w:val="${name} Text Char"/><w:basedOn w:val="DefaultParagraphFont"/><w:link w:val="${id}Text"/><w:uiPriority w:val="99"/><w:semiHidden/><w:rPr><w:sz w:val="20"/><w:szCs w:val="20"/></w:rPr></w:style><w:style w:type="character" w:styleId="${id}Reference"><w:name w:val="${name} reference"/><w:basedOn w:val="DefaultParagraphFont"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/><w:rPr><w:vertAlign w:val="superscript"/></w:rPr></w:style>`;
|
|
1509
|
-
var DEFAULT_STYLES_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:styles xmlns:w="${W}"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:ascii="Calibri" w:eastAsia="Calibri" w:hAnsi="Calibri" w:cs="Times New Roman"/><w:sz w:val="22"/><w:szCs w:val="22"/><w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA"/></w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:after="160" w:line="259" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w:style><w:style w:type="character" w:default="1" w:styleId="DefaultParagraphFont"><w:name w:val="Default Paragraph Font"/><w:uiPriority w:val="1"/><w:semiHidden/><w:unhideWhenUsed/></w:style><w:style w:type="table" w:default="1" w:styleId="TableNormal"><w:name w:val="Normal Table"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/><w:tblPr><w:tblInd w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPr></w:style><w:style w:type="numbering" w:default="1" w:styleId="NoList"><w:name w:val="No List"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/></w:style><w:style w:type="paragraph" w:styleId="Title"><w:name w:val="Title"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:uiPriority w:val="10"/><w:qFormat/><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/><w:contextualSpacing/></w:pPr><w:rPr><w:rFonts w:ascii="Calibri Light" w:hAnsi="Calibri Light" w:eastAsia="Calibri Light" w:cs="Times New Roman"/><w:spacing w:val="-10"/><w:kern w:val="28"/><w:sz w:val="56"/><w:szCs w:val="56"/></w:rPr></w:style>` + heading("Heading1", "heading 1", 0, 240, 32, "2F5496") + heading("Heading2", "heading 2", 1, 40, 26, "2F5496") + heading("Heading3", "heading 3", 2, 40, 24, "1F3763") + toc(1) + toc(2) + toc(3) + noteStyles("Footnote", "footnote") + noteStyles("Endnote", "endnote") + '<w:style w:type="character" w:styleId="Hyperlink"><w:name w:val="Hyperlink"/><w:basedOn w:val="DefaultParagraphFont"/><w:uiPriority w:val="99"/><w:unhideWhenUsed/><w:rPr><w:color w:val="0563C1"/><w:u w:val="single"/></w:rPr></w:style></w:styles>';
|
|
1537
|
+
var DEFAULT_STYLES_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:styles xmlns:w="${W}"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:ascii="Calibri" w:eastAsia="Calibri" w:hAnsi="Calibri" w:cs="Times New Roman"/><w:sz w:val="22"/><w:szCs w:val="22"/><w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA"/></w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:after="160" w:line="259" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w:style><w:style w:type="character" w:default="1" w:styleId="DefaultParagraphFont"><w:name w:val="Default Paragraph Font"/><w:uiPriority w:val="1"/><w:semiHidden/><w:unhideWhenUsed/></w:style><w:style w:type="table" w:default="1" w:styleId="TableNormal"><w:name w:val="Normal Table"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/><w:tblPr><w:tblInd w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPr></w:style><w:style w:type="numbering" w:default="1" w:styleId="NoList"><w:name w:val="No List"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/></w:style><w:style w:type="paragraph" w:styleId="Title"><w:name w:val="Title"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:uiPriority w:val="10"/><w:qFormat/><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/><w:contextualSpacing/></w:pPr><w:rPr><w:rFonts w:ascii="Calibri Light" w:hAnsi="Calibri Light" w:eastAsia="Calibri Light" w:cs="Times New Roman"/><w:spacing w:val="-10"/><w:kern w:val="28"/><w:sz w:val="56"/><w:szCs w:val="56"/></w:rPr></w:style>` + heading("Heading1", "heading 1", 0, 240, 32, "2F5496") + heading("Heading2", "heading 2", 1, 40, 26, "2F5496") + heading("Heading3", "heading 3", 2, 40, 24, "1F3763") + toc(1) + toc(2) + toc(3) + noteStyles("Footnote", "footnote") + noteStyles("Endnote", "endnote") + '<w:style w:type="character" w:styleId="Hyperlink"><w:name w:val="Hyperlink"/><w:basedOn w:val="DefaultParagraphFont"/><w:uiPriority w:val="99"/><w:unhideWhenUsed/><w:rPr><w:color w:val="0563C1"/><w:u w:val="single"/></w:rPr></w:style><w:style w:type="character" w:styleId="PlaceholderText"><w:name w:val="Placeholder Text"/><w:basedOn w:val="DefaultParagraphFont"/><w:uiPriority w:val="99"/><w:semiHidden/><w:rPr><w:color w:val="808080"/></w:rPr></w:style></w:styles>';
|
|
1510
1538
|
var cached;
|
|
1511
1539
|
function defaultStyleCatalogs() {
|
|
1512
1540
|
cached ??= {
|
|
@@ -2296,6 +2324,279 @@ function escapeXmlAttr(value) {
|
|
|
2296
2324
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
2297
2325
|
}
|
|
2298
2326
|
|
|
2327
|
+
// docx/content-control.ts
|
|
2328
|
+
var WORD_2012_NS = "http://schemas.microsoft.com/office/word/2012/wordml";
|
|
2329
|
+
var sdtContent = (sdt) => first2(sdt, "sdtContent");
|
|
2330
|
+
var isSdt = (element) => named2(element, "sdt");
|
|
2331
|
+
var TYPE_ELEMENTS = {
|
|
2332
|
+
text: "text",
|
|
2333
|
+
dropDownList: "dropDownList",
|
|
2334
|
+
comboBox: "comboBox",
|
|
2335
|
+
date: "date",
|
|
2336
|
+
picture: "picture",
|
|
2337
|
+
group: "group",
|
|
2338
|
+
equation: "equation",
|
|
2339
|
+
citation: "citation",
|
|
2340
|
+
bibliography: "bibliography",
|
|
2341
|
+
docPartObj: "docPartObj",
|
|
2342
|
+
docPartList: "docPartList"
|
|
2343
|
+
};
|
|
2344
|
+
function attrW14(element, local) {
|
|
2345
|
+
return element?.getAttributeNS(WORD_2010_NS, local) ?? void 0;
|
|
2346
|
+
}
|
|
2347
|
+
function glyph(element) {
|
|
2348
|
+
const code = attrW14(element, "val");
|
|
2349
|
+
if (!code) return void 0;
|
|
2350
|
+
const font = attrW14(element, "font");
|
|
2351
|
+
return { code, ...font ? { font } : {} };
|
|
2352
|
+
}
|
|
2353
|
+
function parseKind(sdtPr) {
|
|
2354
|
+
for (const child of Array.from(sdtPr.childNodes).filter(isElement)) {
|
|
2355
|
+
if (child.namespaceURI === WORD_NS && TYPE_ELEMENTS[child.localName])
|
|
2356
|
+
return TYPE_ELEMENTS[child.localName];
|
|
2357
|
+
if (child.namespaceURI === WORD_2010_NS && child.localName === "checkbox") return "checkbox";
|
|
2358
|
+
if (child.namespaceURI === WORD_2012_NS && child.localName === "repeatingSection")
|
|
2359
|
+
return "repeatingSection";
|
|
2360
|
+
}
|
|
2361
|
+
return "richText";
|
|
2362
|
+
}
|
|
2363
|
+
var generated = 0;
|
|
2364
|
+
function parseContentControl(sdt, level) {
|
|
2365
|
+
const sdtPr = first2(sdt, "sdtPr");
|
|
2366
|
+
if (!sdtPr) return { id: `sdt-gen-${++generated}`, level, kind: "richText" };
|
|
2367
|
+
const kind = parseKind(sdtPr);
|
|
2368
|
+
const control = {
|
|
2369
|
+
id: getW(first2(sdtPr, "id"), "val") ?? `sdt-gen-${++generated}`,
|
|
2370
|
+
level,
|
|
2371
|
+
kind
|
|
2372
|
+
};
|
|
2373
|
+
const alias = getW(first2(sdtPr, "alias"), "val");
|
|
2374
|
+
if (alias !== void 0) control.alias = alias;
|
|
2375
|
+
const tag = getW(first2(sdtPr, "tag"), "val");
|
|
2376
|
+
if (tag !== void 0) control.tag = tag;
|
|
2377
|
+
const lock = getW(first2(sdtPr, "lock"), "val");
|
|
2378
|
+
if (lock === "sdtLocked" || lock === "contentLocked" || lock === "sdtContentLocked")
|
|
2379
|
+
control.lock = lock;
|
|
2380
|
+
const showing = first2(sdtPr, "showingPlcHdr");
|
|
2381
|
+
if (showing) control.showingPlaceholder = parseOnOff(getW(showing, "val")) ?? true;
|
|
2382
|
+
if (first2(sdtPr, "dataBinding")) control.dataBound = true;
|
|
2383
|
+
if (first2(sdtPr, "temporary")) control.temporary = true;
|
|
2384
|
+
if (kind === "text") {
|
|
2385
|
+
const multi = parseOnOff(getW(first2(sdtPr, "text"), "multiLine"));
|
|
2386
|
+
if (multi) control.multiLine = true;
|
|
2387
|
+
}
|
|
2388
|
+
if (kind === "checkbox") {
|
|
2389
|
+
const box = children(sdtPr, "checkbox", WORD_2010_NS, false)[0];
|
|
2390
|
+
const checked = first(box, "checked", WORD_2010_NS, false);
|
|
2391
|
+
control.checked = parseOnOff(attrW14(checked, "val")) ?? false;
|
|
2392
|
+
const on = glyph(first(box, "checkedState", WORD_2010_NS, false));
|
|
2393
|
+
const off = glyph(first(box, "uncheckedState", WORD_2010_NS, false));
|
|
2394
|
+
if (on) control.checkedGlyph = on;
|
|
2395
|
+
if (off) control.uncheckedGlyph = off;
|
|
2396
|
+
}
|
|
2397
|
+
if (kind === "dropDownList" || kind === "comboBox") {
|
|
2398
|
+
const list = first2(sdtPr, kind);
|
|
2399
|
+
control.items = (list ? Array.from(list.childNodes).filter(isElement) : []).filter((item) => named2(item, "listItem")).map((item) => {
|
|
2400
|
+
const display = getW(item, "displayText");
|
|
2401
|
+
const value = getW(item, "value") ?? display ?? "";
|
|
2402
|
+
return { display: display ?? value, value };
|
|
2403
|
+
});
|
|
2404
|
+
}
|
|
2405
|
+
if (kind === "date") {
|
|
2406
|
+
const date = first2(sdtPr, "date");
|
|
2407
|
+
const fullDate = getW(date, "fullDate");
|
|
2408
|
+
if (fullDate) control.fullDate = fullDate;
|
|
2409
|
+
const format = getW(first2(date, "dateFormat"), "val");
|
|
2410
|
+
if (format) control.dateFormat = format;
|
|
2411
|
+
const lid = getW(first2(date, "lid"), "val");
|
|
2412
|
+
if (lid) control.dateLocale = lid;
|
|
2413
|
+
}
|
|
2414
|
+
control.sourceXml = buildXml(sdtPr);
|
|
2415
|
+
return control;
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2418
|
+
// docx/expect-defined.ts
|
|
2419
|
+
function expectDefined2(value, context) {
|
|
2420
|
+
if (value === void 0 || value === null) {
|
|
2421
|
+
throw new Error(`Internal invariant violated: ${context} is missing.`);
|
|
2422
|
+
}
|
|
2423
|
+
return value;
|
|
2424
|
+
}
|
|
2425
|
+
function isCommentReferenceRun(run) {
|
|
2426
|
+
const content = Array.from(run.childNodes).filter(
|
|
2427
|
+
(child) => isElement(child) && !named2(child, "rPr")
|
|
2428
|
+
);
|
|
2429
|
+
return content.length > 0 && content.every((child) => named2(child, "commentReference"));
|
|
2430
|
+
}
|
|
2431
|
+
|
|
2432
|
+
// docx/write-content-control.ts
|
|
2433
|
+
var PROPERTY_ORDER = [
|
|
2434
|
+
"rPr",
|
|
2435
|
+
"alias",
|
|
2436
|
+
"tag",
|
|
2437
|
+
"id",
|
|
2438
|
+
"lock",
|
|
2439
|
+
"placeholder",
|
|
2440
|
+
"temporary",
|
|
2441
|
+
"showingPlcHdr",
|
|
2442
|
+
"dataBinding",
|
|
2443
|
+
"label",
|
|
2444
|
+
"tabIndex"
|
|
2445
|
+
];
|
|
2446
|
+
var rank = (element) => {
|
|
2447
|
+
const index = element.namespaceURI === WORD_NS ? PROPERTY_ORDER.indexOf(element.localName) : -1;
|
|
2448
|
+
return index < 0 ? PROPERTY_ORDER.length : index;
|
|
2449
|
+
};
|
|
2450
|
+
function place(sdtPr, element) {
|
|
2451
|
+
const siblings = Array.from(sdtPr.childNodes).filter((n2) => n2.nodeType === 1);
|
|
2452
|
+
const after = siblings.find((sibling) => rank(sibling) > rank(element));
|
|
2453
|
+
sdtPr.insertBefore(element, after ?? null);
|
|
2454
|
+
}
|
|
2455
|
+
function setValued(doc, sdtPr, local, value) {
|
|
2456
|
+
for (const existing of children2(sdtPr, local)) sdtPr.removeChild(existing);
|
|
2457
|
+
if (value === void 0) return;
|
|
2458
|
+
const element = makeW(doc, local);
|
|
2459
|
+
element.setAttributeNS(WORD_NS, "w:val", value);
|
|
2460
|
+
place(sdtPr, element);
|
|
2461
|
+
}
|
|
2462
|
+
var same = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
2463
|
+
function w14(doc, local) {
|
|
2464
|
+
const prefix = declareIgnorableExtension(doc, WORD_2010_NS, "w14");
|
|
2465
|
+
return doc.createElementNS(WORD_2010_NS, `${prefix}:${local}`);
|
|
2466
|
+
}
|
|
2467
|
+
function w14Attribute(element, local, value) {
|
|
2468
|
+
const prefix = element.lookupPrefix(WORD_2010_NS) ?? "w14";
|
|
2469
|
+
element.setAttributeNS(WORD_2010_NS, `${prefix}:${local}`, value);
|
|
2470
|
+
}
|
|
2471
|
+
function checkboxElement(sdtPr) {
|
|
2472
|
+
return Array.from(sdtPr.childNodes).find(
|
|
2473
|
+
(n2) => n2.nodeType === 1 && n2.localName === "checkbox" && n2.namespaceURI === WORD_2010_NS
|
|
2474
|
+
);
|
|
2475
|
+
}
|
|
2476
|
+
function writeCheckbox(doc, sdtPr, control) {
|
|
2477
|
+
let box = checkboxElement(sdtPr);
|
|
2478
|
+
if (!box) {
|
|
2479
|
+
box = w14(doc, "checkbox");
|
|
2480
|
+
sdtPr.appendChild(box);
|
|
2481
|
+
}
|
|
2482
|
+
const replace = (local, build, order) => {
|
|
2483
|
+
for (const old of Array.from(box.childNodes))
|
|
2484
|
+
if (old.localName === local) box.removeChild(old);
|
|
2485
|
+
const element = w14(doc, local);
|
|
2486
|
+
build(element);
|
|
2487
|
+
const siblings = Array.from(box.childNodes);
|
|
2488
|
+
box.insertBefore(element, siblings[order] ?? null);
|
|
2489
|
+
};
|
|
2490
|
+
replace("checked", (el4) => w14Attribute(el4, "val", control.checked ? "1" : "0"), 0);
|
|
2491
|
+
if (control.checkedGlyph)
|
|
2492
|
+
replace(
|
|
2493
|
+
"checkedState",
|
|
2494
|
+
(el4) => {
|
|
2495
|
+
w14Attribute(el4, "val", control.checkedGlyph.code);
|
|
2496
|
+
if (control.checkedGlyph.font) w14Attribute(el4, "font", control.checkedGlyph.font);
|
|
2497
|
+
},
|
|
2498
|
+
1
|
|
2499
|
+
);
|
|
2500
|
+
if (control.uncheckedGlyph)
|
|
2501
|
+
replace(
|
|
2502
|
+
"uncheckedState",
|
|
2503
|
+
(el4) => {
|
|
2504
|
+
w14Attribute(el4, "val", control.uncheckedGlyph.code);
|
|
2505
|
+
if (control.uncheckedGlyph.font) w14Attribute(el4, "font", control.uncheckedGlyph.font);
|
|
2506
|
+
},
|
|
2507
|
+
2
|
|
2508
|
+
);
|
|
2509
|
+
}
|
|
2510
|
+
function writeItems(doc, sdtPr, control) {
|
|
2511
|
+
const list = first2(sdtPr, control.kind);
|
|
2512
|
+
if (!list) return;
|
|
2513
|
+
for (const item of children2(list, "listItem")) list.removeChild(item);
|
|
2514
|
+
for (const item of control.items ?? []) {
|
|
2515
|
+
const element = makeW(doc, "listItem");
|
|
2516
|
+
element.setAttributeNS(WORD_NS, "w:displayText", item.display);
|
|
2517
|
+
element.setAttributeNS(WORD_NS, "w:value", item.value);
|
|
2518
|
+
list.appendChild(element);
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
function writeDate(doc, sdtPr, control) {
|
|
2522
|
+
const date = first2(sdtPr, "date");
|
|
2523
|
+
if (!date) return;
|
|
2524
|
+
if (control.fullDate) date.setAttributeNS(WORD_NS, "w:fullDate", control.fullDate);
|
|
2525
|
+
else date.removeAttributeNS(WORD_NS, "fullDate");
|
|
2526
|
+
const set = (local, value, order) => {
|
|
2527
|
+
for (const old of children2(date, local)) date.removeChild(old);
|
|
2528
|
+
if (value === void 0) return;
|
|
2529
|
+
const element = makeW(doc, local);
|
|
2530
|
+
element.setAttributeNS(WORD_NS, "w:val", value);
|
|
2531
|
+
date.insertBefore(element, Array.from(date.childNodes)[order] ?? null);
|
|
2532
|
+
};
|
|
2533
|
+
set("dateFormat", control.dateFormat, 0);
|
|
2534
|
+
set("lid", control.dateLocale, 1);
|
|
2535
|
+
}
|
|
2536
|
+
function patchContentControl(doc, sdt, control) {
|
|
2537
|
+
const sdtPr = first2(sdt, "sdtPr");
|
|
2538
|
+
if (!sdtPr) return;
|
|
2539
|
+
const current = parseContentControl(sdt, control.level);
|
|
2540
|
+
if (control.alias !== current.alias) setValued(doc, sdtPr, "alias", control.alias);
|
|
2541
|
+
if (control.tag !== current.tag) setValued(doc, sdtPr, "tag", control.tag);
|
|
2542
|
+
if (control.lock !== current.lock) setValued(doc, sdtPr, "lock", control.lock);
|
|
2543
|
+
if (Boolean(control.showingPlaceholder) !== Boolean(current.showingPlaceholder)) {
|
|
2544
|
+
for (const old of children2(sdtPr, "showingPlcHdr")) sdtPr.removeChild(old);
|
|
2545
|
+
if (control.showingPlaceholder) place(sdtPr, makeW(doc, "showingPlcHdr"));
|
|
2546
|
+
}
|
|
2547
|
+
if (control.kind === "checkbox") {
|
|
2548
|
+
if (Boolean(control.checked) !== Boolean(current.checked) || !same(control.checkedGlyph, current.checkedGlyph) || !same(control.uncheckedGlyph, current.uncheckedGlyph))
|
|
2549
|
+
writeCheckbox(doc, sdtPr, control);
|
|
2550
|
+
}
|
|
2551
|
+
if ((control.kind === "dropDownList" || control.kind === "comboBox") && !same(control.items, current.items))
|
|
2552
|
+
writeItems(doc, sdtPr, control);
|
|
2553
|
+
if (control.kind === "date" && (control.fullDate !== current.fullDate || control.dateFormat !== current.dateFormat || control.dateLocale !== current.dateLocale))
|
|
2554
|
+
writeDate(doc, sdtPr, control);
|
|
2555
|
+
}
|
|
2556
|
+
function buildProperties(doc, control) {
|
|
2557
|
+
if (control.sourceXml)
|
|
2558
|
+
return doc.importNode(parseXml2(control.sourceXml).documentElement, true);
|
|
2559
|
+
const sdtPr = makeW(doc, "sdtPr");
|
|
2560
|
+
if (control.alias !== void 0) setValued(doc, sdtPr, "alias", control.alias);
|
|
2561
|
+
if (control.tag !== void 0) setValued(doc, sdtPr, "tag", control.tag);
|
|
2562
|
+
setValued(doc, sdtPr, "id", control.id);
|
|
2563
|
+
if (control.lock) setValued(doc, sdtPr, "lock", control.lock);
|
|
2564
|
+
if (control.showingPlaceholder) place(sdtPr, makeW(doc, "showingPlcHdr"));
|
|
2565
|
+
switch (control.kind) {
|
|
2566
|
+
case "text": {
|
|
2567
|
+
const text2 = makeW(doc, "text");
|
|
2568
|
+
if (control.multiLine) text2.setAttributeNS(WORD_NS, "w:multiLine", "1");
|
|
2569
|
+
sdtPr.appendChild(text2);
|
|
2570
|
+
break;
|
|
2571
|
+
}
|
|
2572
|
+
case "checkbox":
|
|
2573
|
+
writeCheckbox(doc, sdtPr, control);
|
|
2574
|
+
break;
|
|
2575
|
+
case "dropDownList":
|
|
2576
|
+
case "comboBox":
|
|
2577
|
+
sdtPr.appendChild(makeW(doc, control.kind));
|
|
2578
|
+
writeItems(doc, sdtPr, control);
|
|
2579
|
+
break;
|
|
2580
|
+
case "date":
|
|
2581
|
+
sdtPr.appendChild(makeW(doc, "date"));
|
|
2582
|
+
writeDate(doc, sdtPr, control);
|
|
2583
|
+
break;
|
|
2584
|
+
case "richText":
|
|
2585
|
+
break;
|
|
2586
|
+
default:
|
|
2587
|
+
sdtPr.appendChild(makeW(doc, control.kind));
|
|
2588
|
+
}
|
|
2589
|
+
return sdtPr;
|
|
2590
|
+
}
|
|
2591
|
+
function createContentControl(doc, control) {
|
|
2592
|
+
const sdt = makeW(doc, "sdt");
|
|
2593
|
+
sdt.appendChild(buildProperties(doc, control));
|
|
2594
|
+
const content = makeW(doc, "sdtContent");
|
|
2595
|
+
sdt.appendChild(content);
|
|
2596
|
+
patchContentControl(doc, sdt, control);
|
|
2597
|
+
return { sdt, content };
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2299
2600
|
// docx/comment-spans.ts
|
|
2300
2601
|
function rangeKeys(run) {
|
|
2301
2602
|
const keys = (run.commentIds ?? []).map((id) => `comment:${id}`);
|
|
@@ -2381,14 +2682,6 @@ function rangeEdges(runs, ranges) {
|
|
|
2381
2682
|
return { opens, closes };
|
|
2382
2683
|
}
|
|
2383
2684
|
|
|
2384
|
-
// docx/expect-defined.ts
|
|
2385
|
-
function expectDefined2(value, context) {
|
|
2386
|
-
if (value === void 0 || value === null) {
|
|
2387
|
-
throw new Error(`Internal invariant violated: ${context} is missing.`);
|
|
2388
|
-
}
|
|
2389
|
-
return value;
|
|
2390
|
-
}
|
|
2391
|
-
|
|
2392
2685
|
// docx/element-order.ts
|
|
2393
2686
|
var RPR_ORDER = [
|
|
2394
2687
|
"rStyle",
|
|
@@ -2440,9 +2733,9 @@ function orderChildren(parent, order) {
|
|
|
2440
2733
|
const elements2 = Array.from(parent.childNodes).filter(isElement);
|
|
2441
2734
|
let previousRank = -1;
|
|
2442
2735
|
const ranked = elements2.map((element, index) => {
|
|
2443
|
-
const
|
|
2444
|
-
if (
|
|
2445
|
-
return { element, index, rank:
|
|
2736
|
+
const rank2 = element.namespaceURI === WORD_NS ? order.indexOf(element.localName ?? "") : -1;
|
|
2737
|
+
if (rank2 >= 0) previousRank = rank2;
|
|
2738
|
+
return { element, index, rank: rank2 >= 0 ? rank2 : previousRank + 0.5 };
|
|
2446
2739
|
});
|
|
2447
2740
|
const sorted = [...ranked].sort((a, b) => a.rank - b.rank || a.index - b.index);
|
|
2448
2741
|
if (sorted.every((entry, index) => entry.element === elements2[index])) return;
|
|
@@ -2706,9 +2999,9 @@ function reconcileBookmarks(doc, starts, ends, names, baseNames, nextId) {
|
|
|
2706
2999
|
return !removed;
|
|
2707
3000
|
});
|
|
2708
3001
|
const keptEnds = ends.filter((end) => !removedIds.has(getW(end, "id") ?? ""));
|
|
2709
|
-
const
|
|
3002
|
+
const present2 = new Set(keptStarts.map((start) => getW(start, "name")));
|
|
2710
3003
|
for (const name of names) {
|
|
2711
|
-
if (
|
|
3004
|
+
if (present2.has(name)) continue;
|
|
2712
3005
|
const id = nextId();
|
|
2713
3006
|
const start = makeW(doc, "bookmarkStart");
|
|
2714
3007
|
start.setAttributeNS(WORD_NS, "w:id", id);
|
|
@@ -2761,7 +3054,7 @@ function parsePropertiesSnapshot(xml, local) {
|
|
|
2761
3054
|
}
|
|
2762
3055
|
|
|
2763
3056
|
// docx/write-revisions.ts
|
|
2764
|
-
var
|
|
3057
|
+
var REVISION_WRAPPER_NAMES2 = ["ins", "del", "moveFrom", "moveTo"];
|
|
2765
3058
|
var COMMENT_ANCHOR_NAMES = [
|
|
2766
3059
|
"commentRangeStart",
|
|
2767
3060
|
"commentRangeEnd",
|
|
@@ -2774,7 +3067,7 @@ var COMMENT_ANCHOR_NAMES = [
|
|
|
2774
3067
|
function isWordElement(element, names) {
|
|
2775
3068
|
return (!element.namespaceURI || element.namespaceURI === WORD_NS) && names.includes(element.localName);
|
|
2776
3069
|
}
|
|
2777
|
-
var isRevisionWrapperElement = (element) => isWordElement(element,
|
|
3070
|
+
var isRevisionWrapperElement = (element) => isWordElement(element, REVISION_WRAPPER_NAMES2);
|
|
2778
3071
|
var isCommentAnchorElement = (element) => isWordElement(element, COMMENT_ANCHOR_NAMES);
|
|
2779
3072
|
function setAttribute4(element, local, value) {
|
|
2780
3073
|
element.setAttributeNS(WORD_NS, `w:${local}`, value);
|
|
@@ -3249,6 +3542,110 @@ function svgDropShadowElement(s, format) {
|
|
|
3249
3542
|
const num = format.number;
|
|
3250
3543
|
return `<feDropShadow dx="${num(s.dx)}" dy="${num(s.dy)}" stdDeviation="${num(s.blur / 2)}" flood-color="${format.color(s.color, "#000000")}" flood-opacity="${num(s.opacity)}" result="shadow"/>`;
|
|
3251
3544
|
}
|
|
3545
|
+
|
|
3546
|
+
// drawingml/write-color.ts
|
|
3547
|
+
var ELEMENTS = {
|
|
3548
|
+
srgb: "srgbClr",
|
|
3549
|
+
scheme: "schemeClr",
|
|
3550
|
+
system: "sysClr",
|
|
3551
|
+
preset: "prstClr",
|
|
3552
|
+
scrgb: "scrgbClr",
|
|
3553
|
+
hsl: "hslClr"
|
|
3554
|
+
};
|
|
3555
|
+
function drawingColorXml(color) {
|
|
3556
|
+
const local = ELEMENTS[color.kind];
|
|
3557
|
+
const doc = parseXml(`<a:${local} xmlns:a="${NS.a}"/>`);
|
|
3558
|
+
const root = doc.documentElement;
|
|
3559
|
+
if (color.kind === "scrgb" || color.kind === "hsl") {
|
|
3560
|
+
const keys = color.kind === "scrgb" ? ["r", "g", "b"] : ["hue", "sat", "lum"];
|
|
3561
|
+
const values = color.value.split(",");
|
|
3562
|
+
keys.forEach((key, i) => root.setAttribute(key, values[i] ?? "0"));
|
|
3563
|
+
} else root.setAttribute("val", color.value);
|
|
3564
|
+
if (color.fallback !== void 0 && color.kind === "system")
|
|
3565
|
+
root.setAttribute("lastClr", color.fallback);
|
|
3566
|
+
for (const transform of color.transforms) {
|
|
3567
|
+
if (!/^[A-Za-z_][\w.-]*$/.test(transform.name))
|
|
3568
|
+
throw new Error(`Invalid DrawingML transform ${transform.name}`);
|
|
3569
|
+
const node = doc.createElementNS(NS.a, `a:${transform.name}`);
|
|
3570
|
+
if (transform.value !== "") node.setAttribute("val", transform.value);
|
|
3571
|
+
root.appendChild(node);
|
|
3572
|
+
}
|
|
3573
|
+
return buildXml(doc);
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3576
|
+
// drawingml/write-fill.ts
|
|
3577
|
+
function drawingFillXml(fill) {
|
|
3578
|
+
if (fill.kind === "none") return "<a:noFill/>";
|
|
3579
|
+
if (fill.kind === "solid") return `<a:solidFill>${drawingColorXml(fill.color)}</a:solidFill>`;
|
|
3580
|
+
if (fill.kind !== "gradient") return void 0;
|
|
3581
|
+
const doc = parseXml(fill.sourceXml ?? `<a:gradFill xmlns:a="${NS.a}"/>`);
|
|
3582
|
+
const root = doc.documentElement;
|
|
3583
|
+
if (root.namespaceURI !== NS.a || root.localName !== "gradFill")
|
|
3584
|
+
throw new Error("Invalid gradient source XML");
|
|
3585
|
+
const fragment = (xml) => doc.importNode(elements(parseXml(`<w xmlns:a="${NS.a}">${xml}</w>`).documentElement)[0], true);
|
|
3586
|
+
let list = first(root, "gsLst", NS.a);
|
|
3587
|
+
if (!list) {
|
|
3588
|
+
list = doc.createElementNS(NS.a, "a:gsLst");
|
|
3589
|
+
root.insertBefore(list, root.firstChild);
|
|
3590
|
+
}
|
|
3591
|
+
const stops = children(list, "gs", NS.a).filter(
|
|
3592
|
+
(node) => parseDrawingColorIn(node) && Number.isFinite(Number.parseInt(node.getAttribute("pos") ?? "", 10))
|
|
3593
|
+
);
|
|
3594
|
+
fill.stops.forEach((stop, index) => {
|
|
3595
|
+
const node = stops[index] ?? doc.createElementNS(NS.a, "a:gs");
|
|
3596
|
+
if (!node.parentNode) list.appendChild(node);
|
|
3597
|
+
node.setAttribute("pos", String(Math.round(stop.position * 1e3)));
|
|
3598
|
+
for (const old of elements(node))
|
|
3599
|
+
if (old.namespaceURI === NS.a && old.localName.endsWith("Clr")) node.removeChild(old);
|
|
3600
|
+
node.insertBefore(fragment(drawingColorXml(stop.color)), node.firstChild);
|
|
3601
|
+
});
|
|
3602
|
+
for (const stop of stops.slice(fill.stops.length)) list.removeChild(stop);
|
|
3603
|
+
for (const node of elements(root))
|
|
3604
|
+
if (node.namespaceURI === NS.a && (node.localName === "lin" && (fill.angle === void 0 || fill.path !== void 0) || node.localName === "path" && fill.path === void 0))
|
|
3605
|
+
root.removeChild(node);
|
|
3606
|
+
if (fill.angle !== void 0 && fill.path === void 0) {
|
|
3607
|
+
let linear = first(root, "lin", NS.a);
|
|
3608
|
+
if (!linear) {
|
|
3609
|
+
linear = doc.createElementNS(NS.a, "a:lin");
|
|
3610
|
+
root.insertBefore(
|
|
3611
|
+
linear,
|
|
3612
|
+
first(root, "tileRect", NS.a) ?? first(root, "extLst", NS.a) ?? null
|
|
3613
|
+
);
|
|
3614
|
+
}
|
|
3615
|
+
linear.setAttribute("ang", String(Math.round(fill.angle * 6e4)));
|
|
3616
|
+
if (fill.scaled !== void 0) linear.setAttribute("scaled", fill.scaled ? "1" : "0");
|
|
3617
|
+
}
|
|
3618
|
+
if (fill.path !== void 0) {
|
|
3619
|
+
let path = first(root, "path", NS.a);
|
|
3620
|
+
if (!path) {
|
|
3621
|
+
path = doc.createElementNS(NS.a, "a:path");
|
|
3622
|
+
root.insertBefore(path, first(root, "tileRect", NS.a) ?? first(root, "extLst", NS.a) ?? null);
|
|
3623
|
+
}
|
|
3624
|
+
path.setAttribute("path", fill.path);
|
|
3625
|
+
if (!fill.fillToRect) {
|
|
3626
|
+
const old = first(path, "fillToRect", NS.a);
|
|
3627
|
+
if (old) path.removeChild(old);
|
|
3628
|
+
} else {
|
|
3629
|
+
let focus = first(path, "fillToRect", NS.a);
|
|
3630
|
+
if (!focus) {
|
|
3631
|
+
focus = doc.createElementNS(NS.a, "a:fillToRect");
|
|
3632
|
+
path.appendChild(focus);
|
|
3633
|
+
}
|
|
3634
|
+
for (const [key, value] of Object.entries(fill.fillToRect))
|
|
3635
|
+
focus.setAttribute(key, String(Math.round(value * 1e5)));
|
|
3636
|
+
}
|
|
3637
|
+
}
|
|
3638
|
+
if (fill.tileRect) {
|
|
3639
|
+
let tile = first(root, "tileRect", NS.a);
|
|
3640
|
+
if (!tile) {
|
|
3641
|
+
tile = doc.createElementNS(NS.a, "a:tileRect");
|
|
3642
|
+
root.insertBefore(tile, first(root, "extLst", NS.a) ?? null);
|
|
3643
|
+
}
|
|
3644
|
+
for (const [key, value] of Object.entries(fill.tileRect))
|
|
3645
|
+
tile.setAttribute(key, String(Math.round(value * 1e5)));
|
|
3646
|
+
}
|
|
3647
|
+
return buildXml(doc);
|
|
3648
|
+
}
|
|
3252
3649
|
function hexToRgb(color) {
|
|
3253
3650
|
const parsed = hexToRgbChannels(color);
|
|
3254
3651
|
if (parsed) return parsed;
|
|
@@ -3272,21 +3669,21 @@ function lerpStops(a, b, t) {
|
|
|
3272
3669
|
opacity: oa + (ob - oa) * t
|
|
3273
3670
|
};
|
|
3274
3671
|
}
|
|
3275
|
-
function colorAt(stops,
|
|
3672
|
+
function colorAt(stops, position2) {
|
|
3276
3673
|
const first3 = stops[0];
|
|
3277
3674
|
const last = stops[stops.length - 1];
|
|
3278
|
-
if (
|
|
3675
|
+
if (position2 <= first3.position) {
|
|
3279
3676
|
return { color: first3.color, opacity: first3.opacity ?? 1 };
|
|
3280
3677
|
}
|
|
3281
|
-
if (
|
|
3678
|
+
if (position2 >= last.position) {
|
|
3282
3679
|
return { color: last.color, opacity: last.opacity ?? 1 };
|
|
3283
3680
|
}
|
|
3284
3681
|
for (let i = 0; i < stops.length - 1; i += 1) {
|
|
3285
3682
|
const from = stops[i];
|
|
3286
3683
|
const to = stops[i + 1];
|
|
3287
|
-
if (
|
|
3684
|
+
if (position2 >= from.position && position2 <= to.position) {
|
|
3288
3685
|
const span = to.position - from.position;
|
|
3289
|
-
const t = span > 0 ? (
|
|
3686
|
+
const t = span > 0 ? (position2 - from.position) / span : 0;
|
|
3290
3687
|
return lerpStops(from, to, t);
|
|
3291
3688
|
}
|
|
3292
3689
|
}
|
|
@@ -3343,8 +3740,714 @@ function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
|
|
|
3343
3740
|
);
|
|
3344
3741
|
}
|
|
3345
3742
|
}
|
|
3346
|
-
const
|
|
3347
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="none">${
|
|
3743
|
+
const paint2 = masked ? `<defs><mask id="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="100" height="100" mask-type="luminance" color-interpolation="sRGB">${alphaRects.join("")}</mask></defs><g mask="url(#alpha)">${rects.join("")}</g>` : rects.join("");
|
|
3744
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="none">${paint2}</svg>`;
|
|
3745
|
+
}
|
|
3746
|
+
|
|
3747
|
+
// docx/shape-parse.ts
|
|
3748
|
+
var A_NS2 = "http://schemas.openxmlformats.org/drawingml/2006/main";
|
|
3749
|
+
var WPS_NS2 = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
|
|
3750
|
+
var W_NS2 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
3751
|
+
|
|
3752
|
+
// chart/regression.ts
|
|
3753
|
+
function computeLinearRegression(xVals, yVals) {
|
|
3754
|
+
const n2 = xVals.length;
|
|
3755
|
+
if (n2 < 2) {
|
|
3756
|
+
return { slope: 0, intercept: 0, rSquared: 0 };
|
|
3757
|
+
}
|
|
3758
|
+
let sumX = 0;
|
|
3759
|
+
let sumY = 0;
|
|
3760
|
+
let sumXY = 0;
|
|
3761
|
+
let sumXX = 0;
|
|
3762
|
+
for (let i = 0; i < n2; i++) {
|
|
3763
|
+
sumX += xVals[i];
|
|
3764
|
+
sumY += yVals[i];
|
|
3765
|
+
sumXY += xVals[i] * yVals[i];
|
|
3766
|
+
sumXX += xVals[i] * xVals[i];
|
|
3767
|
+
}
|
|
3768
|
+
const denom = n2 * sumXX - sumX * sumX;
|
|
3769
|
+
if (Math.abs(denom) < 1e-12) {
|
|
3770
|
+
return { slope: 0, intercept: sumY / n2, rSquared: 0 };
|
|
3771
|
+
}
|
|
3772
|
+
const slope = (n2 * sumXY - sumX * sumY) / denom;
|
|
3773
|
+
const intercept = (sumY - slope * sumX) / n2;
|
|
3774
|
+
const ssRes = yVals.reduce((s, y, i) => s + (y - (slope * xVals[i] + intercept)) ** 2, 0);
|
|
3775
|
+
const meanY = sumY / n2;
|
|
3776
|
+
const ssTot = yVals.reduce((s, y) => s + (y - meanY) ** 2, 0);
|
|
3777
|
+
const rSquared = ssTot > 0 ? 1 - ssRes / ssTot : 0;
|
|
3778
|
+
return { slope, intercept, rSquared };
|
|
3779
|
+
}
|
|
3780
|
+
function fitPolynomial(xVals, yVals, order) {
|
|
3781
|
+
const n2 = xVals.length;
|
|
3782
|
+
const m = order + 1;
|
|
3783
|
+
const matrix = Array.from({ length: m }, () => Array(m + 1).fill(0));
|
|
3784
|
+
for (let i = 0; i < m; i++) {
|
|
3785
|
+
for (let j = 0; j < m; j++) {
|
|
3786
|
+
let sum2 = 0;
|
|
3787
|
+
for (let k = 0; k < n2; k++) {
|
|
3788
|
+
sum2 += xVals[k] ** (i + j);
|
|
3789
|
+
}
|
|
3790
|
+
matrix[i][j] = sum2;
|
|
3791
|
+
}
|
|
3792
|
+
let sum = 0;
|
|
3793
|
+
for (let k = 0; k < n2; k++) {
|
|
3794
|
+
sum += yVals[k] * xVals[k] ** i;
|
|
3795
|
+
}
|
|
3796
|
+
matrix[i][m] = sum;
|
|
3797
|
+
}
|
|
3798
|
+
for (let i = 0; i < m; i++) {
|
|
3799
|
+
let maxRow = i;
|
|
3800
|
+
for (let k = i + 1; k < m; k++) {
|
|
3801
|
+
if (Math.abs(matrix[k][i]) > Math.abs(matrix[maxRow][i])) {
|
|
3802
|
+
maxRow = k;
|
|
3803
|
+
}
|
|
3804
|
+
}
|
|
3805
|
+
[matrix[i], matrix[maxRow]] = [matrix[maxRow], matrix[i]];
|
|
3806
|
+
const pivot = matrix[i][i];
|
|
3807
|
+
if (Math.abs(pivot) < 1e-12) {
|
|
3808
|
+
continue;
|
|
3809
|
+
}
|
|
3810
|
+
for (let j = i; j <= m; j++) {
|
|
3811
|
+
matrix[i][j] = matrix[i][j] / pivot;
|
|
3812
|
+
}
|
|
3813
|
+
for (let k = 0; k < m; k++) {
|
|
3814
|
+
if (k === i) {
|
|
3815
|
+
continue;
|
|
3816
|
+
}
|
|
3817
|
+
const factor = matrix[k][i];
|
|
3818
|
+
for (let j = i; j <= m; j++) {
|
|
3819
|
+
matrix[k][j] = matrix[k][j] - factor * matrix[i][j];
|
|
3820
|
+
}
|
|
3821
|
+
}
|
|
3822
|
+
}
|
|
3823
|
+
return matrix.map((row) => row[m]);
|
|
3824
|
+
}
|
|
3825
|
+
function computeRSquared(xVals, yVals, evalFn) {
|
|
3826
|
+
const n2 = xVals.length;
|
|
3827
|
+
if (n2 === 0) {
|
|
3828
|
+
return 0;
|
|
3829
|
+
}
|
|
3830
|
+
const meanY = yVals.reduce((s, y) => s + y, 0) / n2;
|
|
3831
|
+
let ssRes = 0;
|
|
3832
|
+
let ssTot = 0;
|
|
3833
|
+
for (let i = 0; i < n2; i++) {
|
|
3834
|
+
ssRes += (yVals[i] - evalFn(xVals[i])) ** 2;
|
|
3835
|
+
ssTot += (yVals[i] - meanY) ** 2;
|
|
3836
|
+
}
|
|
3837
|
+
return ssTot > 0 ? 1 - ssRes / ssTot : 0;
|
|
3838
|
+
}
|
|
3839
|
+
|
|
3840
|
+
// chart/box-stats.ts
|
|
3841
|
+
function groupRowsByCategory(rawCategories) {
|
|
3842
|
+
const uniqueCategories = [];
|
|
3843
|
+
const rowIndexesByCategory = /* @__PURE__ */ new Map();
|
|
3844
|
+
rawCategories.forEach((rawLabel, rowIndex) => {
|
|
3845
|
+
const label = rawLabel ?? "";
|
|
3846
|
+
let rows = rowIndexesByCategory.get(label);
|
|
3847
|
+
if (!rows) {
|
|
3848
|
+
rows = [];
|
|
3849
|
+
rowIndexesByCategory.set(label, rows);
|
|
3850
|
+
uniqueCategories.push(label);
|
|
3851
|
+
}
|
|
3852
|
+
rows.push(rowIndex);
|
|
3853
|
+
});
|
|
3854
|
+
return { uniqueCategories, rowIndexesByCategory };
|
|
3855
|
+
}
|
|
3856
|
+
|
|
3857
|
+
// chart/bubble-radius.ts
|
|
3858
|
+
function computeBubbleRadius(sizeVal, maxBubble, medianRadius, options) {
|
|
3859
|
+
const scale = (options?.bubbleScale ?? 100) / 100;
|
|
3860
|
+
if (sizeVal === void 0) return medianRadius * scale;
|
|
3861
|
+
const denom = maxBubble > 0 ? maxBubble : 1;
|
|
3862
|
+
const magnitude = Math.abs(sizeVal);
|
|
3863
|
+
const ratio = (options?.sizeRepresents ?? "w") === "area" ? Math.sqrt(magnitude) / Math.sqrt(denom) : magnitude / denom;
|
|
3864
|
+
return medianRadius * scale * 0.5 + ratio * medianRadius * scale * 1.5;
|
|
3865
|
+
}
|
|
3866
|
+
function maxBubbleSize(sizes) {
|
|
3867
|
+
return sizes.length > 0 ? Math.max(1, ...sizes.map(Math.abs)) : 1;
|
|
3868
|
+
}
|
|
3869
|
+
function medianBubbleRadius(plotWidth, plotHeight) {
|
|
3870
|
+
return Math.min(plotWidth, plotHeight) * 0.04;
|
|
3871
|
+
}
|
|
3872
|
+
|
|
3873
|
+
// chart/stock-candles.ts
|
|
3874
|
+
var STOCK_DEFAULT_UP_FILL = "#FFFFFF";
|
|
3875
|
+
var STOCK_DEFAULT_DOWN_FILL = "#404040";
|
|
3876
|
+
var STOCK_DEFAULT_WICK_COLOR = "#334155";
|
|
3877
|
+
var STOCK_TICK_WIDTH = 1.5;
|
|
3878
|
+
function stockSlots(count, closeLast = false) {
|
|
3879
|
+
if (count < 3) return void 0;
|
|
3880
|
+
const four = count >= 4;
|
|
3881
|
+
return {
|
|
3882
|
+
...four ? { open: 0 } : {},
|
|
3883
|
+
high: four ? 1 : 0,
|
|
3884
|
+
low: four ? 2 : 1,
|
|
3885
|
+
close: closeLast ? count - 1 : four ? 3 : 2
|
|
3886
|
+
};
|
|
3887
|
+
}
|
|
3888
|
+
var present = (v) => v !== null && v !== void 0;
|
|
3889
|
+
function stockCandle(input) {
|
|
3890
|
+
const { high, low, close, open, x, band, y } = input;
|
|
3891
|
+
if (!present(high) || !present(low)) return void 0;
|
|
3892
|
+
const candleWidth = band * (input.bodyShare ?? 0.5);
|
|
3893
|
+
const candle = { wick: { x, y1: y(high), y2: y(low) } };
|
|
3894
|
+
if (input.hasOpen && present(open) && present(close)) {
|
|
3895
|
+
const openY = y(open);
|
|
3896
|
+
const closeY = y(close);
|
|
3897
|
+
candle.body = {
|
|
3898
|
+
x: x - candleWidth / 2,
|
|
3899
|
+
y: Math.min(openY, closeY),
|
|
3900
|
+
w: candleWidth,
|
|
3901
|
+
h: Math.max(Math.abs(openY - closeY), 1),
|
|
3902
|
+
up: close >= open
|
|
3903
|
+
};
|
|
3904
|
+
} else if (present(close)) {
|
|
3905
|
+
candle.tick = {
|
|
3906
|
+
x1: x,
|
|
3907
|
+
x2: x + Math.max(candleWidth * 0.4, 4),
|
|
3908
|
+
y: y(close)
|
|
3909
|
+
};
|
|
3910
|
+
}
|
|
3911
|
+
return candle;
|
|
3912
|
+
}
|
|
3913
|
+
|
|
3914
|
+
// chart/treemap-squarify.ts
|
|
3915
|
+
function worstAspectRatio(areas, side) {
|
|
3916
|
+
const sum = areas.reduce((total, area) => total + area, 0);
|
|
3917
|
+
const max = Math.max(...areas);
|
|
3918
|
+
const min = Math.min(...areas);
|
|
3919
|
+
const sideSq = side * side;
|
|
3920
|
+
const sumSq = sum * sum;
|
|
3921
|
+
return Math.max(sideSq * max / sumSq, sumSq / (sideSq * min));
|
|
3922
|
+
}
|
|
3923
|
+
function squarify(nodes, box) {
|
|
3924
|
+
const sorted = [...nodes].sort((a, b) => b.weight - a.weight);
|
|
3925
|
+
const total = sorted.reduce((sum, node) => sum + node.weight, 0);
|
|
3926
|
+
const scale = total > 0 ? box.w * box.h / total : box.w * box.h / sorted.length;
|
|
3927
|
+
const items = sorted.map((node) => ({ node, area: (total > 0 ? node.weight : 1) * scale }));
|
|
3928
|
+
const result = [];
|
|
3929
|
+
let rect2 = { ...box };
|
|
3930
|
+
let remaining = items;
|
|
3931
|
+
for (let first3 = remaining[0]; first3 !== void 0; first3 = remaining[0]) {
|
|
3932
|
+
const side = Math.min(rect2.w, rect2.h);
|
|
3933
|
+
let row = [first3];
|
|
3934
|
+
let rowAreas = [first3.area];
|
|
3935
|
+
let worst = worstAspectRatio(rowAreas, side);
|
|
3936
|
+
let cursor = 1;
|
|
3937
|
+
for (let next = remaining[cursor]; next !== void 0; next = remaining[cursor]) {
|
|
3938
|
+
const candidateAreas = [...rowAreas, next.area];
|
|
3939
|
+
const candidateWorst = worstAspectRatio(candidateAreas, side);
|
|
3940
|
+
if (candidateWorst > worst) {
|
|
3941
|
+
break;
|
|
3942
|
+
}
|
|
3943
|
+
row = [...row, next];
|
|
3944
|
+
rowAreas = candidateAreas;
|
|
3945
|
+
worst = candidateWorst;
|
|
3946
|
+
cursor++;
|
|
3947
|
+
}
|
|
3948
|
+
const rowTotalArea = rowAreas.reduce((sum, area) => sum + area, 0);
|
|
3949
|
+
const thickness = side > 0 ? rowTotalArea / side : 0;
|
|
3950
|
+
const layoutVertically = rect2.w >= rect2.h;
|
|
3951
|
+
let offset = layoutVertically ? rect2.y : rect2.x;
|
|
3952
|
+
for (const item of row) {
|
|
3953
|
+
const length = thickness > 0 ? item.area / thickness : 0;
|
|
3954
|
+
if (layoutVertically) {
|
|
3955
|
+
result.push([item.node, { x: rect2.x, y: offset, w: thickness, h: length }]);
|
|
3956
|
+
} else {
|
|
3957
|
+
result.push([item.node, { x: offset, y: rect2.y, w: length, h: thickness }]);
|
|
3958
|
+
}
|
|
3959
|
+
offset += length;
|
|
3960
|
+
}
|
|
3961
|
+
rect2 = layoutVertically ? { ...rect2, x: rect2.x + thickness, w: rect2.w - thickness } : { ...rect2, y: rect2.y + thickness, h: rect2.h - thickness };
|
|
3962
|
+
remaining = remaining.slice(row.length);
|
|
3963
|
+
}
|
|
3964
|
+
return result;
|
|
3965
|
+
}
|
|
3966
|
+
|
|
3967
|
+
// chart/hierarchy.ts
|
|
3968
|
+
function normalizeLevels(levels, pointCount) {
|
|
3969
|
+
return levels.map((level) => {
|
|
3970
|
+
let previous = "";
|
|
3971
|
+
return Array.from({ length: pointCount }, (_, index) => {
|
|
3972
|
+
const label = level[index]?.trim() ?? "";
|
|
3973
|
+
if (label) previous = label;
|
|
3974
|
+
return label || previous;
|
|
3975
|
+
});
|
|
3976
|
+
});
|
|
3977
|
+
}
|
|
3978
|
+
function findOrAddParent(children3, label, colorIndex, parentLabelLayout) {
|
|
3979
|
+
const existing = children3.find((child) => child.children && child.label === label);
|
|
3980
|
+
if (existing?.children) return existing;
|
|
3981
|
+
const parent = { label, weight: 0, children: [], colorIndex, parentLabelLayout };
|
|
3982
|
+
children3.push(parent);
|
|
3983
|
+
return parent;
|
|
3984
|
+
}
|
|
3985
|
+
function buildSeriesHierarchy(series, seriesIndex, categoryLabels, categoryLevels, colorStride) {
|
|
3986
|
+
const pointCount = series.values.length;
|
|
3987
|
+
const levels = normalizeLevels(categoryLevels ?? [], pointCount);
|
|
3988
|
+
const layout = series.parentLabelLayout ?? "banner";
|
|
3989
|
+
const roots = [];
|
|
3990
|
+
for (let pointIndex = 0; pointIndex < pointCount; pointIndex++) {
|
|
3991
|
+
let children3 = roots;
|
|
3992
|
+
for (let levelIndex = levels.length - 1; levelIndex >= 1; levelIndex--) {
|
|
3993
|
+
const label = levels[levelIndex]?.[pointIndex] || `Group ${levelIndex}`;
|
|
3994
|
+
children3 = findOrAddParent(children3, label, pointIndex, layout).children;
|
|
3995
|
+
}
|
|
3996
|
+
children3.push({
|
|
3997
|
+
label: levels[0]?.[pointIndex] || categoryLabels[pointIndex] || String(pointIndex + 1),
|
|
3998
|
+
weight: Math.abs(series.values[pointIndex] ?? 0),
|
|
3999
|
+
seriesIndex,
|
|
4000
|
+
pointIndex,
|
|
4001
|
+
colorIndex: seriesIndex * colorStride + pointIndex,
|
|
4002
|
+
parentLabelLayout: layout
|
|
4003
|
+
});
|
|
4004
|
+
}
|
|
4005
|
+
return roots;
|
|
4006
|
+
}
|
|
4007
|
+
function aggregate(node) {
|
|
4008
|
+
if (node.children) node.weight = node.children.reduce((sum, child) => sum + aggregate(child), 0);
|
|
4009
|
+
return node.weight;
|
|
4010
|
+
}
|
|
4011
|
+
function propagateColor(node, colorIndex) {
|
|
4012
|
+
node.colorIndex = colorIndex;
|
|
4013
|
+
for (const child of node.children ?? []) propagateColor(child, colorIndex);
|
|
4014
|
+
}
|
|
4015
|
+
function buildHierarchyRoots(series, categoryLabels, categoryLevels) {
|
|
4016
|
+
const colorStride = Math.max(categoryLabels.length, ...series.map((s) => s.values.length), 1);
|
|
4017
|
+
let roots = series.flatMap(
|
|
4018
|
+
(s, index) => buildSeriesHierarchy(s, index, categoryLabels, categoryLevels, colorStride)
|
|
4019
|
+
);
|
|
4020
|
+
if (series.length > 1)
|
|
4021
|
+
roots = series.map((s, index) => ({
|
|
4022
|
+
label: s.name,
|
|
4023
|
+
weight: 0,
|
|
4024
|
+
children: buildSeriesHierarchy(s, index, categoryLabels, categoryLevels, colorStride),
|
|
4025
|
+
colorIndex: index * colorStride,
|
|
4026
|
+
parentLabelLayout: s.parentLabelLayout ?? "banner"
|
|
4027
|
+
}));
|
|
4028
|
+
for (const root of roots) aggregate(root);
|
|
4029
|
+
roots.forEach((root, index) => propagateColor(root, index));
|
|
4030
|
+
return roots;
|
|
4031
|
+
}
|
|
4032
|
+
function hierarchyBranchLabels(series, categoryLabels, categoryLevels) {
|
|
4033
|
+
if (series.length > 1) return series.map((s) => s.name);
|
|
4034
|
+
if (categoryLevels && categoryLevels.length > 1) {
|
|
4035
|
+
const pointCount = series[0]?.values.length ?? categoryLabels.length;
|
|
4036
|
+
const topLevel = normalizeLevels(categoryLevels, pointCount).at(-1) ?? [];
|
|
4037
|
+
const seen = [];
|
|
4038
|
+
for (const label of topLevel) if (!seen.includes(label)) seen.push(label);
|
|
4039
|
+
return seen;
|
|
4040
|
+
}
|
|
4041
|
+
return [...categoryLabels];
|
|
4042
|
+
}
|
|
4043
|
+
var BANNER_HEIGHT = 16;
|
|
4044
|
+
function layoutTreemap(nodes, box) {
|
|
4045
|
+
const cells = [];
|
|
4046
|
+
for (const [node, allocation] of squarify(nodes, box)) {
|
|
4047
|
+
const cell = {
|
|
4048
|
+
x: allocation.x + 1,
|
|
4049
|
+
y: allocation.y + 1,
|
|
4050
|
+
w: Math.max(allocation.w - 2, 1),
|
|
4051
|
+
h: Math.max(allocation.h - 2, 1)
|
|
4052
|
+
};
|
|
4053
|
+
if (node.children) {
|
|
4054
|
+
const showParent = node.parentLabelLayout !== "none" && cell.w > 28 && cell.h > 16;
|
|
4055
|
+
if (showParent)
|
|
4056
|
+
cells.push({ kind: "parent", label: node.label, x: cell.x + 4, y: cell.y + 11 });
|
|
4057
|
+
const banner = showParent && node.parentLabelLayout === "banner" ? BANNER_HEIGHT : 0;
|
|
4058
|
+
cells.push(
|
|
4059
|
+
...layoutTreemap(node.children, {
|
|
4060
|
+
...cell,
|
|
4061
|
+
y: cell.y + banner,
|
|
4062
|
+
h: Math.max(cell.h - banner, 1)
|
|
4063
|
+
})
|
|
4064
|
+
);
|
|
4065
|
+
continue;
|
|
4066
|
+
}
|
|
4067
|
+
cells.push({
|
|
4068
|
+
kind: "leaf",
|
|
4069
|
+
...cell,
|
|
4070
|
+
label: node.label,
|
|
4071
|
+
colorIndex: node.colorIndex,
|
|
4072
|
+
seriesIndex: node.seriesIndex ?? 0,
|
|
4073
|
+
pointIndex: node.pointIndex ?? 0,
|
|
4074
|
+
labelFits: cell.w > 30 && cell.h > 14,
|
|
4075
|
+
labelSize: Math.min(10, cell.h * 0.3)
|
|
4076
|
+
});
|
|
4077
|
+
}
|
|
4078
|
+
return cells;
|
|
4079
|
+
}
|
|
4080
|
+
|
|
4081
|
+
// chart/sunburst-arcs.ts
|
|
4082
|
+
function arcLabelPlacement(cx, cy, radius, startAngle, endAngle) {
|
|
4083
|
+
const midAngle = (startAngle + endAngle) / 2;
|
|
4084
|
+
let rotation = midAngle * 180 / Math.PI + 90;
|
|
4085
|
+
if (rotation > 90 && rotation < 270) rotation -= 180;
|
|
4086
|
+
return {
|
|
4087
|
+
labelX: cx + radius * Math.cos(midAngle),
|
|
4088
|
+
labelY: cy + radius * Math.sin(midAngle),
|
|
4089
|
+
labelRotation: rotation
|
|
4090
|
+
};
|
|
4091
|
+
}
|
|
4092
|
+
function sunburstArcPath(cx, cy, innerRadius, outerRadius, startAngle, endAngle) {
|
|
4093
|
+
const sweep = endAngle - startAngle;
|
|
4094
|
+
const largeArc = sweep > Math.PI ? 1 : 0;
|
|
4095
|
+
const x1 = cx + outerRadius * Math.cos(startAngle);
|
|
4096
|
+
const y1 = cy + outerRadius * Math.sin(startAngle);
|
|
4097
|
+
const x2 = cx + outerRadius * Math.cos(endAngle);
|
|
4098
|
+
const y2 = cy + outerRadius * Math.sin(endAngle);
|
|
4099
|
+
const x3 = cx + innerRadius * Math.cos(endAngle);
|
|
4100
|
+
const y3 = cy + innerRadius * Math.sin(endAngle);
|
|
4101
|
+
const x4 = cx + innerRadius * Math.cos(startAngle);
|
|
4102
|
+
const y4 = cy + innerRadius * Math.sin(startAngle);
|
|
4103
|
+
return `M ${x1} ${y1} A ${outerRadius} ${outerRadius} 0 ${largeArc} 1 ${x2} ${y2} L ${x3} ${y3} A ${innerRadius} ${innerRadius} 0 ${largeArc} 0 ${x4} ${y4} Z`;
|
|
4104
|
+
}
|
|
4105
|
+
function computeSunburstArcs(series, cx, cy, maxR) {
|
|
4106
|
+
const seriesCount = Math.max(series.length, 1);
|
|
4107
|
+
const ringWidth = maxR / (seriesCount + 0.5);
|
|
4108
|
+
const out = [];
|
|
4109
|
+
series.forEach((s, si) => {
|
|
4110
|
+
const values = s.values;
|
|
4111
|
+
const innerRadius = ringWidth * (si + 0.5);
|
|
4112
|
+
const outerRadius = ringWidth * (si + 1.5);
|
|
4113
|
+
const total = values.reduce((acc, value) => acc + Math.abs(value), 0) || 1;
|
|
4114
|
+
let startAngle = -Math.PI / 2;
|
|
4115
|
+
for (let pointIndex = 0; pointIndex < values.length; pointIndex++) {
|
|
4116
|
+
const endAngle = startAngle + Math.abs(values[pointIndex] ?? 0) / total * Math.PI * 2;
|
|
4117
|
+
out.push({
|
|
4118
|
+
d: sunburstArcPath(cx, cy, innerRadius, outerRadius, startAngle, endAngle),
|
|
4119
|
+
colorIndex: pointIndex,
|
|
4120
|
+
opacity: Math.max(0.1, 0.9 - si * 0.1),
|
|
4121
|
+
pointIndex,
|
|
4122
|
+
level: si,
|
|
4123
|
+
...arcLabelPlacement(cx, cy, (innerRadius + outerRadius) / 2, startAngle, endAngle)
|
|
4124
|
+
});
|
|
4125
|
+
startAngle = endAngle;
|
|
4126
|
+
}
|
|
4127
|
+
});
|
|
4128
|
+
return out;
|
|
4129
|
+
}
|
|
4130
|
+
function hierarchyKey(levels, level, index) {
|
|
4131
|
+
return levels.slice(level).map((labels) => labels[index] ?? "").join("\0");
|
|
4132
|
+
}
|
|
4133
|
+
function computeHierarchicalSunburstArcs(categoryLevels, values, cx, cy, maxR) {
|
|
4134
|
+
const levels = categoryLevels.filter((level) => level.length > 0);
|
|
4135
|
+
const leafCount = Math.max(values.length, ...levels.map((level) => level.length), 0);
|
|
4136
|
+
if (levels.length === 0 || leafCount === 0) return [];
|
|
4137
|
+
const rawWeights = Array.from({ length: leafCount }, (_, index) => Math.abs(values[index] ?? 0));
|
|
4138
|
+
const weights = rawWeights.some((value) => value !== 0) ? rawWeights : rawWeights.map(() => 1);
|
|
4139
|
+
const total = weights.reduce((sum, value) => sum + value, 0);
|
|
4140
|
+
const prefix = [0];
|
|
4141
|
+
for (const weight of weights) prefix.push((prefix[prefix.length - 1] ?? 0) + weight);
|
|
4142
|
+
const ringWidth = maxR / (levels.length + 0.5);
|
|
4143
|
+
const rootLabels = levels[levels.length - 1] ?? [];
|
|
4144
|
+
const rootColors = /* @__PURE__ */ new Map();
|
|
4145
|
+
const out = [];
|
|
4146
|
+
for (let level = levels.length - 1; level >= 0; level--) {
|
|
4147
|
+
const ringIndex = levels.length - 1 - level;
|
|
4148
|
+
const innerRadius = ringWidth * (ringIndex + 0.5);
|
|
4149
|
+
const outerRadius = ringWidth * (ringIndex + 1.5);
|
|
4150
|
+
let start = 0;
|
|
4151
|
+
while (start < leafCount) {
|
|
4152
|
+
const key = hierarchyKey(levels, level, start);
|
|
4153
|
+
let end = start + 1;
|
|
4154
|
+
while (end < leafCount && hierarchyKey(levels, level, end) === key) end++;
|
|
4155
|
+
const startAngle = -Math.PI / 2 + (prefix[start] ?? 0) / total * Math.PI * 2;
|
|
4156
|
+
const endAngle = -Math.PI / 2 + (prefix[end] ?? 0) / total * Math.PI * 2;
|
|
4157
|
+
const rootLabel = rootLabels[start] ?? "";
|
|
4158
|
+
if (!rootColors.has(rootLabel)) rootColors.set(rootLabel, rootColors.size);
|
|
4159
|
+
out.push({
|
|
4160
|
+
d: sunburstArcPath(cx, cy, innerRadius, outerRadius, startAngle, endAngle),
|
|
4161
|
+
colorIndex: rootColors.get(rootLabel) ?? start,
|
|
4162
|
+
opacity: Math.max(0.1, 0.9 - ringIndex * 0.1),
|
|
4163
|
+
level: ringIndex,
|
|
4164
|
+
label: levels[level]?.[start] ?? "",
|
|
4165
|
+
...level === 0 && end === start + 1 ? { pointIndex: start } : {},
|
|
4166
|
+
...arcLabelPlacement(cx, cy, (innerRadius + outerRadius) / 2, startAngle, endAngle)
|
|
4167
|
+
});
|
|
4168
|
+
start = end;
|
|
4169
|
+
}
|
|
4170
|
+
}
|
|
4171
|
+
return out;
|
|
4172
|
+
}
|
|
4173
|
+
|
|
4174
|
+
// chart/histogram-binning.ts
|
|
4175
|
+
function binLabel(lower, upper, closed, format) {
|
|
4176
|
+
return closed === "r" ? `(${format(lower)}, ${format(upper)}]` : `[${format(lower)}, ${format(upper)})`;
|
|
4177
|
+
}
|
|
4178
|
+
function scottBinCount(values, min, max) {
|
|
4179
|
+
if (values.length < 2 || max <= min) {
|
|
4180
|
+
return 1;
|
|
4181
|
+
}
|
|
4182
|
+
const mean = values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
4183
|
+
const variance = values.reduce((sum, value) => sum + (value - mean) ** 2, 0) / (values.length - 1);
|
|
4184
|
+
const sd = Math.sqrt(variance);
|
|
4185
|
+
if (!(sd > 0)) {
|
|
4186
|
+
return 1;
|
|
4187
|
+
}
|
|
4188
|
+
const width = 3.49 * sd * values.length ** (-1 / 3);
|
|
4189
|
+
return Math.max(1, Math.ceil((max - min) / width));
|
|
4190
|
+
}
|
|
4191
|
+
function computeHistogramBins(values, options, format = String) {
|
|
4192
|
+
const closed = options.intervalClosed ?? "l";
|
|
4193
|
+
const finite2 = values.map((value, sourceIndex) => ({ value, sourceIndex })).filter((item) => Number.isFinite(item.value));
|
|
4194
|
+
if (finite2.length === 0) {
|
|
4195
|
+
return [];
|
|
4196
|
+
}
|
|
4197
|
+
const underflow = typeof options.underflow === "number" ? options.underflow : void 0;
|
|
4198
|
+
const overflow = typeof options.overflow === "number" ? options.overflow : void 0;
|
|
4199
|
+
const under = underflow === void 0 ? [] : finite2.filter(
|
|
4200
|
+
(item) => closed === "r" ? item.value <= underflow : item.value < underflow
|
|
4201
|
+
);
|
|
4202
|
+
const over = overflow === void 0 ? [] : finite2.filter((item) => closed === "l" ? item.value >= overflow : item.value > overflow);
|
|
4203
|
+
const regular = finite2.filter((item) => !under.includes(item) && !over.includes(item));
|
|
4204
|
+
const result = [];
|
|
4205
|
+
if (underflow !== void 0) {
|
|
4206
|
+
result.push({
|
|
4207
|
+
value: under.length,
|
|
4208
|
+
label: `${closed === "r" ? "\u2264" : "<"} ${format(underflow)}`,
|
|
4209
|
+
sourceIndices: under.map((item) => item.sourceIndex)
|
|
4210
|
+
});
|
|
4211
|
+
}
|
|
4212
|
+
if (regular.length > 0) {
|
|
4213
|
+
const min = Math.min(...regular.map((item) => item.value));
|
|
4214
|
+
const max = Math.max(...regular.map((item) => item.value));
|
|
4215
|
+
const requestedSize = options.binSize && options.binSize > 0 ? options.binSize : void 0;
|
|
4216
|
+
const requestedCount = options.binCount && options.binCount > 0 ? options.binCount : void 0;
|
|
4217
|
+
const start = requestedSize ? Math.floor(min / requestedSize) * requestedSize : min;
|
|
4218
|
+
const count = requestedSize ? Math.max(
|
|
4219
|
+
closed === "l" ? Math.floor((max - start) / requestedSize) + 1 : Math.ceil((max - start) / requestedSize),
|
|
4220
|
+
1
|
|
4221
|
+
) : Math.max(
|
|
4222
|
+
requestedCount ?? scottBinCount(
|
|
4223
|
+
regular.map((item) => item.value),
|
|
4224
|
+
min,
|
|
4225
|
+
max
|
|
4226
|
+
),
|
|
4227
|
+
1
|
|
4228
|
+
);
|
|
4229
|
+
const width = requestedSize ?? Math.max((max - start) / count, 1);
|
|
4230
|
+
const bins = Array.from({ length: count }, (_, index) => ({
|
|
4231
|
+
value: 0,
|
|
4232
|
+
label: binLabel(start + index * width, start + (index + 1) * width, closed, format),
|
|
4233
|
+
sourceIndices: []
|
|
4234
|
+
}));
|
|
4235
|
+
for (const item of regular) {
|
|
4236
|
+
const rawIndex = closed === "r" ? Math.ceil((item.value - start) / width) - 1 : Math.floor((item.value - start) / width);
|
|
4237
|
+
const index = Math.max(0, Math.min(rawIndex, bins.length - 1));
|
|
4238
|
+
const bin = bins[index];
|
|
4239
|
+
if (!bin) continue;
|
|
4240
|
+
bin.value += 1;
|
|
4241
|
+
bin.sourceIndices.push(item.sourceIndex);
|
|
4242
|
+
}
|
|
4243
|
+
result.push(...bins);
|
|
4244
|
+
}
|
|
4245
|
+
if (overflow !== void 0) {
|
|
4246
|
+
result.push({
|
|
4247
|
+
value: over.length,
|
|
4248
|
+
label: `${closed === "l" ? "\u2265" : ">"} ${format(overflow)}`,
|
|
4249
|
+
sourceIndices: over.map((item) => item.sourceIndex)
|
|
4250
|
+
});
|
|
4251
|
+
}
|
|
4252
|
+
return result;
|
|
4253
|
+
}
|
|
4254
|
+
function aggregateByCategory(values, rawCategories) {
|
|
4255
|
+
const { uniqueCategories, rowIndexesByCategory } = groupRowsByCategory(rawCategories);
|
|
4256
|
+
return uniqueCategories.map((label) => {
|
|
4257
|
+
const rows = rowIndexesByCategory.get(label) ?? [];
|
|
4258
|
+
return {
|
|
4259
|
+
value: rows.reduce((sum, row) => sum + (values[row] ?? 0), 0),
|
|
4260
|
+
label,
|
|
4261
|
+
sourceIndices: rows
|
|
4262
|
+
};
|
|
4263
|
+
});
|
|
4264
|
+
}
|
|
4265
|
+
|
|
4266
|
+
// chart/waterfall.ts
|
|
4267
|
+
function buildWaterfallSteps(values, options) {
|
|
4268
|
+
const subtotalIndices = new Set(
|
|
4269
|
+
options?.subtotalIndices ?? (values.length > 0 ? [values.length - 1] : [])
|
|
4270
|
+
);
|
|
4271
|
+
const steps = [];
|
|
4272
|
+
let runningTotal = 0;
|
|
4273
|
+
for (let sourceIndex = 0; sourceIndex < values.length; sourceIndex++) {
|
|
4274
|
+
const value = values[sourceIndex] ?? 0;
|
|
4275
|
+
const isSubtotal = subtotalIndices.has(sourceIndex);
|
|
4276
|
+
const startValue = isSubtotal ? 0 : runningTotal;
|
|
4277
|
+
const endValue = isSubtotal ? value : runningTotal + value;
|
|
4278
|
+
steps.push({ sourceIndex, value, startValue, endValue, isSubtotal });
|
|
4279
|
+
runningTotal = endValue;
|
|
4280
|
+
}
|
|
4281
|
+
return steps;
|
|
4282
|
+
}
|
|
4283
|
+
|
|
4284
|
+
// chart/trendline-equation.ts
|
|
4285
|
+
var SIGNIFICANT_DIGITS = 4;
|
|
4286
|
+
function formatTrendlineCoefficient(value) {
|
|
4287
|
+
if (!Number.isFinite(value) || value === 0) {
|
|
4288
|
+
return "0";
|
|
4289
|
+
}
|
|
4290
|
+
const rounded = Number(value.toPrecision(SIGNIFICANT_DIGITS));
|
|
4291
|
+
return rounded === 0 ? "0" : String(rounded);
|
|
4292
|
+
}
|
|
4293
|
+
function signedTerm(value) {
|
|
4294
|
+
return { sign: value < 0 ? "-" : "+", abs: formatTrendlineCoefficient(Math.abs(value)) };
|
|
4295
|
+
}
|
|
4296
|
+
function formatLinearEquation(slope, intercept) {
|
|
4297
|
+
const { sign, abs } = signedTerm(intercept);
|
|
4298
|
+
return `y = ${formatTrendlineCoefficient(slope)}x ${sign} ${abs}`;
|
|
4299
|
+
}
|
|
4300
|
+
function formatExponentialEquation(a, b) {
|
|
4301
|
+
return `y = ${formatTrendlineCoefficient(a)} e^(${formatTrendlineCoefficient(b)}x)`;
|
|
4302
|
+
}
|
|
4303
|
+
function formatLogarithmicEquation(slope, intercept) {
|
|
4304
|
+
const { sign, abs } = signedTerm(intercept);
|
|
4305
|
+
return `y = ${formatTrendlineCoefficient(slope)}ln(x) ${sign} ${abs}`;
|
|
4306
|
+
}
|
|
4307
|
+
function formatPowerEquation(a, b) {
|
|
4308
|
+
return `y = ${formatTrendlineCoefficient(a)}x^${formatTrendlineCoefficient(b)}`;
|
|
4309
|
+
}
|
|
4310
|
+
function formatPolynomialEquation(coeffsAscending) {
|
|
4311
|
+
const order = coeffsAscending.length - 1;
|
|
4312
|
+
let out = "y = ";
|
|
4313
|
+
for (let power = order; power >= 0; power--) {
|
|
4314
|
+
const coeff = coeffsAscending[power] ?? 0;
|
|
4315
|
+
const { sign, abs } = signedTerm(coeff);
|
|
4316
|
+
const variable = power === 0 ? "" : power === 1 ? "x" : `x^${power}`;
|
|
4317
|
+
out += power === order ? `${sign === "-" ? "-" : ""}${abs}${variable}` : ` ${sign} ${abs}${variable}`;
|
|
4318
|
+
}
|
|
4319
|
+
return out;
|
|
4320
|
+
}
|
|
4321
|
+
|
|
4322
|
+
// chart/trendline-fit.ts
|
|
4323
|
+
var noFit = () => ({
|
|
4324
|
+
points: [],
|
|
4325
|
+
equation: "",
|
|
4326
|
+
rSquared: 0,
|
|
4327
|
+
coefficients: []
|
|
4328
|
+
});
|
|
4329
|
+
function fitModel(options, xVals, yVals) {
|
|
4330
|
+
const xs = [...xVals];
|
|
4331
|
+
const ys = [...yVals];
|
|
4332
|
+
switch (options.kind) {
|
|
4333
|
+
case "linear": {
|
|
4334
|
+
const reg = computeLinearRegression(xs, ys);
|
|
4335
|
+
const fixed = options.intercept;
|
|
4336
|
+
const slope = fixed !== void 0 ? ys.reduce((s, y, i) => s + (y - fixed) * xs[i], 0) / xs.reduce((s, x) => s + x * x, 0) : reg.slope;
|
|
4337
|
+
const b = fixed ?? reg.intercept;
|
|
4338
|
+
return {
|
|
4339
|
+
evaluate: (x) => slope * x + b,
|
|
4340
|
+
equation: formatLinearEquation(slope, b),
|
|
4341
|
+
rSquared: reg.rSquared,
|
|
4342
|
+
coefficients: [b, slope]
|
|
4343
|
+
};
|
|
4344
|
+
}
|
|
4345
|
+
case "exponential": {
|
|
4346
|
+
const logY = ys.filter((y) => y > 0).map((y) => Math.log(y));
|
|
4347
|
+
const posX = xs.filter((_x, i) => ys[i] > 0);
|
|
4348
|
+
if (logY.length < 2) return void 0;
|
|
4349
|
+
const reg = computeLinearRegression(posX, logY);
|
|
4350
|
+
const a = Math.exp(reg.intercept);
|
|
4351
|
+
const b = reg.slope;
|
|
4352
|
+
return {
|
|
4353
|
+
evaluate: (x) => a * Math.exp(b * x),
|
|
4354
|
+
equation: formatExponentialEquation(a, b),
|
|
4355
|
+
rSquared: reg.rSquared,
|
|
4356
|
+
coefficients: [a, b]
|
|
4357
|
+
};
|
|
4358
|
+
}
|
|
4359
|
+
case "logarithmic": {
|
|
4360
|
+
const lnX = xs.filter((x) => x > 0).map((x) => Math.log(x));
|
|
4361
|
+
const posY = ys.filter((_y, i) => xs[i] > 0);
|
|
4362
|
+
if (lnX.length < 2) return void 0;
|
|
4363
|
+
const reg = computeLinearRegression(lnX, posY);
|
|
4364
|
+
return {
|
|
4365
|
+
evaluate: (x) => x > 0 ? reg.slope * Math.log(x) + reg.intercept : 0,
|
|
4366
|
+
equation: formatLogarithmicEquation(reg.slope, reg.intercept),
|
|
4367
|
+
rSquared: reg.rSquared,
|
|
4368
|
+
coefficients: [reg.intercept, reg.slope]
|
|
4369
|
+
};
|
|
4370
|
+
}
|
|
4371
|
+
case "power": {
|
|
4372
|
+
const logX = xs.filter((x, i) => x > 0 && ys[i] > 0).map((x) => Math.log(x));
|
|
4373
|
+
const logY = ys.filter((y, i) => y > 0 && xs[i] > 0).map((y) => Math.log(y));
|
|
4374
|
+
if (logX.length < 2) return void 0;
|
|
4375
|
+
const reg = computeLinearRegression(logX, logY);
|
|
4376
|
+
const a = Math.exp(reg.intercept);
|
|
4377
|
+
return {
|
|
4378
|
+
evaluate: (x) => x > 0 ? a * x ** reg.slope : 0,
|
|
4379
|
+
equation: formatPowerEquation(a, reg.slope),
|
|
4380
|
+
rSquared: reg.rSquared,
|
|
4381
|
+
coefficients: [a, reg.slope]
|
|
4382
|
+
};
|
|
4383
|
+
}
|
|
4384
|
+
case "polynomial": {
|
|
4385
|
+
const order = Math.min(options.order ?? 2, 6);
|
|
4386
|
+
const coeffs = fitPolynomial(xs, ys, order);
|
|
4387
|
+
const evaluate = (x) => coeffs.reduce((s, c, i) => s + c * x ** i, 0);
|
|
4388
|
+
return {
|
|
4389
|
+
evaluate,
|
|
4390
|
+
equation: formatPolynomialEquation(coeffs),
|
|
4391
|
+
rSquared: computeRSquared(xs, ys, evaluate),
|
|
4392
|
+
coefficients: coeffs
|
|
4393
|
+
};
|
|
4394
|
+
}
|
|
4395
|
+
default:
|
|
4396
|
+
return void 0;
|
|
4397
|
+
}
|
|
4398
|
+
}
|
|
4399
|
+
function fitChartTrendline(options, xVals, yVals) {
|
|
4400
|
+
const count = yVals.length;
|
|
4401
|
+
if (count < 2) return noFit();
|
|
4402
|
+
if (options.kind === "movingAvg") {
|
|
4403
|
+
const period = options.period ?? 2;
|
|
4404
|
+
const points2 = [];
|
|
4405
|
+
for (let i = period - 1; i < count; i++) {
|
|
4406
|
+
let sum = 0;
|
|
4407
|
+
for (let j = i - period + 1; j <= i; j++) sum += yVals[j];
|
|
4408
|
+
points2.push({ x: xVals[i], y: sum / period });
|
|
4409
|
+
}
|
|
4410
|
+
return { points: points2, equation: `${period}-period moving average`, rSquared: 0, coefficients: [] };
|
|
4411
|
+
}
|
|
4412
|
+
const model = fitModel(options, xVals, yVals);
|
|
4413
|
+
if (!model) return noFit();
|
|
4414
|
+
const startX = Math.min(...xVals) - (options.backward ?? 0);
|
|
4415
|
+
const endX = Math.max(...xVals) + (options.forward ?? 0);
|
|
4416
|
+
const steps = Math.max(Math.ceil((endX - startX) * 4), 20);
|
|
4417
|
+
const points = [];
|
|
4418
|
+
for (let step = 0; step <= steps; step++) {
|
|
4419
|
+
const x = startX + (endX - startX) * step / steps;
|
|
4420
|
+
const y = model.evaluate(x);
|
|
4421
|
+
if (Number.isFinite(y)) points.push({ x, y });
|
|
4422
|
+
}
|
|
4423
|
+
return {
|
|
4424
|
+
points,
|
|
4425
|
+
equation: model.equation,
|
|
4426
|
+
rSquared: model.rSquared,
|
|
4427
|
+
coefficients: model.coefficients
|
|
4428
|
+
};
|
|
4429
|
+
}
|
|
4430
|
+
|
|
4431
|
+
// chart/error-bar-amount.ts
|
|
4432
|
+
function chartSampleVariance(values) {
|
|
4433
|
+
const count = values.length;
|
|
4434
|
+
if (count === 0) return 0;
|
|
4435
|
+
const mean = values.reduce((sum, value) => sum + value, 0) / count;
|
|
4436
|
+
return values.reduce((sum, value) => sum + (value - mean) ** 2, 0) / Math.max(count - 1, 1);
|
|
4437
|
+
}
|
|
4438
|
+
function chartErrorBarAmount(options, values, displayIndex, sourceIndex, side) {
|
|
4439
|
+
switch (options.valueType) {
|
|
4440
|
+
case "fixedVal":
|
|
4441
|
+
return options.value ?? 0;
|
|
4442
|
+
case "percentage":
|
|
4443
|
+
return Math.abs(values[displayIndex] ?? 0) * ((options.value ?? 0) / 100);
|
|
4444
|
+
case "stdDev":
|
|
4445
|
+
return Math.sqrt(chartSampleVariance(values)) * (options.value ?? 1);
|
|
4446
|
+
case "stdErr":
|
|
4447
|
+
return Math.sqrt(chartSampleVariance(values) / Math.max(values.length, 1));
|
|
4448
|
+
case "cust":
|
|
4449
|
+
return side === "plus" ? options.customPlus?.[sourceIndex] ?? 0 : options.customMinus?.[sourceIndex] ?? 0;
|
|
4450
|
+
}
|
|
3348
4451
|
}
|
|
3349
4452
|
|
|
3350
4453
|
// chart/color-palettes.ts
|
|
@@ -3615,12 +4718,12 @@ function buildChartGradientDef(id, fill, bounds) {
|
|
|
3615
4718
|
function chartGradientMarkup(def) {
|
|
3616
4719
|
if (def.kind === "rectPath")
|
|
3617
4720
|
return `<pattern id="${escapeXmlAttr(def.id)}" patternUnits="objectBoundingBox" patternContentUnits="objectBoundingBox" width="1" height="1"><image href="${escapeXmlAttr(def.href)}" width="1" height="1" preserveAspectRatio="none"/></pattern>`;
|
|
3618
|
-
const
|
|
4721
|
+
const geometry2 = def.kind === "linearGradient" ? `${def.gradientUnits ? `gradientUnits="${def.gradientUnits}" ` : ""}x1="${def.x1}" y1="${def.y1}" x2="${def.x2}" y2="${def.y2}"` : `cx="${def.cx}" cy="${def.cy}" r="${def.r}"`;
|
|
3619
4722
|
const stops = def.stops.map(
|
|
3620
4723
|
(stop) => `<stop offset="${stop.offset}" stop-color="${escapeXmlAttr(stop.color)}" stop-opacity="${stop.opacity ?? 1}"/>`
|
|
3621
4724
|
).join("");
|
|
3622
4725
|
const transform = def.kind === "radialGradient" && def.gradientTransform ? ` gradientTransform="${escapeXmlAttr(def.gradientTransform)}"` : "";
|
|
3623
|
-
return `<${def.kind} id="${escapeXmlAttr(def.id)}" ${
|
|
4726
|
+
return `<${def.kind} id="${escapeXmlAttr(def.id)}" ${geometry2}${transform}>${stops}</${def.kind}>`;
|
|
3624
4727
|
}
|
|
3625
4728
|
|
|
3626
4729
|
// chart/bar-cluster-geometry.ts
|
|
@@ -3634,6 +4737,17 @@ function clusteredBarGeometry(barGroupWidth, seriesCount, chartData) {
|
|
|
3634
4737
|
return { singleBarWidth, step, clusterWidth: singleBarWidth + step * (seriesCount - 1) };
|
|
3635
4738
|
}
|
|
3636
4739
|
|
|
4740
|
+
// chart/model-analysis.ts
|
|
4741
|
+
var KIND_OF_TYPE = {
|
|
4742
|
+
linear: "linear",
|
|
4743
|
+
exp: "exponential",
|
|
4744
|
+
log: "logarithmic",
|
|
4745
|
+
poly: "polynomial",
|
|
4746
|
+
power: "power",
|
|
4747
|
+
movingAvg: "movingAvg"
|
|
4748
|
+
};
|
|
4749
|
+
var chartTrendlineKind = (type) => type !== void 0 && Object.hasOwn(KIND_OF_TYPE, type) ? KIND_OF_TYPE[type] : void 0;
|
|
4750
|
+
|
|
3637
4751
|
// chart/data-cache.ts
|
|
3638
4752
|
function chartCacheValues(cache) {
|
|
3639
4753
|
if (!cache) return [];
|
|
@@ -3649,6 +4763,91 @@ function chartCacheValues(cache) {
|
|
|
3649
4763
|
}
|
|
3650
4764
|
var chartSourceValues = (source) => chartCacheValues(source?.cache ?? source?.levels?.[0]);
|
|
3651
4765
|
|
|
4766
|
+
// drawingml/write-line.ts
|
|
4767
|
+
var FILLS = /* @__PURE__ */ new Set(["noFill", "solidFill", "gradFill", "pattFill"]);
|
|
4768
|
+
function dropDrawingDeclarations(element) {
|
|
4769
|
+
if (element.getAttribute("xmlns:a") === NS.a) element.removeAttribute("xmlns:a");
|
|
4770
|
+
for (const child of elements(element)) dropDrawingDeclarations(child);
|
|
4771
|
+
}
|
|
4772
|
+
function patchDrawingLine(ln, line2) {
|
|
4773
|
+
if (line2.widthEmu === void 0) ln.removeAttribute("w");
|
|
4774
|
+
else ln.setAttribute("w", String(Math.round(line2.widthEmu)));
|
|
4775
|
+
if (line2.cap === void 0) ln.removeAttribute("cap");
|
|
4776
|
+
else ln.setAttribute("cap", line2.cap);
|
|
4777
|
+
const fill = line2.fill && drawingFillXml(line2.fill);
|
|
4778
|
+
if (fill || !line2.fill) {
|
|
4779
|
+
for (const node of elements(ln))
|
|
4780
|
+
if (node.namespaceURI === NS.a && FILLS.has(node.localName)) ln.removeChild(node);
|
|
4781
|
+
}
|
|
4782
|
+
if (fill) {
|
|
4783
|
+
const parsed = parseXml(`<w xmlns:a="${NS.a}">${fill}</w>`).documentElement;
|
|
4784
|
+
for (const node of elements(parsed).reverse()) {
|
|
4785
|
+
const imported = ln.ownerDocument.importNode(node, true);
|
|
4786
|
+
dropDrawingDeclarations(imported);
|
|
4787
|
+
ln.insertBefore(imported, ln.firstChild);
|
|
4788
|
+
}
|
|
4789
|
+
}
|
|
4790
|
+
const dashes = elements(ln).filter(
|
|
4791
|
+
(node) => node.namespaceURI === NS.a && (node.localName === "prstDash" || node.localName === "custDash")
|
|
4792
|
+
);
|
|
4793
|
+
if (line2.dash === void 0) {
|
|
4794
|
+
for (const node of dashes) if (node.localName === "prstDash") ln.removeChild(node);
|
|
4795
|
+
return;
|
|
4796
|
+
}
|
|
4797
|
+
const dash = ln.ownerDocument.createElementNS(NS.a, "a:prstDash");
|
|
4798
|
+
dash.setAttribute("val", line2.dash);
|
|
4799
|
+
for (const node of dashes) ln.removeChild(node);
|
|
4800
|
+
const afterFill = elements(ln).find(
|
|
4801
|
+
(node) => node.namespaceURI !== NS.a || !FILLS.has(node.localName)
|
|
4802
|
+
);
|
|
4803
|
+
ln.insertBefore(dash, afterFill ?? null);
|
|
4804
|
+
}
|
|
4805
|
+
function drawingLineXml(line2) {
|
|
4806
|
+
const doc = parseXml(`<a:ln xmlns:a="${NS.a}"/>`);
|
|
4807
|
+
patchDrawingLine(doc.documentElement, line2);
|
|
4808
|
+
return buildXml(doc);
|
|
4809
|
+
}
|
|
4810
|
+
|
|
4811
|
+
// chart/render/summary-analysis.ts
|
|
4812
|
+
function summaryTrendline(source) {
|
|
4813
|
+
const kind = chartTrendlineKind(source.trendlineType);
|
|
4814
|
+
if (!kind) return void 0;
|
|
4815
|
+
const out = { kind };
|
|
4816
|
+
if (source.order !== void 0) out.order = source.order;
|
|
4817
|
+
if (source.period !== void 0) out.period = source.period;
|
|
4818
|
+
if (source.forward !== void 0) out.forward = source.forward;
|
|
4819
|
+
if (source.backward !== void 0) out.backward = source.backward;
|
|
4820
|
+
if (source.intercept !== void 0) out.intercept = source.intercept;
|
|
4821
|
+
if (source.name !== void 0) out.name = source.name;
|
|
4822
|
+
if (source.spPr?.line) out.line = source.spPr.line;
|
|
4823
|
+
return out;
|
|
4824
|
+
}
|
|
4825
|
+
var amounts = (source) => chartSourceValues(source).map((value) => typeof value === "number" ? value : 0);
|
|
4826
|
+
function summaryErrorBars(source) {
|
|
4827
|
+
if (!source.valueType) return void 0;
|
|
4828
|
+
const out = {
|
|
4829
|
+
direction: source.direction ?? "y",
|
|
4830
|
+
barType: source.barType ?? "both",
|
|
4831
|
+
valueType: source.valueType
|
|
4832
|
+
};
|
|
4833
|
+
if (source.value !== void 0) out.value = source.value;
|
|
4834
|
+
if (source.valueType === "cust") {
|
|
4835
|
+
out.customPlus = amounts(source.plus);
|
|
4836
|
+
out.customMinus = amounts(source.minus);
|
|
4837
|
+
}
|
|
4838
|
+
if (source.noEndCap !== void 0) out.noEndCap = source.noEndCap;
|
|
4839
|
+
if (source.spPr?.line) out.line = source.spPr.line;
|
|
4840
|
+
return out;
|
|
4841
|
+
}
|
|
4842
|
+
function summaryAnalysis(series) {
|
|
4843
|
+
const trendlines2 = (series.trendlines ?? []).map(summaryTrendline).filter((entry) => entry !== void 0);
|
|
4844
|
+
const errorBars = (series.errorBars ?? []).map(summaryErrorBars).filter((entry) => entry !== void 0);
|
|
4845
|
+
return {
|
|
4846
|
+
...trendlines2.length ? { trendlines: trendlines2 } : {},
|
|
4847
|
+
...errorBars.length ? { errorBars } : {}
|
|
4848
|
+
};
|
|
4849
|
+
}
|
|
4850
|
+
|
|
3652
4851
|
// chart/render/summary-from-space.ts
|
|
3653
4852
|
var solidColor = (fill) => fill?.kind === "solid" ? fill.color : void 0;
|
|
3654
4853
|
var isSolidFill = (fill) => fill?.kind === "solid" || fill?.kind === "unsupported" && fill.element === "solidFill";
|
|
@@ -3669,12 +4868,15 @@ var GROUPINGS = /* @__PURE__ */ new Set(["clustered", "stacked", "percentStacked
|
|
|
3669
4868
|
function chartSummarySeries(source, chartType) {
|
|
3670
4869
|
const categories = source.categories ?? source.xValues;
|
|
3671
4870
|
const values = source.values ?? source.yValues;
|
|
4871
|
+
const numeric = (v) => typeof v === "number" ? v : v === "" ? null : Number.isFinite(Number(v)) ? Number(v) : null;
|
|
3672
4872
|
const out = {
|
|
3673
4873
|
categories: chartSourceValues(categories),
|
|
3674
|
-
values: chartSourceValues(values).map(
|
|
3675
|
-
(v) => typeof v === "number" ? v : v === "" ? null : Number.isFinite(Number(v)) ? Number(v) : null
|
|
3676
|
-
)
|
|
4874
|
+
values: chartSourceValues(values).map(numeric)
|
|
3677
4875
|
};
|
|
4876
|
+
if (source.bubbleSizes) {
|
|
4877
|
+
out.bubbleSizes = chartSourceValues(source.bubbleSizes).map(numeric);
|
|
4878
|
+
if (source.bubbleSizes.formula) out.bubbleSizesRef = source.bubbleSizes.formula;
|
|
4879
|
+
}
|
|
3678
4880
|
if (source.tx?.text !== void 0) out.name = source.tx.text;
|
|
3679
4881
|
const nameRef = source.tx?.reference?.formula;
|
|
3680
4882
|
if (nameRef) out.nameRef = nameRef;
|
|
@@ -3699,18 +4901,68 @@ function chartSummarySeries(source, chartType) {
|
|
|
3699
4901
|
}
|
|
3700
4902
|
if (Object.keys(points).length) out.pointColors = points;
|
|
3701
4903
|
if (Object.keys(pointFills).length) out.pointFills = pointFills;
|
|
4904
|
+
Object.assign(out, summaryAnalysis(source));
|
|
3702
4905
|
return out;
|
|
3703
4906
|
}
|
|
3704
|
-
function
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
4907
|
+
function valueAxisId(chartSpace, axisIds) {
|
|
4908
|
+
return axisIds.find(
|
|
4909
|
+
(id) => chartSpace.plotArea.axes.some((a) => a.id === id && a.kind === "val")
|
|
4910
|
+
);
|
|
4911
|
+
}
|
|
4912
|
+
function stockStyle(group) {
|
|
4913
|
+
return {
|
|
4914
|
+
...group.hiLowLinesSpPr ? { hiLowLines: group.hiLowLinesSpPr } : {},
|
|
4915
|
+
...group.upBars?.spPr ? { upBars: group.upBars.spPr } : {},
|
|
4916
|
+
...group.downBars?.spPr ? { downBars: group.downBars.spPr } : {},
|
|
4917
|
+
...group.upDownBarsGapWidth === void 0 ? {} : { gapWidth: group.upDownBarsGapWidth }
|
|
4918
|
+
};
|
|
4919
|
+
}
|
|
4920
|
+
function extraGroups(chartSpace, firstType) {
|
|
4921
|
+
const [first3, ...rest] = chartSpace.plotArea.groups;
|
|
4922
|
+
if (!first3 || !["column", "line", "area"].includes(firstType)) return [];
|
|
4923
|
+
const primary = valueAxisId(chartSpace, first3.axisIds);
|
|
4924
|
+
const out = [];
|
|
4925
|
+
for (const group of rest) {
|
|
4926
|
+
const stockOverColumns = group.kind === "stock" && firstType === "column";
|
|
4927
|
+
if (group.is3D || !(["bar", "line", "area"].includes(group.kind) || stockOverColumns)) continue;
|
|
4928
|
+
const type = group.kind === "bar" ? "column" : group.kind;
|
|
4929
|
+
const entry = {
|
|
4930
|
+
chartType: type,
|
|
4931
|
+
series: group.series.map((source) => chartSummarySeries(source, type)),
|
|
4932
|
+
secondary: valueAxisId(chartSpace, group.axisIds) !== primary
|
|
4933
|
+
};
|
|
4934
|
+
if (group.grouping && GROUPINGS.has(group.grouping))
|
|
4935
|
+
entry.grouping = group.grouping;
|
|
4936
|
+
if (type === "stock") entry.stock = stockStyle(group);
|
|
4937
|
+
if (type === "column") {
|
|
4938
|
+
if (group.gapWidth !== void 0) entry.barGapWidth = group.gapWidth;
|
|
4939
|
+
if (group.overlap !== void 0) entry.barOverlap = group.overlap;
|
|
4940
|
+
}
|
|
4941
|
+
if (entry.series.length) out.push(entry);
|
|
4942
|
+
}
|
|
4943
|
+
return out;
|
|
4944
|
+
}
|
|
4945
|
+
function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
4946
|
+
const group = chartSpace.plotArea.groups[0];
|
|
4947
|
+
let chartType = group ? GROUP_TYPES[group.kind] : "column";
|
|
4948
|
+
if (chartType === "bar" && group?.barDirection !== "bar") chartType = "column";
|
|
4949
|
+
const series = (group?.series ?? []).map((source) => chartSummarySeries(source, chartType));
|
|
4950
|
+
const summary = {
|
|
4951
|
+
chartType,
|
|
4952
|
+
series,
|
|
4953
|
+
showLegend: chartSpace.legend !== void 0
|
|
4954
|
+
};
|
|
4955
|
+
const combined = extraGroups(chartSpace, chartType);
|
|
4956
|
+
if (combined.length) summary.extraGroups = combined;
|
|
4957
|
+
if (chartType === "stock" && group) summary.stock = stockStyle(group);
|
|
4958
|
+
if (chartType === "bubble" && group) {
|
|
4959
|
+
const sizeRepresents = group.sizeRepresents === "w" ? "w" : "area";
|
|
4960
|
+
summary.bubble = {
|
|
4961
|
+
sizeRepresents,
|
|
4962
|
+
...group.bubbleScale === void 0 ? {} : { bubbleScale: group.bubbleScale },
|
|
4963
|
+
showNegativeBubbles: group.showNegativeBubbles === true
|
|
4964
|
+
};
|
|
4965
|
+
}
|
|
3714
4966
|
const grouping = group?.grouping;
|
|
3715
4967
|
if (grouping && GROUPINGS.has(grouping))
|
|
3716
4968
|
summary.grouping = grouping;
|
|
@@ -3738,6 +4990,193 @@ function chartSummaryFromSpace(chartSpace, extras = {}) {
|
|
|
3738
4990
|
return summary;
|
|
3739
4991
|
}
|
|
3740
4992
|
|
|
4993
|
+
// chart/render/chart-svg-util.ts
|
|
4994
|
+
var TEXT_COLOR = "#595959";
|
|
4995
|
+
var GRID_COLOR = "#D9D9D9";
|
|
4996
|
+
var AXIS_COLOR = "#BFBFBF";
|
|
4997
|
+
var FONT_SIZE = 10;
|
|
4998
|
+
function esc(text2) {
|
|
4999
|
+
return text2.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
5000
|
+
}
|
|
5001
|
+
var n = (value) => String(Math.round(value * 100) / 100);
|
|
5002
|
+
var textWidth = (text2, size = FONT_SIZE) => text2.length * size * 0.55;
|
|
5003
|
+
function text(x, y, content, attrs2 = {}) {
|
|
5004
|
+
const parts = [`x="${n(x)}"`, `y="${n(y)}"`];
|
|
5005
|
+
parts.push(`font-size="${attrs2.size ?? FONT_SIZE}"`);
|
|
5006
|
+
parts.push(`fill="${esc(attrs2.fill ?? TEXT_COLOR)}"`);
|
|
5007
|
+
if (attrs2.anchor && attrs2.anchor !== "start") parts.push(`text-anchor="${attrs2.anchor}"`);
|
|
5008
|
+
if (attrs2.weight) parts.push(`font-weight="${attrs2.weight}"`);
|
|
5009
|
+
if (attrs2.baseline) parts.push(`dominant-baseline="${attrs2.baseline}"`);
|
|
5010
|
+
if (attrs2.family) parts.push(`font-family="${esc(attrs2.family)}"`);
|
|
5011
|
+
if (attrs2.filter) parts.push(`filter="${esc(attrs2.filter)}"`);
|
|
5012
|
+
if (attrs2.italic !== void 0) parts.push(`font-style="${attrs2.italic ? "italic" : "normal"}"`);
|
|
5013
|
+
if (attrs2.underline !== void 0)
|
|
5014
|
+
parts.push(`text-decoration="${attrs2.underline ? "underline" : "none"}"`);
|
|
5015
|
+
return `<text ${parts.join(" ")}>${esc(content)}</text>`;
|
|
5016
|
+
}
|
|
5017
|
+
var line = (x1, y1, x2, y2, stroke, width = 1) => `<line x1="${n(x1)}" y1="${n(y1)}" x2="${n(x2)}" y2="${n(y2)}" stroke="${stroke}" stroke-width="${width}"/>`;
|
|
5018
|
+
var rect = (x, y, w, h, fill, filter) => `<rect x="${n(x)}" y="${n(y)}" width="${n(Math.max(0, w))}" height="${n(Math.max(0, h))}" fill="${fill}"${filter ? ` filter="${esc(filter)}"` : ""}/>`;
|
|
5019
|
+
function fit(content, maxWidth, size = FONT_SIZE) {
|
|
5020
|
+
if (textWidth(content, size) <= maxWidth) return content;
|
|
5021
|
+
const chars = Math.max(1, Math.floor(maxWidth / (size * 0.55)) - 1);
|
|
5022
|
+
return `${content.slice(0, chars)}\u2026`;
|
|
5023
|
+
}
|
|
5024
|
+
|
|
5025
|
+
// chart/render/chart-spacing.ts
|
|
5026
|
+
function chartBarSpacing(chart) {
|
|
5027
|
+
const stacked = chart.grouping === "stacked" || chart.grouping === "percentStacked";
|
|
5028
|
+
return {
|
|
5029
|
+
barGapWidth: chart.barGapWidth ?? DEFAULT_BAR_GAP_WIDTH,
|
|
5030
|
+
barOverlap: chart.barOverlap ?? (stacked ? 100 : 0)
|
|
5031
|
+
};
|
|
5032
|
+
}
|
|
5033
|
+
|
|
5034
|
+
// chart/render/chart-svg-bars.ts
|
|
5035
|
+
function barLayout(model, frame) {
|
|
5036
|
+
const count = Math.max(1, model.series.length);
|
|
5037
|
+
const geometry2 = clusteredBarGeometry(frame.bandSize, count, chartBarSpacing(model));
|
|
5038
|
+
const barSize = geometry2.singleBarWidth;
|
|
5039
|
+
const offset = (si) => model.horizontal ? geometry2.clusterWidth / 2 - barSize - si * geometry2.step : -geometry2.clusterWidth / 2 + si * geometry2.step;
|
|
5040
|
+
return { barSize, offset };
|
|
5041
|
+
}
|
|
5042
|
+
function bars(model, frame, out, values) {
|
|
5043
|
+
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
5044
|
+
const { barSize, offset: barOffset } = barLayout(model, frame);
|
|
5045
|
+
const base = frame.value(0);
|
|
5046
|
+
const pos = new Array(model.categories.length).fill(0);
|
|
5047
|
+
const neg = new Array(model.categories.length).fill(0);
|
|
5048
|
+
model.series.forEach((s, si) => {
|
|
5049
|
+
values[si]?.forEach((v, i) => {
|
|
5050
|
+
if (v === null || i >= model.categories.length) return;
|
|
5051
|
+
let from = 0;
|
|
5052
|
+
let to = v;
|
|
5053
|
+
if (stacked) {
|
|
5054
|
+
const acc = v >= 0 ? pos : neg;
|
|
5055
|
+
from = acc[i] ?? 0;
|
|
5056
|
+
to = from + v;
|
|
5057
|
+
acc[i] = to;
|
|
5058
|
+
}
|
|
5059
|
+
const a = stacked ? frame.value(from) : base;
|
|
5060
|
+
const b = frame.value(to);
|
|
5061
|
+
const offset = barOffset(si);
|
|
5062
|
+
const center = frame.band(i);
|
|
5063
|
+
const width = model.horizontal ? Math.abs(b - a) : barSize;
|
|
5064
|
+
const height = model.horizontal ? barSize : Math.abs(b - a);
|
|
5065
|
+
let color = s.pointColors?.[i] ?? s.color;
|
|
5066
|
+
const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
|
|
5067
|
+
if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
|
|
5068
|
+
const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
|
|
5069
|
+
if (baseId) {
|
|
5070
|
+
const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
|
|
5071
|
+
const def = buildChartGradientDef(id, gradient, {
|
|
5072
|
+
width: Number(n(width)),
|
|
5073
|
+
height: Number(n(height)),
|
|
5074
|
+
shape: "rect"
|
|
5075
|
+
});
|
|
5076
|
+
out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
|
|
5077
|
+
color = `url(#${id})`;
|
|
5078
|
+
}
|
|
5079
|
+
}
|
|
5080
|
+
out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
|
|
5081
|
+
if (model.horizontal)
|
|
5082
|
+
out.push(
|
|
5083
|
+
rect(Math.min(a, b), center + offset, Math.abs(b - a), barSize, color, s.shadowFilter)
|
|
5084
|
+
);
|
|
5085
|
+
else
|
|
5086
|
+
out.push(
|
|
5087
|
+
rect(center + offset, Math.min(a, b), barSize, Math.abs(b - a), color, s.shadowFilter)
|
|
5088
|
+
);
|
|
5089
|
+
out.push("</g>");
|
|
5090
|
+
});
|
|
5091
|
+
});
|
|
5092
|
+
}
|
|
5093
|
+
|
|
5094
|
+
// chart/render/chart-svg-analysis.ts
|
|
5095
|
+
var DASHES = {
|
|
5096
|
+
dot: [1, 3],
|
|
5097
|
+
dash: [4, 3],
|
|
5098
|
+
lgDash: [8, 3],
|
|
5099
|
+
dashDot: [4, 3, 1, 3],
|
|
5100
|
+
lgDashDot: [8, 3, 1, 3],
|
|
5101
|
+
lgDashDotDot: [8, 3, 1, 3, 1, 3],
|
|
5102
|
+
sysDash: [3, 1],
|
|
5103
|
+
sysDot: [1, 1],
|
|
5104
|
+
sysDashDot: [3, 1, 1, 1],
|
|
5105
|
+
sysDashDotDot: [3, 1, 1, 1, 1, 1]
|
|
5106
|
+
};
|
|
5107
|
+
var CAP = 4;
|
|
5108
|
+
function strokeAttributes(stroke) {
|
|
5109
|
+
const pattern = stroke.dash ? DASHES[stroke.dash] : void 0;
|
|
5110
|
+
const dash = pattern ? ` stroke-dasharray="${pattern.map((step) => n(step * stroke.width)).join(" ")}"` : "";
|
|
5111
|
+
return `stroke="${esc(stroke.color)}" stroke-width="${n(stroke.width)}"${dash}`;
|
|
5112
|
+
}
|
|
5113
|
+
var segment = (x1, y1, x2, y2, stroke) => `<line x1="${n(x1)}" y1="${n(y1)}" x2="${n(x2)}" y2="${n(y2)}" ${stroke}/>`;
|
|
5114
|
+
function trendlines(series, si, xs, ys, plane, out) {
|
|
5115
|
+
for (const trendline of series.trendlines ?? []) {
|
|
5116
|
+
const fit2 = fitChartTrendline(trendline.fit, xs, ys);
|
|
5117
|
+
if (fit2.points.length < 2) continue;
|
|
5118
|
+
const points = fit2.points.map(({ x, y }) => plane(x, y).map(n).join(",")).join(" ");
|
|
5119
|
+
out.push(
|
|
5120
|
+
`<polyline points="${points}" fill="none" ${strokeAttributes(trendline.stroke)} data-chart-part="trendline" data-chart-series="${si}"/>`
|
|
5121
|
+
);
|
|
5122
|
+
}
|
|
5123
|
+
}
|
|
5124
|
+
function errorBar(bars2, at, values, plane, out) {
|
|
5125
|
+
const stroke = strokeAttributes(bars2.stroke);
|
|
5126
|
+
for (const side of ["plus", "minus"]) {
|
|
5127
|
+
if (bars2.barType !== side && bars2.barType !== "both") continue;
|
|
5128
|
+
const amount = chartErrorBarAmount(bars2.amount, values, at.displayIndex, at.sourceIndex, side);
|
|
5129
|
+
const sign = side === "plus" ? 1 : -1;
|
|
5130
|
+
const [x1, y1] = plane(at.x, at.y);
|
|
5131
|
+
const [x2, y2] = bars2.direction === "x" ? plane(at.x + sign * amount, at.y) : plane(at.x, at.y + sign * amount);
|
|
5132
|
+
out.push(segment(x1, y1, x2, y2, stroke));
|
|
5133
|
+
if (!bars2.endCap) continue;
|
|
5134
|
+
if (x1 === x2) out.push(segment(x2 - CAP, y2, x2 + CAP, y2, stroke));
|
|
5135
|
+
else out.push(segment(x2, y2 - CAP, x2, y2 + CAP, stroke));
|
|
5136
|
+
}
|
|
5137
|
+
}
|
|
5138
|
+
function plottedPoints(series, xOf) {
|
|
5139
|
+
return series.values.flatMap((y, index) => {
|
|
5140
|
+
const x = xOf(index);
|
|
5141
|
+
return y === null || x === null ? [] : [{ x, y, index }];
|
|
5142
|
+
});
|
|
5143
|
+
}
|
|
5144
|
+
function seriesAnalysis(series, si, xOf, plane, barPlane, categoryAxis, out) {
|
|
5145
|
+
const points = plottedPoints(series, xOf);
|
|
5146
|
+
const xs = points.map((p) => p.x);
|
|
5147
|
+
const ys = points.map((p) => p.y);
|
|
5148
|
+
trendlines(series, si, xs, ys, plane, out);
|
|
5149
|
+
for (const bars2 of series.errorBars ?? []) {
|
|
5150
|
+
if (categoryAxis && bars2.direction === "x") continue;
|
|
5151
|
+
const values = bars2.direction === "x" ? xs : ys;
|
|
5152
|
+
points.forEach(
|
|
5153
|
+
(p, displayIndex) => errorBar(bars2, { x: p.x, y: p.y, displayIndex, sourceIndex: p.index }, values, barPlane, out)
|
|
5154
|
+
);
|
|
5155
|
+
}
|
|
5156
|
+
}
|
|
5157
|
+
function categoryAnalysis(model, frame, out) {
|
|
5158
|
+
if (model.grouping === "stacked" || model.grouping === "percentStacked") return;
|
|
5159
|
+
const plane = (x, y) => model.horizontal ? [frame.value(y), frame.band(x - 1)] : [frame.band(x - 1), frame.value(y)];
|
|
5160
|
+
const barred = model.type === "bar" || model.type === "column";
|
|
5161
|
+
const layout = barred ? barLayout(model, frame) : void 0;
|
|
5162
|
+
model.series.forEach((series, si) => {
|
|
5163
|
+
if (!series.trendlines && !series.errorBars) return;
|
|
5164
|
+
const shift = layout ? layout.offset(si) + layout.barSize / 2 : 0;
|
|
5165
|
+
const barPlane = (x, y) => {
|
|
5166
|
+
const [px, py] = plane(x, y);
|
|
5167
|
+
return model.horizontal ? [px, py + shift] : [px + shift, py];
|
|
5168
|
+
};
|
|
5169
|
+
seriesAnalysis(series, si, (i) => i + 1, plane, barPlane, true, out);
|
|
5170
|
+
});
|
|
5171
|
+
}
|
|
5172
|
+
function scatterAnalysis(model, px, py, out) {
|
|
5173
|
+
const plane = (x, y) => [px(x), py(y)];
|
|
5174
|
+
model.series.forEach((series, si) => {
|
|
5175
|
+
if (!series.trendlines && !series.errorBars) return;
|
|
5176
|
+
seriesAnalysis(series, si, (i) => series.xValues?.[i] ?? null, plane, plane, false, out);
|
|
5177
|
+
});
|
|
5178
|
+
}
|
|
5179
|
+
|
|
3741
5180
|
// chart/render/chart-scale.ts
|
|
3742
5181
|
var clean = (n2) => Number(n2.toPrecision(12));
|
|
3743
5182
|
function* units(raw) {
|
|
@@ -3804,38 +5243,6 @@ function formatAxisValue(value, percent = false) {
|
|
|
3804
5243
|
return `${v < 0 ? "-" : ""}${grouped}${frac ? `.${frac}` : ""}`;
|
|
3805
5244
|
}
|
|
3806
5245
|
|
|
3807
|
-
// chart/render/chart-svg-util.ts
|
|
3808
|
-
var TEXT_COLOR = "#595959";
|
|
3809
|
-
var GRID_COLOR = "#D9D9D9";
|
|
3810
|
-
var AXIS_COLOR = "#BFBFBF";
|
|
3811
|
-
var FONT_SIZE = 10;
|
|
3812
|
-
function esc(text2) {
|
|
3813
|
-
return text2.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
3814
|
-
}
|
|
3815
|
-
var n = (value) => String(Math.round(value * 100) / 100);
|
|
3816
|
-
var textWidth = (text2, size = FONT_SIZE) => text2.length * size * 0.55;
|
|
3817
|
-
function text(x, y, content, attrs = {}) {
|
|
3818
|
-
const parts = [`x="${n(x)}"`, `y="${n(y)}"`];
|
|
3819
|
-
parts.push(`font-size="${attrs.size ?? FONT_SIZE}"`);
|
|
3820
|
-
parts.push(`fill="${esc(attrs.fill ?? TEXT_COLOR)}"`);
|
|
3821
|
-
if (attrs.anchor && attrs.anchor !== "start") parts.push(`text-anchor="${attrs.anchor}"`);
|
|
3822
|
-
if (attrs.weight) parts.push(`font-weight="${attrs.weight}"`);
|
|
3823
|
-
if (attrs.baseline) parts.push(`dominant-baseline="${attrs.baseline}"`);
|
|
3824
|
-
if (attrs.family) parts.push(`font-family="${esc(attrs.family)}"`);
|
|
3825
|
-
if (attrs.filter) parts.push(`filter="${esc(attrs.filter)}"`);
|
|
3826
|
-
if (attrs.italic !== void 0) parts.push(`font-style="${attrs.italic ? "italic" : "normal"}"`);
|
|
3827
|
-
if (attrs.underline !== void 0)
|
|
3828
|
-
parts.push(`text-decoration="${attrs.underline ? "underline" : "none"}"`);
|
|
3829
|
-
return `<text ${parts.join(" ")}>${esc(content)}</text>`;
|
|
3830
|
-
}
|
|
3831
|
-
var line = (x1, y1, x2, y2, stroke, width = 1) => `<line x1="${n(x1)}" y1="${n(y1)}" x2="${n(x2)}" y2="${n(y2)}" stroke="${stroke}" stroke-width="${width}"/>`;
|
|
3832
|
-
var rect = (x, y, w, h, fill, filter) => `<rect x="${n(x)}" y="${n(y)}" width="${n(Math.max(0, w))}" height="${n(Math.max(0, h))}" fill="${fill}"${filter ? ` filter="${esc(filter)}"` : ""}/>`;
|
|
3833
|
-
function fit(content, maxWidth, size = FONT_SIZE) {
|
|
3834
|
-
if (textWidth(content, size) <= maxWidth) return content;
|
|
3835
|
-
const chars = Math.max(1, Math.floor(maxWidth / (size * 0.55)) - 1);
|
|
3836
|
-
return `${content.slice(0, chars)}\u2026`;
|
|
3837
|
-
}
|
|
3838
|
-
|
|
3839
5246
|
// chart/render/theme-palette.ts
|
|
3840
5247
|
var THEME_SLOTS = [
|
|
3841
5248
|
"lt1",
|
|
@@ -3888,45 +5295,6 @@ function autoSeriesColor(theme, index) {
|
|
|
3888
5295
|
return chartPaletteSeriesColor(findChartColorPalette(10), i, i + 1, chartColorScheme(theme));
|
|
3889
5296
|
}
|
|
3890
5297
|
|
|
3891
|
-
// chart/render/chart-value-axis.ts
|
|
3892
|
-
function valueAxis(model) {
|
|
3893
|
-
const stackable = model.type === "bar" || model.type === "column" || model.type === "line" || model.type === "area";
|
|
3894
|
-
if (stackable && model.grouping === "percentStacked")
|
|
3895
|
-
return { ...PERCENT_SCALE, ticks: [...PERCENT_SCALE.ticks], percent: true };
|
|
3896
|
-
let min = Infinity;
|
|
3897
|
-
let max = -Infinity;
|
|
3898
|
-
if (stackable && model.grouping === "stacked") {
|
|
3899
|
-
for (let i = 0; i < model.categories.length; i++) {
|
|
3900
|
-
let pos = 0;
|
|
3901
|
-
let neg = 0;
|
|
3902
|
-
for (const s of model.series) {
|
|
3903
|
-
const v = s.values[i] ?? 0;
|
|
3904
|
-
if (v >= 0) pos += v;
|
|
3905
|
-
else neg += v;
|
|
3906
|
-
}
|
|
3907
|
-
min = Math.min(min, neg);
|
|
3908
|
-
max = Math.max(max, pos);
|
|
3909
|
-
}
|
|
3910
|
-
} else {
|
|
3911
|
-
for (const s of model.series)
|
|
3912
|
-
for (const v of s.values)
|
|
3913
|
-
if (v !== null) {
|
|
3914
|
-
min = Math.min(min, v);
|
|
3915
|
-
max = Math.max(max, v);
|
|
3916
|
-
}
|
|
3917
|
-
}
|
|
3918
|
-
if (min === Infinity) {
|
|
3919
|
-
min = 0;
|
|
3920
|
-
max = 1;
|
|
3921
|
-
}
|
|
3922
|
-
return { ...niceScale(min, max), percent: false };
|
|
3923
|
-
}
|
|
3924
|
-
function categoryTotals(model) {
|
|
3925
|
-
return model.categories.map(
|
|
3926
|
-
(_, i) => model.series.reduce((sum, s) => sum + Math.abs(s.values[i] ?? 0), 0)
|
|
3927
|
-
);
|
|
3928
|
-
}
|
|
3929
|
-
|
|
3930
5298
|
// chart/text-inheritance.ts
|
|
3931
5299
|
var TEXT_KEYS = [
|
|
3932
5300
|
"fontSize",
|
|
@@ -4015,6 +5383,218 @@ function chartAppearance(chart, theme) {
|
|
|
4015
5383
|
return out;
|
|
4016
5384
|
}
|
|
4017
5385
|
|
|
5386
|
+
// chart/render/chart-view-analysis.ts
|
|
5387
|
+
function strokeOf(line2, fallback, resolve) {
|
|
5388
|
+
if (line2?.fill?.kind === "none") return void 0;
|
|
5389
|
+
const color = (line2?.fill?.kind === "solid" ? resolve(line2.fill.color) : void 0) ?? fallback.color;
|
|
5390
|
+
const width = line2?.widthEmu === void 0 ? fallback.width : chartPointsToPixels(line2.widthEmu / 12700);
|
|
5391
|
+
const dash = line2?.dash ?? fallback.dash;
|
|
5392
|
+
return { color, width, ...dash && dash !== "solid" ? { dash } : {} };
|
|
5393
|
+
}
|
|
5394
|
+
function analysisView(source, seriesColor, resolve) {
|
|
5395
|
+
const plain = seriesColor === "none" || seriesColor.startsWith("url(") ? TEXT_COLOR : seriesColor;
|
|
5396
|
+
const trendlines2 = (source.trendlines ?? []).flatMap((entry) => {
|
|
5397
|
+
const { name: _name, line: line2, ...fit2 } = entry;
|
|
5398
|
+
const fallback = { color: plain, width: chartPointsToPixels(1.5), dash: "sysDot" };
|
|
5399
|
+
const stroke = strokeOf(line2, fallback, resolve);
|
|
5400
|
+
return stroke ? [{ fit: fit2, stroke }] : [];
|
|
5401
|
+
});
|
|
5402
|
+
const errorBars = (source.errorBars ?? []).flatMap((entry) => {
|
|
5403
|
+
const { direction, barType, noEndCap, line: line2, ...amount } = entry;
|
|
5404
|
+
const stroke = strokeOf(line2, { color: TEXT_COLOR, width: chartPointsToPixels(0.75) }, resolve);
|
|
5405
|
+
return stroke ? [{ direction, barType, amount, endCap: noEndCap !== true, stroke }] : [];
|
|
5406
|
+
});
|
|
5407
|
+
return {
|
|
5408
|
+
...trendlines2.length ? { trendlines: trendlines2 } : {},
|
|
5409
|
+
...errorBars.length ? { errorBars } : {}
|
|
5410
|
+
};
|
|
5411
|
+
}
|
|
5412
|
+
|
|
5413
|
+
// chart/render/chart-view-series.ts
|
|
5414
|
+
var isRefError = (value) => typeof value === "object" && value !== null && "error" in value;
|
|
5415
|
+
function toText(value) {
|
|
5416
|
+
if (value === null) return "";
|
|
5417
|
+
if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
|
|
5418
|
+
if (isRefError(value)) return value.error;
|
|
5419
|
+
return String(value);
|
|
5420
|
+
}
|
|
5421
|
+
var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
5422
|
+
function resolveRef(ref, evaluateRef) {
|
|
5423
|
+
if (!ref) return void 0;
|
|
5424
|
+
try {
|
|
5425
|
+
const values = evaluateRef(ref);
|
|
5426
|
+
return values.length ? values : void 0;
|
|
5427
|
+
} catch {
|
|
5428
|
+
return void 0;
|
|
5429
|
+
}
|
|
5430
|
+
}
|
|
5431
|
+
function seriesName(series, index, evaluateRef) {
|
|
5432
|
+
const fromRef = resolveRef(series.nameRef, evaluateRef)?.map(toText).filter((t) => t !== "").join(" ");
|
|
5433
|
+
return fromRef || series.name || `Series${index + 1}`;
|
|
5434
|
+
}
|
|
5435
|
+
function seriesContext(chart, theme, options) {
|
|
5436
|
+
const scheme = chartColorScheme(theme);
|
|
5437
|
+
const resolver = { scheme: (name) => scheme[name] };
|
|
5438
|
+
return {
|
|
5439
|
+
theme,
|
|
5440
|
+
scheme,
|
|
5441
|
+
palette: chart.colorPalette === void 0 ? void 0 : findChartColorPalette(chart.colorPalette),
|
|
5442
|
+
evaluateRef: options.evaluateRef ?? (() => []),
|
|
5443
|
+
seriesColor: options.seriesColor,
|
|
5444
|
+
drawingColor: (color) => color && drawingColorCss(resolveDrawingColor(color, resolver, { transformOrder: "document" })),
|
|
5445
|
+
gradient: (fill) => fill?.kind === "gradient" ? resolveChartGradient(
|
|
5446
|
+
fill,
|
|
5447
|
+
(color) => resolveDrawingColor(color, resolver, { transformOrder: "document" })
|
|
5448
|
+
) : void 0
|
|
5449
|
+
};
|
|
5450
|
+
}
|
|
5451
|
+
function seriesView(ctx, s, index, total, categoriesOf) {
|
|
5452
|
+
const { theme, scheme, palette, evaluateRef } = ctx;
|
|
5453
|
+
const values = resolveRef(s.valuesRef, evaluateRef)?.map(toNumber) ?? s.values.map(toNumber);
|
|
5454
|
+
categoriesOf(resolveRef(s.categoriesRef, evaluateRef) ?? s.categories);
|
|
5455
|
+
const paletteColor = palette && chartPaletteSeriesColor(palette, index, total, scheme);
|
|
5456
|
+
const color = s.fill?.kind === "none" ? "none" : ctx.drawingColor(s.fill?.kind === "solid" ? s.fill.color : s.drawingColor) ?? ctx.seriesColor?.(s, index) ?? paletteColor ?? autoSeriesColor(theme, index);
|
|
5457
|
+
const view = { name: seriesName(s, index, evaluateRef), values, color };
|
|
5458
|
+
const shadow = resolveDrawingShadowXml(s.effectsXml, { scheme: (name) => scheme[name] });
|
|
5459
|
+
if (shadow) view.shadow = shadow;
|
|
5460
|
+
const resolvedGradient = ctx.gradient(s.fill);
|
|
5461
|
+
if (resolvedGradient) view.gradient = resolvedGradient;
|
|
5462
|
+
const points = Object.fromEntries(
|
|
5463
|
+
Object.entries(s.pointFills ?? {}).flatMap(([key, fill]) => {
|
|
5464
|
+
const value = ctx.gradient(fill);
|
|
5465
|
+
return value ? [[key, value]] : [];
|
|
5466
|
+
})
|
|
5467
|
+
);
|
|
5468
|
+
if (Object.keys(points).length) view.pointGradients = points;
|
|
5469
|
+
Object.assign(view, analysisView(s, color, ctx.drawingColor));
|
|
5470
|
+
return view;
|
|
5471
|
+
}
|
|
5472
|
+
|
|
5473
|
+
// chart/render/chart-view-families.ts
|
|
5474
|
+
function bubbleView(chart, model, evaluateRef) {
|
|
5475
|
+
chart.series.forEach((source, i) => {
|
|
5476
|
+
const view = model.series[i];
|
|
5477
|
+
if (!view) return;
|
|
5478
|
+
const live = resolveRef(source.bubbleSizesRef, evaluateRef)?.map(toNumber);
|
|
5479
|
+
const sizes = live ?? source.bubbleSizes;
|
|
5480
|
+
if (sizes) view.sizes = sizes;
|
|
5481
|
+
});
|
|
5482
|
+
model.bubble = {
|
|
5483
|
+
sizeRepresents: chart.bubble?.sizeRepresents ?? "area",
|
|
5484
|
+
...chart.bubble?.bubbleScale === void 0 ? {} : { bubbleScale: chart.bubble.bubbleScale },
|
|
5485
|
+
showNegativeBubbles: chart.bubble?.showNegativeBubbles === true
|
|
5486
|
+
};
|
|
5487
|
+
}
|
|
5488
|
+
var columnNumber = (letters) => [...letters].reduce((n2, ch) => n2 * 26 + ch.charCodeAt(0) - 64, 0);
|
|
5489
|
+
function refColumns(ref) {
|
|
5490
|
+
const match = /\$?([A-Z]{1,3})\$?\d+:\$?([A-Z]{1,3})\$?\d+\s*$/i.exec(ref);
|
|
5491
|
+
if (!match) return 1;
|
|
5492
|
+
return Math.max(
|
|
5493
|
+
1,
|
|
5494
|
+
columnNumber((match[2] ?? "").toUpperCase()) - columnNumber((match[1] ?? "").toUpperCase()) + 1
|
|
5495
|
+
);
|
|
5496
|
+
}
|
|
5497
|
+
function liveLevels(ref, evaluateRef) {
|
|
5498
|
+
const columns = ref ? refColumns(ref) : 1;
|
|
5499
|
+
const flat = columns > 1 ? resolveRef(ref, evaluateRef)?.map(toText) : void 0;
|
|
5500
|
+
if (!flat || flat.length % columns !== 0) return void 0;
|
|
5501
|
+
const levels = Array.from({ length: columns }, () => []);
|
|
5502
|
+
flat.forEach((label, i) => levels[columns - 1 - i % columns]?.push(label));
|
|
5503
|
+
return levels;
|
|
5504
|
+
}
|
|
5505
|
+
function hierarchyView(chart, model, evaluateRef) {
|
|
5506
|
+
const first3 = model.series[0];
|
|
5507
|
+
const live = liveLevels(chart.series[0]?.categoriesRef, evaluateRef);
|
|
5508
|
+
if (live?.[0]) model.categories = live[0];
|
|
5509
|
+
const count = Math.max(first3?.values.length ?? 0, model.categories.length);
|
|
5510
|
+
const supplied = live ?? chart.hierarchy?.levels ?? [];
|
|
5511
|
+
const levels = supplied.length > 1 ? normalizeLevels(supplied, count) : [];
|
|
5512
|
+
model.hierarchy = {
|
|
5513
|
+
levels,
|
|
5514
|
+
parentLabelLayout: chart.hierarchy?.parentLabelLayout ?? "banner",
|
|
5515
|
+
labels: chart.hierarchy?.dataLabels !== false,
|
|
5516
|
+
branches: hierarchyBranchLabels(
|
|
5517
|
+
model.series.map((s) => ({ name: s.name, values: s.values.map((v) => v ?? 0) })),
|
|
5518
|
+
model.categories,
|
|
5519
|
+
levels.length > 1 ? levels : void 0
|
|
5520
|
+
)
|
|
5521
|
+
};
|
|
5522
|
+
}
|
|
5523
|
+
|
|
5524
|
+
// chart/render/chart-view-stock.ts
|
|
5525
|
+
var EMU_PER_PX = 9525;
|
|
5526
|
+
function paintOf(fill, ctx) {
|
|
5527
|
+
if (fill?.kind === "none") return "none";
|
|
5528
|
+
return fill?.kind === "solid" ? ctx.drawingColor(fill.color) : void 0;
|
|
5529
|
+
}
|
|
5530
|
+
function lineOf(shape, ctx, color) {
|
|
5531
|
+
const line2 = shape?.line;
|
|
5532
|
+
return {
|
|
5533
|
+
color: paintOf(line2?.fill, ctx) ?? color,
|
|
5534
|
+
width: line2?.widthEmu === void 0 ? 1 : Math.max(0.5, line2.widthEmu / EMU_PER_PX)
|
|
5535
|
+
};
|
|
5536
|
+
}
|
|
5537
|
+
function barOf(shape, ctx, fallback) {
|
|
5538
|
+
const stroke = lineOf(shape, ctx, "#404040");
|
|
5539
|
+
return {
|
|
5540
|
+
fill: paintOf(shape?.fill, ctx) ?? fallback,
|
|
5541
|
+
stroke: stroke.color,
|
|
5542
|
+
strokeWidth: stroke.width
|
|
5543
|
+
};
|
|
5544
|
+
}
|
|
5545
|
+
function stockView(style, ctx) {
|
|
5546
|
+
return {
|
|
5547
|
+
wick: lineOf(style?.hiLowLines, ctx, STOCK_DEFAULT_WICK_COLOR),
|
|
5548
|
+
up: barOf(style?.upBars, ctx, STOCK_DEFAULT_UP_FILL),
|
|
5549
|
+
down: barOf(style?.downBars, ctx, STOCK_DEFAULT_DOWN_FILL),
|
|
5550
|
+
bodyShare: 1 / (1 + Math.max(0, style?.gapWidth ?? 150) / 100)
|
|
5551
|
+
};
|
|
5552
|
+
}
|
|
5553
|
+
|
|
5554
|
+
// chart/render/chart-value-axis.ts
|
|
5555
|
+
function valueExtent(type, grouping, series, categories) {
|
|
5556
|
+
const stackable = type === "bar" || type === "column" || type === "line" || type === "area";
|
|
5557
|
+
let min = Infinity;
|
|
5558
|
+
let max = -Infinity;
|
|
5559
|
+
if (stackable && grouping === "stacked") {
|
|
5560
|
+
for (let i = 0; i < categories; i++) {
|
|
5561
|
+
let pos = 0;
|
|
5562
|
+
let neg = 0;
|
|
5563
|
+
for (const s of series) {
|
|
5564
|
+
const v = s.values[i] ?? 0;
|
|
5565
|
+
if (v >= 0) pos += v;
|
|
5566
|
+
else neg += v;
|
|
5567
|
+
}
|
|
5568
|
+
min = Math.min(min, neg);
|
|
5569
|
+
max = Math.max(max, pos);
|
|
5570
|
+
}
|
|
5571
|
+
} else {
|
|
5572
|
+
for (const s of series)
|
|
5573
|
+
for (const v of s.values)
|
|
5574
|
+
if (v !== null) {
|
|
5575
|
+
min = Math.min(min, v);
|
|
5576
|
+
max = Math.max(max, v);
|
|
5577
|
+
}
|
|
5578
|
+
}
|
|
5579
|
+
return { min, max };
|
|
5580
|
+
}
|
|
5581
|
+
function valueAxis(model) {
|
|
5582
|
+
const stackable = model.type === "bar" || model.type === "column" || model.type === "line" || model.type === "area";
|
|
5583
|
+
if (stackable && model.grouping === "percentStacked")
|
|
5584
|
+
return { ...PERCENT_SCALE, ticks: [...PERCENT_SCALE.ticks], percent: true };
|
|
5585
|
+
let { min, max } = valueExtent(model.type, model.grouping, model.series, model.categories.length);
|
|
5586
|
+
if (min === Infinity) {
|
|
5587
|
+
min = 0;
|
|
5588
|
+
max = 1;
|
|
5589
|
+
}
|
|
5590
|
+
return { ...niceScale(min, max), percent: false };
|
|
5591
|
+
}
|
|
5592
|
+
function categoryTotals(model) {
|
|
5593
|
+
return model.categories.map(
|
|
5594
|
+
(_, i) => model.series.reduce((sum, s) => sum + Math.abs(s.values[i] ?? 0), 0)
|
|
5595
|
+
);
|
|
5596
|
+
}
|
|
5597
|
+
|
|
4018
5598
|
// chart/render/chart-title-text.ts
|
|
4019
5599
|
function properties(run) {
|
|
4020
5600
|
return {
|
|
@@ -4059,8 +5639,87 @@ function chartTitleText(chart, theme) {
|
|
|
4059
5639
|
};
|
|
4060
5640
|
}
|
|
4061
5641
|
|
|
5642
|
+
// chart/render/chart-view-ex.ts
|
|
5643
|
+
function groupsAxis(groups, categories) {
|
|
5644
|
+
let min = Infinity;
|
|
5645
|
+
let max = -Infinity;
|
|
5646
|
+
for (const group of groups) {
|
|
5647
|
+
const extent = valueExtent(group.type, group.grouping, group.series, categories);
|
|
5648
|
+
min = Math.min(min, extent.min);
|
|
5649
|
+
max = Math.max(max, extent.max);
|
|
5650
|
+
}
|
|
5651
|
+
return min === Infinity ? { ...niceScale(0, 1), percent: false } : { ...niceScale(min, max), percent: false };
|
|
5652
|
+
}
|
|
5653
|
+
function chartExtraView(chart, model, ctx, total, categoriesOf) {
|
|
5654
|
+
let index = chart.series.length;
|
|
5655
|
+
const groups = [];
|
|
5656
|
+
for (const group of chart.extraGroups ?? []) {
|
|
5657
|
+
const series = group.series.map((s) => seriesView(ctx, s, index++, total, categoriesOf));
|
|
5658
|
+
const view = {
|
|
5659
|
+
type: group.chartType,
|
|
5660
|
+
grouping: group.grouping ?? (group.chartType === "column" ? "clustered" : "standard"),
|
|
5661
|
+
series,
|
|
5662
|
+
secondary: group.secondary
|
|
5663
|
+
};
|
|
5664
|
+
if (group.chartType === "stock") view.stock = stockView(group.stock, ctx);
|
|
5665
|
+
if (group.barGapWidth !== void 0) view.barGapWidth = group.barGapWidth;
|
|
5666
|
+
if (group.barOverlap !== void 0) view.barOverlap = group.barOverlap;
|
|
5667
|
+
groups.push(view);
|
|
5668
|
+
}
|
|
5669
|
+
if (!groups.length) return;
|
|
5670
|
+
model.extraGroups = groups;
|
|
5671
|
+
}
|
|
5672
|
+
function chartExtraAxes(model) {
|
|
5673
|
+
const groups = model.extraGroups;
|
|
5674
|
+
if (!groups || !model.valueAxis) return;
|
|
5675
|
+
const count = model.categories.length;
|
|
5676
|
+
const secondary = groups.filter((g) => g.secondary);
|
|
5677
|
+
if (secondary.length) model.secondaryAxis = groupsAxis(secondary, count);
|
|
5678
|
+
const shared = groups.filter((g) => !g.secondary);
|
|
5679
|
+
if (!shared.length || model.valueAxis.percent) return;
|
|
5680
|
+
const own2 = valueExtent(model.type, model.grouping, model.series, count);
|
|
5681
|
+
let min = own2.min;
|
|
5682
|
+
let max = own2.max;
|
|
5683
|
+
for (const group of shared) {
|
|
5684
|
+
const extent = valueExtent(group.type, group.grouping, group.series, count);
|
|
5685
|
+
min = Math.min(min, extent.min);
|
|
5686
|
+
max = Math.max(max, extent.max);
|
|
5687
|
+
}
|
|
5688
|
+
model.valueAxis = { ...niceScale(min, max), percent: false };
|
|
5689
|
+
}
|
|
5690
|
+
function waterfallView(chart, model, ctx) {
|
|
5691
|
+
const values = (model.series[0]?.values ?? []).map((v) => v ?? 0);
|
|
5692
|
+
const steps = buildWaterfallSteps(values, chart.waterfall);
|
|
5693
|
+
const role = (i) => ctx.palette && chartPaletteSeriesColor(ctx.palette, i, 3, ctx.scheme) || autoSeriesColor(ctx.theme, i);
|
|
5694
|
+
model.waterfall = {
|
|
5695
|
+
steps,
|
|
5696
|
+
connectors: chart.waterfall?.connectorLines !== false,
|
|
5697
|
+
colors: { increase: role(0), decrease: role(1), total: role(2) }
|
|
5698
|
+
};
|
|
5699
|
+
const ends = steps.flatMap((step) => [step.startValue, step.endValue]);
|
|
5700
|
+
model.valueAxis = {
|
|
5701
|
+
...ends.length ? niceScale(Math.min(...ends), Math.max(...ends)) : niceScale(0, 1),
|
|
5702
|
+
percent: false
|
|
5703
|
+
};
|
|
5704
|
+
const labels = model.categories;
|
|
5705
|
+
model.categories = steps.map((_, i) => labels[i] ?? String(i + 1));
|
|
5706
|
+
}
|
|
5707
|
+
function histogramView(chart, model) {
|
|
5708
|
+
const first3 = model.series[0];
|
|
5709
|
+
if (!first3) return;
|
|
5710
|
+
const raw = first3.values.map((v) => v ?? Number.NaN);
|
|
5711
|
+
const options = chart.histogram ?? {};
|
|
5712
|
+
const bins = options.aggregateByCategory ? aggregateByCategory(
|
|
5713
|
+
first3.values.map((v) => v ?? 0),
|
|
5714
|
+
model.categories
|
|
5715
|
+
) : computeHistogramBins(raw, options, formatAxisValue);
|
|
5716
|
+
model.categories = bins.map((bin) => bin.label);
|
|
5717
|
+
first3.values = bins.map((bin) => bin.value);
|
|
5718
|
+
model.barGapWidth = 0;
|
|
5719
|
+
model.barOverlap = 0;
|
|
5720
|
+
}
|
|
5721
|
+
|
|
4062
5722
|
// chart/render/chart-view.ts
|
|
4063
|
-
var isRefError = (value) => typeof value === "object" && value !== null && "error" in value;
|
|
4064
5723
|
var SUPPORTED = /* @__PURE__ */ new Set([
|
|
4065
5724
|
"bar",
|
|
4066
5725
|
"column",
|
|
@@ -4069,85 +5728,37 @@ var SUPPORTED = /* @__PURE__ */ new Set([
|
|
|
4069
5728
|
"pie",
|
|
4070
5729
|
"doughnut",
|
|
4071
5730
|
"scatter",
|
|
4072
|
-
"radar"
|
|
5731
|
+
"radar",
|
|
5732
|
+
"waterfall",
|
|
5733
|
+
"histogram",
|
|
5734
|
+
"bubble",
|
|
5735
|
+
"stock",
|
|
5736
|
+
"treemap",
|
|
5737
|
+
"sunburst"
|
|
4073
5738
|
]);
|
|
4074
|
-
function toText(value) {
|
|
4075
|
-
if (value === null) return "";
|
|
4076
|
-
if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
|
|
4077
|
-
if (isRefError(value)) return value.error;
|
|
4078
|
-
return String(value);
|
|
4079
|
-
}
|
|
4080
|
-
var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
4081
|
-
function resolveRef(ref, evaluateRef) {
|
|
4082
|
-
if (!ref) return void 0;
|
|
4083
|
-
try {
|
|
4084
|
-
const values = evaluateRef(ref);
|
|
4085
|
-
return values.length ? values : void 0;
|
|
4086
|
-
} catch {
|
|
4087
|
-
return void 0;
|
|
4088
|
-
}
|
|
4089
|
-
}
|
|
4090
|
-
function seriesName(series, index, evaluateRef) {
|
|
4091
|
-
const fromRef = resolveRef(series.nameRef, evaluateRef)?.map(toText).filter((t) => t !== "").join(" ");
|
|
4092
|
-
return fromRef || series.name || `Series${index + 1}`;
|
|
4093
|
-
}
|
|
4094
5739
|
function chartSummaryView(chart, theme, options = {}) {
|
|
4095
|
-
const evaluateRef = options.evaluateRef ?? (() => []);
|
|
4096
5740
|
const type = chart.chartType;
|
|
4097
5741
|
const radial = type === "pie" || type === "doughnut";
|
|
4098
|
-
const
|
|
4099
|
-
const
|
|
4100
|
-
const
|
|
4101
|
-
resolveDrawingColor(
|
|
4102
|
-
color,
|
|
4103
|
-
{
|
|
4104
|
-
scheme: (name) => scheme[name]
|
|
4105
|
-
},
|
|
4106
|
-
{ transformOrder: "document" }
|
|
4107
|
-
)
|
|
4108
|
-
);
|
|
4109
|
-
const gradient = (fill) => fill?.kind === "gradient" ? resolveChartGradient(
|
|
4110
|
-
fill,
|
|
4111
|
-
(color) => resolveDrawingColor(
|
|
4112
|
-
color,
|
|
4113
|
-
{
|
|
4114
|
-
scheme: (name) => scheme[name]
|
|
4115
|
-
},
|
|
4116
|
-
{ transformOrder: "document" }
|
|
4117
|
-
)
|
|
4118
|
-
) : void 0;
|
|
5742
|
+
const byPoint = radial || type === "treemap" || type === "sunburst";
|
|
5743
|
+
const ctx = seriesContext(chart, theme, options);
|
|
5744
|
+
const { palette, scheme, drawingColor } = ctx;
|
|
4119
5745
|
const grouping = chart.grouping ?? (type === "bar" || type === "column" ? "clustered" : "standard");
|
|
4120
|
-
let categories = [];
|
|
4121
5746
|
const rawCategories = [];
|
|
4122
|
-
const
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
});
|
|
4132
|
-
if (shadow) view.shadow = shadow;
|
|
4133
|
-
const resolvedGradient = gradient(s.fill);
|
|
4134
|
-
if (resolvedGradient) view.gradient = resolvedGradient;
|
|
4135
|
-
const points = Object.fromEntries(
|
|
4136
|
-
Object.entries(s.pointFills ?? {}).flatMap(([key, fill]) => {
|
|
4137
|
-
const value = gradient(fill);
|
|
4138
|
-
return value ? [[key, value]] : [];
|
|
4139
|
-
})
|
|
4140
|
-
);
|
|
4141
|
-
if (Object.keys(points).length) view.pointGradients = points;
|
|
4142
|
-
return view;
|
|
4143
|
-
});
|
|
4144
|
-
const longest = Math.max(0, ...series.map((s) => s.values.length));
|
|
5747
|
+
const collect = (cats) => void rawCategories.push(cats);
|
|
5748
|
+
const extra = chart.extraGroups ?? [];
|
|
5749
|
+
const total = chart.series.length + extra.reduce((n2, g) => n2 + g.series.length, 0);
|
|
5750
|
+
const series = chart.series.map((s, i) => seriesView(ctx, s, i, total, collect));
|
|
5751
|
+
const longest = Math.max(
|
|
5752
|
+
0,
|
|
5753
|
+
...series.map((s) => s.values.length),
|
|
5754
|
+
...extra.flatMap((g) => g.series.map((s) => s.values.length))
|
|
5755
|
+
);
|
|
4145
5756
|
const firstCats = rawCategories.find((c) => c.length > 0) ?? [];
|
|
4146
|
-
categories = Array.from(
|
|
5757
|
+
const categories = Array.from(
|
|
4147
5758
|
{ length: Math.max(longest, firstCats.length) },
|
|
4148
5759
|
(_, i) => firstCats[i] !== void 0 ? toText(firstCats[i] ?? null) : String(i + 1)
|
|
4149
5760
|
);
|
|
4150
|
-
if (
|
|
5761
|
+
if (byPoint) {
|
|
4151
5762
|
series.forEach((s, seriesIndex) => {
|
|
4152
5763
|
s.pointColors = s.values.map((_, i) => {
|
|
4153
5764
|
const explicit = drawingColor(chart.series[seriesIndex]?.pointColors?.[i]);
|
|
@@ -4168,8 +5779,8 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
4168
5779
|
for (const [key, fill] of Object.entries(source.pointFills ?? {})) {
|
|
4169
5780
|
if (fill.kind === "none") (s.pointColors ??= [])[Number(key)] = "none";
|
|
4170
5781
|
else if (fill.kind === "solid") {
|
|
4171
|
-
const
|
|
4172
|
-
if (
|
|
5782
|
+
const paint2 = drawingColor(fill.color);
|
|
5783
|
+
if (paint2) (s.pointColors ??= [])[Number(key)] = paint2;
|
|
4173
5784
|
}
|
|
4174
5785
|
}
|
|
4175
5786
|
});
|
|
@@ -4196,7 +5807,7 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
4196
5807
|
if (titleText) model.titleText = titleText;
|
|
4197
5808
|
const appearance = chartAppearance(chart, theme);
|
|
4198
5809
|
if (appearance) model.appearance = appearance;
|
|
4199
|
-
if (type === "scatter") {
|
|
5810
|
+
if (type === "scatter" || type === "bubble") {
|
|
4200
5811
|
series.forEach((s, i) => {
|
|
4201
5812
|
const cats = rawCategories[i] ?? [];
|
|
4202
5813
|
const numeric = cats.length > 0 && cats.every((c) => typeof c === "number");
|
|
@@ -4205,7 +5816,15 @@ function chartSummaryView(chart, theme, options = {}) {
|
|
|
4205
5816
|
const xs = series.flatMap((s) => s.xValues ?? []).filter((x) => x !== null);
|
|
4206
5817
|
model.xAxis = xs.length ? niceScale(Math.min(...xs), Math.max(...xs)) : niceScale(0, 1);
|
|
4207
5818
|
}
|
|
4208
|
-
if (
|
|
5819
|
+
if (type === "stock") model.stock = stockView(chart.stock, ctx);
|
|
5820
|
+
if (type === "bubble") bubbleView(chart, model, ctx.evaluateRef);
|
|
5821
|
+
if (type === "treemap" || type === "sunburst") hierarchyView(chart, model, ctx.evaluateRef);
|
|
5822
|
+
if (type === "histogram") histogramView(chart, model);
|
|
5823
|
+
if (extra.length && (type === "column" || type === "line" || type === "area"))
|
|
5824
|
+
chartExtraView(chart, model, ctx, total, collect);
|
|
5825
|
+
if (type === "waterfall") waterfallView(chart, model, ctx);
|
|
5826
|
+
else if (!byPoint) model.valueAxis = valueAxis(model);
|
|
5827
|
+
chartExtraAxes(model);
|
|
4209
5828
|
return model;
|
|
4210
5829
|
}
|
|
4211
5830
|
|
|
@@ -4247,7 +5866,7 @@ function chartGradientPaint(model, width = 1024, height = 768) {
|
|
|
4247
5866
|
textShadowFilter: shadowPaint(entry.textShadow, `${part}-text-shadow`)
|
|
4248
5867
|
};
|
|
4249
5868
|
}
|
|
4250
|
-
const
|
|
5869
|
+
const paint2 = (gradient, suffix, bounds) => {
|
|
4251
5870
|
const def = buildChartGradientDef(`${prefix}-${suffix}`, gradient, bounds);
|
|
4252
5871
|
defs.push(chartGradientMarkup(def));
|
|
4253
5872
|
return `url(#${def.id})`;
|
|
@@ -4258,18 +5877,18 @@ function chartGradientPaint(model, width = 1024, height = 768) {
|
|
|
4258
5877
|
if (part === "plotArea" && ["circle", "shape"].includes(entry.gradient.path ?? "")) continue;
|
|
4259
5878
|
appearance[part] = {
|
|
4260
5879
|
...entry,
|
|
4261
|
-
fillColor:
|
|
5880
|
+
fillColor: paint2(entry.gradient, part, { width, height, shape: "rect" })
|
|
4262
5881
|
};
|
|
4263
5882
|
}
|
|
4264
5883
|
const series = model.series.map((source, index) => {
|
|
4265
5884
|
const view = { ...source };
|
|
4266
5885
|
if (source.shadow) view.shadowFilter = shadowPaint(source.shadow, `s${index}-shadow`);
|
|
4267
5886
|
const bounds = model.type === "bar" || model.type === "column" ? { width: 1, height: 1, shape: "rect" } : void 0;
|
|
4268
|
-
if (source.gradient) view.color =
|
|
5887
|
+
if (source.gradient) view.color = paint2(source.gradient, `s${index}`, bounds);
|
|
4269
5888
|
if (source.pointGradients) {
|
|
4270
5889
|
view.pointColors = [...source.pointColors ?? []];
|
|
4271
5890
|
for (const [key, gradient] of Object.entries(source.pointGradients))
|
|
4272
|
-
view.pointColors[Number(key)] =
|
|
5891
|
+
view.pointColors[Number(key)] = paint2(gradient, `s${index}-p${key}`, bounds);
|
|
4273
5892
|
}
|
|
4274
5893
|
return view;
|
|
4275
5894
|
});
|
|
@@ -4314,72 +5933,8 @@ function chartAreaRect(model, part, area) {
|
|
|
4314
5933
|
return `${defs}<rect x="${n(area.x)}" y="${n(area.y)}" width="${n(area.w)}" height="${n(area.h)}" fill="${esc(fill)}" stroke="${esc(stroke)}" stroke-width="${n(width)}" data-chart-part="${part}"/>`;
|
|
4315
5934
|
}
|
|
4316
5935
|
|
|
4317
|
-
// chart/render/chart-spacing.ts
|
|
4318
|
-
function chartBarSpacing(chart) {
|
|
4319
|
-
const stacked = chart.grouping === "stacked" || chart.grouping === "percentStacked";
|
|
4320
|
-
return {
|
|
4321
|
-
barGapWidth: chart.barGapWidth ?? DEFAULT_BAR_GAP_WIDTH,
|
|
4322
|
-
barOverlap: chart.barOverlap ?? (stacked ? 100 : 0)
|
|
4323
|
-
};
|
|
4324
|
-
}
|
|
4325
|
-
|
|
4326
|
-
// chart/render/chart-svg-bars.ts
|
|
4327
|
-
function bars(model, frame, out, values) {
|
|
4328
|
-
const stacked = model.grouping === "stacked" || model.grouping === "percentStacked";
|
|
4329
|
-
const count = Math.max(1, model.series.length);
|
|
4330
|
-
const geometry = clusteredBarGeometry(frame.bandSize, count, chartBarSpacing(model));
|
|
4331
|
-
const barSize = geometry.singleBarWidth;
|
|
4332
|
-
const base = frame.value(0);
|
|
4333
|
-
const pos = new Array(model.categories.length).fill(0);
|
|
4334
|
-
const neg = new Array(model.categories.length).fill(0);
|
|
4335
|
-
model.series.forEach((s, si) => {
|
|
4336
|
-
values[si]?.forEach((v, i) => {
|
|
4337
|
-
if (v === null || i >= model.categories.length) return;
|
|
4338
|
-
let from = 0;
|
|
4339
|
-
let to = v;
|
|
4340
|
-
if (stacked) {
|
|
4341
|
-
const acc = v >= 0 ? pos : neg;
|
|
4342
|
-
from = acc[i] ?? 0;
|
|
4343
|
-
to = from + v;
|
|
4344
|
-
acc[i] = to;
|
|
4345
|
-
}
|
|
4346
|
-
const a = stacked ? frame.value(from) : base;
|
|
4347
|
-
const b = frame.value(to);
|
|
4348
|
-
const offset = model.horizontal ? geometry.clusterWidth / 2 - barSize - si * geometry.step : -geometry.clusterWidth / 2 + si * geometry.step;
|
|
4349
|
-
const center = frame.band(i);
|
|
4350
|
-
const width = model.horizontal ? Math.abs(b - a) : barSize;
|
|
4351
|
-
const height = model.horizontal ? barSize : Math.abs(b - a);
|
|
4352
|
-
let color = s.pointColors?.[i] ?? s.color;
|
|
4353
|
-
const gradient = s.pointGradients?.[i] ?? (s.pointColors?.[i] === void 0 ? s.gradient : void 0);
|
|
4354
|
-
if (gradient && (gradient.path === "circle" || gradient.path === "shape")) {
|
|
4355
|
-
const baseId = color.match(/^url\(#(.+)\)$/)?.[1];
|
|
4356
|
-
if (baseId) {
|
|
4357
|
-
const id = baseId.replace(/(-s\d+(?:-p\d+)?)$/, `-mark${i}$1`);
|
|
4358
|
-
const def = buildChartGradientDef(id, gradient, {
|
|
4359
|
-
width: Number(n(width)),
|
|
4360
|
-
height: Number(n(height)),
|
|
4361
|
-
shape: "rect"
|
|
4362
|
-
});
|
|
4363
|
-
out.push(`<defs>${chartGradientMarkup(def)}</defs>`);
|
|
4364
|
-
color = `url(#${id})`;
|
|
4365
|
-
}
|
|
4366
|
-
}
|
|
4367
|
-
out.push(`<g data-chart-series="${si}" data-chart-point="${i}">`);
|
|
4368
|
-
if (model.horizontal)
|
|
4369
|
-
out.push(
|
|
4370
|
-
rect(Math.min(a, b), center + offset, Math.abs(b - a), barSize, color, s.shadowFilter)
|
|
4371
|
-
);
|
|
4372
|
-
else
|
|
4373
|
-
out.push(
|
|
4374
|
-
rect(center + offset, Math.min(a, b), barSize, Math.abs(b - a), color, s.shadowFilter)
|
|
4375
|
-
);
|
|
4376
|
-
out.push("</g>");
|
|
4377
|
-
});
|
|
4378
|
-
});
|
|
4379
|
-
}
|
|
4380
|
-
|
|
4381
5936
|
// chart/render/chart-svg-cartesian.ts
|
|
4382
|
-
function
|
|
5937
|
+
function cartesianAxes(model, area, out) {
|
|
4383
5938
|
const scale = model.valueAxis;
|
|
4384
5939
|
if (!scale) return void 0;
|
|
4385
5940
|
const labels = scale.ticks.map((t) => formatAxisValue(t, scale.percent));
|
|
@@ -4398,6 +5953,9 @@ function axes(model, area, out) {
|
|
|
4398
5953
|
area.w * 0.3,
|
|
4399
5954
|
Math.max(...model.categories.map((c) => textWidth(c, categorySize)), 8) + 6
|
|
4400
5955
|
);
|
|
5956
|
+
const second = horizontal ? void 0 : model.secondaryAxis;
|
|
5957
|
+
const secondLabels = second?.ticks.map((t) => formatAxisValue(t, second.percent)) ?? [];
|
|
5958
|
+
const secondW = second ? valueLabels ? Math.max(...secondLabels.map((l) => textWidth(l, valueSize)), 8) + 8 : 4 : 0;
|
|
4401
5959
|
const plot = horizontal ? {
|
|
4402
5960
|
x: area.x + catW,
|
|
4403
5961
|
y: area.y,
|
|
@@ -4406,7 +5964,7 @@ function axes(model, area, out) {
|
|
|
4406
5964
|
} : {
|
|
4407
5965
|
x: area.x + labelW,
|
|
4408
5966
|
y: area.y + 4,
|
|
4409
|
-
w: Math.max(1, area.w - labelW - 4),
|
|
5967
|
+
w: Math.max(1, area.w - labelW - 4 - secondW),
|
|
4410
5968
|
h: Math.max(1, area.h - Math.max(20, categorySize * 1.5))
|
|
4411
5969
|
};
|
|
4412
5970
|
const span = scale.max - scale.min || 1;
|
|
@@ -4454,7 +6012,32 @@ function axes(model, area, out) {
|
|
|
4454
6012
|
})
|
|
4455
6013
|
);
|
|
4456
6014
|
});
|
|
4457
|
-
|
|
6015
|
+
const frame = { plot, value, band, bandSize };
|
|
6016
|
+
if (second) {
|
|
6017
|
+
const secondSpan = second.max - second.min || 1;
|
|
6018
|
+
frame.secondary = (v) => plot.y + plot.h - (v - second.min) / secondSpan * plot.h;
|
|
6019
|
+
const secondAxis = chartStroke(model, "valueAxis");
|
|
6020
|
+
out.push(
|
|
6021
|
+
line(
|
|
6022
|
+
plot.x + plot.w,
|
|
6023
|
+
plot.y,
|
|
6024
|
+
plot.x + plot.w,
|
|
6025
|
+
plot.y + plot.h,
|
|
6026
|
+
secondAxis.color,
|
|
6027
|
+
secondAxis.width
|
|
6028
|
+
)
|
|
6029
|
+
);
|
|
6030
|
+
if (valueLabels)
|
|
6031
|
+
second.ticks.forEach(
|
|
6032
|
+
(t, i) => out.push(
|
|
6033
|
+
text(plot.x + plot.w + 4, frame.secondary(t) + valueSize * 0.3, secondLabels[i] ?? "", {
|
|
6034
|
+
anchor: "start",
|
|
6035
|
+
...valueAttrs
|
|
6036
|
+
})
|
|
6037
|
+
)
|
|
6038
|
+
);
|
|
6039
|
+
}
|
|
6040
|
+
return frame;
|
|
4458
6041
|
}
|
|
4459
6042
|
function plotted(model) {
|
|
4460
6043
|
if (model.grouping !== "percentStacked") return model.series.map((s) => s.values);
|
|
@@ -4497,17 +6080,17 @@ function linesAndAreas(model, frame, out) {
|
|
|
4497
6080
|
out.push(`<polygon points="${poly}" fill="${color}" fill-opacity="0.85"${filter}/>`);
|
|
4498
6081
|
continue;
|
|
4499
6082
|
}
|
|
4500
|
-
let
|
|
6083
|
+
let segment2 = [];
|
|
4501
6084
|
const flush = () => {
|
|
4502
|
-
if (
|
|
6085
|
+
if (segment2.length > 1)
|
|
4503
6086
|
out.push(
|
|
4504
|
-
`<polyline points="${
|
|
6087
|
+
`<polyline points="${segment2.join(" ")}" fill="none" stroke="${color}" stroke-width="2.25" stroke-linejoin="round"${filter}/>`
|
|
4505
6088
|
);
|
|
4506
|
-
|
|
6089
|
+
segment2 = [];
|
|
4507
6090
|
};
|
|
4508
6091
|
for (const [x, y] of points) {
|
|
4509
6092
|
if (Number.isNaN(x)) flush();
|
|
4510
|
-
else
|
|
6093
|
+
else segment2.push(`${n(x)},${n(y)}`);
|
|
4511
6094
|
}
|
|
4512
6095
|
flush();
|
|
4513
6096
|
for (const [x, y] of points)
|
|
@@ -4515,6 +6098,8 @@ function linesAndAreas(model, frame, out) {
|
|
|
4515
6098
|
out.push(`<circle cx="${n(x)}" cy="${n(y)}" r="2.5" fill="${color}"${filter}/>`);
|
|
4516
6099
|
}
|
|
4517
6100
|
}
|
|
6101
|
+
|
|
6102
|
+
// chart/render/chart-svg-xy.ts
|
|
4518
6103
|
function scatter(model, area, out) {
|
|
4519
6104
|
const ys = model.valueAxis;
|
|
4520
6105
|
const xs = model.xAxis;
|
|
@@ -4536,26 +6121,42 @@ function scatter(model, area, out) {
|
|
|
4536
6121
|
w: Math.max(1, area.w - labelW - 8),
|
|
4537
6122
|
h: Math.max(1, area.h - Math.max(20, categorySize * 1.5))
|
|
4538
6123
|
};
|
|
4539
|
-
const
|
|
4540
|
-
const
|
|
6124
|
+
const bubble = model.type === "bubble" ? model.bubble : void 0;
|
|
6125
|
+
const biggest = maxBubbleSize(
|
|
6126
|
+
model.series.flatMap((s) => (s.sizes ?? []).filter((v) => v !== null))
|
|
6127
|
+
);
|
|
6128
|
+
const median = medianBubbleRadius(plot.w, plot.h);
|
|
6129
|
+
const radiusOf = (size) => bubble && !(size !== void 0 && size < 0 && !bubble.showNegativeBubbles) ? computeBubbleRadius(size, biggest, median, bubble) : void 0;
|
|
6130
|
+
let reach = 0;
|
|
6131
|
+
if (bubble)
|
|
6132
|
+
for (const s of model.series)
|
|
6133
|
+
s.values.forEach((_, i) => {
|
|
6134
|
+
reach = Math.max(reach, radiusOf(s.sizes?.[i] ?? void 0) ?? 0);
|
|
6135
|
+
});
|
|
6136
|
+
const widen = (s, length) => {
|
|
6137
|
+
const pad = reach * (s.max - s.min || 1) / Math.max(1, length - 2 * reach);
|
|
6138
|
+
return { ...s, min: s.min - pad, max: s.max + pad };
|
|
6139
|
+
};
|
|
6140
|
+
const xView = widen(xs, plot.w);
|
|
6141
|
+
const yView = widen(ys, plot.h);
|
|
6142
|
+
const px = (v) => plot.x + (v - xView.min) / (xView.max - xView.min || 1) * plot.w;
|
|
6143
|
+
const py = (v) => plot.y + plot.h - (v - yView.min) / (yView.max - yView.min || 1) * plot.h;
|
|
4541
6144
|
out.push(chartAreaRect(model, "plotArea", plot));
|
|
4542
6145
|
ys.ticks.forEach((t, i) => {
|
|
4543
|
-
out.push(line(plot.x, py(t
|
|
6146
|
+
out.push(line(plot.x, py(t), plot.x + plot.w, py(t), grid.color, grid.width));
|
|
4544
6147
|
if (valueLabels)
|
|
4545
6148
|
out.push(
|
|
4546
|
-
text(plot.x - 4, py(t
|
|
6149
|
+
text(plot.x - 4, py(t) + valueSize * 0.3, yLabels[i] ?? "", {
|
|
4547
6150
|
anchor: "end",
|
|
4548
6151
|
...valueAttrs
|
|
4549
6152
|
})
|
|
4550
6153
|
);
|
|
4551
6154
|
});
|
|
4552
6155
|
for (const t of xs.ticks) {
|
|
4553
|
-
out.push(
|
|
4554
|
-
line(px(t, xs), plot.y + plot.h, px(t, xs), plot.y + plot.h + 3, xAxis.color, xAxis.width)
|
|
4555
|
-
);
|
|
6156
|
+
out.push(line(px(t), plot.y + plot.h, px(t), plot.y + plot.h + 3, xAxis.color, xAxis.width));
|
|
4556
6157
|
if (categoryLabels)
|
|
4557
6158
|
out.push(
|
|
4558
|
-
text(px(t
|
|
6159
|
+
text(px(t), plot.y + plot.h + categorySize + 3, formatAxisValue(t), {
|
|
4559
6160
|
anchor: "middle",
|
|
4560
6161
|
...categoryAttrs
|
|
4561
6162
|
})
|
|
@@ -4565,25 +6166,159 @@ function scatter(model, area, out) {
|
|
|
4565
6166
|
line(plot.x, plot.y + plot.h, plot.x + plot.w, plot.y + plot.h, xAxis.color, xAxis.width)
|
|
4566
6167
|
);
|
|
4567
6168
|
out.push(line(plot.x, plot.y, plot.x, plot.y + plot.h, yAxis.color, yAxis.width));
|
|
4568
|
-
for (const s of model.series)
|
|
6169
|
+
for (const [si, s] of model.series.entries())
|
|
4569
6170
|
s.values.forEach((v, i) => {
|
|
4570
6171
|
const x = s.xValues?.[i] ?? null;
|
|
4571
6172
|
if (v === null || x === null) return;
|
|
6173
|
+
const filter = s.shadowFilter ? ` filter="${s.shadowFilter}"` : "";
|
|
6174
|
+
const fill = s.pointColors?.[i] ?? s.color;
|
|
6175
|
+
if (!bubble) {
|
|
6176
|
+
out.push(`<circle cx="${n(px(x))}" cy="${n(py(v))}" r="3" fill="${fill}"${filter}/>`);
|
|
6177
|
+
return;
|
|
6178
|
+
}
|
|
6179
|
+
const r = radiusOf(s.sizes?.[i] ?? void 0);
|
|
6180
|
+
if (r === void 0) return;
|
|
4572
6181
|
out.push(
|
|
4573
|
-
`<circle cx="${n(px(x
|
|
6182
|
+
`<circle cx="${n(px(x))}" cy="${n(py(v))}" r="${n(r)}" fill="${fill}" fill-opacity="0.6" data-chart-series="${si}" data-chart-point="${i}"${filter}/>`
|
|
4574
6183
|
);
|
|
4575
6184
|
});
|
|
6185
|
+
scatterAnalysis(model, px, py, out);
|
|
6186
|
+
}
|
|
6187
|
+
|
|
6188
|
+
// chart/render/chart-svg-stock.ts
|
|
6189
|
+
function stockBars(model, frame, out) {
|
|
6190
|
+
const slots = stockSlots(model.series.length);
|
|
6191
|
+
if (!slots) return;
|
|
6192
|
+
const style = model.stock ?? stockView(void 0, { drawingColor: () => void 0 });
|
|
6193
|
+
const at = (role, i) => role === void 0 ? void 0 : model.series[role]?.values[i];
|
|
6194
|
+
const closeColor = model.series[slots.close]?.color ?? style.wick.color;
|
|
6195
|
+
model.categories.forEach((_, i) => {
|
|
6196
|
+
const candle = stockCandle({
|
|
6197
|
+
x: frame.band(i),
|
|
6198
|
+
band: frame.bandSize,
|
|
6199
|
+
high: at(slots.high, i),
|
|
6200
|
+
low: at(slots.low, i),
|
|
6201
|
+
close: at(slots.close, i),
|
|
6202
|
+
open: at(slots.open, i),
|
|
6203
|
+
hasOpen: slots.open !== void 0,
|
|
6204
|
+
bodyShare: style.bodyShare,
|
|
6205
|
+
y: frame.value
|
|
6206
|
+
});
|
|
6207
|
+
if (!candle) return;
|
|
6208
|
+
out.push(`<g data-chart-series="${slots.close}" data-chart-point="${i}">`);
|
|
6209
|
+
out.push(
|
|
6210
|
+
line(
|
|
6211
|
+
candle.wick.x,
|
|
6212
|
+
candle.wick.y1,
|
|
6213
|
+
candle.wick.x,
|
|
6214
|
+
candle.wick.y2,
|
|
6215
|
+
style.wick.color,
|
|
6216
|
+
style.wick.width
|
|
6217
|
+
)
|
|
6218
|
+
);
|
|
6219
|
+
if (candle.body) {
|
|
6220
|
+
const { x, y, w, h, up } = candle.body;
|
|
6221
|
+
const bar = up ? style.up : style.down;
|
|
6222
|
+
const stroke = bar.stroke === "none" ? "" : ` stroke="${esc(bar.stroke)}" stroke-width="${n(bar.strokeWidth)}"`;
|
|
6223
|
+
out.push(rect(x, y, w, h, bar.fill).replace("/>", `${stroke}/>`));
|
|
6224
|
+
} else if (candle.tick) {
|
|
6225
|
+
out.push(
|
|
6226
|
+
line(
|
|
6227
|
+
candle.tick.x1,
|
|
6228
|
+
candle.tick.y,
|
|
6229
|
+
candle.tick.x2,
|
|
6230
|
+
candle.tick.y,
|
|
6231
|
+
closeColor,
|
|
6232
|
+
STOCK_TICK_WIDTH
|
|
6233
|
+
)
|
|
6234
|
+
);
|
|
6235
|
+
}
|
|
6236
|
+
out.push("</g>");
|
|
6237
|
+
});
|
|
6238
|
+
}
|
|
6239
|
+
|
|
6240
|
+
// chart/render/chart-svg-waterfall.ts
|
|
6241
|
+
var CONNECTOR_COLOR = "#7F7F7F";
|
|
6242
|
+
var BAR_SHARE = 2 / 3;
|
|
6243
|
+
function waterfallBars(model, frame, out) {
|
|
6244
|
+
const view = model.waterfall;
|
|
6245
|
+
if (!view) return;
|
|
6246
|
+
const width = frame.bandSize * BAR_SHARE;
|
|
6247
|
+
view.steps.forEach((step, i) => {
|
|
6248
|
+
const a = frame.value(step.startValue);
|
|
6249
|
+
const b = frame.value(step.endValue);
|
|
6250
|
+
const color = step.isSubtotal ? view.colors.total : step.value >= 0 ? view.colors.increase : view.colors.decrease;
|
|
6251
|
+
const x = frame.band(i) - width / 2;
|
|
6252
|
+
out.push(`<g data-chart-series="0" data-chart-point="${step.sourceIndex}">`);
|
|
6253
|
+
out.push(rect(x, Math.min(a, b), width, Math.max(Math.abs(b - a), 1), color));
|
|
6254
|
+
out.push("</g>");
|
|
6255
|
+
const next = view.steps[i + 1];
|
|
6256
|
+
if (view.connectors && next) {
|
|
6257
|
+
const xNext = frame.band(i + 1) - width / 2;
|
|
6258
|
+
out.push(
|
|
6259
|
+
line(x + width, b, xNext, b, CONNECTOR_COLOR, 0.75).replace(
|
|
6260
|
+
"/>",
|
|
6261
|
+
` stroke-dasharray="${n(3)} ${n(2)}"/>`
|
|
6262
|
+
)
|
|
6263
|
+
);
|
|
6264
|
+
}
|
|
6265
|
+
});
|
|
6266
|
+
}
|
|
6267
|
+
|
|
6268
|
+
// chart/render/chart-svg-plots.ts
|
|
6269
|
+
var RANK = {
|
|
6270
|
+
area: 0,
|
|
6271
|
+
bar: 1,
|
|
6272
|
+
column: 1,
|
|
6273
|
+
histogram: 1,
|
|
6274
|
+
line: 2,
|
|
6275
|
+
stock: 2
|
|
6276
|
+
};
|
|
6277
|
+
function paint(layer, out) {
|
|
6278
|
+
const { model, frame } = layer;
|
|
6279
|
+
if (model.type === "stock") stockBars(model, frame, out);
|
|
6280
|
+
else if (model.type === "bar" || model.type === "column" || model.type === "histogram")
|
|
6281
|
+
bars(model, frame, out, plotted(model));
|
|
6282
|
+
else linesAndAreas(model, frame, out);
|
|
4576
6283
|
}
|
|
4577
6284
|
function cartesianSvg(model, area) {
|
|
4578
6285
|
const out = [];
|
|
4579
|
-
if (model.type === "scatter") {
|
|
6286
|
+
if (model.type === "scatter" || model.type === "bubble") {
|
|
4580
6287
|
scatter(model, area, out);
|
|
4581
6288
|
return out.join("");
|
|
4582
6289
|
}
|
|
4583
|
-
const frame =
|
|
6290
|
+
const frame = cartesianAxes(model, area, out);
|
|
4584
6291
|
if (!frame) return "";
|
|
4585
|
-
if (model.type === "
|
|
4586
|
-
|
|
6292
|
+
if (model.type === "waterfall") {
|
|
6293
|
+
waterfallBars(model, frame, out);
|
|
6294
|
+
return out.join("");
|
|
6295
|
+
}
|
|
6296
|
+
if (model.type === "stock") {
|
|
6297
|
+
stockBars(model, frame, out);
|
|
6298
|
+
return out.join("");
|
|
6299
|
+
}
|
|
6300
|
+
const layers = [{ model, frame }];
|
|
6301
|
+
for (const group of model.extraGroups ?? []) {
|
|
6302
|
+
const grouped = {
|
|
6303
|
+
...model,
|
|
6304
|
+
type: group.type,
|
|
6305
|
+
grouping: group.grouping,
|
|
6306
|
+
series: group.series,
|
|
6307
|
+
horizontal: false
|
|
6308
|
+
};
|
|
6309
|
+
if (group.stock) grouped.stock = group.stock;
|
|
6310
|
+
else delete grouped.stock;
|
|
6311
|
+
if (group.barGapWidth !== void 0) grouped.barGapWidth = group.barGapWidth;
|
|
6312
|
+
else delete grouped.barGapWidth;
|
|
6313
|
+
if (group.barOverlap !== void 0) grouped.barOverlap = group.barOverlap;
|
|
6314
|
+
else delete grouped.barOverlap;
|
|
6315
|
+
const value = group.secondary && frame.secondary ? frame.secondary : frame.value;
|
|
6316
|
+
layers.push({ model: grouped, frame: { ...frame, value } });
|
|
6317
|
+
}
|
|
6318
|
+
layers.map((layer, order) => ({ layer, order })).sort(
|
|
6319
|
+
(a, b) => (RANK[a.layer.model.type] ?? 1) - (RANK[b.layer.model.type] ?? 1) || a.order - b.order
|
|
6320
|
+
).forEach(({ layer }) => paint(layer, out));
|
|
6321
|
+
categoryAnalysis(model, frame, out);
|
|
4587
6322
|
return out.join("");
|
|
4588
6323
|
}
|
|
4589
6324
|
|
|
@@ -4685,28 +6420,110 @@ function radarSvg(model, area) {
|
|
|
4685
6420
|
return out.join("");
|
|
4686
6421
|
}
|
|
4687
6422
|
|
|
6423
|
+
// chart/render/chart-svg-hierarchy.ts
|
|
6424
|
+
var colorAt2 = (model, index) => {
|
|
6425
|
+
const first3 = model.series[0];
|
|
6426
|
+
const colors = first3?.pointColors;
|
|
6427
|
+
return (colors && colors.length > 0 ? colors[index % colors.length] : void 0) ?? first3?.color ?? "#4472C4";
|
|
6428
|
+
};
|
|
6429
|
+
var leafValues = (model) => (model.series[0]?.values ?? []).map((v) => v ?? 0);
|
|
6430
|
+
function treemapSvg(model, area) {
|
|
6431
|
+
const out = [chartAreaRect(model, "plotArea", area)];
|
|
6432
|
+
const hierarchy = model.hierarchy;
|
|
6433
|
+
const series = model.series.map((s) => ({
|
|
6434
|
+
name: s.name,
|
|
6435
|
+
values: s.values.map((v) => v ?? 0),
|
|
6436
|
+
// Without data labels Office draws no parent banners either, so no space is reserved.
|
|
6437
|
+
parentLabelLayout: hierarchy?.labels === false ? "none" : hierarchy?.parentLabelLayout
|
|
6438
|
+
}));
|
|
6439
|
+
const roots = buildHierarchyRoots(
|
|
6440
|
+
series,
|
|
6441
|
+
model.categories,
|
|
6442
|
+
hierarchy && hierarchy.levels.length > 1 ? hierarchy.levels : void 0
|
|
6443
|
+
);
|
|
6444
|
+
const cells = layoutTreemap(roots, { x: area.x, y: area.y, w: area.w, h: area.h });
|
|
6445
|
+
for (const cell of cells) {
|
|
6446
|
+
if (cell.kind === "parent") {
|
|
6447
|
+
if (hierarchy?.labels !== false)
|
|
6448
|
+
out.push(text(cell.x, cell.y, cell.label, { size: 10, weight: "bold", fill: "#303030" }));
|
|
6449
|
+
continue;
|
|
6450
|
+
}
|
|
6451
|
+
out.push(`<g data-chart-series="${cell.seriesIndex}" data-chart-point="${cell.pointIndex}">`);
|
|
6452
|
+
out.push(
|
|
6453
|
+
rect(cell.x, cell.y, cell.w, cell.h, colorAt2(model, cell.colorIndex)).replace(
|
|
6454
|
+
"/>",
|
|
6455
|
+
' rx="2"/>'
|
|
6456
|
+
)
|
|
6457
|
+
);
|
|
6458
|
+
if (cell.labelFits && hierarchy?.labels !== false)
|
|
6459
|
+
out.push(
|
|
6460
|
+
text(
|
|
6461
|
+
cell.x + cell.w / 2,
|
|
6462
|
+
cell.y + cell.h / 2,
|
|
6463
|
+
fit(cell.label, cell.w - 4, cell.labelSize),
|
|
6464
|
+
{
|
|
6465
|
+
anchor: "middle",
|
|
6466
|
+
size: cell.labelSize,
|
|
6467
|
+
weight: "bold",
|
|
6468
|
+
fill: "#FFFFFF",
|
|
6469
|
+
baseline: "central"
|
|
6470
|
+
}
|
|
6471
|
+
)
|
|
6472
|
+
);
|
|
6473
|
+
out.push("</g>");
|
|
6474
|
+
}
|
|
6475
|
+
return out.join("");
|
|
6476
|
+
}
|
|
6477
|
+
function sunburstSvg(model, area) {
|
|
6478
|
+
const out = [chartAreaRect(model, "plotArea", area)];
|
|
6479
|
+
const cx = area.x + area.w / 2;
|
|
6480
|
+
const cy = area.y + area.h / 2;
|
|
6481
|
+
const maxR = Math.min(area.w, area.h) / 2 - 4;
|
|
6482
|
+
if (maxR <= 0) return out.join("");
|
|
6483
|
+
const levels = model.hierarchy?.levels ?? [];
|
|
6484
|
+
const arcs = levels.length > 1 ? computeHierarchicalSunburstArcs(levels, leafValues(model), cx, cy, maxR) : computeSunburstArcs(
|
|
6485
|
+
model.series.map((s) => ({ values: s.values.map((v) => v ?? 0) })),
|
|
6486
|
+
cx,
|
|
6487
|
+
cy,
|
|
6488
|
+
maxR
|
|
6489
|
+
);
|
|
6490
|
+
for (const arc of arcs)
|
|
6491
|
+
out.push(
|
|
6492
|
+
`<path d="${arc.d}" fill="${colorAt2(model, arc.colorIndex)}" stroke="#FFFFFF" stroke-width="1.5"${arc.pointIndex === void 0 ? "" : ` data-chart-series="0" data-chart-point="${arc.pointIndex}"`}/>`
|
|
6493
|
+
);
|
|
6494
|
+
const flatLabels = levels.length > 1 || model.series.length !== 1 ? void 0 : model.categories;
|
|
6495
|
+
for (const arc of model.hierarchy?.labels === false ? [] : arcs) {
|
|
6496
|
+
const label = arc.label ?? (arc.pointIndex === void 0 ? void 0 : flatLabels?.[arc.pointIndex]);
|
|
6497
|
+
if (!label) continue;
|
|
6498
|
+
out.push(
|
|
6499
|
+
`<text x="${n(arc.labelX)}" y="${n(arc.labelY)}" font-size="10" fill="#FFFFFF" text-anchor="middle" dominant-baseline="central" transform="rotate(${n(arc.labelRotation)}, ${n(arc.labelX)}, ${n(arc.labelY)})">${esc(label)}</text>`
|
|
6500
|
+
);
|
|
6501
|
+
}
|
|
6502
|
+
return out.join("");
|
|
6503
|
+
}
|
|
6504
|
+
|
|
4688
6505
|
// chart/render/chart-svg-text-metrics.ts
|
|
4689
6506
|
var CHART_FONT_FAMILY = "Calibri, Carlito, Arial, sans-serif";
|
|
4690
|
-
function cssFont(
|
|
4691
|
-
return `${
|
|
6507
|
+
function cssFont(attrs2) {
|
|
6508
|
+
return `${attrs2.italic ? "italic" : "normal"} ${attrs2.weight ?? "normal"} ${attrs2.size ?? 10}px ${attrs2.family ?? CHART_FONT_FAMILY}`;
|
|
4692
6509
|
}
|
|
4693
|
-
function chartFontMetrics(
|
|
4694
|
-
const metrics = options.measureFont?.(cssFont(
|
|
6510
|
+
function chartFontMetrics(attrs2, options) {
|
|
6511
|
+
const metrics = options.measureFont?.(cssFont(attrs2));
|
|
4695
6512
|
return metrics && Number.isFinite(metrics.ascent) && Number.isFinite(metrics.descent) && metrics.ascent >= 0 && metrics.descent >= 0 && metrics.ascent + metrics.descent > 0 ? metrics : void 0;
|
|
4696
6513
|
}
|
|
4697
|
-
function chartTextWidth(content,
|
|
4698
|
-
const width = options.measureText?.(content, cssFont(
|
|
4699
|
-
return width !== void 0 && Number.isFinite(width) && width >= 0 ? width : textWidth(content,
|
|
6514
|
+
function chartTextWidth(content, attrs2, options) {
|
|
6515
|
+
const width = options.measureText?.(content, cssFont(attrs2));
|
|
6516
|
+
return width !== void 0 && Number.isFinite(width) && width >= 0 ? width : textWidth(content, attrs2.size);
|
|
4700
6517
|
}
|
|
4701
|
-
function fitChartText(content, maxWidth,
|
|
4702
|
-
if (!options.measureText) return fit(content, maxWidth,
|
|
4703
|
-
if (chartTextWidth(content,
|
|
6518
|
+
function fitChartText(content, maxWidth, attrs2, options) {
|
|
6519
|
+
if (!options.measureText) return fit(content, maxWidth, attrs2.size);
|
|
6520
|
+
if (chartTextWidth(content, attrs2, options) <= maxWidth) return content;
|
|
4704
6521
|
const points = [...content];
|
|
4705
6522
|
let low = 0;
|
|
4706
6523
|
let high = points.length;
|
|
4707
6524
|
while (low < high) {
|
|
4708
6525
|
const mid = Math.ceil((low + high) / 2);
|
|
4709
|
-
if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`,
|
|
6526
|
+
if (chartTextWidth(`${points.slice(0, mid).join("")}\u2026`, attrs2, options) <= maxWidth) low = mid;
|
|
4710
6527
|
else high = mid - 1;
|
|
4711
6528
|
}
|
|
4712
6529
|
return `${points.slice(0, low).join("")}\u2026`;
|
|
@@ -4728,13 +6545,13 @@ function chartLegendSvg(model, area, frame, options) {
|
|
|
4728
6545
|
});
|
|
4729
6546
|
if (!manual) return { plot, markup: automatic.join(""), foreground: !!model.legendOverlay };
|
|
4730
6547
|
const entries = legendEntries(model);
|
|
4731
|
-
const
|
|
4732
|
-
const size =
|
|
4733
|
-
const font = chartFontMetrics(
|
|
6548
|
+
const attrs2 = chartTextAttributes(model, "legend");
|
|
6549
|
+
const size = attrs2.size ?? 10;
|
|
6550
|
+
const font = chartFontMetrics(attrs2, options);
|
|
4734
6551
|
const keySize = size / 2;
|
|
4735
6552
|
const keyGap = size / 4;
|
|
4736
6553
|
const widths = entries.map(
|
|
4737
|
-
(entry) => chartTextWidth(entry.label,
|
|
6554
|
+
(entry) => chartTextWidth(entry.label, attrs2, options) + keySize + keyGap
|
|
4738
6555
|
);
|
|
4739
6556
|
const horizontal = manual.width > manual.height && widths.reduce((sum, width) => sum + width, 0) + size <= manual.width;
|
|
4740
6557
|
const rowWidth = horizontal ? manual.width / entries.length : manual.width;
|
|
@@ -4749,8 +6566,8 @@ function chartLegendSvg(model, area, frame, options) {
|
|
|
4749
6566
|
];
|
|
4750
6567
|
const baselineOffset = font ? (font.ascent - font.descent) / 2 : size * 0.35;
|
|
4751
6568
|
entries.forEach((entry, i) => {
|
|
4752
|
-
const available = horizontal ? chartTextWidth(entry.label,
|
|
4753
|
-
const label = fitChartText(entry.label, available,
|
|
6569
|
+
const available = horizontal ? chartTextWidth(entry.label, attrs2, options) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
|
|
6570
|
+
const label = fitChartText(entry.label, available, attrs2, options);
|
|
4754
6571
|
const contentWidth = Math.min(
|
|
4755
6572
|
horizontal ? widths[i] ?? 0 : Math.max(...widths),
|
|
4756
6573
|
rowWidth - size / 2
|
|
@@ -4758,7 +6575,7 @@ function chartLegendSvg(model, area, frame, options) {
|
|
|
4758
6575
|
const x = horizontal ? horizontalX : manual.x + Math.max(size / 4, (rowWidth - contentWidth) / 2);
|
|
4759
6576
|
const centerY = manual.y + (horizontal ? 0 : i * rowHeight) + rowHeight / 2;
|
|
4760
6577
|
markup.push(rect(x, centerY - keySize / 2, keySize, keySize, entry.color));
|
|
4761
|
-
markup.push(text(x + keySize + keyGap, centerY + baselineOffset, label,
|
|
6578
|
+
markup.push(text(x + keySize + keyGap, centerY + baselineOffset, label, attrs2));
|
|
4762
6579
|
if (horizontal) horizontalX += (widths[i] ?? 0) + horizontalGap;
|
|
4763
6580
|
});
|
|
4764
6581
|
return {
|
|
@@ -4775,18 +6592,34 @@ function legendEntries(model) {
|
|
|
4775
6592
|
color: first3?.pointColors?.[i] ?? first3?.color ?? "#4472C4"
|
|
4776
6593
|
}));
|
|
4777
6594
|
}
|
|
4778
|
-
|
|
6595
|
+
if ((model.type === "treemap" || model.type === "sunburst") && model.hierarchy) {
|
|
6596
|
+
const first3 = model.series[0];
|
|
6597
|
+
return model.hierarchy.branches.map((label, i) => ({
|
|
6598
|
+
label,
|
|
6599
|
+
color: first3?.pointColors?.[i % Math.max(1, first3.pointColors.length)] ?? first3?.color ?? "#4472C4"
|
|
6600
|
+
}));
|
|
6601
|
+
}
|
|
6602
|
+
if (model.type === "waterfall" && model.waterfall)
|
|
6603
|
+
return [
|
|
6604
|
+
{ label: "Increase", color: model.waterfall.colors.increase },
|
|
6605
|
+
{ label: "Decrease", color: model.waterfall.colors.decrease },
|
|
6606
|
+
{ label: "Total", color: model.waterfall.colors.total }
|
|
6607
|
+
];
|
|
6608
|
+
return [...model.series, ...(model.extraGroups ?? []).flatMap((g) => g.series)].map((s) => ({
|
|
6609
|
+
label: s.name,
|
|
6610
|
+
color: s.color
|
|
6611
|
+
}));
|
|
4779
6612
|
}
|
|
4780
6613
|
function automaticLegend(model, area, out, options, bounds) {
|
|
4781
6614
|
const entries = legendEntries(model);
|
|
4782
6615
|
if (!model.showLegend || entries.length === 0) return area;
|
|
4783
6616
|
const pos = model.legendPosition;
|
|
4784
|
-
const
|
|
4785
|
-
const size =
|
|
6617
|
+
const attrs2 = chartTextAttributes(model, "legend");
|
|
6618
|
+
const size = attrs2.size ?? 10;
|
|
4786
6619
|
const rowH = Math.max(16, size * 1.4);
|
|
4787
6620
|
if (pos === "t" || pos === "b") {
|
|
4788
6621
|
const widths = entries.map(
|
|
4789
|
-
(e) => Math.min(chartTextWidth(e.label,
|
|
6622
|
+
(e) => Math.min(chartTextWidth(e.label, attrs2, options) + 20, area.w / 2)
|
|
4790
6623
|
);
|
|
4791
6624
|
const total = widths.reduce((a, b) => a + b, 0);
|
|
4792
6625
|
let x2 = area.x + Math.max(0, (area.w - total) / 2);
|
|
@@ -4803,14 +6636,14 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
4803
6636
|
entries.forEach((e, i) => {
|
|
4804
6637
|
const w = widths[i] ?? 0;
|
|
4805
6638
|
out.push(rect(x2, y, 8, 8, e.color));
|
|
4806
|
-
out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16,
|
|
6639
|
+
out.push(text(x2 + 12, y + 8, fitChartText(e.label, w - 16, attrs2, options), attrs2));
|
|
4807
6640
|
x2 += w;
|
|
4808
6641
|
});
|
|
4809
6642
|
return pos === "t" ? { x: area.x, y: area.y + rowH + 4, w: area.w, h: area.h - rowH - 4 } : { x: area.x, y: area.y, w: area.w, h: area.h - rowH - 4 };
|
|
4810
6643
|
}
|
|
4811
6644
|
const width = Math.min(
|
|
4812
6645
|
area.w * 0.35,
|
|
4813
|
-
Math.max(...entries.map((e) => chartTextWidth(e.label,
|
|
6646
|
+
Math.max(...entries.map((e) => chartTextWidth(e.label, attrs2, options))) + 22
|
|
4814
6647
|
);
|
|
4815
6648
|
const height = entries.length * rowH;
|
|
4816
6649
|
const x = pos === "l" ? area.x + 4 : area.x + area.w - width;
|
|
@@ -4828,7 +6661,7 @@ function automaticLegend(model, area, out, options, bounds) {
|
|
|
4828
6661
|
const y = y0 + i * rowH;
|
|
4829
6662
|
if (y + rowH > area.y + area.h + 2) return;
|
|
4830
6663
|
out.push(rect(x, y + 3, 8, 8, e.color));
|
|
4831
|
-
out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16,
|
|
6664
|
+
out.push(text(x + 12, y + 11, fitChartText(e.label, width - 16, attrs2, options), attrs2));
|
|
4832
6665
|
});
|
|
4833
6666
|
return pos === "l" ? { x: area.x + width + 8, y: area.y, w: area.w - width - 8, h: area.h } : { x: area.x, y: area.y, w: area.w - width - 8, h: area.h };
|
|
4834
6667
|
}
|
|
@@ -4885,8 +6718,8 @@ function wrapStyledRuns(runs, maxWidth, measure, options = {}) {
|
|
|
4885
6718
|
spaces = [];
|
|
4886
6719
|
if (options.breakWords && wordWidth > maxWidth) {
|
|
4887
6720
|
for (const piece of group.pieces) {
|
|
4888
|
-
for (const { segment } of graphemes.segment(piece.text)) {
|
|
4889
|
-
const next = { ...piece, text:
|
|
6721
|
+
for (const { segment: segment2 } of graphemes.segment(piece.text)) {
|
|
6722
|
+
const next = { ...piece, text: segment2 };
|
|
4890
6723
|
if (line2.length && width(merged(line2, [next])) > maxWidth) flush();
|
|
4891
6724
|
line2 = merged(line2, [next]);
|
|
4892
6725
|
}
|
|
@@ -4968,7 +6801,7 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
4968
6801
|
width: runs.reduce((sum, run) => sum + chartTextWidth(run.text, run.attrs, options), 0),
|
|
4969
6802
|
size: runs.length ? Math.max(...runs.map((run) => run.attrs.size ?? 14)) : base.size ?? 14,
|
|
4970
6803
|
fontMetrics: (runs.length ? runs.map((run) => run.attrs) : [base]).map(
|
|
4971
|
-
(
|
|
6804
|
+
(attrs2) => chartFontMetrics(attrs2, options)
|
|
4972
6805
|
)
|
|
4973
6806
|
};
|
|
4974
6807
|
});
|
|
@@ -5033,8 +6866,8 @@ function chartRichTitleSvg(model, width, options = {}, frameHeight = 400) {
|
|
|
5033
6866
|
|
|
5034
6867
|
// chart/render/chart-svg.ts
|
|
5035
6868
|
function renderChartSvg(model, width, height, options = {}) {
|
|
5036
|
-
const
|
|
5037
|
-
model =
|
|
6869
|
+
const paint2 = chartGradientPaint(model, Math.max(1, width), Math.max(1, height));
|
|
6870
|
+
model = paint2.model;
|
|
5038
6871
|
const w = Math.max(1, width);
|
|
5039
6872
|
const h = Math.max(1, height);
|
|
5040
6873
|
const out = [];
|
|
@@ -5043,7 +6876,7 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
5043
6876
|
`<svg xmlns="http://www.w3.org/2000/svg" width="${n(w)}" height="${n(h)}" viewBox="0 0 ${n(w)} ${n(h)}" font-family="${esc(CHART_FONT_FAMILY)}" role="img">`
|
|
5044
6877
|
);
|
|
5045
6878
|
if (model.title) out.push(`<title>${esc(model.title)}</title>`);
|
|
5046
|
-
if (
|
|
6879
|
+
if (paint2.defs) out.push(paint2.defs);
|
|
5047
6880
|
out.push(chartAreaRect(model, "chartArea", { x: 0, y: 0, w, h }));
|
|
5048
6881
|
let area = { x: 8, y: 8, w: w - 16, h: h - 16 };
|
|
5049
6882
|
const richTitle = chartRichTitleSvg(model, w, options, h);
|
|
@@ -5053,11 +6886,11 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
5053
6886
|
if (!model.titleOverlay)
|
|
5054
6887
|
area = { ...area, y: area.y + richTitle.height, h: area.h - richTitle.height };
|
|
5055
6888
|
} else if (model.title) {
|
|
5056
|
-
const
|
|
5057
|
-
const size =
|
|
5058
|
-
const label = fitChartText(model.title, w - 16,
|
|
5059
|
-
const titleWidth = Math.min(w - 16, chartTextWidth(label,
|
|
5060
|
-
const font = chartFontMetrics(
|
|
6889
|
+
const attrs2 = chartTextAttributes(model, "title", 14);
|
|
6890
|
+
const size = attrs2.size ?? 14;
|
|
6891
|
+
const label = fitChartText(model.title, w - 16, attrs2, options);
|
|
6892
|
+
const titleWidth = Math.min(w - 16, chartTextWidth(label, attrs2, options) + 8);
|
|
6893
|
+
const font = chartFontMetrics(attrs2, options);
|
|
5061
6894
|
const titleHeight = Math.max(24, font ? font.ascent + font.descent + 4 : size * 1.4 + 4);
|
|
5062
6895
|
out.push(
|
|
5063
6896
|
chartAreaRect(model, "title", {
|
|
@@ -5071,7 +6904,7 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
5071
6904
|
text(w / 2, 8 + size, label, {
|
|
5072
6905
|
anchor: "middle",
|
|
5073
6906
|
fill: "#404040",
|
|
5074
|
-
...
|
|
6907
|
+
...attrs2
|
|
5075
6908
|
})
|
|
5076
6909
|
);
|
|
5077
6910
|
if (!model.titleOverlay)
|
|
@@ -5091,6 +6924,8 @@ function renderChartSvg(model, width, height, options = {}) {
|
|
|
5091
6924
|
if (area.w > 4 && area.h > 4) {
|
|
5092
6925
|
if (model.type === "pie" || model.type === "doughnut") out.push(pieSvg(model, area));
|
|
5093
6926
|
else if (model.type === "radar") out.push(radarSvg(model, area));
|
|
6927
|
+
else if (model.type === "treemap") out.push(treemapSvg(model, area));
|
|
6928
|
+
else if (model.type === "sunburst") out.push(sunburstSvg(model, area));
|
|
5094
6929
|
else out.push(cartesianSvg(model, area));
|
|
5095
6930
|
}
|
|
5096
6931
|
if (legend.foreground) out.push(legend.markup);
|
|
@@ -5108,7 +6943,13 @@ var DRAWN_CHART_TYPES = /* @__PURE__ */ new Set([
|
|
|
5108
6943
|
"pie",
|
|
5109
6944
|
"doughnut",
|
|
5110
6945
|
"scatter",
|
|
5111
|
-
"radar"
|
|
6946
|
+
"radar",
|
|
6947
|
+
"waterfall",
|
|
6948
|
+
"histogram",
|
|
6949
|
+
"bubble",
|
|
6950
|
+
"stock",
|
|
6951
|
+
"treemap",
|
|
6952
|
+
"sunburst"
|
|
5112
6953
|
]);
|
|
5113
6954
|
function chartThemePalette(theme, fonts = {}) {
|
|
5114
6955
|
return {
|
|
@@ -5134,6 +6975,11 @@ function renderChartSpaceSvg(space, options) {
|
|
|
5134
6975
|
const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
|
|
5135
6976
|
return renderChartSvg(view, width, height, svg);
|
|
5136
6977
|
}
|
|
6978
|
+
function renderChartSummarySvg(summary, options) {
|
|
6979
|
+
const { width, height, theme, fonts, ...svg } = options;
|
|
6980
|
+
const view = chartSummaryView(summary, chartThemePalette(theme, fonts));
|
|
6981
|
+
return renderChartSvg(view, width, height, svg);
|
|
6982
|
+
}
|
|
5137
6983
|
|
|
5138
6984
|
// docx/breaks.ts
|
|
5139
6985
|
function isCachedPageBreak(element) {
|
|
@@ -5167,13 +7013,286 @@ function isModeledBreak(element) {
|
|
|
5167
7013
|
return true;
|
|
5168
7014
|
}
|
|
5169
7015
|
|
|
5170
|
-
// docx/write-
|
|
5171
|
-
var A_NS2 = "http://schemas.openxmlformats.org/drawingml/2006/main";
|
|
7016
|
+
// docx/write-shape.ts
|
|
5172
7017
|
var WP_NS2 = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
|
|
5173
|
-
|
|
7018
|
+
var el2 = (doc, ns, name) => makeNS(doc, ns, name);
|
|
7019
|
+
var add2 = (parent, ...items) => {
|
|
7020
|
+
for (const item of items) parent.appendChild(item);
|
|
7021
|
+
return parent;
|
|
7022
|
+
};
|
|
7023
|
+
var emu2 = (px) => String(Math.max(1, Math.round(px * EMU_PER_PIXEL)));
|
|
7024
|
+
var emuOffset = (px) => String(Math.round(px * EMU_PER_PIXEL));
|
|
7025
|
+
var attrs = (element, values) => {
|
|
7026
|
+
for (const [name, value] of Object.entries(values)) element.setAttribute(name, value);
|
|
7027
|
+
return element;
|
|
7028
|
+
};
|
|
7029
|
+
function dropDeclarations(element) {
|
|
7030
|
+
if (element.getAttribute("xmlns:a") === A_NS2) element.removeAttribute("xmlns:a");
|
|
7031
|
+
for (const node of Array.from(element.childNodes))
|
|
7032
|
+
if (node.nodeType === 1) dropDeclarations(node);
|
|
7033
|
+
}
|
|
7034
|
+
function importFragment(doc, xml) {
|
|
7035
|
+
const wrapper = parseXml(`<w xmlns:a="${A_NS2}">${xml}</w>`).documentElement;
|
|
7036
|
+
return Array.from(wrapper.childNodes).filter((node) => node.nodeType === 1).map((node) => {
|
|
7037
|
+
const imported = doc.importNode(node, true);
|
|
7038
|
+
dropDeclarations(imported);
|
|
7039
|
+
return imported;
|
|
7040
|
+
});
|
|
7041
|
+
}
|
|
7042
|
+
var srgb = (fill) => fill?.kind === "solid" && fill.color.kind === "srgb" ? fill.color.value : void 0;
|
|
7043
|
+
function explicitTextColor(spec) {
|
|
7044
|
+
if (!spec.fill) return void 0;
|
|
7045
|
+
if (spec.fill.kind === "none") return "000000";
|
|
7046
|
+
const hex = srgb(spec.fill);
|
|
7047
|
+
if (!hex || !/^[0-9a-f]{6}$/i.test(hex)) return void 0;
|
|
7048
|
+
const channel = (i) => Number.parseInt(hex.slice(i, i + 2), 16) / 255;
|
|
7049
|
+
const light = 0.2126 * channel(0) + 0.7152 * channel(2) + 0.0722 * channel(4) > 0.6;
|
|
7050
|
+
return light ? "000000" : void 0;
|
|
7051
|
+
}
|
|
7052
|
+
function textParagraphs(doc, lines, color) {
|
|
7053
|
+
return lines.map((line2) => {
|
|
7054
|
+
const paragraph = makeW(doc, "p");
|
|
7055
|
+
const props = makeW(doc, "pPr");
|
|
7056
|
+
const jc = makeW(doc, "jc");
|
|
7057
|
+
jc.setAttributeNS(W_NS2, "w:val", "center");
|
|
7058
|
+
add2(paragraph, add2(props, jc));
|
|
7059
|
+
if (line2) {
|
|
7060
|
+
const run = makeW(doc, "r");
|
|
7061
|
+
if (color) {
|
|
7062
|
+
const rPr = makeW(doc, "rPr");
|
|
7063
|
+
const c = makeW(doc, "color");
|
|
7064
|
+
c.setAttributeNS(W_NS2, "w:val", color);
|
|
7065
|
+
add2(run, add2(rPr, c));
|
|
7066
|
+
}
|
|
7067
|
+
const t = makeW(doc, "t");
|
|
7068
|
+
if (/^\s|\s$/.test(line2))
|
|
7069
|
+
t.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve");
|
|
7070
|
+
t.textContent = line2;
|
|
7071
|
+
add2(paragraph, add2(run, t));
|
|
7072
|
+
}
|
|
7073
|
+
return paragraph;
|
|
7074
|
+
});
|
|
7075
|
+
}
|
|
7076
|
+
function shapeStyle(doc) {
|
|
7077
|
+
const ref = (name, idx, scheme, shade) => {
|
|
7078
|
+
const node = attrs(el2(doc, A_NS2, `a:${name}`), { idx });
|
|
7079
|
+
const color = attrs(el2(doc, A_NS2, "a:schemeClr"), { val: scheme });
|
|
7080
|
+
if (shade) add2(color, attrs(el2(doc, A_NS2, "a:shade"), { val: shade }));
|
|
7081
|
+
return add2(node, color);
|
|
7082
|
+
};
|
|
7083
|
+
return add2(
|
|
7084
|
+
el2(doc, WPS_NS2, "wps:style"),
|
|
7085
|
+
ref("lnRef", "2", "accent1", "50000"),
|
|
7086
|
+
ref("fillRef", "1", "accent1"),
|
|
7087
|
+
ref("effectRef", "0", "accent1"),
|
|
7088
|
+
ref("fontRef", "minor", "lt1")
|
|
7089
|
+
);
|
|
7090
|
+
}
|
|
7091
|
+
function wrapElement(doc, placement) {
|
|
7092
|
+
switch (placement.wrap) {
|
|
7093
|
+
case "square":
|
|
7094
|
+
return attrs(el2(doc, WP_NS2, "wp:wrapSquare"), { wrapText: "bothSides" });
|
|
7095
|
+
case "tight":
|
|
7096
|
+
case "through": {
|
|
7097
|
+
const wrap = attrs(
|
|
7098
|
+
el2(doc, WP_NS2, `wp:wrap${placement.wrap === "tight" ? "Tight" : "Through"}`),
|
|
7099
|
+
{
|
|
7100
|
+
wrapText: "bothSides"
|
|
7101
|
+
}
|
|
7102
|
+
);
|
|
7103
|
+
const polygon = attrs(el2(doc, WP_NS2, "wp:wrapPolygon"), { edited: "0" });
|
|
7104
|
+
const point = (name, x, y) => attrs(el2(doc, WP_NS2, `wp:${name}`), { x, y });
|
|
7105
|
+
return add2(
|
|
7106
|
+
wrap,
|
|
7107
|
+
add2(
|
|
7108
|
+
polygon,
|
|
7109
|
+
point("start", "0", "0"),
|
|
7110
|
+
point("lineTo", "0", "21600"),
|
|
7111
|
+
point("lineTo", "21600", "21600"),
|
|
7112
|
+
point("lineTo", "21600", "0"),
|
|
7113
|
+
point("lineTo", "0", "0")
|
|
7114
|
+
)
|
|
7115
|
+
);
|
|
7116
|
+
}
|
|
7117
|
+
case "topAndBottom":
|
|
7118
|
+
return el2(doc, WP_NS2, "wp:wrapTopAndBottom");
|
|
7119
|
+
default:
|
|
7120
|
+
return el2(doc, WP_NS2, "wp:wrapNone");
|
|
7121
|
+
}
|
|
7122
|
+
}
|
|
7123
|
+
function position(doc, axis, relativeFrom, align, offsetPx) {
|
|
7124
|
+
const node = attrs(el2(doc, WP_NS2, `wp:position${axis}`), { relativeFrom });
|
|
7125
|
+
if (align) {
|
|
7126
|
+
const a = el2(doc, WP_NS2, "wp:align");
|
|
7127
|
+
a.textContent = align;
|
|
7128
|
+
return add2(node, a);
|
|
7129
|
+
}
|
|
7130
|
+
const offset = el2(doc, WP_NS2, "wp:posOffset");
|
|
7131
|
+
offset.textContent = emuOffset(offsetPx ?? 0);
|
|
7132
|
+
return add2(node, offset);
|
|
7133
|
+
}
|
|
7134
|
+
function geometry(doc, spec) {
|
|
7135
|
+
const prst = attrs(el2(doc, A_NS2, "a:prstGeom"), { prst: spec.preset });
|
|
7136
|
+
const avLst = el2(doc, A_NS2, "a:avLst");
|
|
7137
|
+
for (const [name, value] of Object.entries(spec.adjustments ?? {}))
|
|
7138
|
+
add2(avLst, attrs(el2(doc, A_NS2, "a:gd"), { name, fmla: `val ${Math.round(value)}` }));
|
|
7139
|
+
const nodes = [add2(prst, avLst)];
|
|
7140
|
+
if (spec.fill) {
|
|
7141
|
+
const xml = drawingFillXml(spec.fill);
|
|
7142
|
+
if (xml) nodes.push(...importFragment(doc, xml));
|
|
7143
|
+
}
|
|
7144
|
+
if (spec.line) nodes.push(...importFragment(doc, drawingLineXml(spec.line)));
|
|
7145
|
+
return nodes;
|
|
7146
|
+
}
|
|
7147
|
+
function buildShapeDrawing(doc, image, identity, relativeHeight = 251658240) {
|
|
7148
|
+
const spec = image.shape;
|
|
7149
|
+
const drawing = makeW(doc, "drawing");
|
|
7150
|
+
const placement = image.placement;
|
|
7151
|
+
const anchored = Boolean(image.anchored);
|
|
7152
|
+
const holder = el2(doc, WP_NS2, anchored ? "wp:anchor" : "wp:inline");
|
|
7153
|
+
if (anchored) {
|
|
7154
|
+
attrs(holder, {
|
|
7155
|
+
distT: "0",
|
|
7156
|
+
distB: "0",
|
|
7157
|
+
distL: "114300",
|
|
7158
|
+
distR: "114300",
|
|
7159
|
+
simplePos: "0",
|
|
7160
|
+
relativeHeight: String(relativeHeight),
|
|
7161
|
+
behindDoc: placement?.behindText ? "1" : "0",
|
|
7162
|
+
locked: "0",
|
|
7163
|
+
layoutInCell: "1",
|
|
7164
|
+
allowOverlap: "1"
|
|
7165
|
+
});
|
|
7166
|
+
add2(
|
|
7167
|
+
holder,
|
|
7168
|
+
attrs(el2(doc, WP_NS2, "wp:simplePos"), { x: "0", y: "0" }),
|
|
7169
|
+
position(
|
|
7170
|
+
doc,
|
|
7171
|
+
"H",
|
|
7172
|
+
placement?.relativeFrom ?? "column",
|
|
7173
|
+
placement?.align,
|
|
7174
|
+
placement?.offsetXPx
|
|
7175
|
+
),
|
|
7176
|
+
position(
|
|
7177
|
+
doc,
|
|
7178
|
+
"V",
|
|
7179
|
+
placement?.relativeFromV ?? "paragraph",
|
|
7180
|
+
placement?.alignV,
|
|
7181
|
+
placement?.offsetYPx
|
|
7182
|
+
)
|
|
7183
|
+
);
|
|
7184
|
+
} else for (const side of ["distT", "distB", "distL", "distR"]) holder.setAttribute(side, "0");
|
|
7185
|
+
add2(
|
|
7186
|
+
holder,
|
|
7187
|
+
attrs(el2(doc, WP_NS2, "wp:extent"), { cx: emu2(image.widthPx), cy: emu2(image.heightPx) }),
|
|
7188
|
+
attrs(el2(doc, WP_NS2, "wp:effectExtent"), { l: "0", t: "0", r: "0", b: "0" })
|
|
7189
|
+
);
|
|
7190
|
+
if (anchored) add2(holder, wrapElement(doc, placement ?? { wrap: "none" }));
|
|
7191
|
+
const docPr = attrs(el2(doc, WP_NS2, "wp:docPr"), {
|
|
7192
|
+
id: identity.id,
|
|
7193
|
+
name: identity.name ?? `Shape ${identity.id}`
|
|
7194
|
+
});
|
|
7195
|
+
if (identity.descr) docPr.setAttribute("descr", identity.descr);
|
|
7196
|
+
if (identity.title) docPr.setAttribute("title", identity.title);
|
|
7197
|
+
const xfrm = attrs(el2(doc, A_NS2, "a:xfrm"), {});
|
|
7198
|
+
if (spec.rotation) xfrm.setAttribute("rot", String(Math.round(spec.rotation * 6e4)));
|
|
7199
|
+
if (spec.flipH) xfrm.setAttribute("flipH", "1");
|
|
7200
|
+
if (spec.flipV) xfrm.setAttribute("flipV", "1");
|
|
7201
|
+
add2(
|
|
7202
|
+
xfrm,
|
|
7203
|
+
attrs(el2(doc, A_NS2, "a:off"), { x: "0", y: "0" }),
|
|
7204
|
+
attrs(el2(doc, A_NS2, "a:ext"), { cx: emu2(image.widthPx), cy: emu2(image.heightPx) })
|
|
7205
|
+
);
|
|
7206
|
+
const spPr = add2(el2(doc, WPS_NS2, "wps:spPr"), xfrm, ...geometry(doc, spec));
|
|
7207
|
+
const wsp = add2(
|
|
7208
|
+
el2(doc, WPS_NS2, "wps:wsp"),
|
|
7209
|
+
el2(doc, WPS_NS2, "wps:cNvSpPr"),
|
|
7210
|
+
spPr,
|
|
7211
|
+
shapeStyle(doc)
|
|
7212
|
+
);
|
|
7213
|
+
if (spec.text?.length) {
|
|
7214
|
+
const content = add2(
|
|
7215
|
+
el2(doc, W_NS2, "w:txbxContent"),
|
|
7216
|
+
...textParagraphs(doc, spec.text, explicitTextColor(spec))
|
|
7217
|
+
);
|
|
7218
|
+
add2(wsp, add2(el2(doc, WPS_NS2, "wps:txbx"), content));
|
|
7219
|
+
}
|
|
7220
|
+
const body = attrs(el2(doc, WPS_NS2, "wps:bodyPr"), {
|
|
7221
|
+
rot: "0",
|
|
7222
|
+
vert: "horz",
|
|
7223
|
+
wrap: "square",
|
|
7224
|
+
lIns: "91440",
|
|
7225
|
+
tIns: "45720",
|
|
7226
|
+
rIns: "91440",
|
|
7227
|
+
bIns: "45720",
|
|
7228
|
+
anchor: "ctr",
|
|
7229
|
+
anchorCtr: "0"
|
|
7230
|
+
});
|
|
7231
|
+
add2(wsp, add2(body, el2(doc, A_NS2, "a:noAutofit")));
|
|
7232
|
+
const graphicData = attrs(el2(doc, A_NS2, "a:graphicData"), { uri: WPS_NS2 });
|
|
7233
|
+
add2(
|
|
7234
|
+
holder,
|
|
7235
|
+
docPr,
|
|
7236
|
+
el2(doc, WP_NS2, "wp:cNvGraphicFramePr"),
|
|
7237
|
+
add2(el2(doc, A_NS2, "a:graphic"), add2(graphicData, wsp))
|
|
7238
|
+
);
|
|
7239
|
+
return add2(drawing, holder);
|
|
7240
|
+
}
|
|
7241
|
+
var firstNs = (root, ns, local) => root.getElementsByTagNameNS(ns, local)[0];
|
|
7242
|
+
function rebuildShapeDrawing(doc, image, old) {
|
|
7243
|
+
const oldDocPr = firstNs(old, WP_NS2, "docPr");
|
|
7244
|
+
const identity = {
|
|
7245
|
+
id: oldDocPr?.getAttribute("id") ?? "1",
|
|
7246
|
+
...oldDocPr?.getAttribute("name") ? { name: oldDocPr.getAttribute("name") } : {},
|
|
7247
|
+
...oldDocPr?.getAttribute("descr") ? { descr: oldDocPr.getAttribute("descr") } : {},
|
|
7248
|
+
...oldDocPr?.getAttribute("title") ? { title: oldDocPr.getAttribute("title") } : {}
|
|
7249
|
+
};
|
|
7250
|
+
const oldAnchor = firstNs(old, WP_NS2, "anchor");
|
|
7251
|
+
const relativeHeight = Number(oldAnchor?.getAttribute("relativeHeight")) || void 0;
|
|
7252
|
+
const next = buildShapeDrawing(doc, image, identity, relativeHeight);
|
|
7253
|
+
const wsp = firstNs(next, WPS_NS2, "wsp");
|
|
7254
|
+
const keep = (local) => {
|
|
7255
|
+
const previous = firstNs(old, WPS_NS2, local);
|
|
7256
|
+
const current = firstNs(next, WPS_NS2, local);
|
|
7257
|
+
if (previous && current) wsp.replaceChild(previous.cloneNode(true), current);
|
|
7258
|
+
};
|
|
7259
|
+
keep("style");
|
|
7260
|
+
keep("bodyPr");
|
|
7261
|
+
if (!image.shape?.textEditable) {
|
|
7262
|
+
const text2 = firstNs(old, WPS_NS2, "txbx");
|
|
7263
|
+
const current = firstNs(next, WPS_NS2, "txbx");
|
|
7264
|
+
if (text2 && current) wsp.replaceChild(text2.cloneNode(true), current);
|
|
7265
|
+
else if (text2) wsp.insertBefore(text2.cloneNode(true), firstNs(next, WPS_NS2, "bodyPr") ?? null);
|
|
7266
|
+
}
|
|
7267
|
+
return next;
|
|
7268
|
+
}
|
|
7269
|
+
|
|
7270
|
+
// docx/write-drawing.ts
|
|
7271
|
+
var A_NS3 = "http://schemas.openxmlformats.org/drawingml/2006/main";
|
|
7272
|
+
var WP_NS3 = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
|
|
7273
|
+
function alternateContentDrawing(content) {
|
|
7274
|
+
const choice = Array.from(content.childNodes).filter(isElement).find((node) => node.localName === "Choice");
|
|
7275
|
+
return choice && findDrawingChild(choice);
|
|
7276
|
+
}
|
|
7277
|
+
function drawingContainer(run) {
|
|
5174
7278
|
if (!run) return void 0;
|
|
5175
7279
|
for (const child of Array.from(run.childNodes))
|
|
5176
7280
|
if (isElement(child) && (named2(child, "drawing") || named2(child, "pict"))) return child;
|
|
7281
|
+
for (const child of Array.from(run.childNodes))
|
|
7282
|
+
if (isElement(child) && child.localName === "AlternateContent" && alternateContentDrawing(child))
|
|
7283
|
+
return child;
|
|
7284
|
+
return void 0;
|
|
7285
|
+
}
|
|
7286
|
+
function findDrawingChild(run) {
|
|
7287
|
+
if (!run) return void 0;
|
|
7288
|
+
for (const child of Array.from(run.childNodes)) {
|
|
7289
|
+
if (!isElement(child)) continue;
|
|
7290
|
+
if (named2(child, "drawing") || named2(child, "pict")) return child;
|
|
7291
|
+
if (child.localName === "AlternateContent") {
|
|
7292
|
+
const inner = alternateContentDrawing(child);
|
|
7293
|
+
if (inner) return inner;
|
|
7294
|
+
}
|
|
7295
|
+
}
|
|
5177
7296
|
return void 0;
|
|
5178
7297
|
}
|
|
5179
7298
|
function sameUnderlyingImage(a, b) {
|
|
@@ -5191,9 +7310,9 @@ function updateExtent(drawing, widthPx, heightPx) {
|
|
|
5191
7310
|
const cx = String(Math.max(1, Math.round(widthPx * EMU_PER_PIXEL)));
|
|
5192
7311
|
const cy = String(Math.max(1, Math.round(heightPx * EMU_PER_PIXEL)));
|
|
5193
7312
|
walk(drawing, (node) => {
|
|
5194
|
-
const isExtent = node.namespaceURI ===
|
|
7313
|
+
const isExtent = node.namespaceURI === WP_NS3 && node.localName === "extent";
|
|
5195
7314
|
const parent = node.parentNode;
|
|
5196
|
-
const isExt = node.namespaceURI ===
|
|
7315
|
+
const isExt = node.namespaceURI === A_NS3 && node.localName === "ext" && parent?.namespaceURI === A_NS3 && parent.localName === "xfrm";
|
|
5197
7316
|
if (isExtent || isExt) {
|
|
5198
7317
|
node.setAttribute("cx", cx);
|
|
5199
7318
|
node.setAttribute("cy", cy);
|
|
@@ -5202,13 +7321,47 @@ function updateExtent(drawing, widthPx, heightPx) {
|
|
|
5202
7321
|
}
|
|
5203
7322
|
function updateDocPr(drawing, altText, title) {
|
|
5204
7323
|
walk(drawing, (node) => {
|
|
5205
|
-
if (node.namespaceURI !==
|
|
7324
|
+
if (node.namespaceURI !== WP_NS3 || node.localName !== "docPr") return;
|
|
5206
7325
|
if (altText) node.setAttribute("descr", altText);
|
|
5207
7326
|
else node.removeAttribute("descr");
|
|
5208
7327
|
if (title) node.setAttribute("title", title);
|
|
5209
7328
|
else node.removeAttribute("title");
|
|
5210
7329
|
});
|
|
5211
7330
|
}
|
|
7331
|
+
function patchPosition(doc, anchor, name, relativeFrom, align, offsetPx) {
|
|
7332
|
+
const position2 = Array.from(anchor.childNodes).find(
|
|
7333
|
+
(child) => isElement(child) && child.namespaceURI === WP_NS3 && child.localName === name
|
|
7334
|
+
);
|
|
7335
|
+
if (!position2) return;
|
|
7336
|
+
if (relativeFrom) position2.setAttribute("relativeFrom", relativeFrom);
|
|
7337
|
+
for (const child of Array.from(position2.childNodes)) position2.removeChild(child);
|
|
7338
|
+
const value = align ? makeNS(doc, WP_NS3, "wp:align") : makeNS(doc, WP_NS3, "wp:posOffset");
|
|
7339
|
+
value.appendChild(
|
|
7340
|
+
doc.createTextNode(align ?? String(Math.round((offsetPx ?? 0) * EMU_PER_PIXEL)))
|
|
7341
|
+
);
|
|
7342
|
+
position2.appendChild(value);
|
|
7343
|
+
}
|
|
7344
|
+
function updatePlacement(drawing, doc, placement) {
|
|
7345
|
+
walk(drawing, (node) => {
|
|
7346
|
+
if (node.namespaceURI !== WP_NS3 || node.localName !== "anchor") return;
|
|
7347
|
+
patchPosition(
|
|
7348
|
+
doc,
|
|
7349
|
+
node,
|
|
7350
|
+
"positionH",
|
|
7351
|
+
placement.relativeFrom,
|
|
7352
|
+
placement.align,
|
|
7353
|
+
placement.offsetXPx
|
|
7354
|
+
);
|
|
7355
|
+
patchPosition(
|
|
7356
|
+
doc,
|
|
7357
|
+
node,
|
|
7358
|
+
"positionV",
|
|
7359
|
+
placement.relativeFromV,
|
|
7360
|
+
placement.alignV,
|
|
7361
|
+
placement.offsetYPx
|
|
7362
|
+
);
|
|
7363
|
+
});
|
|
7364
|
+
}
|
|
5212
7365
|
function clearNonProperties(node, keep) {
|
|
5213
7366
|
for (const child of Array.from(node.childNodes)) {
|
|
5214
7367
|
if (isElement(child) && (named2(child, "rPr") || child === keep)) continue;
|
|
@@ -5218,19 +7371,29 @@ function clearNonProperties(node, keep) {
|
|
|
5218
7371
|
function createImageRun(doc, image, base, old, allocator) {
|
|
5219
7372
|
const node = old ?? makeW(doc, "r");
|
|
5220
7373
|
const oldDrawing = findDrawingChild(old);
|
|
7374
|
+
const oldContainer = drawingContainer(old);
|
|
5221
7375
|
if (!base && oldDrawing)
|
|
5222
7376
|
throw new Error(
|
|
5223
7377
|
"Cannot safely insert a picture here: this position lines up with a different existing picture. Edit further away from surrounding pictures, then save."
|
|
5224
7378
|
);
|
|
5225
7379
|
if (base && oldDrawing && image.textBoxEditable && base.textBoxEditable) {
|
|
5226
7380
|
patchTextBox(doc, oldDrawing, image, base);
|
|
5227
|
-
clearNonProperties(node,
|
|
7381
|
+
clearNonProperties(node, oldContainer);
|
|
5228
7382
|
return node;
|
|
5229
7383
|
}
|
|
5230
7384
|
if (base && oldDrawing && image.unsupported && JSON.stringify(image) === JSON.stringify(base)) {
|
|
5231
|
-
clearNonProperties(node,
|
|
7385
|
+
clearNonProperties(node, oldContainer);
|
|
7386
|
+
return node;
|
|
7387
|
+
}
|
|
7388
|
+
if (base && oldDrawing && image.shape?.editable && base.shape?.editable) {
|
|
7389
|
+
const next = rebuildShapeDrawing(doc, image, oldDrawing);
|
|
7390
|
+
clearNonProperties(node);
|
|
7391
|
+
node.appendChild(next);
|
|
5232
7392
|
return node;
|
|
5233
7393
|
}
|
|
7394
|
+
if (!base && image.shape?.editable && !image.partName) {
|
|
7395
|
+
throw new Error("Cannot insert a shape without an id allocator.");
|
|
7396
|
+
}
|
|
5234
7397
|
if (image.watermark) {
|
|
5235
7398
|
clearNonProperties(node);
|
|
5236
7399
|
node.appendChild(
|
|
@@ -5246,7 +7409,9 @@ function createImageRun(doc, image, base, old, allocator) {
|
|
|
5246
7409
|
updateExtent(oldDrawing, image.widthPx, image.heightPx);
|
|
5247
7410
|
if (image.altText !== base.altText || image.title !== base.title)
|
|
5248
7411
|
updateDocPr(oldDrawing, image.altText, image.title);
|
|
5249
|
-
|
|
7412
|
+
if (image.anchored && image.placement && JSON.stringify(image.placement) !== JSON.stringify(base.placement))
|
|
7413
|
+
updatePlacement(oldDrawing, doc, image.placement);
|
|
7414
|
+
clearNonProperties(node, oldContainer);
|
|
5250
7415
|
return node;
|
|
5251
7416
|
}
|
|
5252
7417
|
if (base)
|
|
@@ -5568,20 +7733,39 @@ var MATH_NAMESPACES = /* @__PURE__ */ new Set([
|
|
|
5568
7733
|
"http://schemas.openxmlformats.org/officeDocument/2006/math",
|
|
5569
7734
|
"http://purl.oclc.org/ooxml/officeDocument/math"
|
|
5570
7735
|
]);
|
|
7736
|
+
var MATH_NS = "http://schemas.openxmlformats.org/officeDocument/2006/math";
|
|
5571
7737
|
function isEquationElement(element) {
|
|
5572
7738
|
return MATH_NAMESPACES.has(element.namespaceURI ?? "") && (element.localName === "oMath" || element.localName === "oMathPara");
|
|
5573
7739
|
}
|
|
5574
|
-
function
|
|
5575
|
-
|
|
7740
|
+
function writeEquation(doc, run, base, old) {
|
|
7741
|
+
const equation = run.equation;
|
|
7742
|
+
if (!equation || run.text !== "") throw new Error("An equation run holds no text.");
|
|
7743
|
+
if (old && isEquationElement(old) && base?.equation?.omml === equation.omml && base.equation.display === equation.display)
|
|
7744
|
+
return old.cloneNode(true);
|
|
7745
|
+
let source;
|
|
7746
|
+
try {
|
|
7747
|
+
source = parseXml2(equation.omml).documentElement;
|
|
7748
|
+
} catch (cause) {
|
|
5576
7749
|
throw new Error(
|
|
5577
|
-
|
|
7750
|
+
`Equation markup could not be read: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
7751
|
+
{ cause }
|
|
5578
7752
|
);
|
|
5579
|
-
}
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
)
|
|
5584
|
-
|
|
7753
|
+
}
|
|
7754
|
+
if (!isEquationElement(source))
|
|
7755
|
+
throw new Error("Equation markup must be an m:oMath or m:oMathPara element.");
|
|
7756
|
+
let element = doc.importNode(source, true);
|
|
7757
|
+
if (equation.display && element.localName === "oMath") {
|
|
7758
|
+
const para = doc.createElementNS(MATH_NS, "m:oMathPara");
|
|
7759
|
+
para.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:m", MATH_NS);
|
|
7760
|
+
para.appendChild(element);
|
|
7761
|
+
element = para;
|
|
7762
|
+
} else if (!equation.display && element.localName === "oMathPara") {
|
|
7763
|
+
const inner = Array.from(element.childNodes).find(
|
|
7764
|
+
(node) => node.nodeType === 1 && node.localName === "oMath"
|
|
7765
|
+
);
|
|
7766
|
+
if (inner) element = inner;
|
|
7767
|
+
}
|
|
7768
|
+
return element;
|
|
5585
7769
|
}
|
|
5586
7770
|
|
|
5587
7771
|
// docx/write-inline.ts
|
|
@@ -5602,6 +7786,11 @@ function runIsSafe(run) {
|
|
|
5602
7786
|
for (const element of content) {
|
|
5603
7787
|
if (element.localName === "br" && hasSpecialBreak(element)) return false;
|
|
5604
7788
|
if (element.localName === "cr" && element.attributes.length > 0) return false;
|
|
7789
|
+
if (element.localName === "AlternateContent") {
|
|
7790
|
+
if (!alternateContentDrawing(element)) return false;
|
|
7791
|
+
kinds.add("drawing");
|
|
7792
|
+
continue;
|
|
7793
|
+
}
|
|
5605
7794
|
const allowed = ["t", "tab", "br", "cr", "noBreakHyphen", "delText", "drawing", "pict"];
|
|
5606
7795
|
if (!allowed.includes(element.localName)) return false;
|
|
5607
7796
|
kinds.add(element.localName);
|
|
@@ -5620,8 +7809,8 @@ function runsOf(parent, container, slots) {
|
|
|
5620
7809
|
if (isCommentReferenceRun(child)) continue;
|
|
5621
7810
|
if (!runIsSafe(child)) return false;
|
|
5622
7811
|
slots.push({ element: child, ...container && { container } });
|
|
5623
|
-
} else if (isRevisionWrapperElement(child) && !container) {
|
|
5624
|
-
if (!runsOf(child,
|
|
7812
|
+
} else if (isRevisionWrapperElement(child) && (!container || isSdt(container))) {
|
|
7813
|
+
if (!runsOf(child, container, slots)) return false;
|
|
5625
7814
|
} else if ((named2(child, "hyperlink") || named2(child, "fldSimple")) && !container) {
|
|
5626
7815
|
const before = slots.length;
|
|
5627
7816
|
if (!runsOf(child, child, slots)) return false;
|
|
@@ -5648,6 +7837,11 @@ function collectInlineSlots(paragraph) {
|
|
|
5648
7837
|
slots.push({ element: child });
|
|
5649
7838
|
} else if (isRevisionWrapperElement(child)) {
|
|
5650
7839
|
if (!runsOf(child, void 0, slots)) return void 0;
|
|
7840
|
+
} else if (isSdt(child)) {
|
|
7841
|
+
const content = sdtContent(child);
|
|
7842
|
+
const before = slots.length;
|
|
7843
|
+
if (content && !runsOf(content, child, slots)) return void 0;
|
|
7844
|
+
if (slots.length === before) slots.push({ container: child });
|
|
5651
7845
|
} else if (named2(child, "hyperlink") || named2(child, "fldSimple")) {
|
|
5652
7846
|
const before = slots.length;
|
|
5653
7847
|
if (!runsOf(child, child, slots)) return void 0;
|
|
@@ -5658,7 +7852,7 @@ function collectInlineSlots(paragraph) {
|
|
|
5658
7852
|
}
|
|
5659
7853
|
function replaceableInlineChildren(paragraph) {
|
|
5660
7854
|
return Array.from(paragraph.childNodes).filter(
|
|
5661
|
-
(child) => isElement(child) && (isEquationElement(child) || named2(child, "r") || named2(child, "hyperlink") || named2(child, "fldSimple") || isRevisionWrapperElement(child) || isCommentAnchorElement(child))
|
|
7855
|
+
(child) => isElement(child) && (isEquationElement(child) || named2(child, "r") || named2(child, "hyperlink") || named2(child, "fldSimple") || isSdt(child) || isRevisionWrapperElement(child) || isCommentAnchorElement(child))
|
|
5662
7856
|
);
|
|
5663
7857
|
}
|
|
5664
7858
|
function sameLink(a, b) {
|
|
@@ -5681,7 +7875,7 @@ function newHyperlink(doc, link, allocator) {
|
|
|
5681
7875
|
}
|
|
5682
7876
|
function runNodes(doc, run, base, old, opens, closes, allocator) {
|
|
5683
7877
|
const nodes = opens.flatMap((edge) => rangeStartNodes(doc, edge));
|
|
5684
|
-
const node = run.equation ?
|
|
7878
|
+
const node = run.equation ? writeEquation(doc, run, base, old) : createRun(doc, run, base, old);
|
|
5685
7879
|
const revision = run.revision;
|
|
5686
7880
|
if (revision && ["insert", "delete", "moveFrom", "moveTo"].includes(revision.kind)) {
|
|
5687
7881
|
if (revision.kind === "delete") convertToDeleteText(doc, node);
|
|
@@ -5720,9 +7914,14 @@ function buildInlineContent(doc, runs, base, slots, allocator, ranges) {
|
|
|
5720
7914
|
while (index < runs.length && sameGroup(containerGroup(runAt(index)), group)) index++;
|
|
5721
7915
|
const oldContainers = new Set(slots.slice(start, index).map((slot) => slot?.container));
|
|
5722
7916
|
const [onlyContainer] = oldContainers;
|
|
5723
|
-
oldContainers.size === 1 && onlyContainer !== void 0 && onlyContainer.localName === (group.kind === "link" ? "hyperlink" : "fldSimple") && base?.slice(start, index).every((run) => sameGroup(run && containerGroup(run), group)) === true;
|
|
7917
|
+
oldContainers.size === 1 && onlyContainer !== void 0 && onlyContainer.localName === (group.kind === "link" ? "hyperlink" : group.kind === "control" ? "sdt" : "fldSimple") && base?.slice(start, index).every((run) => sameGroup(run && containerGroup(run), group)) === true;
|
|
5724
7918
|
let container;
|
|
5725
|
-
|
|
7919
|
+
let target;
|
|
7920
|
+
if (group.kind === "control") {
|
|
7921
|
+
const created = createContentControl(doc, group.control);
|
|
7922
|
+
container = created.sdt;
|
|
7923
|
+
target = created.content;
|
|
7924
|
+
} else if (group.kind === "link") container = newHyperlink(doc, group.link);
|
|
5726
7925
|
else {
|
|
5727
7926
|
container = makeW(doc, "fldSimple");
|
|
5728
7927
|
setW2(container, "instr", ` ${group.instr} `);
|
|
@@ -5730,12 +7929,13 @@ function buildInlineContent(doc, runs, base, slots, allocator, ranges) {
|
|
|
5730
7929
|
if (group.kind === "simpleField") writeFieldFlags(container, runAt(start).fieldFlags);
|
|
5731
7930
|
const edges = group.kind === "simpleField" ? takeSimpleFieldCommentEdges(doc, runs, start, index, opens, closes) : { before: [], after: [] };
|
|
5732
7931
|
for (let item = start; item < index; item++)
|
|
5733
|
-
for (const node of nodesFor(item)) container.appendChild(node);
|
|
7932
|
+
for (const node of nodesFor(item)) (target ?? container).appendChild(node);
|
|
5734
7933
|
output.push(...edges.before, container, ...edges.after);
|
|
5735
7934
|
}
|
|
5736
7935
|
return output;
|
|
5737
7936
|
}
|
|
5738
7937
|
function containerGroup(run) {
|
|
7938
|
+
if (run.contentControl) return { kind: "control", control: run.contentControl };
|
|
5739
7939
|
if (run.link) return { kind: "link", link: run.link };
|
|
5740
7940
|
if (run.field?.simple)
|
|
5741
7941
|
return {
|
|
@@ -5748,6 +7948,8 @@ function containerGroup(run) {
|
|
|
5748
7948
|
}
|
|
5749
7949
|
function sameGroup(a, b) {
|
|
5750
7950
|
if (!a || !b) return a === b;
|
|
7951
|
+
if (a.kind === "control" || b.kind === "control")
|
|
7952
|
+
return a.kind === "control" && b.kind === "control" && a.control.id === b.control.id;
|
|
5751
7953
|
if (a.kind === "link" && b.kind === "link") return sameLink(a.link, b.link);
|
|
5752
7954
|
return a.kind === "simpleField" && b.kind === "simpleField" && a.instr === b.instr && a.instanceId === b.instanceId && sameFieldFlags(a.fieldFlags, b.fieldFlags);
|
|
5753
7955
|
}
|
|
@@ -5922,11 +8124,12 @@ function createParagraph(doc, paragraph, allocator, spans) {
|
|
|
5922
8124
|
}
|
|
5923
8125
|
|
|
5924
8126
|
// docx/numbering-parse.ts
|
|
8127
|
+
var own = (map, key) => Object.prototype.hasOwnProperty.call(map, key) ? map[key] : void 0;
|
|
5925
8128
|
function resolveNumberingLevel(catalog, numId, level) {
|
|
5926
|
-
const num = catalog.nums
|
|
8129
|
+
const num = own(catalog.nums, numId);
|
|
5927
8130
|
if (!num) return void 0;
|
|
5928
8131
|
const override = num.levelOverrides?.[level];
|
|
5929
|
-
const sourceAbstract = catalog.abstractNums
|
|
8132
|
+
const sourceAbstract = own(catalog.abstractNums, num.abstractNumId)?.levels[level];
|
|
5930
8133
|
const abstract = sourceAbstract?.startWasOmitted && sourceAbstract.start === 1 ? { ...sourceAbstract, start: 0 } : sourceAbstract;
|
|
5931
8134
|
let base = override?.lvl ?? abstract;
|
|
5932
8135
|
if (!base) return void 0;
|
|
@@ -5969,6 +8172,9 @@ function themeCatalogColorScheme(theme) {
|
|
|
5969
8172
|
}
|
|
5970
8173
|
function docxChartPaint(chart, widthPx, heightPx, theme) {
|
|
5971
8174
|
const space = chart?.chartSpace;
|
|
8175
|
+
const extended = chart?.chartEx;
|
|
8176
|
+
if (chart && extended) return paintExtended(chart, extended, widthPx, heightPx, theme);
|
|
8177
|
+
if (chart && chart.layoutId) return { label: `Chart (${chart.layoutId})` };
|
|
5972
8178
|
if (!space) return { label: "Chart" };
|
|
5973
8179
|
const kind = chartSpaceKind(space);
|
|
5974
8180
|
if (!kind.drawn) return { label: kind.type ? `Chart (${kind.type})` : "Chart" };
|
|
@@ -5990,6 +8196,23 @@ function docxChartPaint(chart, widthPx, heightPx, theme) {
|
|
|
5990
8196
|
return { label: kind.type ? `Chart (${kind.type})` : "Chart" };
|
|
5991
8197
|
}
|
|
5992
8198
|
}
|
|
8199
|
+
function paintExtended(chart, summary, widthPx, heightPx, theme) {
|
|
8200
|
+
try {
|
|
8201
|
+
const fonts = {
|
|
8202
|
+
...theme?.fonts.major.latin ? { major: theme.fonts.major.latin } : {},
|
|
8203
|
+
...theme?.fonts.minor.latin ? { minor: theme.fonts.minor.latin } : {}
|
|
8204
|
+
};
|
|
8205
|
+
const svg = renderChartSummarySvg(summary, {
|
|
8206
|
+
width: Math.max(1, Math.round(widthPx)),
|
|
8207
|
+
height: Math.max(1, Math.round(heightPx)),
|
|
8208
|
+
theme: themeCatalogColorScheme(theme),
|
|
8209
|
+
fonts
|
|
8210
|
+
});
|
|
8211
|
+
return { svg, label: chart.title ? `Chart: ${chart.title}` : "Chart" };
|
|
8212
|
+
} catch {
|
|
8213
|
+
return { label: `Chart (${chart.layoutId ?? "extended"})` };
|
|
8214
|
+
}
|
|
8215
|
+
}
|
|
5993
8216
|
|
|
5994
8217
|
// docx/diagram-theme.ts
|
|
5995
8218
|
function diagramColorTheme(theme) {
|
|
@@ -6239,6 +8462,56 @@ function applyAll(model, apply) {
|
|
|
6239
8462
|
var acceptAllRevisions = (model) => applyAll(model, acceptRevision);
|
|
6240
8463
|
var rejectAllRevisions = (model) => applyAll(model, rejectRevision);
|
|
6241
8464
|
|
|
8465
|
+
// docx/field-date.ts
|
|
8466
|
+
var TOKENS = /yyyy|yy|MMMM|MMM|MM|M|dddd|ddd|dd|d|HH|H|hh|h|mm|ss|am\/pm|AM\/PM|'[^']*'/g;
|
|
8467
|
+
function formatWordDate(date, picture, locale = "en-US") {
|
|
8468
|
+
const name = (options) => new Intl.DateTimeFormat(locale, options).format(date);
|
|
8469
|
+
const pad = (value) => String(value).padStart(2, "0");
|
|
8470
|
+
const hours12 = date.getHours() % 12 || 12;
|
|
8471
|
+
return picture.replace(TOKENS, (token) => {
|
|
8472
|
+
switch (token) {
|
|
8473
|
+
case "yyyy":
|
|
8474
|
+
return String(date.getFullYear());
|
|
8475
|
+
case "yy":
|
|
8476
|
+
return pad(date.getFullYear() % 100);
|
|
8477
|
+
case "MMMM":
|
|
8478
|
+
return name({ month: "long" });
|
|
8479
|
+
case "MMM":
|
|
8480
|
+
return name({ month: "short" });
|
|
8481
|
+
case "MM":
|
|
8482
|
+
return pad(date.getMonth() + 1);
|
|
8483
|
+
case "M":
|
|
8484
|
+
return String(date.getMonth() + 1);
|
|
8485
|
+
case "dddd":
|
|
8486
|
+
return name({ weekday: "long" });
|
|
8487
|
+
case "ddd":
|
|
8488
|
+
return name({ weekday: "short" });
|
|
8489
|
+
case "dd":
|
|
8490
|
+
return pad(date.getDate());
|
|
8491
|
+
case "d":
|
|
8492
|
+
return String(date.getDate());
|
|
8493
|
+
case "HH":
|
|
8494
|
+
return pad(date.getHours());
|
|
8495
|
+
case "H":
|
|
8496
|
+
return String(date.getHours());
|
|
8497
|
+
case "hh":
|
|
8498
|
+
return pad(hours12);
|
|
8499
|
+
case "h":
|
|
8500
|
+
return String(hours12);
|
|
8501
|
+
case "mm":
|
|
8502
|
+
return pad(date.getMinutes());
|
|
8503
|
+
case "ss":
|
|
8504
|
+
return pad(date.getSeconds());
|
|
8505
|
+
case "am/pm":
|
|
8506
|
+
return date.getHours() < 12 ? "am" : "pm";
|
|
8507
|
+
case "AM/PM":
|
|
8508
|
+
return date.getHours() < 12 ? "AM" : "PM";
|
|
8509
|
+
default:
|
|
8510
|
+
return token.slice(1, -1);
|
|
8511
|
+
}
|
|
8512
|
+
});
|
|
8513
|
+
}
|
|
8514
|
+
|
|
6242
8515
|
// docx/table-visuals.ts
|
|
6243
8516
|
var NONE = { style: "none" };
|
|
6244
8517
|
function edgeFrom(borders, side, onBoundary) {
|
|
@@ -6288,7 +8561,7 @@ function sectionsFromLayout(json, prior, blocks) {
|
|
|
6288
8561
|
return kept.map((section, index) => {
|
|
6289
8562
|
const end = endOf(section, index, kept);
|
|
6290
8563
|
const source = priorSections.find((candidate) => candidate.endsAtBlockId === section.endsAtBlockId) ?? priorSections.find(
|
|
6291
|
-
(candidate,
|
|
8564
|
+
(candidate, position2) => endOf(candidate, position2, priorSections) >= end
|
|
6292
8565
|
) ?? priorSections.at(-1);
|
|
6293
8566
|
return {
|
|
6294
8567
|
...section,
|
|
@@ -6326,17 +8599,17 @@ function twipsAttr(value) {
|
|
|
6326
8599
|
function signedTwipsAttr(value) {
|
|
6327
8600
|
return typeof value === "number" && Number.isFinite(value) ? roundSignedTwips(value) : void 0;
|
|
6328
8601
|
}
|
|
6329
|
-
function paragraphTwipsFromAttrs(
|
|
8602
|
+
function paragraphTwipsFromAttrs(attrs2) {
|
|
6330
8603
|
const result = {};
|
|
6331
|
-
const spacingBefore = twipsAttr(
|
|
6332
|
-
const spacingAfter = twipsAttr(
|
|
6333
|
-
const lineSpacing = signedTwipsAttr(
|
|
6334
|
-
const left = signedTwipsAttr(
|
|
6335
|
-
const right = signedTwipsAttr(
|
|
6336
|
-
const start = signedTwipsAttr(
|
|
6337
|
-
const end = signedTwipsAttr(
|
|
6338
|
-
const firstLine = twipsAttr(
|
|
6339
|
-
const hanging = twipsAttr(
|
|
8604
|
+
const spacingBefore = twipsAttr(attrs2.spacingBeforeTwips);
|
|
8605
|
+
const spacingAfter = twipsAttr(attrs2.spacingAfterTwips);
|
|
8606
|
+
const lineSpacing = signedTwipsAttr(attrs2.lineSpacingTwips);
|
|
8607
|
+
const left = signedTwipsAttr(attrs2.indentLeftTwips);
|
|
8608
|
+
const right = signedTwipsAttr(attrs2.indentRightTwips);
|
|
8609
|
+
const start = signedTwipsAttr(attrs2.indentStartTwips);
|
|
8610
|
+
const end = signedTwipsAttr(attrs2.indentEndTwips);
|
|
8611
|
+
const firstLine = twipsAttr(attrs2.firstLineTwips);
|
|
8612
|
+
const hanging = twipsAttr(attrs2.hangingTwips);
|
|
6340
8613
|
if (spacingBefore !== void 0) result.spacingBeforeTwips = spacingBefore;
|
|
6341
8614
|
if (spacingAfter !== void 0) result.spacingAfterTwips = spacingAfter;
|
|
6342
8615
|
if (lineSpacing !== void 0) result.lineSpacingTwips = lineSpacing;
|
|
@@ -6349,6 +8622,60 @@ function paragraphTwipsFromAttrs(attrs) {
|
|
|
6349
8622
|
return result;
|
|
6350
8623
|
}
|
|
6351
8624
|
|
|
8625
|
+
// docx/content-control-model.ts
|
|
8626
|
+
var isContentControlLocked = (control, scope) => {
|
|
8627
|
+
if (!control?.lock) return false;
|
|
8628
|
+
return scope === "content" ? control.lock === "contentLocked" || control.lock === "sdtContentLocked" : control.lock === "sdtLocked" || control.lock === "sdtContentLocked";
|
|
8629
|
+
};
|
|
8630
|
+
|
|
8631
|
+
// docx/content-control-edit.ts
|
|
8632
|
+
var DEFAULT_GLYPHS = {
|
|
8633
|
+
checked: { code: "2612", font: "MS Gothic" },
|
|
8634
|
+
unchecked: { code: "2610", font: "MS Gothic" }
|
|
8635
|
+
};
|
|
8636
|
+
var glyphText = (code) => String.fromCodePoint(Number.parseInt(code, 16) || 9744);
|
|
8637
|
+
var canEditControlContent = (control) => !isContentControlLocked(control, "content");
|
|
8638
|
+
function checkboxState(control, checked) {
|
|
8639
|
+
const glyph2 = (checked ? control.checkedGlyph : control.uncheckedGlyph) ?? (checked ? DEFAULT_GLYPHS.checked : DEFAULT_GLYPHS.unchecked);
|
|
8640
|
+
return {
|
|
8641
|
+
control: { ...control, checked },
|
|
8642
|
+
text: glyphText(glyph2.code),
|
|
8643
|
+
...glyph2.font ? { font: glyph2.font } : {}
|
|
8644
|
+
};
|
|
8645
|
+
}
|
|
8646
|
+
var toggleCheckbox = (control) => checkboxState(control, !control.checked);
|
|
8647
|
+
function selectListItem(control, index) {
|
|
8648
|
+
const item = control.items?.[index];
|
|
8649
|
+
if (!item) return void 0;
|
|
8650
|
+
const { showingPlaceholder: _placeholder, ...rest } = control;
|
|
8651
|
+
return { control: rest, text: item.display };
|
|
8652
|
+
}
|
|
8653
|
+
var fullDateOf = (date) => `${String(date.getFullYear()).padStart(4, "0")}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}T00:00:00Z`;
|
|
8654
|
+
function setControlDate(control, date) {
|
|
8655
|
+
const { showingPlaceholder: _placeholder, ...rest } = control;
|
|
8656
|
+
return {
|
|
8657
|
+
control: { ...rest, fullDate: fullDateOf(date) },
|
|
8658
|
+
text: formatWordDate(date, control.dateFormat ?? "M/d/yyyy", control.dateLocale ?? "en-US")
|
|
8659
|
+
};
|
|
8660
|
+
}
|
|
8661
|
+
function defaultPlaceholder(control) {
|
|
8662
|
+
switch (control.kind) {
|
|
8663
|
+
case "date":
|
|
8664
|
+
return "Click or tap to enter a date.";
|
|
8665
|
+
case "dropDownList":
|
|
8666
|
+
case "comboBox":
|
|
8667
|
+
return "Choose an item.";
|
|
8668
|
+
case "picture":
|
|
8669
|
+
return "";
|
|
8670
|
+
default:
|
|
8671
|
+
return "Click or tap here to enter text.";
|
|
8672
|
+
}
|
|
8673
|
+
}
|
|
8674
|
+
function withValue(control) {
|
|
8675
|
+
const { showingPlaceholder: _placeholder, ...rest } = control;
|
|
8676
|
+
return rest;
|
|
8677
|
+
}
|
|
8678
|
+
|
|
6352
8679
|
// docx/layout/ligatures.ts
|
|
6353
8680
|
function ligatureCss(value) {
|
|
6354
8681
|
const enabled2 = (token) => value === "all" || value.toLowerCase().includes(token);
|
|
@@ -6429,9 +8756,9 @@ var runPropertiesMark = {
|
|
|
6429
8756
|
parseDOM: [
|
|
6430
8757
|
{
|
|
6431
8758
|
tag: "span[data-run-props]",
|
|
6432
|
-
getAttrs: (
|
|
8759
|
+
getAttrs: (el4) => {
|
|
6433
8760
|
try {
|
|
6434
|
-
return { props: JSON.parse(
|
|
8761
|
+
return { props: JSON.parse(el4.dataset.runProps || "null") };
|
|
6435
8762
|
} catch {
|
|
6436
8763
|
return { props: null };
|
|
6437
8764
|
}
|
|
@@ -6511,6 +8838,8 @@ function applyMarkFormatting(run, child) {
|
|
|
6511
8838
|
}
|
|
6512
8839
|
const commentIds = commentIdsFromMarks(child.marks);
|
|
6513
8840
|
if (commentIds.length) run.commentIds = commentIds;
|
|
8841
|
+
const control = propertyOfMark(child, "contentControl");
|
|
8842
|
+
if (control?.attrs.data) run.contentControl = JSON.parse(String(control.attrs.data));
|
|
6514
8843
|
const field = propertyOfMark(child, "field");
|
|
6515
8844
|
if (field)
|
|
6516
8845
|
run.field = {
|
|
@@ -6580,6 +8909,12 @@ function marksForRun(run, schema) {
|
|
|
6580
8909
|
color: run.color || null
|
|
6581
8910
|
})
|
|
6582
8911
|
);
|
|
8912
|
+
if (run.contentControl)
|
|
8913
|
+
marks.push(
|
|
8914
|
+
expectDefined(schema.marks.contentControl, "contentControl mark").create({
|
|
8915
|
+
data: JSON.stringify(run.contentControl)
|
|
8916
|
+
})
|
|
8917
|
+
);
|
|
6583
8918
|
if (run.field)
|
|
6584
8919
|
marks.push(
|
|
6585
8920
|
expectDefined(schema.marks.field, "field mark").create({
|
|
@@ -6696,7 +9031,8 @@ function runToInlineNodes(run, schema, noteNumber) {
|
|
|
6696
9031
|
textBoxEditable: run.image.textBoxEditable ?? null,
|
|
6697
9032
|
textBoxBorder: run.image.textBoxBorder ?? null,
|
|
6698
9033
|
diagram: run.image.diagram ? JSON.stringify(run.image.diagram) : null,
|
|
6699
|
-
chart: run.image.chart ? JSON.stringify(run.image.chart) : null
|
|
9034
|
+
chart: run.image.chart ? JSON.stringify(run.image.chart) : null,
|
|
9035
|
+
shape: run.image.shape ? JSON.stringify(run.image.shape) : null
|
|
6700
9036
|
},
|
|
6701
9037
|
void 0,
|
|
6702
9038
|
marks2
|
|
@@ -6781,6 +9117,7 @@ function appendInlineNode(runs, child) {
|
|
|
6781
9117
|
...child.attrs.unsupported ? { unsupported: child.attrs.unsupported } : {},
|
|
6782
9118
|
...typeof child.attrs.diagram === "string" ? { diagram: JSON.parse(child.attrs.diagram) } : {},
|
|
6783
9119
|
...typeof child.attrs.chart === "string" ? { chart: JSON.parse(child.attrs.chart) } : {},
|
|
9120
|
+
...typeof child.attrs.shape === "string" ? { shape: JSON.parse(child.attrs.shape) } : {},
|
|
6784
9121
|
...typeof child.attrs.placement === "string" ? { placement: JSON.parse(child.attrs.placement) } : {},
|
|
6785
9122
|
...typeof child.attrs.textBoxText === "string" ? { textBoxText: JSON.parse(child.attrs.textBoxText) } : {},
|
|
6786
9123
|
...child.attrs.textBoxEditable ? { textBoxEditable: true } : {},
|
|
@@ -6818,7 +9155,7 @@ function appendInlineNode(runs, child) {
|
|
|
6818
9155
|
const sameComments = JSON.stringify(previous?.commentIds) === JSON.stringify(run.commentIds);
|
|
6819
9156
|
const sameLink2 = JSON.stringify(previous?.link ?? null) === JSON.stringify(run.link ?? null);
|
|
6820
9157
|
const sameExtra = JSON.stringify(previous && extraRunProperties(previous)) === JSON.stringify(extraRunProperties(run));
|
|
6821
|
-
if (previous && !previous.break && !previous.image && !previous.equation && !previous.noteReference && !previous.fieldChar && previous.fieldCode === void 0 && JSON.stringify(previous.field) === JSON.stringify(run.field) && sameRevision && sameComments && sameExtra && sameLink2 && fields.every((field) => previous[field] === run[field]))
|
|
9158
|
+
if (previous && !previous.break && !previous.image && !previous.equation && !previous.noteReference && !previous.fieldChar && previous.fieldCode === void 0 && JSON.stringify(previous.field) === JSON.stringify(run.field) && JSON.stringify(previous.contentControl) === JSON.stringify(run.contentControl) && sameRevision && sameComments && sameExtra && sameLink2 && fields.every((field) => previous[field] === run[field]))
|
|
6822
9159
|
previous.text += run.text;
|
|
6823
9160
|
else runs.push(run);
|
|
6824
9161
|
}
|
|
@@ -6841,8 +9178,8 @@ var RUN_FORMAT_MARKS = /* @__PURE__ */ new Set([
|
|
|
6841
9178
|
function setInlineRunFormatting(tr, pos, run) {
|
|
6842
9179
|
const node = tr.doc.nodeAt(pos);
|
|
6843
9180
|
const projected = runToInlineNodes(run, tr.doc.type.schema)[0];
|
|
6844
|
-
const
|
|
6845
|
-
for (const [key, value] of Object.entries(
|
|
9181
|
+
const attrs2 = updatedInlineRunAttributes(node, projected.attrs.format);
|
|
9182
|
+
for (const [key, value] of Object.entries(attrs2))
|
|
6846
9183
|
if (node.attrs[key] !== value) tr.setNodeAttribute(pos, key, value);
|
|
6847
9184
|
for (const mark of node.marks)
|
|
6848
9185
|
if (RUN_FORMAT_MARKS.has(mark.type.name)) tr.removeMark(pos, pos + node.nodeSize, mark.type);
|
|
@@ -7474,8 +9811,8 @@ var WordYjsInlineCommentAnchors = class {
|
|
|
7474
9811
|
capture(doc, from, to, mapping) {
|
|
7475
9812
|
const ranges = [];
|
|
7476
9813
|
const relative = (pos, assoc) => {
|
|
7477
|
-
const
|
|
7478
|
-
const absolute = Y2.createAbsolutePositionFromRelativePosition(
|
|
9814
|
+
const position2 = absolutePositionToRelativePosition(pos, this.fragment, mapping);
|
|
9815
|
+
const absolute = Y2.createAbsolutePositionFromRelativePosition(position2, this.fragment.doc);
|
|
7479
9816
|
if (!absolute) throw new Error("Cannot resolve an inline comment anchor.");
|
|
7480
9817
|
return Array.from(
|
|
7481
9818
|
Y2.encodeRelativePosition(
|
|
@@ -7684,8 +10021,8 @@ function removeSharedAnchor(fragment, id) {
|
|
|
7684
10021
|
let offset = 0;
|
|
7685
10022
|
for (const part of child.toDelta()) {
|
|
7686
10023
|
const length = typeof part.insert === "string" ? part.insert.length : 1;
|
|
7687
|
-
for (const [key,
|
|
7688
|
-
if (key.startsWith("comment--") && Array.isArray(
|
|
10024
|
+
for (const [key, attrs2] of Object.entries(part.attributes ?? {})) {
|
|
10025
|
+
if (key.startsWith("comment--") && Array.isArray(attrs2.ids) && attrs2.ids.includes(id))
|
|
7689
10026
|
child.format(offset, length, { [key]: null });
|
|
7690
10027
|
}
|
|
7691
10028
|
offset += length;
|
|
@@ -7742,10 +10079,10 @@ function guardDeletedNodeSelection(doc, view, binding) {
|
|
|
7742
10079
|
doc.on("beforeObserverCalls", guard);
|
|
7743
10080
|
return () => doc.off("beforeObserverCalls", guard);
|
|
7744
10081
|
}
|
|
7745
|
-
function wordYjsDocumentAttributes(
|
|
10082
|
+
function wordYjsDocumentAttributes(attrs2, canWrite) {
|
|
7746
10083
|
const patch = (state) => {
|
|
7747
10084
|
const tr = state.tr;
|
|
7748
|
-
for (const [key, value] of
|
|
10085
|
+
for (const [key, value] of attrs2.entries()) {
|
|
7749
10086
|
if (key !== "commentThreads" && key in (state.doc.type.spec.attrs ?? {}) && JSON.stringify(state.doc.attrs[key]) !== JSON.stringify(value))
|
|
7750
10087
|
tr.setDocAttribute(key, value);
|
|
7751
10088
|
}
|
|
@@ -7762,18 +10099,18 @@ function wordYjsDocumentAttributes(attrs, canWrite) {
|
|
|
7762
10099
|
binding?.mux(() => view.dispatch(tr));
|
|
7763
10100
|
}
|
|
7764
10101
|
};
|
|
7765
|
-
|
|
10102
|
+
attrs2.observe(changed);
|
|
7766
10103
|
return {
|
|
7767
10104
|
update: (next, previous) => {
|
|
7768
10105
|
if (previous.doc.attrs === next.state.doc.attrs || !canWrite()) return;
|
|
7769
|
-
|
|
10106
|
+
attrs2.doc.transact((transaction) => {
|
|
7770
10107
|
transaction.meta.set("addToHistory", thisPlugin.getState(next.state));
|
|
7771
10108
|
for (const [key, value] of Object.entries(next.state.doc.attrs))
|
|
7772
|
-
if (key !== "commentThreads" && JSON.stringify(
|
|
7773
|
-
|
|
10109
|
+
if (key !== "commentThreads" && JSON.stringify(attrs2.get(key)) !== JSON.stringify(value))
|
|
10110
|
+
attrs2.set(key, value);
|
|
7774
10111
|
}, ySyncPluginKey);
|
|
7775
10112
|
},
|
|
7776
|
-
destroy: () =>
|
|
10113
|
+
destroy: () => attrs2.unobserve(changed)
|
|
7777
10114
|
};
|
|
7778
10115
|
}
|
|
7779
10116
|
});
|
|
@@ -8024,6 +10361,8 @@ function tableStructureGuardPlugin() {
|
|
|
8024
10361
|
if (child.type !== other.type) return false;
|
|
8025
10362
|
if (child.type.name === "paragraph") {
|
|
8026
10363
|
if (child.attrs.id !== other.attrs.id) return false;
|
|
10364
|
+
} else if (child.type.name === "table") {
|
|
10365
|
+
if (!child.sameMarkup(other) || !sameStructure(child, other)) return false;
|
|
8027
10366
|
} else if (!child.eq(other)) return false;
|
|
8028
10367
|
}
|
|
8029
10368
|
}
|
|
@@ -8069,8 +10408,8 @@ function restoreSectionParts(layout, json, blocks) {
|
|
|
8069
10408
|
const base = layout.at(-1);
|
|
8070
10409
|
if (!base) return layout;
|
|
8071
10410
|
const sources = parts.map((part, i) => {
|
|
8072
|
-
const { headers: _headers, footers: _footers, ...
|
|
8073
|
-
return { ...
|
|
10411
|
+
const { headers: _headers, footers: _footers, ...geometry2 } = layout[i] ?? base;
|
|
10412
|
+
return { ...geometry2, ...part };
|
|
8074
10413
|
});
|
|
8075
10414
|
return sectionsFromLayout(sectionLayoutJson(layout), sources, blocks);
|
|
8076
10415
|
}
|
|
@@ -8107,10 +10446,10 @@ var insertWordHardBreak = (state, dispatch, view) => {
|
|
|
8107
10446
|
// docx/ui/chart-spec.ts
|
|
8108
10447
|
var SVG_NS2 = "http://www.w3.org/2000/svg";
|
|
8109
10448
|
function elementSpec(element, root) {
|
|
8110
|
-
const
|
|
10449
|
+
const attrs2 = {};
|
|
8111
10450
|
for (const attr2 of Array.from(element.attributes)) {
|
|
8112
10451
|
if (attr2.name === "xmlns" || attr2.name.startsWith("xmlns:") || /^on/i.test(attr2.name)) continue;
|
|
8113
|
-
|
|
10452
|
+
attrs2[attr2.name] = attr2.value;
|
|
8114
10453
|
}
|
|
8115
10454
|
const children3 = [];
|
|
8116
10455
|
for (const child of Array.from(element.childNodes)) {
|
|
@@ -8118,7 +10457,7 @@ function elementSpec(element, root) {
|
|
|
8118
10457
|
else if (child.nodeType === 3 && child.nodeValue) children3.push(child.nodeValue);
|
|
8119
10458
|
}
|
|
8120
10459
|
const tag = root ? `${SVG_NS2} ${element.localName}` : element.localName;
|
|
8121
|
-
return [tag,
|
|
10460
|
+
return [tag, attrs2, ...children3];
|
|
8122
10461
|
}
|
|
8123
10462
|
function svgMarkupSpec(svg) {
|
|
8124
10463
|
return elementSpec(parseXml(svg, { label: "Chart SVG" }).documentElement, true);
|
|
@@ -8135,9 +10474,9 @@ function nodeChart(node) {
|
|
|
8135
10474
|
function chartNodeSpec(node, theme) {
|
|
8136
10475
|
const width = Number(node.attrs.widthPx) || 96;
|
|
8137
10476
|
const height = Number(node.attrs.heightPx) || 96;
|
|
8138
|
-
const
|
|
10477
|
+
const paint2 = docxChartPaint(nodeChart(node), width, height, theme);
|
|
8139
10478
|
const style = `width:${width}px;height:${height}px`;
|
|
8140
|
-
if (!
|
|
10479
|
+
if (!paint2.svg)
|
|
8141
10480
|
return [
|
|
8142
10481
|
"span",
|
|
8143
10482
|
{
|
|
@@ -8147,7 +10486,7 @@ function chartNodeSpec(node, theme) {
|
|
|
8147
10486
|
class: "dve-image-placeholder",
|
|
8148
10487
|
style
|
|
8149
10488
|
},
|
|
8150
|
-
|
|
10489
|
+
paint2.label
|
|
8151
10490
|
];
|
|
8152
10491
|
return [
|
|
8153
10492
|
"span",
|
|
@@ -8156,9 +10495,9 @@ function chartNodeSpec(node, theme) {
|
|
|
8156
10495
|
...inlineRunPropertiesDomAttrs(node),
|
|
8157
10496
|
class: "dve-chart",
|
|
8158
10497
|
style,
|
|
8159
|
-
title:
|
|
10498
|
+
title: paint2.label
|
|
8160
10499
|
},
|
|
8161
|
-
svgMarkupSpec(
|
|
10500
|
+
svgMarkupSpec(paint2.svg)
|
|
8162
10501
|
];
|
|
8163
10502
|
}
|
|
8164
10503
|
|
|
@@ -8216,22 +10555,24 @@ var imageNodeSpec = {
|
|
|
8216
10555
|
/** A SmartArt graphic (`DocxDiagram`) as JSON; shown read-only by the SmartArt node view. */
|
|
8217
10556
|
diagram: { default: null },
|
|
8218
10557
|
/** A chart (`DocxChart`) as JSON; painted read-only from its cached values (`chart-spec.ts`). */
|
|
8219
|
-
chart: { default: null }
|
|
10558
|
+
chart: { default: null },
|
|
10559
|
+
/** A drawing shape (`ShapeSpec`) as JSON; drawn as SVG by the shape node view. */
|
|
10560
|
+
shape: { default: null }
|
|
8220
10561
|
},
|
|
8221
10562
|
parseDOM: [
|
|
8222
10563
|
{
|
|
8223
10564
|
tag: "img[data-docx-image], span[data-docx-image-placeholder]",
|
|
8224
|
-
getAttrs: (
|
|
8225
|
-
format:
|
|
8226
|
-
relId:
|
|
8227
|
-
partName:
|
|
8228
|
-
contentType:
|
|
8229
|
-
widthPx: Number(
|
|
8230
|
-
heightPx: Number(
|
|
8231
|
-
altText:
|
|
8232
|
-
title:
|
|
8233
|
-
anchored:
|
|
8234
|
-
unsupported:
|
|
10565
|
+
getAttrs: (el4) => ({
|
|
10566
|
+
format: el4.dataset.runProperties ?? null,
|
|
10567
|
+
relId: el4.dataset.relId || "",
|
|
10568
|
+
partName: el4.dataset.partName || "",
|
|
10569
|
+
contentType: el4.dataset.contentType || "",
|
|
10570
|
+
widthPx: Number(el4.dataset.widthPx) || 96,
|
|
10571
|
+
heightPx: Number(el4.dataset.heightPx) || 96,
|
|
10572
|
+
altText: el4.getAttribute("alt") || null,
|
|
10573
|
+
title: el4.getAttribute("title") || null,
|
|
10574
|
+
anchored: el4.dataset.anchored === "1",
|
|
10575
|
+
unsupported: el4.dataset.unsupported || null
|
|
8235
10576
|
})
|
|
8236
10577
|
}
|
|
8237
10578
|
],
|
|
@@ -8282,10 +10623,10 @@ var linkMarkSpec = {
|
|
|
8282
10623
|
parseDOM: [
|
|
8283
10624
|
{
|
|
8284
10625
|
tag: "a[data-docx-link]",
|
|
8285
|
-
getAttrs: (
|
|
8286
|
-
href:
|
|
8287
|
-
anchor:
|
|
8288
|
-
tooltip:
|
|
10626
|
+
getAttrs: (el4) => ({
|
|
10627
|
+
href: el4.dataset.href || (el4.dataset.anchor ? null : el4.getAttribute("href")) || null,
|
|
10628
|
+
anchor: el4.dataset.anchor || null,
|
|
10629
|
+
tooltip: el4.getAttribute("title") || null
|
|
8289
10630
|
})
|
|
8290
10631
|
}
|
|
8291
10632
|
],
|
|
@@ -8513,32 +10854,33 @@ var PARAGRAPH_KEEP_KEYS = [
|
|
|
8513
10854
|
"contextualSpacing",
|
|
8514
10855
|
"suppressLineNumbers"
|
|
8515
10856
|
];
|
|
8516
|
-
function paragraphFromAttrs(
|
|
10857
|
+
function paragraphFromAttrs(attrs2, id, runs) {
|
|
8517
10858
|
return {
|
|
8518
10859
|
type: "paragraph",
|
|
8519
10860
|
id,
|
|
8520
10861
|
runs,
|
|
8521
|
-
...
|
|
8522
|
-
...
|
|
8523
|
-
...
|
|
8524
|
-
...
|
|
8525
|
-
...
|
|
8526
|
-
...
|
|
8527
|
-
...
|
|
8528
|
-
...
|
|
8529
|
-
...
|
|
8530
|
-
...paragraphTwipsFromAttrs(
|
|
8531
|
-
...
|
|
8532
|
-
...
|
|
8533
|
-
...
|
|
8534
|
-
...
|
|
10862
|
+
...attrs2.restoredParagraphPropertiesXml ? { restoredParagraphPropertiesXml: String(attrs2.restoredParagraphPropertiesXml) } : {},
|
|
10863
|
+
...attrs2.sourceParagraphPropertiesXml ? { sourceParagraphPropertiesXml: String(attrs2.sourceParagraphPropertiesXml) } : {},
|
|
10864
|
+
...attrs2.markRevision ? { markRevision: structuredClone(attrs2.markRevision) } : {},
|
|
10865
|
+
...attrs2.formatRevision ? { formatRevision: structuredClone(attrs2.formatRevision) } : {},
|
|
10866
|
+
...attrs2.align != null ? { align: attrs2.align } : {},
|
|
10867
|
+
...attrs2.justification != null ? { justification: attrs2.justification } : {},
|
|
10868
|
+
...attrs2.outlineLevel != null ? { outlineLevel: Number(attrs2.outlineLevel) } : {},
|
|
10869
|
+
...attrs2.direction != null ? { direction: attrs2.direction } : {},
|
|
10870
|
+
...attrs2.style ? { style: attrs2.style } : {},
|
|
10871
|
+
...paragraphTwipsFromAttrs(attrs2),
|
|
10872
|
+
...attrs2.lineSpacingRule != null ? { lineSpacingRule: attrs2.lineSpacingRule } : {},
|
|
10873
|
+
...attrs2.numId != null ? { numbering: { numId: attrs2.numId, level: attrs2.ilvl ?? 0 } } : {},
|
|
10874
|
+
...attrs2.pageBreakBefore != null ? { pageBreakBefore: Boolean(attrs2.pageBreakBefore) } : {},
|
|
10875
|
+
...attrs2.tabStops?.length ? { tabStops: structuredClone(attrs2.tabStops) } : {},
|
|
8535
10876
|
...Object.fromEntries(
|
|
8536
|
-
PARAGRAPH_KEEP_KEYS.filter((key) =>
|
|
10877
|
+
PARAGRAPH_KEEP_KEYS.filter((key) => attrs2[key] != null).map((key) => [key, attrs2[key]])
|
|
8537
10878
|
),
|
|
8538
|
-
...
|
|
8539
|
-
...
|
|
8540
|
-
...
|
|
8541
|
-
...
|
|
10879
|
+
...attrs2.dropCap ? { dropCap: { ...attrs2.dropCap } } : {},
|
|
10880
|
+
...attrs2.borders ? { borders: structuredClone(attrs2.borders) } : {},
|
|
10881
|
+
...attrs2.shadingFill ? { shadingFill: attrs2.shadingFill } : {},
|
|
10882
|
+
...attrs2.bookmarks?.length ? { bookmarks: [...attrs2.bookmarks] } : {},
|
|
10883
|
+
...attrs2.contentControl ? { contentControl: structuredClone(attrs2.contentControl) } : {}
|
|
8542
10884
|
};
|
|
8543
10885
|
}
|
|
8544
10886
|
function paragraphAttrs(paragraph) {
|
|
@@ -8575,7 +10917,8 @@ function paragraphAttrs(paragraph) {
|
|
|
8575
10917
|
dropCap: paragraph.dropCap ?? null,
|
|
8576
10918
|
borders: paragraph.borders ?? null,
|
|
8577
10919
|
shadingFill: paragraph.shadingFill ?? null,
|
|
8578
|
-
bookmarks: paragraph.bookmarks ?? []
|
|
10920
|
+
bookmarks: paragraph.bookmarks ?? [],
|
|
10921
|
+
contentControl: paragraph.contentControl ?? null
|
|
8579
10922
|
};
|
|
8580
10923
|
}
|
|
8581
10924
|
|
|
@@ -8611,8 +10954,8 @@ var reviewMarks = {
|
|
|
8611
10954
|
parseDOM: [
|
|
8612
10955
|
{
|
|
8613
10956
|
tag: "span[data-inline-comment-ids]",
|
|
8614
|
-
getAttrs: (
|
|
8615
|
-
ids: (
|
|
10957
|
+
getAttrs: (el4) => ({
|
|
10958
|
+
ids: (el4.dataset.inlineCommentIds ?? "").split(",").filter(Boolean)
|
|
8616
10959
|
})
|
|
8617
10960
|
}
|
|
8618
10961
|
],
|
|
@@ -8640,11 +10983,11 @@ var reviewMarks = {
|
|
|
8640
10983
|
parseDOM: [
|
|
8641
10984
|
{
|
|
8642
10985
|
tag: "ins[data-revision-id]",
|
|
8643
|
-
getAttrs: (
|
|
8644
|
-
author:
|
|
8645
|
-
date:
|
|
8646
|
-
dateUtc:
|
|
8647
|
-
id:
|
|
10986
|
+
getAttrs: (el4) => ({
|
|
10987
|
+
author: el4.dataset.author || "",
|
|
10988
|
+
date: el4.dataset.date || null,
|
|
10989
|
+
dateUtc: el4.dataset.dateUtc || null,
|
|
10990
|
+
id: el4.dataset.revisionId || "",
|
|
8648
10991
|
move: null
|
|
8649
10992
|
})
|
|
8650
10993
|
}
|
|
@@ -8675,11 +11018,11 @@ var reviewMarks = {
|
|
|
8675
11018
|
parseDOM: [
|
|
8676
11019
|
{
|
|
8677
11020
|
tag: "del[data-revision-id]",
|
|
8678
|
-
getAttrs: (
|
|
8679
|
-
author:
|
|
8680
|
-
date:
|
|
8681
|
-
dateUtc:
|
|
8682
|
-
id:
|
|
11021
|
+
getAttrs: (el4) => ({
|
|
11022
|
+
author: el4.dataset.author || "",
|
|
11023
|
+
date: el4.dataset.date || null,
|
|
11024
|
+
dateUtc: el4.dataset.dateUtc || null,
|
|
11025
|
+
id: el4.dataset.revisionId || "",
|
|
8683
11026
|
move: null
|
|
8684
11027
|
})
|
|
8685
11028
|
}
|
|
@@ -8705,8 +11048,8 @@ var reviewMarks = {
|
|
|
8705
11048
|
parseDOM: [
|
|
8706
11049
|
{
|
|
8707
11050
|
tag: "span[data-comment-ids]",
|
|
8708
|
-
getAttrs: (
|
|
8709
|
-
ids: (
|
|
11051
|
+
getAttrs: (el4) => ({
|
|
11052
|
+
ids: (el4.dataset.commentIds || "").split(",").filter(Boolean)
|
|
8710
11053
|
})
|
|
8711
11054
|
}
|
|
8712
11055
|
],
|
|
@@ -8907,7 +11250,7 @@ function resolveParagraphFormatting(tr, pos, mode) {
|
|
|
8907
11250
|
if (!node) return;
|
|
8908
11251
|
const revision = paragraphFormattingRevision(node);
|
|
8909
11252
|
if (!revision) return;
|
|
8910
|
-
const
|
|
11253
|
+
const attrs2 = { ...node.attrs, formatRevision: null };
|
|
8911
11254
|
if (mode === "reject") {
|
|
8912
11255
|
const paragraph = {
|
|
8913
11256
|
type: "paragraph",
|
|
@@ -8919,14 +11262,14 @@ function resolveParagraphFormatting(tr, pos, mode) {
|
|
|
8919
11262
|
restoreParagraphFormatting(paragraph);
|
|
8920
11263
|
for (const key of PARAGRAPH_FORMAT_KEYS)
|
|
8921
11264
|
if (Object.hasOwn(node.attrs, key))
|
|
8922
|
-
|
|
8923
|
-
|
|
8924
|
-
|
|
8925
|
-
|
|
11265
|
+
attrs2[key] = paragraph[key] ?? node.type.spec.attrs?.[key]?.default ?? null;
|
|
11266
|
+
attrs2.numId = paragraph.numbering?.numId ?? null;
|
|
11267
|
+
attrs2.ilvl = paragraph.numbering?.level ?? null;
|
|
11268
|
+
attrs2.restoredParagraphPropertiesXml = paragraph.restoredParagraphPropertiesXml;
|
|
8926
11269
|
if (paragraph.sourceParagraphPropertiesXml)
|
|
8927
|
-
|
|
11270
|
+
attrs2.sourceParagraphPropertiesXml = paragraph.sourceParagraphPropertiesXml;
|
|
8928
11271
|
}
|
|
8929
|
-
tr.setNodeMarkup(pos, void 0,
|
|
11272
|
+
tr.setNodeMarkup(pos, void 0, attrs2);
|
|
8930
11273
|
}
|
|
8931
11274
|
|
|
8932
11275
|
// docx/ui/track-paragraph-formatting.ts
|
|
@@ -9167,22 +11510,22 @@ function applyTrackedReplace(transform, { from, to, slice }, author, date, nextR
|
|
|
9167
11510
|
const schema = transform.doc.type.schema;
|
|
9168
11511
|
const change = { deletionIds: [], deletedText: "", insertedText: "" };
|
|
9169
11512
|
const segments = segmentsOf(transform.doc, from, to, author);
|
|
9170
|
-
const keptLength = segments.filter((
|
|
11513
|
+
const keptLength = segments.filter((segment2) => !segment2.ownInsertion).reduce((sum, segment2) => sum + (segment2.to - segment2.from), 0);
|
|
9171
11514
|
const insertAt = from + keptLength;
|
|
9172
|
-
for (const
|
|
9173
|
-
if (!
|
|
9174
|
-
change.deletedText += transform.doc.textBetween(
|
|
9175
|
-
for (const
|
|
9176
|
-
if (
|
|
11515
|
+
for (const segment2 of segments)
|
|
11516
|
+
if (!segment2.ownInsertion)
|
|
11517
|
+
change.deletedText += transform.doc.textBetween(segment2.from, segment2.to, "\n");
|
|
11518
|
+
for (const segment2 of [...segments].reverse()) {
|
|
11519
|
+
if (segment2.ownInsertion) transform.delete(segment2.from, segment2.to);
|
|
9177
11520
|
else {
|
|
9178
11521
|
const id = nextRevisionId();
|
|
9179
11522
|
change.deletionIds.push(id);
|
|
9180
11523
|
transform.addMark(
|
|
9181
|
-
|
|
9182
|
-
|
|
11524
|
+
segment2.from,
|
|
11525
|
+
segment2.to,
|
|
9183
11526
|
expectDefined(schema.marks.deletion, "deletion mark").create({ author, date, id })
|
|
9184
11527
|
);
|
|
9185
|
-
canonicalizeHardBreaks(transform,
|
|
11528
|
+
canonicalizeHardBreaks(transform, segment2.from, segment2.to);
|
|
9186
11529
|
}
|
|
9187
11530
|
}
|
|
9188
11531
|
if (slice.size) {
|
|
@@ -9384,8 +11727,8 @@ function partModel(doc) {
|
|
|
9384
11727
|
const model = { ...createDocument(), blocks: [] };
|
|
9385
11728
|
if (typeof doc.attrs.sectionParts !== "string") return model;
|
|
9386
11729
|
const parts = JSON.parse(doc.attrs.sectionParts);
|
|
9387
|
-
const
|
|
9388
|
-
return { ...model, sections: parts.map((part) => ({ ...
|
|
11730
|
+
const geometry2 = sectionsOf(model)[0];
|
|
11731
|
+
return { ...model, sections: parts.map((part) => ({ ...geometry2, ...part })) };
|
|
9389
11732
|
}
|
|
9390
11733
|
function hasSectionPartRevisions(doc) {
|
|
9391
11734
|
return listRevisions(partModel(doc)).length > 0;
|
|
@@ -9753,6 +12096,15 @@ var RIBBON_ACTION_IDS = [
|
|
|
9753
12096
|
"line-numbers",
|
|
9754
12097
|
"multilevel-list",
|
|
9755
12098
|
"drop-cap",
|
|
12099
|
+
"content-control",
|
|
12100
|
+
"shapes",
|
|
12101
|
+
"shape-fill",
|
|
12102
|
+
"shape-outline",
|
|
12103
|
+
"shape-outline-weight",
|
|
12104
|
+
"wrap-text",
|
|
12105
|
+
"shape-height",
|
|
12106
|
+
"shape-width",
|
|
12107
|
+
"equation",
|
|
9756
12108
|
"change-case",
|
|
9757
12109
|
"format-painter",
|
|
9758
12110
|
"show-paragraph-marks",
|
|
@@ -9925,6 +12277,15 @@ var RIBBON_ACTION_LABELS = {
|
|
|
9925
12277
|
"line-numbers": "Line numbers",
|
|
9926
12278
|
"multilevel-list": "Multilevel list",
|
|
9927
12279
|
"drop-cap": "Drop cap",
|
|
12280
|
+
"content-control": "Content control",
|
|
12281
|
+
shapes: "Shapes",
|
|
12282
|
+
"shape-fill": "Shape fill",
|
|
12283
|
+
"shape-outline": "Shape outline",
|
|
12284
|
+
"shape-outline-weight": "Shape outline weight",
|
|
12285
|
+
"wrap-text": "Wrap text",
|
|
12286
|
+
"shape-height": "Shape height (inches)",
|
|
12287
|
+
"shape-width": "Shape width (inches)",
|
|
12288
|
+
equation: "Equation",
|
|
9928
12289
|
"change-case": "Change case",
|
|
9929
12290
|
"format-painter": "Format painter",
|
|
9930
12291
|
"show-paragraph-marks": "Show paragraph marks",
|
|
@@ -10075,7 +12436,7 @@ function swatchColor(value) {
|
|
|
10075
12436
|
// docx/ui/run-compare.ts
|
|
10076
12437
|
var sameJson2 = (left, right) => JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
|
|
10077
12438
|
function sameRevisionMeta(left, right) {
|
|
10078
|
-
return JSON.stringify(left.revision) === JSON.stringify(right.revision) && JSON.stringify(left.commentIds) === JSON.stringify(right.commentIds) && JSON.stringify(extraRunProperties(left)) === JSON.stringify(extraRunProperties(right)) && JSON.stringify(left.field) === JSON.stringify(right.field) && left.fieldChar === right.fieldChar && left.fieldCode === right.fieldCode;
|
|
12439
|
+
return JSON.stringify(left.revision) === JSON.stringify(right.revision) && JSON.stringify(left.commentIds) === JSON.stringify(right.commentIds) && JSON.stringify(extraRunProperties(left)) === JSON.stringify(extraRunProperties(right)) && JSON.stringify(left.field) === JSON.stringify(right.field) && JSON.stringify(left.contentControl) === JSON.stringify(right.contentControl) && left.fieldChar === right.fieldChar && left.fieldCode === right.fieldCode;
|
|
10079
12440
|
}
|
|
10080
12441
|
function sameRuns(left, right) {
|
|
10081
12442
|
const compact = (runs) => runs.reduce((result, run) => {
|
|
@@ -10177,6 +12538,27 @@ var wordHighlightColors = {
|
|
|
10177
12538
|
darkGray: "#808080",
|
|
10178
12539
|
lightGray: "#c0c0c0"
|
|
10179
12540
|
};
|
|
12541
|
+
function contentControlDom(data) {
|
|
12542
|
+
let control = {};
|
|
12543
|
+
try {
|
|
12544
|
+
control = JSON.parse(data);
|
|
12545
|
+
} catch {
|
|
12546
|
+
control = {};
|
|
12547
|
+
}
|
|
12548
|
+
return [
|
|
12549
|
+
"span",
|
|
12550
|
+
{
|
|
12551
|
+
class: "dve-sdt",
|
|
12552
|
+
"data-sdt": data,
|
|
12553
|
+
"data-sdt-id": String(control.id ?? ""),
|
|
12554
|
+
"data-sdt-kind": String(control.kind ?? "richText"),
|
|
12555
|
+
...control.alias ? { "data-sdt-title": String(control.alias) } : {},
|
|
12556
|
+
...control.showingPlaceholder ? { "data-sdt-placeholder": "1" } : {},
|
|
12557
|
+
...control.lock ? { "data-sdt-lock": String(control.lock) } : {}
|
|
12558
|
+
},
|
|
12559
|
+
0
|
|
12560
|
+
];
|
|
12561
|
+
}
|
|
10180
12562
|
var markSpecs = {
|
|
10181
12563
|
bold: { parseDOM: [{ tag: "strong" }, { tag: "b" }], toDOM: () => ["strong", 0] },
|
|
10182
12564
|
italic: { parseDOM: [{ tag: "em" }, { tag: "i" }], toDOM: () => ["em", 0] },
|
|
@@ -10190,8 +12572,8 @@ var markSpecs = {
|
|
|
10190
12572
|
parseDOM: [
|
|
10191
12573
|
{
|
|
10192
12574
|
tag: 'span[style*="background-color"]',
|
|
10193
|
-
getAttrs: (
|
|
10194
|
-
const color =
|
|
12575
|
+
getAttrs: (el4) => {
|
|
12576
|
+
const color = el4.style.backgroundColor.toLowerCase();
|
|
10195
12577
|
if (color === "white" || color === "rgb(255, 255, 255)" || color === "#ffffff")
|
|
10196
12578
|
return false;
|
|
10197
12579
|
const entry = Object.entries(wordHighlightColors).find(([, css]) => {
|
|
@@ -10228,20 +12610,20 @@ var markSpecs = {
|
|
|
10228
12610
|
parseDOM: [
|
|
10229
12611
|
{
|
|
10230
12612
|
tag: "span[lang], span[data-docx-east-asia-language], span[data-docx-bidi-language]",
|
|
10231
|
-
getAttrs: (
|
|
10232
|
-
language:
|
|
10233
|
-
eastAsiaLanguage:
|
|
10234
|
-
bidiLanguage:
|
|
12613
|
+
getAttrs: (el4) => ({
|
|
12614
|
+
language: el4.getAttribute("lang"),
|
|
12615
|
+
eastAsiaLanguage: el4.dataset.docxEastAsiaLanguage || null,
|
|
12616
|
+
bidiLanguage: el4.dataset.docxBidiLanguage || null
|
|
10235
12617
|
})
|
|
10236
12618
|
}
|
|
10237
12619
|
],
|
|
10238
12620
|
toDOM: (mark) => {
|
|
10239
|
-
const
|
|
10240
|
-
if (mark.attrs.language)
|
|
12621
|
+
const attrs2 = {};
|
|
12622
|
+
if (mark.attrs.language) attrs2.lang = mark.attrs.language;
|
|
10241
12623
|
if (mark.attrs.eastAsiaLanguage)
|
|
10242
|
-
|
|
10243
|
-
if (mark.attrs.bidiLanguage)
|
|
10244
|
-
return ["span",
|
|
12624
|
+
attrs2["data-docx-east-asia-language"] = mark.attrs.eastAsiaLanguage;
|
|
12625
|
+
if (mark.attrs.bidiLanguage) attrs2["data-docx-bidi-language"] = mark.attrs.bidiLanguage;
|
|
12626
|
+
return ["span", attrs2, 0];
|
|
10245
12627
|
}
|
|
10246
12628
|
},
|
|
10247
12629
|
runRtl: {
|
|
@@ -10261,14 +12643,14 @@ var markSpecs = {
|
|
|
10261
12643
|
parseDOM: [
|
|
10262
12644
|
{
|
|
10263
12645
|
tag: "span",
|
|
10264
|
-
getAttrs: (
|
|
10265
|
-
const style =
|
|
10266
|
-
const
|
|
12646
|
+
getAttrs: (el4) => {
|
|
12647
|
+
const style = el4.style;
|
|
12648
|
+
const attrs2 = {
|
|
10267
12649
|
family: pastedFontFamily(style.fontFamily),
|
|
10268
12650
|
size: style.fontSize ? parseFontSize(style.fontSize) : null,
|
|
10269
12651
|
color: pastedColor(style.color)
|
|
10270
12652
|
};
|
|
10271
|
-
return
|
|
12653
|
+
return attrs2.family || attrs2.size || attrs2.color ? attrs2 : false;
|
|
10272
12654
|
}
|
|
10273
12655
|
}
|
|
10274
12656
|
],
|
|
@@ -10290,11 +12672,22 @@ var markSpecs = {
|
|
|
10290
12672
|
parseDOM: [
|
|
10291
12673
|
{
|
|
10292
12674
|
tag: "span[data-docx-style]",
|
|
10293
|
-
getAttrs: (
|
|
12675
|
+
getAttrs: (el4) => ({ id: el4.dataset.docxStyle || null })
|
|
10294
12676
|
}
|
|
10295
12677
|
],
|
|
10296
12678
|
toDOM: (mark) => ["span", { "data-docx-style": mark.attrs.id }, 0]
|
|
10297
12679
|
},
|
|
12680
|
+
/** Inline content control (`w:sdt`): the whole control as JSON, drawn with Word's outline and title tab. */
|
|
12681
|
+
contentControl: {
|
|
12682
|
+
attrs: { data: { default: "" } },
|
|
12683
|
+
parseDOM: [
|
|
12684
|
+
{
|
|
12685
|
+
tag: "span[data-sdt]",
|
|
12686
|
+
getAttrs: (el4) => ({ data: el4.dataset.sdt || "" })
|
|
12687
|
+
}
|
|
12688
|
+
],
|
|
12689
|
+
toDOM: (mark) => contentControlDom(String(mark.attrs.data))
|
|
12690
|
+
},
|
|
10298
12691
|
/** Field result text: carries the field code so results can be recalculated and re-wrapped. */
|
|
10299
12692
|
field: {
|
|
10300
12693
|
attrs: { instr: { default: "" }, simple: { default: false } },
|
|
@@ -10302,9 +12695,9 @@ var markSpecs = {
|
|
|
10302
12695
|
parseDOM: [
|
|
10303
12696
|
{
|
|
10304
12697
|
tag: "span[data-field]",
|
|
10305
|
-
getAttrs: (
|
|
10306
|
-
instr:
|
|
10307
|
-
simple:
|
|
12698
|
+
getAttrs: (el4) => ({
|
|
12699
|
+
instr: el4.dataset.field || "",
|
|
12700
|
+
simple: el4.dataset.fieldSimple === "1"
|
|
10308
12701
|
})
|
|
10309
12702
|
}
|
|
10310
12703
|
],
|
|
@@ -10393,15 +12786,15 @@ function parseBordersJson(value) {
|
|
|
10393
12786
|
}
|
|
10394
12787
|
}
|
|
10395
12788
|
var twipsPx = (value) => Number.isSafeInteger(value) ? `${Number(value) / 15}px` : null;
|
|
10396
|
-
function tableStyle(
|
|
10397
|
-
const borders = parseBordersJson(
|
|
10398
|
-
const margins = marginValues(
|
|
12789
|
+
function tableStyle(attrs2) {
|
|
12790
|
+
const borders = parseBordersJson(attrs2.borders);
|
|
12791
|
+
const margins = marginValues(attrs2.cellMargins);
|
|
10399
12792
|
const declarations = [
|
|
10400
12793
|
"border-collapse:collapse",
|
|
10401
|
-
twipsPx(
|
|
10402
|
-
|
|
10403
|
-
|
|
10404
|
-
twipsPx(
|
|
12794
|
+
twipsPx(attrs2.widthTwips) && `width:${twipsPx(attrs2.widthTwips)}`,
|
|
12795
|
+
attrs2.alignment === "center" && "margin-left:auto;margin-right:auto",
|
|
12796
|
+
attrs2.alignment === "right" && "margin-left:auto",
|
|
12797
|
+
twipsPx(attrs2.indentTwips) && attrs2.alignment !== "center" && `margin-left:${twipsPx(attrs2.indentTwips)}`,
|
|
10405
12798
|
// Cells without their own resolved borders (e.g. a table inserted in the editor) draw the
|
|
10406
12799
|
// table's inside line; tables with no border information fall back to dashed gridlines.
|
|
10407
12800
|
borders && `--dve-cell-border:${cssBorderSide(borders.insideH ?? borders.top) ?? "none"}`,
|
|
@@ -10431,14 +12824,14 @@ function cellPadding(value) {
|
|
|
10431
12824
|
(side) => margins[side] === void 0 ? `var(--dve-cell-padding-${side}, ${DEFAULT_CELL_MARGINS[side] / 15}px)` : `${margins[side]}px`
|
|
10432
12825
|
).join(" ")}`;
|
|
10433
12826
|
}
|
|
10434
|
-
function tableCellStyle(
|
|
10435
|
-
const borders = parseBordersJson(
|
|
10436
|
-
const verticalAlign =
|
|
12827
|
+
function tableCellStyle(attrs2) {
|
|
12828
|
+
const borders = parseBordersJson(attrs2.borders);
|
|
12829
|
+
const verticalAlign = attrs2.verticalAlign === "center" ? "middle" : attrs2.verticalAlign === "bottom" ? "bottom" : "top";
|
|
10437
12830
|
const declarations = [
|
|
10438
|
-
cellPadding(
|
|
12831
|
+
cellPadding(attrs2.margins),
|
|
10439
12832
|
`vertical-align:${verticalAlign}`,
|
|
10440
|
-
twipsPx(
|
|
10441
|
-
typeof
|
|
12833
|
+
twipsPx(attrs2.widthTwips) && `width:${twipsPx(attrs2.widthTwips)}`,
|
|
12834
|
+
typeof attrs2.shadingFill === "string" && `background-color:${attrs2.shadingFill}`,
|
|
10442
12835
|
...["top", "bottom", "left", "right"].map(
|
|
10443
12836
|
(side) => borders && (cssBorderSide(borders[side]) ? `border-${side}:${cssBorderSide(borders[side])}` : `border-${side}-style:none`)
|
|
10444
12837
|
)
|
|
@@ -10600,4 +12993,221 @@ function fitZoomPercent(mode, viewport, page) {
|
|
|
10600
12993
|
return Math.max(10, Math.min(500, Math.floor(ratio * 100)));
|
|
10601
12994
|
}
|
|
10602
12995
|
|
|
10603
|
-
|
|
12996
|
+
// docx/ui/content-control-spans.ts
|
|
12997
|
+
function controlOfMark(mark) {
|
|
12998
|
+
if (!mark?.attrs.data) return void 0;
|
|
12999
|
+
try {
|
|
13000
|
+
return JSON.parse(String(mark.attrs.data));
|
|
13001
|
+
} catch {
|
|
13002
|
+
return void 0;
|
|
13003
|
+
}
|
|
13004
|
+
}
|
|
13005
|
+
var markOf = (node) => node.marks.find((mark) => mark.type.name === "contentControl");
|
|
13006
|
+
function controlSpans(doc) {
|
|
13007
|
+
const spans = [];
|
|
13008
|
+
doc.descendants((node, pos) => {
|
|
13009
|
+
if (node.type.name === "paragraph" && node.attrs.contentControl) {
|
|
13010
|
+
const control2 = node.attrs.contentControl;
|
|
13011
|
+
const previous2 = spans.at(-1);
|
|
13012
|
+
if (previous2?.level === "block" && previous2.control.id === control2.id && previous2.to === pos)
|
|
13013
|
+
previous2.to = pos + node.nodeSize;
|
|
13014
|
+
else spans.push({ control: control2, level: "block", from: pos, to: pos + node.nodeSize });
|
|
13015
|
+
}
|
|
13016
|
+
if (!node.isInline) return true;
|
|
13017
|
+
const control = controlOfMark(markOf(node));
|
|
13018
|
+
if (!control) return false;
|
|
13019
|
+
const previous = spans.at(-1);
|
|
13020
|
+
if (previous?.level === "inline" && previous.control.id === control.id && previous.to === pos) {
|
|
13021
|
+
previous.to = pos + node.nodeSize;
|
|
13022
|
+
previous.control = control;
|
|
13023
|
+
} else spans.push({ control, level: "inline", from: pos, to: pos + node.nodeSize });
|
|
13024
|
+
return false;
|
|
13025
|
+
});
|
|
13026
|
+
return spans;
|
|
13027
|
+
}
|
|
13028
|
+
function controlAt(spans, pos, edges = false) {
|
|
13029
|
+
const inside = spans.filter((span) => pos > span.from && pos < span.to);
|
|
13030
|
+
const found = inside.find((span) => span.level === "inline") ?? inside[0];
|
|
13031
|
+
if (found || !edges) return found;
|
|
13032
|
+
return spans.find((span) => span.level === "inline" && (pos === span.from || pos === span.to));
|
|
13033
|
+
}
|
|
13034
|
+
var controlAtSelection = (state, edges = true) => controlAt(controlSpans(state.doc), state.selection.from, edges);
|
|
13035
|
+
|
|
13036
|
+
// docx/ui/content-control-commands.ts
|
|
13037
|
+
var CONTROL_EDIT_META = "dve-content-control";
|
|
13038
|
+
var PLACEHOLDER_STYLE = "PlaceholderText";
|
|
13039
|
+
var isPlaceholderStyle = (mark) => mark.type.name === "characterStyle" && mark.attrs.id === PLACEHOLDER_STYLE;
|
|
13040
|
+
function contentMarks(state, span, change) {
|
|
13041
|
+
const schema = state.schema;
|
|
13042
|
+
const first3 = state.doc.nodeAt(span.from);
|
|
13043
|
+
const kept = (first3?.marks ?? []).filter(
|
|
13044
|
+
(mark) => mark.type.name !== "contentControl" && !isPlaceholderStyle(mark)
|
|
13045
|
+
);
|
|
13046
|
+
const marks = change.font ? kept.filter((mark) => mark.type.name !== "font") : kept.filter(() => true);
|
|
13047
|
+
if (change.font) {
|
|
13048
|
+
const font = kept.find((mark) => mark.type.name === "font");
|
|
13049
|
+
marks.push(
|
|
13050
|
+
schema.marks.font.create({ size: null, color: null, ...font?.attrs, family: change.font })
|
|
13051
|
+
);
|
|
13052
|
+
}
|
|
13053
|
+
marks.push(schema.marks.contentControl.create({ data: JSON.stringify(change.control) }));
|
|
13054
|
+
return marks;
|
|
13055
|
+
}
|
|
13056
|
+
function replaceControlContent(state, span, change) {
|
|
13057
|
+
const tr = state.tr.replaceWith(
|
|
13058
|
+
span.from,
|
|
13059
|
+
span.to,
|
|
13060
|
+
state.schema.text(change.text, contentMarks(state, span, change))
|
|
13061
|
+
);
|
|
13062
|
+
return tr.setMeta(CONTROL_EDIT_META, true);
|
|
13063
|
+
}
|
|
13064
|
+
function updateControlProperties(state, span, control) {
|
|
13065
|
+
const tr = state.tr.setMeta(CONTROL_EDIT_META, true);
|
|
13066
|
+
if (span.level === "block") {
|
|
13067
|
+
state.doc.nodesBetween(span.from, span.to, (node, pos) => {
|
|
13068
|
+
if (node.type.name === "paragraph" && node.attrs.contentControl?.id === span.control.id)
|
|
13069
|
+
tr.setNodeMarkup(pos, void 0, { ...node.attrs, contentControl: control });
|
|
13070
|
+
return node.type.name !== "paragraph";
|
|
13071
|
+
});
|
|
13072
|
+
return tr;
|
|
13073
|
+
}
|
|
13074
|
+
const type = state.schema.marks.contentControl;
|
|
13075
|
+
tr.removeMark(span.from, span.to, type);
|
|
13076
|
+
return tr.addMark(span.from, span.to, type.create({ data: JSON.stringify(control) }));
|
|
13077
|
+
}
|
|
13078
|
+
var spanById = (state, id) => controlSpans(state.doc).find((span) => span.level === "inline" && span.control.id === id);
|
|
13079
|
+
function toggleCheckboxControl(state, id) {
|
|
13080
|
+
const span = spanById(state, id);
|
|
13081
|
+
if (!span || span.control.kind !== "checkbox" || !canEditControlContent(span.control))
|
|
13082
|
+
return void 0;
|
|
13083
|
+
return replaceControlContent(state, span, toggleCheckbox(span.control));
|
|
13084
|
+
}
|
|
13085
|
+
function chooseListItem(state, id, index) {
|
|
13086
|
+
const span = spanById(state, id);
|
|
13087
|
+
const change = span && canEditControlContent(span.control) && selectListItem(span.control, index);
|
|
13088
|
+
return span && change ? replaceControlContent(state, span, change) : void 0;
|
|
13089
|
+
}
|
|
13090
|
+
function chooseDate(state, id, date) {
|
|
13091
|
+
const span = spanById(state, id);
|
|
13092
|
+
if (!span || span.control.kind !== "date" || !canEditControlContent(span.control))
|
|
13093
|
+
return void 0;
|
|
13094
|
+
return replaceControlContent(state, span, setControlDate(span.control, date));
|
|
13095
|
+
}
|
|
13096
|
+
var placeholderChange = (control) => ({
|
|
13097
|
+
control: { ...control, showingPlaceholder: true },
|
|
13098
|
+
text: defaultPlaceholder(control)
|
|
13099
|
+
});
|
|
13100
|
+
function typeOverPlaceholder(state, from, text2, to = from) {
|
|
13101
|
+
const span = controlAt(controlSpans(state.doc), from, true);
|
|
13102
|
+
if (span?.level !== "inline") return void 0;
|
|
13103
|
+
const { control } = span;
|
|
13104
|
+
if (control.kind === "checkbox" || control.kind === "dropDownList") {
|
|
13105
|
+
const inside = from > span.from && from < span.to || from === span.from && to === span.to;
|
|
13106
|
+
if (inside || from === span.from && to > from) return "blocked";
|
|
13107
|
+
const type = state.schema.marks.contentControl;
|
|
13108
|
+
return state.tr.insertText(text2, from).removeMark(from, from + text2.length, type);
|
|
13109
|
+
}
|
|
13110
|
+
if (!control.showingPlaceholder) return void 0;
|
|
13111
|
+
if (!canEditControlContent(control)) return "blocked";
|
|
13112
|
+
const tr = replaceControlContent(state, span, { control: withValue(control), text: text2 });
|
|
13113
|
+
const end = tr.mapping.map(span.to);
|
|
13114
|
+
return tr.setSelection(TextSelection.near(tr.doc.resolve(end)));
|
|
13115
|
+
}
|
|
13116
|
+
function deleteToPlaceholder(state, direction) {
|
|
13117
|
+
const { selection } = state;
|
|
13118
|
+
const span = controlAt(controlSpans(state.doc), selection.from, true);
|
|
13119
|
+
if (span?.level !== "inline" || span.control.showingPlaceholder) return void 0;
|
|
13120
|
+
if (!canEditControlContent(span.control) || span.control.kind === "checkbox") return void 0;
|
|
13121
|
+
const [from, to] = selection.empty ? direction === "backward" ? [selection.from - 1, selection.from] : [selection.from, selection.from + 1] : [selection.from, selection.to];
|
|
13122
|
+
if (from > span.from || to < span.to) return void 0;
|
|
13123
|
+
return replaceControlContent(state, span, placeholderChange(span.control));
|
|
13124
|
+
}
|
|
13125
|
+
var newControlId = (doc) => {
|
|
13126
|
+
const used = new Set(controlSpans(doc).map((span) => span.control.id));
|
|
13127
|
+
let id;
|
|
13128
|
+
do
|
|
13129
|
+
id = String(Math.floor(Math.random() * 2 ** 31) + 1);
|
|
13130
|
+
while (used.has(id));
|
|
13131
|
+
return id;
|
|
13132
|
+
};
|
|
13133
|
+
function insertContentControl(state, kind, options = {}) {
|
|
13134
|
+
const type = state.schema.marks.contentControl;
|
|
13135
|
+
if (!type) return void 0;
|
|
13136
|
+
const { selection } = state;
|
|
13137
|
+
const base = {
|
|
13138
|
+
id: newControlId(state.doc),
|
|
13139
|
+
level: "inline",
|
|
13140
|
+
kind,
|
|
13141
|
+
...options.alias ? { alias: options.alias } : {},
|
|
13142
|
+
...options.tag ? { tag: options.tag } : {},
|
|
13143
|
+
...options.items ? { items: options.items } : {},
|
|
13144
|
+
...kind === "date" ? { dateFormat: options.dateFormat ?? "M/d/yyyy", dateLocale: "en-US" } : {}
|
|
13145
|
+
};
|
|
13146
|
+
const wrapsText = !selection.empty && (kind === "richText" || kind === "text");
|
|
13147
|
+
if (wrapsText) {
|
|
13148
|
+
return state.tr.addMark(selection.from, selection.to, type.create({ data: JSON.stringify(base) })).setMeta(CONTROL_EDIT_META, true);
|
|
13149
|
+
}
|
|
13150
|
+
const change = kind === "checkbox" ? checkboxState({ ...base, checked: false }, false) : placeholderChange(base);
|
|
13151
|
+
const marks = [type.create({ data: JSON.stringify(change.control) })];
|
|
13152
|
+
if (kind !== "checkbox" && state.schema.marks.characterStyle)
|
|
13153
|
+
marks.push(state.schema.marks.characterStyle.create({ id: PLACEHOLDER_STYLE }));
|
|
13154
|
+
if (change.font && state.schema.marks.font)
|
|
13155
|
+
marks.push(state.schema.marks.font.create({ family: change.font, size: null, color: null }));
|
|
13156
|
+
const start = state.selection.from;
|
|
13157
|
+
const tr = state.tr.replaceSelectionWith(state.schema.text(change.text, marks), false);
|
|
13158
|
+
if (kind !== "checkbox")
|
|
13159
|
+
tr.setSelection(TextSelection.create(tr.doc, start, start + change.text.length));
|
|
13160
|
+
return tr.setMeta(CONTROL_EDIT_META, true);
|
|
13161
|
+
}
|
|
13162
|
+
var isRemote = (tr) => tr.getMeta("y-sync$") !== void 0;
|
|
13163
|
+
var isRangeStep = (step) => step instanceof ReplaceStep || step instanceof ReplaceAroundStep || step instanceof AddMarkStep || step instanceof RemoveMarkStep;
|
|
13164
|
+
function violatesControlLock(tr, state) {
|
|
13165
|
+
const locked = controlSpans(state.doc).filter((span) => span.control.lock);
|
|
13166
|
+
if (!locked.length) return false;
|
|
13167
|
+
return tr.steps.some((step, index) => {
|
|
13168
|
+
if (!isRangeStep(step)) return false;
|
|
13169
|
+
const { from, to } = step;
|
|
13170
|
+
const inserts = from === to;
|
|
13171
|
+
const before = tr.mapping.slice(0, index);
|
|
13172
|
+
return locked.some((span) => {
|
|
13173
|
+
const spanFrom = before.map(span.from, 1);
|
|
13174
|
+
const spanTo = before.map(span.to, -1);
|
|
13175
|
+
const removesWhole = !inserts && from <= spanFrom && to >= spanTo;
|
|
13176
|
+
if (isContentControlLocked(span.control, "control") && removesWhole) return true;
|
|
13177
|
+
if (!isContentControlLocked(span.control, "content") || removesWhole) return false;
|
|
13178
|
+
if (span.level === "block") {
|
|
13179
|
+
const innerFrom = spanFrom + 1;
|
|
13180
|
+
const innerTo = spanTo - 1;
|
|
13181
|
+
return inserts ? from >= innerFrom && from <= innerTo : from < innerTo && to > innerFrom;
|
|
13182
|
+
}
|
|
13183
|
+
return inserts ? from > spanFrom && from < spanTo : from < spanTo && to > spanFrom;
|
|
13184
|
+
});
|
|
13185
|
+
});
|
|
13186
|
+
}
|
|
13187
|
+
function contentControlPlugin() {
|
|
13188
|
+
return new Plugin({
|
|
13189
|
+
filterTransaction: (tr, state) => !tr.docChanged || Boolean(tr.getMeta(CONTROL_EDIT_META)) || isRemote(tr) || !violatesControlLock(tr, state),
|
|
13190
|
+
props: {
|
|
13191
|
+
handleTextInput: (view, from, to, text2) => {
|
|
13192
|
+
if (!view.editable) return false;
|
|
13193
|
+
const result = typeOverPlaceholder(view.state, from, text2, to);
|
|
13194
|
+
if (result === "blocked") return true;
|
|
13195
|
+
if (!result) return false;
|
|
13196
|
+
view.dispatch(result);
|
|
13197
|
+
return true;
|
|
13198
|
+
},
|
|
13199
|
+
handleKeyDown: (view, event) => {
|
|
13200
|
+
if (!view.editable || event.key !== "Backspace" && event.key !== "Delete") return false;
|
|
13201
|
+
const tr = deleteToPlaceholder(
|
|
13202
|
+
view.state,
|
|
13203
|
+
event.key === "Backspace" ? "backward" : "forward"
|
|
13204
|
+
);
|
|
13205
|
+
if (!tr) return false;
|
|
13206
|
+
view.dispatch(tr);
|
|
13207
|
+
return true;
|
|
13208
|
+
}
|
|
13209
|
+
}
|
|
13210
|
+
});
|
|
13211
|
+
}
|
|
13212
|
+
|
|
13213
|
+
export { CONTROL_EDIT_META, CollaborationAuthority, CollaborationClient, DirtyState, EDITOR_THEME_MODES, FIELD_RESULT_REPAIR_META, HEADER_FOOTER_INPUT, NotePartsStep, PAGE_GAP, PARAGRAPH_KEEP_KEYS, REMOTE_TRANSACTION_META, RIBBON_ACTION_IDS, RIBBON_ACTION_LABELS, SectionPartsStep, THEME_KEYS, WordYjsCollaboration, WordYjsComments, WordYjsMedia, acceptAllChanges, acceptChangeAtCursor, acceptRevisionRange, addComment, appendInlineNode, applyMarkFormatting, applyRunFormattingPatch, applyThemeColors, applyWordLink, authorColor, backstageFocus, chartNodeSpec, chooseDate, chooseListItem, clearDirectRunFormatting, collectRevisionRanges, commentAnchors, commentHistoryAttributes, commentIdsAtSelection, commentIdsFromMarks, commentIdsFromNode, commentThreadsFromDoc, contentControlPlugin, controlAt, controlAtSelection, controlOfMark, controlSpans, countWords, createCollaborationIdGenerator, createToggleFormat, cssBorderSide, darkTheme, deleteAroundMarkers, deleteComment, deleteFieldSelection, deleteToPlaceholder, dispatchIsolatedCommand, documentWordCount, expectDefined, explicitOffFields, extraRunFields, extraRunProperties, fieldGuardPlugin, fieldMarkerNodeSpec, fieldResultRanges, fieldsBalanced, fitZoomPercent, formattingRevision, freezeBatch, goToComment, goToNextChange, goToPreviousChange, hardBreakNodeSpec, hasAnyChange, hasChangeAtCursor, hasNoteRevisions, imageNodeSpec, inlineNodeRun, insertContentControl, insertWordHardBreak, isNavigableHref, isRibbonActionId, isWordYjsRemoteTransaction, ligatureCss, ligatureStyle, lightTheme, linkFromMarks, linkMarkSpec, markSpecs, marksForRun, moveName, newControlId, nodeChart, nodeNumbering, normalizeRibbonActions, normalizeThemeMode, notePartsJson, noteReferenceNodeSpec, pageBreakNodeSpec, paragraphAttrs, paragraphBoxCss, paragraphFormattingRevision, paragraphFromAttrs, parseBatch, parseBordersJson, placementClass, refreshWordYjsPresence, rejectAllChanges, rejectChangeAtCursor, rejectRevisionRange, removeCommentAnchor, removeCommentThread, removeWordLink, repairCollaborativeDocumentIds, repairCollaborativeParagraphIds, replaceAroundMarkers, replaceControlContent, replyToComment, resolveCellVisuals, resolveComment, resolveNoteRevisions, restoreNoteParts, restoreSectionParts, reviewMarks, ribbonActionIdForLabel, runPropertiesMark, runToInlineNodes, sameJson2 as sameJson, sameRuns, sectionPartsJson, setCommentThreads, setReviewRecordingPreferences, svgMarkupSpec, swatchColor, tableCellStyle, tableStructureGuardPlugin, tableStyle, themeDrawing, themeToCssVars, toggleCheckboxControl, toggleTrackChanges, toggleTrackFormatting, toggleTrackMoves, trackChangesPlugin, trackChangesPluginKey, typeOverPlaceholder, updateCommentThreads, updateControlProperties, violatesControlLock, wordHighlightColors, wordLinkRangeAt, wordYjsPluginKey, wordYjsPresencePlugin, wordYjsRedo, wordYjsUndo };
|