web-doc 0.6.2 → 0.8.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/THIRD_PARTY_NOTICES.md +33 -1
- package/dist/adapters/docx-images.d.ts +13 -4
- package/dist/adapters/docx-images.js +3 -0
- package/dist/adapters/docx-paragraphs.d.ts +65 -0
- package/dist/adapters/docx-paragraphs.js +165 -0
- package/dist/adapters/docx-prepass.d.ts +17 -0
- package/dist/adapters/docx-prepass.js +230 -0
- package/dist/adapters/office.d.ts +31 -5
- package/dist/adapters/office.js +60 -29
- package/dist/adapters/pdf.d.ts +9 -0
- package/dist/adapters/pdf.js +10 -0
- package/dist/assets/pdfium/pdfium.wasm +0 -0
- package/dist/contracts.d.ts +53 -2
- package/dist/edit/ai/outline.d.ts +47 -0
- package/dist/edit/ai/outline.js +338 -0
- package/dist/edit/ai/targets.d.ts +16 -0
- package/dist/edit/ai/targets.js +309 -0
- package/dist/edit/ai/tools.d.ts +28 -0
- package/dist/edit/ai/tools.js +605 -0
- package/dist/edit/ai/types.d.ts +175 -0
- package/dist/edit/ai/types.js +1 -0
- package/dist/edit/assets.d.ts +23 -0
- package/dist/edit/assets.js +75 -0
- package/dist/edit/docx/elements.d.ts +6 -0
- package/dist/edit/docx/elements.js +90 -0
- package/dist/edit/docx/engine.d.ts +57 -0
- package/dist/edit/docx/engine.js +547 -0
- package/dist/edit/docx/handlers.d.ts +3 -0
- package/dist/edit/docx/handlers.js +15 -0
- package/dist/edit/docx/ids.d.ts +45 -0
- package/dist/edit/docx/ids.js +101 -0
- package/dist/edit/docx/model.d.ts +94 -0
- package/dist/edit/docx/model.js +350 -0
- package/dist/edit/docx/operations.d.ts +47 -0
- package/dist/edit/docx/operations.js +3 -0
- package/dist/edit/docx/provider.d.ts +16 -0
- package/dist/edit/docx/provider.js +37 -0
- package/dist/edit/docx/schemas.d.ts +6 -0
- package/dist/edit/docx/schemas.js +192 -0
- package/dist/edit/docx/session.d.ts +48 -0
- package/dist/edit/docx/session.js +467 -0
- package/dist/edit/docx/structure-ops.d.ts +6 -0
- package/dist/edit/docx/structure-ops.js +529 -0
- package/dist/edit/docx/style.d.ts +45 -0
- package/dist/edit/docx/style.js +375 -0
- package/dist/edit/docx/table-ops.d.ts +4 -0
- package/dist/edit/docx/table-ops.js +241 -0
- package/dist/edit/docx/text-ops.d.ts +40 -0
- package/dist/edit/docx/text-ops.js +491 -0
- package/dist/edit/docx/text.d.ts +34 -0
- package/dist/edit/docx/text.js +284 -0
- package/dist/edit/docx/tracked.d.ts +52 -0
- package/dist/edit/docx/tracked.js +347 -0
- package/dist/edit/docx/types.d.ts +206 -0
- package/dist/edit/docx/types.js +1 -0
- package/dist/edit/docx/write.d.ts +64 -0
- package/dist/edit/docx/write.js +375 -0
- package/dist/edit/engine.d.ts +128 -0
- package/dist/edit/engine.js +1 -0
- package/dist/edit/history.d.ts +77 -0
- package/dist/edit/history.js +123 -0
- package/dist/edit/ooxml/names.d.ts +20 -0
- package/dist/edit/ooxml/names.js +61 -0
- package/dist/edit/ooxml/opc.d.ts +50 -0
- package/dist/edit/ooxml/opc.js +150 -0
- package/dist/edit/ooxml/package.d.ts +82 -0
- package/dist/edit/ooxml/package.js +233 -0
- package/dist/edit/ooxml/patch.d.ts +51 -0
- package/dist/edit/ooxml/patch.js +250 -0
- package/dist/edit/ooxml/transaction.d.ts +39 -0
- package/dist/edit/ooxml/transaction.js +316 -0
- package/dist/edit/ooxml/worker.d.ts +8 -0
- package/dist/edit/ooxml/worker.js +12 -0
- package/dist/edit/ooxml/writer.d.ts +21 -0
- package/dist/edit/ooxml/writer.js +187 -0
- package/dist/edit/ooxml/xml.d.ts +74 -0
- package/dist/edit/ooxml/xml.js +451 -0
- package/dist/edit/ooxml/zip.d.ts +54 -0
- package/dist/edit/ooxml/zip.js +280 -0
- package/dist/edit/operations.d.ts +19 -0
- package/dist/edit/operations.js +137 -0
- package/dist/edit/pdf/engine/compact.d.ts +6 -0
- package/dist/edit/pdf/engine/compact.js +442 -0
- package/dist/edit/pdf/engine/document.d.ts +95 -0
- package/dist/edit/pdf/engine/document.js +868 -0
- package/dist/edit/pdf/engine/elements.d.ts +45 -0
- package/dist/edit/pdf/engine/elements.js +313 -0
- package/dist/edit/pdf/engine/existing-text.d.ts +4 -0
- package/dist/edit/pdf/engine/existing-text.js +424 -0
- package/dist/edit/pdf/engine/fonts.d.ts +78 -0
- package/dist/edit/pdf/engine/fonts.js +466 -0
- package/dist/edit/pdf/engine/geometry.d.ts +36 -0
- package/dist/edit/pdf/engine/geometry.js +97 -0
- package/dist/edit/pdf/engine/handler.d.ts +21 -0
- package/dist/edit/pdf/engine/handler.js +108 -0
- package/dist/edit/pdf/engine/images.d.ts +33 -0
- package/dist/edit/pdf/engine/images.js +188 -0
- package/dist/edit/pdf/engine/layout.d.ts +23 -0
- package/dist/edit/pdf/engine/layout.js +177 -0
- package/dist/edit/pdf/engine/operations.d.ts +67 -0
- package/dist/edit/pdf/engine/operations.js +3 -0
- package/dist/edit/pdf/engine/pages.d.ts +6 -0
- package/dist/edit/pdf/engine/pages.js +98 -0
- package/dist/edit/pdf/engine/pdfium.d.ts +195 -0
- package/dist/edit/pdf/engine/pdfium.js +249 -0
- package/dist/edit/pdf/engine/shapes.d.ts +4 -0
- package/dist/edit/pdf/engine/shapes.js +183 -0
- package/dist/edit/pdf/engine/tables.d.ts +44 -0
- package/dist/edit/pdf/engine/tables.js +315 -0
- package/dist/edit/pdf/engine/text-box.d.ts +71 -0
- package/dist/edit/pdf/engine/text-box.js +317 -0
- package/dist/edit/pdf/engine/text-layout.d.ts +28 -0
- package/dist/edit/pdf/engine/text-layout.js +67 -0
- package/dist/edit/pdf/engine/transform.d.ts +5 -0
- package/dist/edit/pdf/engine/transform.js +137 -0
- package/dist/edit/pdf/provider.d.ts +35 -0
- package/dist/edit/pdf/provider.js +92 -0
- package/dist/edit/pdf/range-map.d.ts +16 -0
- package/dist/edit/pdf/range-map.js +107 -0
- package/dist/edit/pdf/schemas.d.ts +11 -0
- package/dist/edit/pdf/schemas.js +291 -0
- package/dist/edit/pdf/selection.d.ts +5 -0
- package/dist/edit/pdf/selection.js +152 -0
- package/dist/edit/pdf/session.d.ts +63 -0
- package/dist/edit/pdf/session.js +312 -0
- package/dist/edit/pdf/types.d.ts +336 -0
- package/dist/edit/pdf/types.js +1 -0
- package/dist/edit/pptx/elements.d.ts +74 -0
- package/dist/edit/pptx/elements.js +301 -0
- package/dist/edit/pptx/engine.d.ts +37 -0
- package/dist/edit/pptx/engine.js +466 -0
- package/dist/edit/pptx/geometry.d.ts +72 -0
- package/dist/edit/pptx/geometry.js +193 -0
- package/dist/edit/pptx/handler.d.ts +7 -0
- package/dist/edit/pptx/handler.js +99 -0
- package/dist/edit/pptx/handlers.d.ts +3 -0
- package/dist/edit/pptx/handlers.js +21 -0
- package/dist/edit/pptx/image-table-ops.d.ts +5 -0
- package/dist/edit/pptx/image-table-ops.js +233 -0
- package/dist/edit/pptx/model.d.ts +69 -0
- package/dist/edit/pptx/model.js +170 -0
- package/dist/edit/pptx/operations.d.ts +50 -0
- package/dist/edit/pptx/operations.js +11 -0
- package/dist/edit/pptx/provider.d.ts +17 -0
- package/dist/edit/pptx/provider.js +40 -0
- package/dist/edit/pptx/schemas.d.ts +6 -0
- package/dist/edit/pptx/schemas.js +220 -0
- package/dist/edit/pptx/session.d.ts +54 -0
- package/dist/edit/pptx/session.js +145 -0
- package/dist/edit/pptx/shape-ops.d.ts +10 -0
- package/dist/edit/pptx/shape-ops.js +486 -0
- package/dist/edit/pptx/slide-ops.d.ts +6 -0
- package/dist/edit/pptx/slide-ops.js +353 -0
- package/dist/edit/pptx/style.d.ts +31 -0
- package/dist/edit/pptx/style.js +181 -0
- package/dist/edit/pptx/text-ops.d.ts +13 -0
- package/dist/edit/pptx/text-ops.js +267 -0
- package/dist/edit/pptx/text-write.d.ts +67 -0
- package/dist/edit/pptx/text-write.js +293 -0
- package/dist/edit/pptx/text.d.ts +41 -0
- package/dist/edit/pptx/text.js +99 -0
- package/dist/edit/pptx/types.d.ts +232 -0
- package/dist/edit/pptx/types.js +1 -0
- package/dist/edit/schema.d.ts +11 -0
- package/dist/edit/schema.js +275 -0
- package/dist/edit/session.d.ts +77 -0
- package/dist/edit/session.js +943 -0
- package/dist/edit/sessions.d.ts +8 -0
- package/dist/edit/sessions.js +1 -0
- package/dist/edit/types.d.ts +290 -0
- package/dist/edit/types.js +1 -0
- package/dist/edit/worker-engine.d.ts +31 -0
- package/dist/edit/worker-engine.js +91 -0
- package/dist/fonts/THIRD_PARTY_NOTICES.md +3 -0
- package/dist/fonts/manifest.json +6 -1
- package/dist/fonts/noto-sans-latin-cyrillic.ttf +0 -0
- package/dist/fonts.d.ts +2 -0
- package/dist/fonts.js +4 -0
- package/dist/fuzzy-alignment.d.ts +11 -4
- package/dist/fuzzy-alignment.js +3 -9
- package/dist/headless.d.ts +5 -1
- package/dist/headless.js +8 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.js +16 -2
- package/dist/limits.js +6 -0
- package/dist/ooxml-edit-worker.d.ts +1 -0
- package/dist/ooxml-edit-worker.js +8 -0
- package/dist/pdf-edit-worker.d.ts +1 -0
- package/dist/pdf-edit-worker.js +35 -0
- package/dist/spreadsheet-viewport.d.ts +5 -0
- package/dist/spreadsheet-viewport.js +11 -0
- package/dist/ui.js +7 -0
- package/dist/viewer.d.ts +6 -0
- package/dist/viewer.js +293 -19
- package/dist/viewport.d.ts +13 -0
- package/dist/viewport.js +126 -1
- package/dist/worker-protocol.d.ts +39 -2
- package/dist/workers/fuzzy-search-worker.js +1 -1
- package/dist/workers/ooxml-edit-worker.js +9212 -0
- package/dist/workers/pdf-edit-worker.js +10847 -0
- package/package.json +3 -3
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { ViewerError } from "../../errors.js";
|
|
2
|
+
/*
|
|
3
|
+
* The deck index: which parts are the presentation, its slides in order,
|
|
4
|
+
* their layouts, the masters and their themes. Built from the package at a
|
|
5
|
+
* revision and rebuilt when the revision changes; everything else about a
|
|
6
|
+
* slide is read on demand.
|
|
7
|
+
*/
|
|
8
|
+
export const PRESENTATION_NS = "http://schemas.openxmlformats.org/presentationml/2006/main";
|
|
9
|
+
const OFFICE_RELATIONSHIPS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/";
|
|
10
|
+
export const RELATIONSHIP_TYPES = {
|
|
11
|
+
officeDocument: `${OFFICE_RELATIONSHIPS}officeDocument`,
|
|
12
|
+
slide: `${OFFICE_RELATIONSHIPS}slide`,
|
|
13
|
+
slideLayout: `${OFFICE_RELATIONSHIPS}slideLayout`,
|
|
14
|
+
slideMaster: `${OFFICE_RELATIONSHIPS}slideMaster`,
|
|
15
|
+
notesSlide: `${OFFICE_RELATIONSHIPS}notesSlide`,
|
|
16
|
+
theme: `${OFFICE_RELATIONSHIPS}theme`,
|
|
17
|
+
image: `${OFFICE_RELATIONSHIPS}image`,
|
|
18
|
+
};
|
|
19
|
+
/** The number in a part name like `/ppt/slides/slide12.xml`. */
|
|
20
|
+
export function partNumber(part) {
|
|
21
|
+
const match = /(\d+)\.xml$/i.exec(part);
|
|
22
|
+
return match ? Number(match[1]) : 0;
|
|
23
|
+
}
|
|
24
|
+
export class DeckModel {
|
|
25
|
+
revision;
|
|
26
|
+
presentationPart;
|
|
27
|
+
presentation;
|
|
28
|
+
slideSize;
|
|
29
|
+
slides;
|
|
30
|
+
layouts;
|
|
31
|
+
masters;
|
|
32
|
+
#pkg;
|
|
33
|
+
#themeFonts = new Map();
|
|
34
|
+
constructor(pkg, revision, presentationPart, presentation,
|
|
35
|
+
/** EMU. */
|
|
36
|
+
slideSize, slides, layouts, masters) {
|
|
37
|
+
this.revision = revision;
|
|
38
|
+
this.presentationPart = presentationPart;
|
|
39
|
+
this.presentation = presentation;
|
|
40
|
+
this.slideSize = slideSize;
|
|
41
|
+
this.slides = slides;
|
|
42
|
+
this.layouts = layouts;
|
|
43
|
+
this.masters = masters;
|
|
44
|
+
this.#pkg = pkg;
|
|
45
|
+
}
|
|
46
|
+
static async load(pkg, signal) {
|
|
47
|
+
const root = await pkg.relationships("/", signal);
|
|
48
|
+
const main = root.byType(RELATIONSHIP_TYPES.officeDocument)[0]?.targetPart;
|
|
49
|
+
if (!main)
|
|
50
|
+
throw new ViewerError("invalid-file", "The package has no presentation part");
|
|
51
|
+
const presentation = await pkg.xml(main, signal);
|
|
52
|
+
const size = presentation.find("sldSz");
|
|
53
|
+
const slideSize = {
|
|
54
|
+
cx: Number(size ? presentation.attribute(size, "cx") : NaN) || 9144000,
|
|
55
|
+
cy: Number(size ? presentation.attribute(size, "cy") : NaN) || 6858000,
|
|
56
|
+
};
|
|
57
|
+
const rels = await pkg.relationships(main, signal);
|
|
58
|
+
const masters = [];
|
|
59
|
+
const layouts = [];
|
|
60
|
+
const layoutByPart = new Map();
|
|
61
|
+
for (const masterId of presentation.findAll("sldMasterId")) {
|
|
62
|
+
const rId = presentation.attribute(masterId, "r:id");
|
|
63
|
+
const part = rId ? rels.byId(rId)?.targetPart : undefined;
|
|
64
|
+
if (!part || !pkg.has(part))
|
|
65
|
+
continue;
|
|
66
|
+
const masterRels = await pkg.relationships(part, signal);
|
|
67
|
+
const theme = masterRels.byType(RELATIONSHIP_TYPES.theme)[0]?.targetPart;
|
|
68
|
+
const layoutParts = masterRels
|
|
69
|
+
.byType(RELATIONSHIP_TYPES.slideLayout)
|
|
70
|
+
.map((relationship) => relationship.targetPart)
|
|
71
|
+
.filter((name) => !!name && pkg.has(name))
|
|
72
|
+
.sort((a, b) => partNumber(a) - partNumber(b));
|
|
73
|
+
const master = {
|
|
74
|
+
id: `master${partNumber(part)}`,
|
|
75
|
+
part,
|
|
76
|
+
...(theme ? { theme } : {}),
|
|
77
|
+
layouts: layoutParts,
|
|
78
|
+
};
|
|
79
|
+
masters.push(master);
|
|
80
|
+
for (const layoutPart of layoutParts) {
|
|
81
|
+
if (layoutByPart.has(layoutPart))
|
|
82
|
+
continue;
|
|
83
|
+
const xml = await pkg.xml(layoutPart, signal);
|
|
84
|
+
const cSld = xml.find("cSld");
|
|
85
|
+
const type = xml.attribute(xml.root, "type");
|
|
86
|
+
const layout = {
|
|
87
|
+
id: `layout${partNumber(layoutPart)}`,
|
|
88
|
+
part: layoutPart,
|
|
89
|
+
name: (cSld ? xml.attribute(cSld, "name") : undefined) ?? "",
|
|
90
|
+
...(type ? { type } : {}),
|
|
91
|
+
master,
|
|
92
|
+
};
|
|
93
|
+
layouts.push(layout);
|
|
94
|
+
layoutByPart.set(layoutPart, layout);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const slides = [];
|
|
98
|
+
for (const node of presentation.findAll("sldId")) {
|
|
99
|
+
// Section lists (p14:sldId) name slides too; only p:sldIdLst lists them.
|
|
100
|
+
if (node.namespace !== PRESENTATION_NS)
|
|
101
|
+
continue;
|
|
102
|
+
const rId = presentation.attribute(node, "r:id");
|
|
103
|
+
const id = presentation.attribute(node, "id");
|
|
104
|
+
const part = rId ? rels.byId(rId)?.targetPart : undefined;
|
|
105
|
+
if (!rId || !id || !part || !pkg.has(part))
|
|
106
|
+
throw new ViewerError("invalid-file", `Slide ${id ?? "?"} of the presentation has no part`);
|
|
107
|
+
const slideRels = await pkg.relationships(part, signal);
|
|
108
|
+
const layoutPart = slideRels.byType(RELATIONSHIP_TYPES.slideLayout)[0]
|
|
109
|
+
?.targetPart;
|
|
110
|
+
const layout = layoutPart ? layoutByPart.get(layoutPart) : undefined;
|
|
111
|
+
const number = partNumber(part);
|
|
112
|
+
if (slides.some((slide) => slide.number === number))
|
|
113
|
+
throw new ViewerError("invalid-file", `Two slide parts share the number ${number}`, { details: { part } });
|
|
114
|
+
slides.push({
|
|
115
|
+
key: `sld${number}`,
|
|
116
|
+
number,
|
|
117
|
+
part,
|
|
118
|
+
id,
|
|
119
|
+
rId,
|
|
120
|
+
node,
|
|
121
|
+
...(layout ? { layout } : {}),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return new DeckModel(pkg, pkg.revision, main, presentation, slideSize, slides, layouts, masters);
|
|
125
|
+
}
|
|
126
|
+
get pageCount() {
|
|
127
|
+
return this.slides.length;
|
|
128
|
+
}
|
|
129
|
+
slideAt(pageIndex) {
|
|
130
|
+
const slide = this.slides[pageIndex];
|
|
131
|
+
if (!Number.isInteger(pageIndex) || !slide)
|
|
132
|
+
throw new ViewerError("invalid-operation", `Slide index ${pageIndex} is out of range`, { details: { pageIndex, pageCount: this.slides.length } });
|
|
133
|
+
return slide;
|
|
134
|
+
}
|
|
135
|
+
slideByKey(key) {
|
|
136
|
+
return this.slides.find((slide) => slide.key === key);
|
|
137
|
+
}
|
|
138
|
+
layoutById(id) {
|
|
139
|
+
return this.layouts.find((layout) => layout.id === id);
|
|
140
|
+
}
|
|
141
|
+
/** Whether a slide is hidden (`p:sld/@show="0"`). */
|
|
142
|
+
async hidden(slide, signal) {
|
|
143
|
+
const xml = await this.#pkg.xml(slide.part, signal);
|
|
144
|
+
return xml.attribute(xml.root, "show") === "0";
|
|
145
|
+
}
|
|
146
|
+
/** The major and minor Latin faces of a master's theme. */
|
|
147
|
+
themeFonts(master) {
|
|
148
|
+
const theme = master?.theme;
|
|
149
|
+
if (!theme || !this.#pkg.has(theme))
|
|
150
|
+
return Promise.resolve({ major: "Calibri Light", minor: "Calibri" });
|
|
151
|
+
let fonts = this.#themeFonts.get(theme);
|
|
152
|
+
if (!fonts) {
|
|
153
|
+
fonts = this.#pkg.xml(theme).then((xml) => {
|
|
154
|
+
const face = (scheme) => {
|
|
155
|
+
const node = xml.find(scheme);
|
|
156
|
+
const latin = node
|
|
157
|
+
? node.children.find((child) => child.local === "latin")
|
|
158
|
+
: undefined;
|
|
159
|
+
return latin ? xml.attribute(latin, "typeface") : undefined;
|
|
160
|
+
};
|
|
161
|
+
return {
|
|
162
|
+
major: face("majorFont") || "Calibri Light",
|
|
163
|
+
minor: face("minorFont") || "Calibri",
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
this.#themeFonts.set(theme, fonts);
|
|
167
|
+
}
|
|
168
|
+
return fonts;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { ResourceLimits, ViewerWarning } from "../../contracts.js";
|
|
2
|
+
import type { AssetSource } from "../assets.js";
|
|
3
|
+
import type { OoxmlPackage } from "../ooxml/package.js";
|
|
4
|
+
import type { CommittedChange } from "../ooxml/transaction.js";
|
|
5
|
+
import type { OperationIssue } from "../types.js";
|
|
6
|
+
import type { ShapeRecord, SlideElements } from "./elements.js";
|
|
7
|
+
import type { DeckModel } from "./model.js";
|
|
8
|
+
import type { PptxOperation } from "./types.js";
|
|
9
|
+
export interface PptxOperationContext {
|
|
10
|
+
readonly pkg: OoxmlPackage;
|
|
11
|
+
readonly model: DeckModel;
|
|
12
|
+
readonly limits: ResourceLimits;
|
|
13
|
+
/** Bytes behind `asset:` references. */
|
|
14
|
+
readonly assets: AssetSource;
|
|
15
|
+
/** Slides after the operations before this one in the batch; the model's count when applying. */
|
|
16
|
+
readonly pageCount: number;
|
|
17
|
+
/** The batch's state id, for ids an operation derives. */
|
|
18
|
+
readonly stateId: number;
|
|
19
|
+
readonly operationIndex: number;
|
|
20
|
+
/** Every element of a slide, read at the current revision. */
|
|
21
|
+
elements(pageIndex: number): Promise<SlideElements>;
|
|
22
|
+
/** The element an id names, at the current revision. */
|
|
23
|
+
locate(id: string): Promise<ShapeRecord | undefined>;
|
|
24
|
+
/**
|
|
25
|
+
* A `p:cNvPr` id for an element created on a slide: above every id the
|
|
26
|
+
* slide holds and above every id the session already issued there, so
|
|
27
|
+
* an id is never reused after a deletion.
|
|
28
|
+
*/
|
|
29
|
+
allocateShapeId(elements: SlideElements): number;
|
|
30
|
+
}
|
|
31
|
+
export interface PptxOperationResult {
|
|
32
|
+
readonly createdIds: readonly string[];
|
|
33
|
+
readonly removedIds?: readonly string[];
|
|
34
|
+
readonly changedPages: readonly number[];
|
|
35
|
+
readonly warnings: readonly ViewerWarning[];
|
|
36
|
+
/** Parts the operation's transaction changed, added and removed; absent means "everything may have". */
|
|
37
|
+
readonly parts?: {
|
|
38
|
+
readonly changed: readonly string[];
|
|
39
|
+
readonly added: readonly string[];
|
|
40
|
+
readonly removed: readonly string[];
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export type Issue = (path: string, code: string, message: string) => void;
|
|
44
|
+
export interface PptxOperationHandler<T extends PptxOperation = PptxOperation> {
|
|
45
|
+
validate(operation: T, context: PptxOperationContext, issue: Issue): Promise<void>;
|
|
46
|
+
apply(operation: T, context: PptxOperationContext): Promise<PptxOperationResult>;
|
|
47
|
+
}
|
|
48
|
+
export declare function issueCollector(operationIndex: number, issues: OperationIssue[]): Issue;
|
|
49
|
+
/** The parts a transaction touched, in the shape an operation result carries. */
|
|
50
|
+
export declare function committedParts(change: CommittedChange): NonNullable<PptxOperationResult["parts"]>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function issueCollector(operationIndex, issues) {
|
|
2
|
+
return (path, code, message) => issues.push({ operationIndex, path, code, message });
|
|
3
|
+
}
|
|
4
|
+
/** The parts a transaction touched, in the shape an operation result carries. */
|
|
5
|
+
export function committedParts(change) {
|
|
6
|
+
return {
|
|
7
|
+
changed: change.changedParts,
|
|
8
|
+
added: change.addedParts,
|
|
9
|
+
removed: change.removedParts,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { EditEngineContext } from "../engine.js";
|
|
2
|
+
import { type OoxmlEditProviderOptions } from "../ooxml/worker.js";
|
|
3
|
+
import { WorkerEngineClient } from "../worker-engine.js";
|
|
4
|
+
import type { PptxEngineReads } from "./engine.js";
|
|
5
|
+
import type { PptxLayoutInfo, PptxSlideInfo } from "./types.js";
|
|
6
|
+
export type PptxEditProviderOptions = OoxmlEditProviderOptions;
|
|
7
|
+
/**
|
|
8
|
+
* Starts the OOXML edit worker for `original` as a PPTX engine. Loaded
|
|
9
|
+
* lazily by the Office adapter's provider on the first `edit()`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function loadPptxEditEngine(original: Uint8Array, context: EditEngineContext, options?: PptxEditProviderOptions): Promise<PptxEditEngineClient>;
|
|
12
|
+
export declare class PptxEditEngineClient extends WorkerEngineClient implements PptxEngineReads {
|
|
13
|
+
readonly schemas: import("../types.js").OperationSchemaSet;
|
|
14
|
+
start(original: Uint8Array): Promise<void>;
|
|
15
|
+
slides(signal: AbortSignal): Promise<readonly PptxSlideInfo[]>;
|
|
16
|
+
layouts(signal: AbortSignal): Promise<readonly PptxLayoutInfo[]>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { WorkerRpcClient } from "../../worker-client.js";
|
|
2
|
+
import { createOoxmlEditWorker, } from "../ooxml/worker.js";
|
|
3
|
+
import { WorkerEngineClient } from "../worker-engine.js";
|
|
4
|
+
import { pptxOperationSchemas } from "./schemas.js";
|
|
5
|
+
/**
|
|
6
|
+
* Starts the OOXML edit worker for `original` as a PPTX engine. Loaded
|
|
7
|
+
* lazily by the Office adapter's provider on the first `edit()`.
|
|
8
|
+
*/
|
|
9
|
+
export async function loadPptxEditEngine(original, context, options = {}) {
|
|
10
|
+
const worker = createOoxmlEditWorker(options, context);
|
|
11
|
+
const rpc = new WorkerRpcClient(worker);
|
|
12
|
+
const engine = new PptxEditEngineClient(rpc, context);
|
|
13
|
+
try {
|
|
14
|
+
await engine.start(original);
|
|
15
|
+
return engine;
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
rpc.destroy();
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export class PptxEditEngineClient extends WorkerEngineClient {
|
|
23
|
+
schemas = pptxOperationSchemas;
|
|
24
|
+
async start(original) {
|
|
25
|
+
const data = original.slice().buffer;
|
|
26
|
+
const open = {
|
|
27
|
+
data,
|
|
28
|
+
limits: this.context.limits,
|
|
29
|
+
format: "pptx",
|
|
30
|
+
...(this.context.fileName ? { fileName: this.context.fileName } : {}),
|
|
31
|
+
};
|
|
32
|
+
await this.request("edit-open", open, this.context.signal, [data]);
|
|
33
|
+
}
|
|
34
|
+
slides(signal) {
|
|
35
|
+
return this.request("edit-pptx-slides", undefined, signal);
|
|
36
|
+
}
|
|
37
|
+
layouts(signal) {
|
|
38
|
+
return this.request("edit-pptx-layouts", undefined, signal);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { OperationSchemaSet } from "../types.js";
|
|
2
|
+
/** Operations with an engine handler; grows as the tasks land. */
|
|
3
|
+
export declare const IMPLEMENTED_OPERATIONS: readonly string[];
|
|
4
|
+
export declare const pptxOperationSchemas: OperationSchemaSet;
|
|
5
|
+
/** Every schema, implemented or not, for the conformance test. */
|
|
6
|
+
export declare const pptxOperationSchemaDrafts: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* JSON Schemas of the PPTX operations, shared by the worker (engine
|
|
3
|
+
* validation), the main thread (shape checks) and clients (`session.schemas`).
|
|
4
|
+
* Only keywords the in-repo validator implements may appear here. The
|
|
5
|
+
* exported set lists the operations that have an engine handler.
|
|
6
|
+
*/
|
|
7
|
+
const definitions = {
|
|
8
|
+
// DrawingML coordinates are bounded (ST_Coordinate: ±27,273,042,316,900 EMU).
|
|
9
|
+
coordinate: {
|
|
10
|
+
type: "number",
|
|
11
|
+
minimum: -2_800_000_000,
|
|
12
|
+
maximum: 2_800_000_000,
|
|
13
|
+
},
|
|
14
|
+
extent: { type: "number", exclusiveMinimum: 0, maximum: 2_800_000_000 },
|
|
15
|
+
rect: {
|
|
16
|
+
type: "object",
|
|
17
|
+
required: ["x", "y", "width", "height"],
|
|
18
|
+
additionalProperties: false,
|
|
19
|
+
properties: {
|
|
20
|
+
x: { $ref: "#/$defs/coordinate" },
|
|
21
|
+
y: { $ref: "#/$defs/coordinate" },
|
|
22
|
+
width: { $ref: "#/$defs/extent" },
|
|
23
|
+
height: { $ref: "#/$defs/extent" },
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
point: {
|
|
27
|
+
type: "object",
|
|
28
|
+
required: ["x", "y"],
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
properties: {
|
|
31
|
+
x: { $ref: "#/$defs/coordinate" },
|
|
32
|
+
y: { $ref: "#/$defs/coordinate" },
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
offset: {
|
|
36
|
+
type: "object",
|
|
37
|
+
required: ["dx", "dy"],
|
|
38
|
+
additionalProperties: false,
|
|
39
|
+
properties: {
|
|
40
|
+
dx: { $ref: "#/$defs/coordinate" },
|
|
41
|
+
dy: { $ref: "#/$defs/coordinate" },
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
target: { type: "string", minLength: 1, maxLength: 200 },
|
|
45
|
+
textPosition: {
|
|
46
|
+
type: "object",
|
|
47
|
+
required: ["elementId", "offset"],
|
|
48
|
+
additionalProperties: false,
|
|
49
|
+
properties: {
|
|
50
|
+
elementId: { $ref: "#/$defs/target" },
|
|
51
|
+
offset: { type: "integer", minimum: 0 },
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
textRange: {
|
|
55
|
+
type: "object",
|
|
56
|
+
required: ["start", "end"],
|
|
57
|
+
additionalProperties: false,
|
|
58
|
+
properties: {
|
|
59
|
+
start: { $ref: "#/$defs/textPosition" },
|
|
60
|
+
end: { $ref: "#/$defs/textPosition" },
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
text: { type: "string", maxLength: 100_000 },
|
|
64
|
+
rgb: { type: "string", pattern: "^#[0-9A-Fa-f]{6}$" },
|
|
65
|
+
themeColor: {
|
|
66
|
+
type: "object",
|
|
67
|
+
required: ["theme"],
|
|
68
|
+
additionalProperties: false,
|
|
69
|
+
properties: {
|
|
70
|
+
theme: { type: "string", minLength: 1, maxLength: 20 },
|
|
71
|
+
mods: { type: "object" },
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
color: { oneOf: [{ $ref: "#/$defs/rgb" }, { $ref: "#/$defs/themeColor" }] },
|
|
75
|
+
colorOrNone: {
|
|
76
|
+
oneOf: [
|
|
77
|
+
{ $ref: "#/$defs/rgb" },
|
|
78
|
+
{ $ref: "#/$defs/themeColor" },
|
|
79
|
+
{ const: "none" },
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
textStyle: {
|
|
83
|
+
type: "object",
|
|
84
|
+
additionalProperties: false,
|
|
85
|
+
properties: {
|
|
86
|
+
fontFamily: { type: "string", minLength: 1, maxLength: 100 },
|
|
87
|
+
fontSize: { type: "number", minimum: 1, maximum: 400 },
|
|
88
|
+
bold: { type: "boolean" },
|
|
89
|
+
italic: { type: "boolean" },
|
|
90
|
+
underline: { type: "boolean" },
|
|
91
|
+
color: { $ref: "#/$defs/color" },
|
|
92
|
+
align: { enum: ["left", "center", "right", "justify"] },
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
line: {
|
|
96
|
+
type: "object",
|
|
97
|
+
required: ["color"],
|
|
98
|
+
additionalProperties: false,
|
|
99
|
+
properties: {
|
|
100
|
+
color: { $ref: "#/$defs/colorOrNone" },
|
|
101
|
+
width: { type: "number", minimum: 0, maximum: 100 },
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
tableStyle: {
|
|
105
|
+
type: "object",
|
|
106
|
+
additionalProperties: false,
|
|
107
|
+
properties: {
|
|
108
|
+
firstRow: { type: "boolean" },
|
|
109
|
+
bandRow: { type: "boolean" },
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
tableRows: {
|
|
113
|
+
type: "array",
|
|
114
|
+
minItems: 1,
|
|
115
|
+
maxItems: 100,
|
|
116
|
+
items: {
|
|
117
|
+
type: "array",
|
|
118
|
+
minItems: 1,
|
|
119
|
+
maxItems: 20,
|
|
120
|
+
items: { type: "string", maxLength: 10_000 },
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
index: { type: "integer", minimum: 0, maximum: 100_000 },
|
|
124
|
+
};
|
|
125
|
+
function operation(name, properties, required) {
|
|
126
|
+
return {
|
|
127
|
+
type: "object",
|
|
128
|
+
required: ["op", ...required],
|
|
129
|
+
additionalProperties: false,
|
|
130
|
+
properties: { op: { const: name }, ...properties },
|
|
131
|
+
$defs: definitions,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const all = {
|
|
135
|
+
replaceText: operation("replaceText", {
|
|
136
|
+
target: { $ref: "#/$defs/target" },
|
|
137
|
+
text: { $ref: "#/$defs/text" },
|
|
138
|
+
range: { $ref: "#/$defs/textRange" },
|
|
139
|
+
}, ["target", "text"]),
|
|
140
|
+
setTextStyle: operation("setTextStyle", {
|
|
141
|
+
target: { $ref: "#/$defs/target" },
|
|
142
|
+
range: { $ref: "#/$defs/textRange" },
|
|
143
|
+
style: { $ref: "#/$defs/textStyle" },
|
|
144
|
+
}, ["target", "style"]),
|
|
145
|
+
setShapeStyle: operation("setShapeStyle", {
|
|
146
|
+
target: { $ref: "#/$defs/target" },
|
|
147
|
+
fill: { oneOf: [{ $ref: "#/$defs/colorOrNone" }, { type: "null" }] },
|
|
148
|
+
line: {
|
|
149
|
+
oneOf: [{ $ref: "#/$defs/line" }, { const: "none" }, { type: "null" }],
|
|
150
|
+
},
|
|
151
|
+
}, ["target"]),
|
|
152
|
+
moveElement: operation("moveElement", {
|
|
153
|
+
target: { $ref: "#/$defs/target" },
|
|
154
|
+
to: { $ref: "#/$defs/point" },
|
|
155
|
+
by: { $ref: "#/$defs/offset" },
|
|
156
|
+
}, ["target"]),
|
|
157
|
+
resizeElement: operation("resizeElement", { target: { $ref: "#/$defs/target" }, rect: { $ref: "#/$defs/rect" } }, ["target", "rect"]),
|
|
158
|
+
deleteElement: operation("deleteElement", { target: { $ref: "#/$defs/target" } }, ["target"]),
|
|
159
|
+
insertTextBox: operation("insertTextBox", {
|
|
160
|
+
pageIndex: { $ref: "#/$defs/index" },
|
|
161
|
+
rect: { $ref: "#/$defs/rect" },
|
|
162
|
+
text: { $ref: "#/$defs/text" },
|
|
163
|
+
style: { $ref: "#/$defs/textStyle" },
|
|
164
|
+
}, ["pageIndex", "rect", "text"]),
|
|
165
|
+
insertImage: operation("insertImage", {
|
|
166
|
+
pageIndex: { $ref: "#/$defs/index" },
|
|
167
|
+
rect: { $ref: "#/$defs/rect" },
|
|
168
|
+
data: { "x-binary": true, type: "string", contentEncoding: "base64" },
|
|
169
|
+
mimeType: { enum: ["image/png", "image/jpeg"] },
|
|
170
|
+
}, ["pageIndex", "rect", "data", "mimeType"]),
|
|
171
|
+
insertTable: operation("insertTable", {
|
|
172
|
+
pageIndex: { $ref: "#/$defs/index" },
|
|
173
|
+
rect: { $ref: "#/$defs/rect" },
|
|
174
|
+
rows: { $ref: "#/$defs/tableRows" },
|
|
175
|
+
columnWidths: {
|
|
176
|
+
type: "array",
|
|
177
|
+
minItems: 1,
|
|
178
|
+
maxItems: 20,
|
|
179
|
+
items: { type: "number", exclusiveMinimum: 0 },
|
|
180
|
+
},
|
|
181
|
+
style: { $ref: "#/$defs/tableStyle" },
|
|
182
|
+
}, ["pageIndex", "rect", "rows"]),
|
|
183
|
+
setTableCell: operation("setTableCell", {
|
|
184
|
+
target: { $ref: "#/$defs/target" },
|
|
185
|
+
row: { $ref: "#/$defs/index" },
|
|
186
|
+
column: { $ref: "#/$defs/index" },
|
|
187
|
+
text: { $ref: "#/$defs/text" },
|
|
188
|
+
}, ["target", "row", "column", "text"]),
|
|
189
|
+
insertSlide: operation("insertSlide", {
|
|
190
|
+
index: { $ref: "#/$defs/index" },
|
|
191
|
+
layout: { type: "string", minLength: 1, maxLength: 50 },
|
|
192
|
+
}, ["index"]),
|
|
193
|
+
duplicateSlide: operation("duplicateSlide", { pageIndex: { $ref: "#/$defs/index" }, index: { $ref: "#/$defs/index" } }, ["pageIndex"]),
|
|
194
|
+
deleteSlide: operation("deleteSlide", { pageIndex: { $ref: "#/$defs/index" } }, ["pageIndex"]),
|
|
195
|
+
moveSlide: operation("moveSlide", { from: { $ref: "#/$defs/index" }, to: { $ref: "#/$defs/index" } }, ["from", "to"]),
|
|
196
|
+
};
|
|
197
|
+
/** Operations with an engine handler; grows as the tasks land. */
|
|
198
|
+
export const IMPLEMENTED_OPERATIONS = [
|
|
199
|
+
"replaceText",
|
|
200
|
+
"setTextStyle",
|
|
201
|
+
"setShapeStyle",
|
|
202
|
+
"moveElement",
|
|
203
|
+
"resizeElement",
|
|
204
|
+
"deleteElement",
|
|
205
|
+
"insertTextBox",
|
|
206
|
+
"insertImage",
|
|
207
|
+
"insertTable",
|
|
208
|
+
"setTableCell",
|
|
209
|
+
"insertSlide",
|
|
210
|
+
"duplicateSlide",
|
|
211
|
+
"deleteSlide",
|
|
212
|
+
"moveSlide",
|
|
213
|
+
];
|
|
214
|
+
export const pptxOperationSchemas = Object.freeze({
|
|
215
|
+
format: "pptx",
|
|
216
|
+
version: 1,
|
|
217
|
+
operations: Object.freeze(Object.fromEntries(IMPLEMENTED_OPERATIONS.map((name) => [name, all[name]]))),
|
|
218
|
+
});
|
|
219
|
+
/** Every schema, implemented or not, for the conformance test. */
|
|
220
|
+
export const pptxOperationSchemaDrafts = all;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { DescribeOptions, DocumentDescription, EditCheckpoint, OutlineOptions, OutlineResult, TargetCandidate, TargetQuery, ToolCall, ToolCallOptions, ToolResult, ToolSet } from "../ai/types.js";
|
|
2
|
+
import type { EditSessionCore } from "../engine.js";
|
|
3
|
+
import type { ApplyOptions, AssetOptions, EditFindOptions, EditOperation, EditReceipt, EditState, ElementQuery, HistoryOptions, OperationSchemaSet, PagePoint, ReadItem, ReadOptions, ReadResult, SavedDocument, TextTarget } from "../types.js";
|
|
4
|
+
import type { PptxDeleteElementOperation, PptxDeleteSlideOperation, PptxDuplicateSlideOperation, PptxEditSession, PptxElement, PptxFields, PptxInsertImageOperation, PptxInsertSlideOperation, PptxInsertTableOperation, PptxInsertTextBoxOperation, PptxLayoutInfo, PptxMoveElementOperation, PptxMoveSlideOperation, PptxOperation, PptxReplaceTextOperation, PptxResizeElementOperation, PptxSaveOptions, PptxSetShapeStyleOperation, PptxSetTableCellOperation, PptxSetTextStyleOperation, PptxSlideInfo } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* The PPTX session: the core session narrowed to PPTX operations and
|
|
7
|
+
* elements, plus the slide and layout reads. Each typed method is `apply()`
|
|
8
|
+
* with a single operation.
|
|
9
|
+
*/
|
|
10
|
+
export declare class PptxSession implements PptxEditSession {
|
|
11
|
+
#private;
|
|
12
|
+
readonly format: "pptx";
|
|
13
|
+
constructor(core: EditSessionCore);
|
|
14
|
+
get sessionId(): string;
|
|
15
|
+
get state(): EditState;
|
|
16
|
+
get schemas(): OperationSchemaSet;
|
|
17
|
+
apply(operations: readonly PptxOperation[], options?: ApplyOptions): Promise<EditReceipt>;
|
|
18
|
+
applyJson(operations: readonly EditOperation[], options?: ApplyOptions): Promise<EditReceipt>;
|
|
19
|
+
undo(options?: HistoryOptions): Promise<EditReceipt>;
|
|
20
|
+
redo(options?: HistoryOptions): Promise<EditReceipt>;
|
|
21
|
+
reset(options?: HistoryOptions): Promise<EditReceipt>;
|
|
22
|
+
save(options?: PptxSaveOptions): Promise<SavedDocument>;
|
|
23
|
+
markSaved(stateToken: string): void;
|
|
24
|
+
addAsset(data: Uint8Array, options?: AssetOptions): Promise<string>;
|
|
25
|
+
getElements(query?: ElementQuery, options?: ReadOptions): Promise<ReadResult<PptxElement>>;
|
|
26
|
+
getElement(id: string, options?: ReadOptions): Promise<ReadItem<PptxElement>>;
|
|
27
|
+
elementsAt(pageIndex: number, point: PagePoint, options?: ReadOptions): Promise<ReadResult<PptxElement>>;
|
|
28
|
+
findText(query: string, options?: EditFindOptions): Promise<ReadResult<TextTarget>>;
|
|
29
|
+
getOutline(options?: OutlineOptions): Promise<OutlineResult>;
|
|
30
|
+
describe(options?: DescribeOptions): Promise<ReadItem<DocumentDescription>>;
|
|
31
|
+
resolveTargets(query: TargetQuery, options?: ReadOptions): Promise<ReadResult<TargetCandidate>>;
|
|
32
|
+
createCheckpoint(label?: string): Promise<EditCheckpoint>;
|
|
33
|
+
listCheckpoints(): readonly EditCheckpoint[];
|
|
34
|
+
restoreCheckpoint(id: string, options?: HistoryOptions): Promise<EditReceipt>;
|
|
35
|
+
dropCheckpoint(id: string): void;
|
|
36
|
+
get tools(): ToolSet;
|
|
37
|
+
callTool(call: ToolCall, options?: ToolCallOptions): Promise<ToolResult>;
|
|
38
|
+
getSlides(options?: ReadOptions): Promise<ReadResult<PptxSlideInfo>>;
|
|
39
|
+
getLayouts(options?: ReadOptions): Promise<ReadResult<PptxLayoutInfo>>;
|
|
40
|
+
replaceText(fields: PptxFields<PptxReplaceTextOperation>, options?: ApplyOptions): Promise<EditReceipt>;
|
|
41
|
+
setTextStyle(fields: PptxFields<PptxSetTextStyleOperation>, options?: ApplyOptions): Promise<EditReceipt>;
|
|
42
|
+
setShapeStyle(fields: PptxFields<PptxSetShapeStyleOperation>, options?: ApplyOptions): Promise<EditReceipt>;
|
|
43
|
+
moveElement(fields: PptxFields<PptxMoveElementOperation>, options?: ApplyOptions): Promise<EditReceipt>;
|
|
44
|
+
resizeElement(fields: PptxFields<PptxResizeElementOperation>, options?: ApplyOptions): Promise<EditReceipt>;
|
|
45
|
+
deleteElement(fields: PptxFields<PptxDeleteElementOperation>, options?: ApplyOptions): Promise<EditReceipt>;
|
|
46
|
+
insertTextBox(fields: PptxFields<PptxInsertTextBoxOperation>, options?: ApplyOptions): Promise<EditReceipt>;
|
|
47
|
+
insertImage(fields: PptxFields<PptxInsertImageOperation>, options?: ApplyOptions): Promise<EditReceipt>;
|
|
48
|
+
insertTable(fields: PptxFields<PptxInsertTableOperation>, options?: ApplyOptions): Promise<EditReceipt>;
|
|
49
|
+
setTableCell(fields: PptxFields<PptxSetTableCellOperation>, options?: ApplyOptions): Promise<EditReceipt>;
|
|
50
|
+
insertSlide(fields: PptxFields<PptxInsertSlideOperation>, options?: ApplyOptions): Promise<EditReceipt>;
|
|
51
|
+
duplicateSlide(fields: PptxFields<PptxDuplicateSlideOperation>, options?: ApplyOptions): Promise<EditReceipt>;
|
|
52
|
+
deleteSlide(fields: PptxFields<PptxDeleteSlideOperation>, options?: ApplyOptions): Promise<EditReceipt>;
|
|
53
|
+
moveSlide(fields: PptxFields<PptxMoveSlideOperation>, options?: ApplyOptions): Promise<EditReceipt>;
|
|
54
|
+
}
|