@capyclaw/ppt-workbench 0.0.0-stage → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +126 -3
- package/THIRD_PARTY_NOTICES.md +21 -0
- package/contract/ppt-contract.json +1529 -0
- package/cordis.patch.yml +25 -0
- package/core/audit.js +500 -0
- package/core/chart.js +199 -0
- package/core/color.js +80 -0
- package/core/deck-layout.js +195 -0
- package/core/formula.js +80 -0
- package/core/hfmath/hershey.js +1763 -0
- package/core/hfmath/index.js +1176 -0
- package/core/hfmath/stretch.js +41 -0
- package/core/hfmath/symbols.js +408 -0
- package/core/ops/browser.js +28 -0
- package/core/ops/chart.js +64 -0
- package/core/ops/deck.js +21 -0
- package/core/ops/dispatcher.js +2 -0
- package/core/ops/element.js +55 -0
- package/core/ops/history.js +11 -0
- package/core/ops/import.js +95 -0
- package/core/ops/index.js +39 -0
- package/core/ops/playback.js +9 -0
- package/core/ops/recolor.js +33 -0
- package/core/ops/slide.js +66 -0
- package/core/ops/table.js +85 -0
- package/core/ops/text.js +35 -0
- package/core/ops/view.js +13 -0
- package/core/ops.js +12 -0
- package/core/quick.js +52 -0
- package/core/shape-library.js +122 -0
- package/core/table.js +178 -0
- package/core/text.js +200 -0
- package/editor/app.js +5366 -0
- package/editor/heartbeat-worker.js +116 -0
- package/editor/index.html +89 -0
- package/editor/ppt-full-app.js +376 -0
- package/lib/host.mjs +98 -0
- package/package.json +51 -4
- package/server/audit.mjs +2 -0
- package/server/bridge-client.mjs +174 -0
- package/server/constants.mjs +20 -0
- package/server/contract-snapshots.mjs +62 -0
- package/server/contract.mjs +24 -0
- package/server/deck-layout.mjs +2 -0
- package/server/http-utils.mjs +2 -0
- package/server/infra/http.mjs +113 -0
- package/server/infra/runtime/context.mjs +128 -0
- package/server/infra/store/blob-store.mjs +109 -0
- package/server/infra/tuning.mjs +82 -0
- package/server/infra/util/fs-lock.mjs +132 -0
- package/server/infra/workspace/manager.mjs +657 -0
- package/server/mcp/dispatch.mjs +2 -0
- package/server/mcp/handler.mjs +2 -0
- package/server/mcp/instructions.mjs +40 -0
- package/server/mcp-http.mjs +3 -0
- package/server/ppt-shim.mjs +156 -0
- package/server/relay.mjs +245 -0
- package/server/routes/assets.mjs +2 -0
- package/server/routes/bridge.mjs +47 -0
- package/server/routes/editor.mjs +9 -0
- package/server/routes/import.mjs +258 -0
- package/server/routes/mcp.mjs +17 -0
- package/server/runtime/recovery.mjs +9 -0
- package/server/runtime/watch.mjs +17 -0
- package/server/shared/SHARED_MANIFEST.json +47 -0
- package/server/shared/asset-service.mjs +217 -0
- package/server/shared/editor-host.mjs +125 -0
- package/server/shared/kit/editor/lease.mjs +139 -0
- package/server/shared/kit/service/api.mjs +45 -0
- package/server/shared/kit/service/http.mjs +113 -0
- package/server/shared/kit/service/mcp-http.mjs +142 -0
- package/server/shared/kit/service/single-instance.mjs +72 -0
- package/server/shared/kit/tools/validate.mjs +115 -0
- package/server/shared/kit/tuning.mjs +82 -0
- package/server/shared/kit/util/fs-lock.mjs +132 -0
- package/server/shared/service-host.mjs +511 -0
- package/server/shared/state-service.mjs +249 -0
- package/server/shared/tool-host.mjs +341 -0
- package/server/shared/tuning.mjs +63 -0
- package/server/single-instance.mjs +2 -0
- package/server/store/backends/file-backend.mjs +13 -0
- package/server/store/checkpoints.mjs +28 -0
- package/server/store/doc.mjs +52 -0
- package/server/store/index.mjs +34 -0
- package/server/store/journal.mjs +9 -0
- package/server/store/lease.mjs +2 -0
- package/server/store/sanitize.mjs +32 -0
- package/server/store.mjs +2 -0
- package/server/tools/capabilities/apply.mjs +33 -0
- package/server/tools/capabilities/audit.mjs +24 -0
- package/server/tools/capabilities/chart.mjs +83 -0
- package/server/tools/capabilities/compose.mjs +97 -0
- package/server/tools/capabilities/contract.mjs +34 -0
- package/server/tools/capabilities/deck.mjs +27 -0
- package/server/tools/capabilities/element.mjs +67 -0
- package/server/tools/capabilities/export.mjs +95 -0
- package/server/tools/capabilities/formula.mjs +72 -0
- package/server/tools/capabilities/history.mjs +29 -0
- package/server/tools/capabilities/image.mjs +152 -0
- package/server/tools/capabilities/imagesearch.mjs +152 -0
- package/server/tools/capabilities/import.mjs +180 -0
- package/server/tools/capabilities/index.mjs +58 -0
- package/server/tools/capabilities/line.mjs +58 -0
- package/server/tools/capabilities/notes.mjs +33 -0
- package/server/tools/capabilities/present.mjs +34 -0
- package/server/tools/capabilities/recolor.mjs +60 -0
- package/server/tools/capabilities/screenshot.mjs +86 -0
- package/server/tools/capabilities/shape.mjs +64 -0
- package/server/tools/capabilities/slide.mjs +81 -0
- package/server/tools/capabilities/style.mjs +48 -0
- package/server/tools/capabilities/table.mjs +127 -0
- package/server/tools/capabilities/task.mjs +52 -0
- package/server/tools/capabilities/text.mjs +82 -0
- package/server/tools/domains/color.mjs +4 -0
- package/server/tools/domains/image.mjs +49 -0
- package/server/tools/domains/index.mjs +7 -0
- package/server/tools/domains/pptx-export.mjs +566 -0
- package/server/tools/domains/recolor.mjs +25 -0
- package/server/tools/domains/remote-image.mjs +291 -0
- package/server/tools/domains/slide.mjs +21 -0
- package/server/tools/domains/text-style.mjs +11 -0
- package/server/tools/domains/tooling.mjs +13 -0
- package/server/tools/index.mjs +14 -0
- package/server/tools/kernel/define.mjs +5 -0
- package/server/tools/kernel/ports.mjs +42 -0
- package/server/tools/kernel/registry.mjs +17 -0
- package/server/tools.mjs +18 -0
- package/server/tuning.mjs +86 -0
- package/server/validate.mjs +2 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
function curve(a, b, c, d, steps = 8) {
|
|
2
|
+
const points = [];
|
|
3
|
+
for (let i = 0; i <= steps; i++) {
|
|
4
|
+
const t = i / steps;
|
|
5
|
+
const u = 1 - t;
|
|
6
|
+
points.push([
|
|
7
|
+
u ** 3 * a[0] + 3 * u ** 2 * t * b[0] + 3 * u * t ** 2 * c[0] + t ** 3 * d[0],
|
|
8
|
+
u ** 3 * a[1] + 3 * u ** 2 * t * b[1] + 3 * u * t ** 2 * c[1] + t ** 3 * d[1]
|
|
9
|
+
]);
|
|
10
|
+
}
|
|
11
|
+
return points;
|
|
12
|
+
}
|
|
13
|
+
function stretch(kind, width, height, reversed = false) {
|
|
14
|
+
let lines;
|
|
15
|
+
if (kind === "arrow") {
|
|
16
|
+
const head = Math.min(height, width / 2);
|
|
17
|
+
lines = [
|
|
18
|
+
[[0, height / 2], [width, height / 2]],
|
|
19
|
+
[[width - head, 0], [width, height / 2], [width - head, height]]
|
|
20
|
+
];
|
|
21
|
+
} else if (kind === "brace") {
|
|
22
|
+
const cap = Math.min(width / 4, height * 0.8);
|
|
23
|
+
const mid = width / 2;
|
|
24
|
+
const half = height / 2;
|
|
25
|
+
lines = [[
|
|
26
|
+
...curve([0, height], [0, half], [cap / 2, half], [cap, half]),
|
|
27
|
+
[mid - cap, half],
|
|
28
|
+
...curve([mid - cap, half], [mid - cap / 2, half], [mid, half], [mid, 0]).slice(1),
|
|
29
|
+
...curve([mid, 0], [mid, half], [mid + cap / 2, half], [mid + cap, half]).slice(1),
|
|
30
|
+
[width - cap, half],
|
|
31
|
+
...curve([width - cap, half], [width - cap / 2, half], [width, half], [width, height]).slice(1)
|
|
32
|
+
]];
|
|
33
|
+
} else {
|
|
34
|
+
lines = [curve([0, height], [0, -height / 3], [width, -height / 3], [width, height], 32)];
|
|
35
|
+
}
|
|
36
|
+
if (!reversed) return lines;
|
|
37
|
+
return lines.map((line) => line.map(([x, y]) => kind === "arrow" ? [width - x, y] : [x, height - y]));
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
stretch
|
|
41
|
+
};
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
const SYMB = {
|
|
2
|
+
"\\frac": { glyph: 0, arity: 2, flags: { frac: true } },
|
|
3
|
+
"\\dfrac": { glyph: 0, arity: 2, flags: { frac: true } },
|
|
4
|
+
"\\tfrac": { glyph: 0, arity: 2, flags: { frac: true } },
|
|
5
|
+
"\\binom": { glyph: 0, arity: 2, flags: { binom: true } },
|
|
6
|
+
"\\dbinom": { glyph: 0, arity: 2, flags: { binom: true } },
|
|
7
|
+
"\\tbinom": { glyph: 0, arity: 2, flags: { binom: true } },
|
|
8
|
+
"\\overset": { glyph: 0, arity: 2, flags: { above: true } },
|
|
9
|
+
"\\stackrel": { glyph: 0, arity: 2, flags: { above: true } },
|
|
10
|
+
"\\underset": { glyph: 0, arity: 2, flags: { below: true } },
|
|
11
|
+
"\\xrightarrow": { glyph: 0, arity: 1, flags: { xarrow: true, opt: true } },
|
|
12
|
+
"\\xleftarrow": { glyph: 0, arity: 1, flags: { xarrow: true, opt: true, left: true } },
|
|
13
|
+
"\\operatorname": { glyph: 0, arity: 1, flags: {} },
|
|
14
|
+
"\\operatorname*": { glyph: 0, arity: 1, flags: { big: true } },
|
|
15
|
+
"\\sqrt": { glyph: 2267, arity: 1, flags: { opt: true, xfl: true, yfl: true } },
|
|
16
|
+
"^": { glyph: 0, arity: 1, flags: {} },
|
|
17
|
+
"_": { glyph: 0, arity: 1, flags: {} },
|
|
18
|
+
"(": { glyph: 2221, arity: 0, flags: { yfl: true } },
|
|
19
|
+
")": { glyph: 2222, arity: 0, flags: { yfl: true } },
|
|
20
|
+
"[": { glyph: 2223, arity: 0, flags: { yfl: true } },
|
|
21
|
+
"]": { glyph: 2224, arity: 0, flags: { yfl: true } },
|
|
22
|
+
"\\langle": { glyph: 2227, arity: 0, flags: { yfl: true } },
|
|
23
|
+
"\\rangle": { glyph: 2228, arity: 0, flags: { yfl: true } },
|
|
24
|
+
"|": { glyph: 2229, arity: 0, flags: { yfl: true } },
|
|
25
|
+
"\\|": { glyph: 2230, arity: 0, flags: { yfl: true } },
|
|
26
|
+
"\\{": { glyph: 2225, arity: 0, flags: { yfl: true } },
|
|
27
|
+
"\\}": { glyph: 2226, arity: 0, flags: { yfl: true } },
|
|
28
|
+
"\\lparen": { glyph: 2221, flags: { yfl: true } },
|
|
29
|
+
"\\rparen": { glyph: 2222, flags: { yfl: true } },
|
|
30
|
+
"\\lbrack": { glyph: 2223, flags: { yfl: true } },
|
|
31
|
+
"\\rbrack": { glyph: 2224, flags: { yfl: true } },
|
|
32
|
+
"\\lbrace": { glyph: 2225, flags: { yfl: true } },
|
|
33
|
+
"\\rbrace": { glyph: 2226, flags: { yfl: true } },
|
|
34
|
+
"\\lvert": { glyph: 2229, flags: { yfl: true } },
|
|
35
|
+
"\\rvert": { glyph: 2229, flags: { yfl: true } },
|
|
36
|
+
"\\vert": { glyph: 2229, flags: { yfl: true } },
|
|
37
|
+
"\\lVert": { glyph: 2230, flags: { yfl: true } },
|
|
38
|
+
"\\rVert": { glyph: 2230, flags: { yfl: true } },
|
|
39
|
+
"\\Vert": { glyph: 2230, flags: { yfl: true } },
|
|
40
|
+
"\\lfloor": { glyph: 5051, flags: { yfl: true } },
|
|
41
|
+
"\\rfloor": { glyph: 5052, flags: { yfl: true } },
|
|
42
|
+
"\\lceil": { glyph: 5053, flags: { yfl: true } },
|
|
43
|
+
"\\rceil": { glyph: 5054, flags: { yfl: true } },
|
|
44
|
+
"\\backslash": { glyph: 5055, flags: { yfl: true } },
|
|
45
|
+
"\\#": { glyph: 2275, arity: 0, flags: {} },
|
|
46
|
+
"\\$": { glyph: 2274, arity: 0, flags: {} },
|
|
47
|
+
"\\&": { glyph: 2273, arity: 0, flags: {} },
|
|
48
|
+
"\\%": { glyph: 2271, arity: 0, flags: {} },
|
|
49
|
+
/* semantics*/
|
|
50
|
+
"\\begin": { glyph: 0, arity: 1, flags: {} },
|
|
51
|
+
"\\end": { glyph: 0, arity: 1, flags: {} },
|
|
52
|
+
"\\left": { glyph: 0, arity: 1, flags: {} },
|
|
53
|
+
"\\right": { glyph: 0, arity: 1, flags: {} },
|
|
54
|
+
"\\middle": { glyph: 0, arity: 1, flags: {} },
|
|
55
|
+
"\\big": { glyph: 0, arity: 1, size: 1.2, flags: {} },
|
|
56
|
+
"\\bigl": { glyph: 0, arity: 1, size: 1.2, flags: {} },
|
|
57
|
+
"\\bigr": { glyph: 0, arity: 1, size: 1.2, flags: {} },
|
|
58
|
+
"\\bigm": { glyph: 0, arity: 1, size: 1.2, flags: {} },
|
|
59
|
+
"\\Big": { glyph: 0, arity: 1, size: 1.6, flags: {} },
|
|
60
|
+
"\\Bigl": { glyph: 0, arity: 1, size: 1.6, flags: {} },
|
|
61
|
+
"\\Bigr": { glyph: 0, arity: 1, size: 1.6, flags: {} },
|
|
62
|
+
"\\Bigm": { glyph: 0, arity: 1, size: 1.6, flags: {} },
|
|
63
|
+
"\\bigg": { glyph: 0, arity: 1, size: 2, flags: {} },
|
|
64
|
+
"\\biggl": { glyph: 0, arity: 1, size: 2, flags: {} },
|
|
65
|
+
"\\biggr": { glyph: 0, arity: 1, size: 2, flags: {} },
|
|
66
|
+
"\\biggm": { glyph: 0, arity: 1, size: 2, flags: {} },
|
|
67
|
+
"\\Bigg": { glyph: 0, arity: 1, size: 2.5, flags: {} },
|
|
68
|
+
"\\Biggl": { glyph: 0, arity: 1, size: 2.5, flags: {} },
|
|
69
|
+
"\\Biggr": { glyph: 0, arity: 1, size: 2.5, flags: {} },
|
|
70
|
+
"\\Biggm": { glyph: 0, arity: 1, size: 2.5, flags: {} },
|
|
71
|
+
/* operators*/
|
|
72
|
+
"\\cdot": { glyph: 2236, arity: 0, flags: {} },
|
|
73
|
+
"\\pm": { glyph: 2233, arity: 0, flags: {} },
|
|
74
|
+
"\\mp": { glyph: 2234, arity: 0, flags: {} },
|
|
75
|
+
"\\times": { glyph: 2235, arity: 0, flags: {} },
|
|
76
|
+
"\\div": { glyph: 2237, arity: 0, flags: {} },
|
|
77
|
+
"\\leqq": { glyph: 2243, arity: 0, flags: {} },
|
|
78
|
+
"\\geqq": { glyph: 2244, arity: 0, flags: {} },
|
|
79
|
+
"\\leq": { glyph: 2243, arity: 0, flags: {} },
|
|
80
|
+
"\\geq": { glyph: 2244, arity: 0, flags: {} },
|
|
81
|
+
"\\propto": { glyph: 2245, arity: 0, flags: {} },
|
|
82
|
+
"\\sim": { glyph: 2246, arity: 0, flags: {} },
|
|
83
|
+
"\\equiv": { glyph: 2240, arity: 0, flags: {} },
|
|
84
|
+
"\\dagger": { glyph: 2277, arity: 0, flags: {} },
|
|
85
|
+
"\\ddagger": { glyph: 2278, arity: 0, flags: {} },
|
|
86
|
+
"\\ell": { glyph: 662, arity: 0, flags: {} },
|
|
87
|
+
"\\otimes": { glyph: 5035, flags: {} },
|
|
88
|
+
"\\ominus": { glyph: 5036, flags: {} },
|
|
89
|
+
"\\oslash": { glyph: 5037, flags: {} },
|
|
90
|
+
"\\uplus": { glyph: 5038, flags: {} },
|
|
91
|
+
"\\parallel": { glyph: 5039, flags: {} },
|
|
92
|
+
"\\nparallel": { glyph: 5040, flags: {} },
|
|
93
|
+
"\\nmid": { glyph: 5041, flags: {} },
|
|
94
|
+
"\\ll": { glyph: 5042, flags: {} },
|
|
95
|
+
"\\gg": { glyph: 5043, flags: {} },
|
|
96
|
+
"\\cong": { glyph: 5044, flags: {} },
|
|
97
|
+
"\\asymp": { glyph: 5045, flags: {} },
|
|
98
|
+
"\\prec": { glyph: 5046, flags: {} },
|
|
99
|
+
"\\succ": { glyph: 5047, flags: {} },
|
|
100
|
+
"\\preceq": { glyph: 5048, flags: {} },
|
|
101
|
+
"\\succeq": { glyph: 5049, flags: {} },
|
|
102
|
+
"\\vdash": { glyph: 5056, flags: {} },
|
|
103
|
+
"\\dashv": { glyph: 5057, flags: {} },
|
|
104
|
+
"\\models": { glyph: 5058, flags: {} },
|
|
105
|
+
/* ellipses: dots selects the baseline or centered form from its context. */
|
|
106
|
+
"\\dots": { glyph: 5030, flags: {} },
|
|
107
|
+
"\\ldots": { glyph: 5030, flags: {} },
|
|
108
|
+
"\\cdots": { glyph: 5031, flags: {} },
|
|
109
|
+
"\\vdots": { glyph: 5032, flags: {} },
|
|
110
|
+
"\\ddots": { glyph: 5033, flags: {} },
|
|
111
|
+
/* accents*/
|
|
112
|
+
"\\vec": { glyph: 2261, arity: 1, flags: { hat: true, xfl: true, yfl: true } },
|
|
113
|
+
"\\overrightarrow": { glyph: 2261, arity: 1, flags: { hat: true, xfl: true, yfl: true } },
|
|
114
|
+
"\\overleftarrow": { glyph: 2263, arity: 1, flags: { hat: true, xfl: true, yfl: true } },
|
|
115
|
+
"\\bar": { glyph: 2231, arity: 1, flags: { hat: true, xfl: true } },
|
|
116
|
+
"\\overline": { glyph: 2231, arity: 1, flags: { hat: true, xfl: true } },
|
|
117
|
+
"\\widehat": { glyph: 2247, arity: 1, flags: { hat: true, xfl: true, yfl: true } },
|
|
118
|
+
"\\hat": { glyph: 2247, arity: 1, flags: { hat: true } },
|
|
119
|
+
"\\acute": { glyph: 2248, arity: 1, flags: { hat: true } },
|
|
120
|
+
"\\grave": { glyph: 2249, arity: 1, flags: { hat: true } },
|
|
121
|
+
"\\breve": { glyph: 2250, arity: 1, flags: { hat: true } },
|
|
122
|
+
"\\tilde": { glyph: 2246, arity: 1, flags: { hat: true } },
|
|
123
|
+
"\\underline": { glyph: 2231, arity: 1, flags: { mat: true, xfl: true } },
|
|
124
|
+
"\\dot": { glyph: 2236, arity: 1, flags: { hat: true } },
|
|
125
|
+
"\\ddot": { glyph: 5034, arity: 1, flags: { hat: true } },
|
|
126
|
+
"\\check": { glyph: 5059, arity: 1, flags: { hat: true } },
|
|
127
|
+
"\\mathring": { glyph: 5060, arity: 1, flags: { hat: true } },
|
|
128
|
+
"\\widetilde": { glyph: 2246, arity: 1, flags: { hat: true, xfl: true, yfl: true } },
|
|
129
|
+
"\\overleftrightarrow": { glyph: 5015, arity: 1, flags: { hat: true, xfl: true, yfl: true } },
|
|
130
|
+
"\\boxed": { glyph: 5050, arity: 1, flags: { xfl: true, yfl: true } },
|
|
131
|
+
"\\overbrace": { glyph: 0, arity: 1, flags: { group: true, brace: true } },
|
|
132
|
+
"\\underbrace": { glyph: 0, arity: 1, flags: { group: true, brace: true, under: true } },
|
|
133
|
+
"\\overparen": { glyph: 0, arity: 1, flags: { group: true } },
|
|
134
|
+
"\\underparen": { glyph: 0, arity: 1, flags: { group: true, under: true } },
|
|
135
|
+
"\\not": { glyph: 2220, arity: 1, flags: {} },
|
|
136
|
+
"\\neq": { glyph: 2239, arity: 0, flags: {} },
|
|
137
|
+
"\\ne": { glyph: 2239, arity: 0, flags: {} },
|
|
138
|
+
"\\le": { glyph: 2243, flags: {} },
|
|
139
|
+
"\\ge": { glyph: 2244, flags: {} },
|
|
140
|
+
"\\approx": { glyph: 5011, flags: {} },
|
|
141
|
+
"\\simeq": { glyph: 5012, flags: {} },
|
|
142
|
+
"\\forall": { glyph: 5e3, flags: {} },
|
|
143
|
+
"\\nexists": { glyph: 5001, flags: {} },
|
|
144
|
+
"\\notin": { glyph: 5002, flags: {} },
|
|
145
|
+
"\\ni": { glyph: 5003, flags: {} },
|
|
146
|
+
"\\owns": { glyph: 5003, flags: {} },
|
|
147
|
+
"\\emptyset": { glyph: 5004, flags: {} },
|
|
148
|
+
"\\varnothing": { glyph: 5004, flags: {} },
|
|
149
|
+
"\\subseteq": { glyph: 5005, flags: {} },
|
|
150
|
+
"\\supseteq": { glyph: 5006, flags: {} },
|
|
151
|
+
"\\nsubseteq": { glyph: 5007, flags: {} },
|
|
152
|
+
"\\nsupseteq": { glyph: 5008, flags: {} },
|
|
153
|
+
"\\land": { glyph: 5009, flags: {} },
|
|
154
|
+
"\\wedge": { glyph: 5009, flags: {} },
|
|
155
|
+
"\\lor": { glyph: 5010, flags: {} },
|
|
156
|
+
"\\vee": { glyph: 5010, flags: {} },
|
|
157
|
+
"\\neg": { glyph: 5013, flags: {} },
|
|
158
|
+
"\\lnot": { glyph: 5013, flags: {} },
|
|
159
|
+
"\\setminus": { glyph: 5014, flags: {} },
|
|
160
|
+
"\\smallsetminus": { glyph: 5014, flags: {} },
|
|
161
|
+
"\\exists": { glyph: 2279, arity: 0, flags: {} },
|
|
162
|
+
"\\in": { glyph: 2260, arity: 0, flags: {} },
|
|
163
|
+
"\\subset": { glyph: 2256, arity: 0, flags: {} },
|
|
164
|
+
"\\supset": { glyph: 2258, arity: 0, flags: {} },
|
|
165
|
+
"\\cup": { glyph: 2257, arity: 0, flags: {} },
|
|
166
|
+
"\\cap": { glyph: 2259, arity: 0, flags: {} },
|
|
167
|
+
"\\infty": { glyph: 2270, arity: 0, flags: {} },
|
|
168
|
+
"\\partial": { glyph: 2265, arity: 0, flags: {} },
|
|
169
|
+
"\\nabla": { glyph: 2266, arity: 0, flags: {} },
|
|
170
|
+
"\\aleph": { glyph: 2077, arity: 0, flags: {} },
|
|
171
|
+
"\\wp": { glyph: 2190, arity: 0, flags: {} },
|
|
172
|
+
"\\therefore": { glyph: 740, arity: 0, flags: {} },
|
|
173
|
+
"\\mid": { glyph: 2229, arity: 0, flags: {} },
|
|
174
|
+
"\\sum": { glyph: 2402, arity: 0, flags: { big: true } },
|
|
175
|
+
"\\prod": { glyph: 2401, arity: 0, flags: { big: true } },
|
|
176
|
+
"\\bigoplus": { glyph: 2284, arity: 0, flags: { big: true } },
|
|
177
|
+
"\\bigodot": { glyph: 2281, arity: 0, flags: { big: true } },
|
|
178
|
+
"\\bigotimes": { glyph: 5035, flags: { big: true, xfl: true, yfl: true } },
|
|
179
|
+
"\\bigcup": { glyph: 2257, flags: { big: true, xfl: true, yfl: true } },
|
|
180
|
+
"\\bigcap": { glyph: 2259, flags: { big: true, xfl: true, yfl: true } },
|
|
181
|
+
"\\bigvee": { glyph: 5010, flags: { big: true, xfl: true, yfl: true } },
|
|
182
|
+
"\\bigwedge": { glyph: 5009, flags: { big: true, xfl: true, yfl: true } },
|
|
183
|
+
"\\biguplus": { glyph: 5038, flags: { big: true, xfl: true, yfl: true } },
|
|
184
|
+
"\\int": { glyph: 2412, arity: 0, flags: { yfl: true, integral: true } },
|
|
185
|
+
"\\oint": { glyph: 2269, arity: 0, flags: { yfl: true, integral: true } },
|
|
186
|
+
"\\iint": { glyph: 5020, flags: { yfl: true, integral: true } },
|
|
187
|
+
"\\iiint": { glyph: 5021, flags: { yfl: true, integral: true } },
|
|
188
|
+
"\\iiiint": { glyph: 5022, flags: { yfl: true, integral: true } },
|
|
189
|
+
"\\oplus": { glyph: 1284, arity: 0, flags: {} },
|
|
190
|
+
"\\odot": { glyph: 1281, arity: 0, flags: {} },
|
|
191
|
+
"\\perp": { glyph: 738, arity: 0, flags: {} },
|
|
192
|
+
"\\angle": { glyph: 739, arity: 0, flags: {} },
|
|
193
|
+
"\\triangle": { glyph: 842, arity: 0, flags: {} },
|
|
194
|
+
"\\Box": { glyph: 841, arity: 0, flags: {} },
|
|
195
|
+
"\\rightarrow": { glyph: 2261, arity: 0, flags: {} },
|
|
196
|
+
"\\to": { glyph: 2261, arity: 0, flags: {} },
|
|
197
|
+
"\\leftarrow": { glyph: 2263, arity: 0, flags: {} },
|
|
198
|
+
"\\gets": { glyph: 2263, arity: 0, flags: {} },
|
|
199
|
+
"\\leftrightarrow": { glyph: 5015, flags: {} },
|
|
200
|
+
"\\Rightarrow": { glyph: 5016, flags: {} },
|
|
201
|
+
"\\implies": { glyph: 5016, flags: {} },
|
|
202
|
+
"\\Leftarrow": { glyph: 5017, flags: {} },
|
|
203
|
+
"\\impliedby": { glyph: 5017, flags: {} },
|
|
204
|
+
"\\Leftrightarrow": { glyph: 5018, flags: {} },
|
|
205
|
+
"\\iff": { glyph: 5018, flags: {} },
|
|
206
|
+
"\\mapsto": { glyph: 5019, flags: {} },
|
|
207
|
+
"\\circ": { glyph: 902, arity: 0, flags: {} },
|
|
208
|
+
"\\bigcirc": { glyph: 904, arity: 0, flags: {} },
|
|
209
|
+
"\\bullet": { glyph: 828, arity: 0, flags: {} },
|
|
210
|
+
"\\star": { glyph: 856, arity: 0, flags: {} },
|
|
211
|
+
"\\diamond": { glyph: 743, arity: 0, flags: {} },
|
|
212
|
+
"\\ast": { glyph: 728, arity: 0, flags: {} },
|
|
213
|
+
/* verbatim symbols*/
|
|
214
|
+
"\\log": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
215
|
+
"\\ln": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
216
|
+
"\\exp": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
217
|
+
"\\mod": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
218
|
+
"\\lim": { glyph: 0, arity: 0, flags: { txt: true, big: true } },
|
|
219
|
+
"\\det": { glyph: 0, flags: { txt: true } },
|
|
220
|
+
"\\gcd": { glyph: 0, flags: { txt: true, big: true } },
|
|
221
|
+
"\\max": { glyph: 0, flags: { txt: true, big: true } },
|
|
222
|
+
"\\min": { glyph: 0, flags: { txt: true, big: true } },
|
|
223
|
+
"\\sup": { glyph: 0, flags: { txt: true, big: true } },
|
|
224
|
+
"\\inf": { glyph: 0, flags: { txt: true, big: true } },
|
|
225
|
+
"\\limsup": { glyph: 0, text: "lim sup", flags: { txt: true, big: true } },
|
|
226
|
+
"\\liminf": { glyph: 0, text: "lim inf", flags: { txt: true, big: true } },
|
|
227
|
+
"\\arg": { glyph: 0, flags: { txt: true } },
|
|
228
|
+
"\\ker": { glyph: 0, flags: { txt: true } },
|
|
229
|
+
"\\dim": { glyph: 0, flags: { txt: true } },
|
|
230
|
+
"\\deg": { glyph: 0, flags: { txt: true } },
|
|
231
|
+
"\\Pr": { glyph: 0, flags: { txt: true, big: true } },
|
|
232
|
+
"\\sin": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
233
|
+
"\\cos": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
234
|
+
"\\tan": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
235
|
+
"\\csc": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
236
|
+
"\\sec": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
237
|
+
"\\cot": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
238
|
+
"\\sinh": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
239
|
+
"\\cosh": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
240
|
+
"\\tanh": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
241
|
+
"\\csch": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
242
|
+
"\\sech": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
243
|
+
"\\coth": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
244
|
+
"\\arcsin": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
245
|
+
"\\arccos": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
246
|
+
"\\arctan": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
247
|
+
"\\arccsc": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
248
|
+
"\\arcsec": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
249
|
+
"\\arccot": { glyph: 0, arity: 0, flags: { txt: true } },
|
|
250
|
+
/* font modes*/
|
|
251
|
+
"\\text": { glyph: 0, arity: 1, flags: {} },
|
|
252
|
+
"\\mathnormal": { glyph: 0, arity: 1, flags: {} },
|
|
253
|
+
"\\mathrm": { glyph: 0, arity: 1, flags: {} },
|
|
254
|
+
"\\mathit": { glyph: 0, arity: 1, flags: {} },
|
|
255
|
+
"\\mathbf": { glyph: 0, arity: 1, flags: {} },
|
|
256
|
+
"\\mathsf": { glyph: 0, arity: 1, flags: {} },
|
|
257
|
+
"\\mathtt": { glyph: 0, arity: 1, flags: {} },
|
|
258
|
+
"\\mathfrak": { glyph: 0, arity: 1, flags: {} },
|
|
259
|
+
"\\mathcal": { glyph: 0, arity: 1, flags: {} },
|
|
260
|
+
"\\mathbb": { glyph: 0, arity: 1, flags: {} },
|
|
261
|
+
"\\mathscr": { glyph: 0, arity: 1, flags: {} },
|
|
262
|
+
"\\rm": { glyph: 0, arity: 1, flags: {} },
|
|
263
|
+
"\\it": { glyph: 0, arity: 1, flags: {} },
|
|
264
|
+
"\\bf": { glyph: 0, arity: 1, flags: {} },
|
|
265
|
+
"\\sf": { glyph: 0, arity: 1, flags: {} },
|
|
266
|
+
"\\tt": { glyph: 0, arity: 1, flags: {} },
|
|
267
|
+
"\\frak": { glyph: 0, arity: 1, flags: {} },
|
|
268
|
+
"\\cal": { glyph: 0, arity: 1, flags: {} },
|
|
269
|
+
"\\bb": { glyph: 0, arity: 1, flags: {} },
|
|
270
|
+
"\\scr": { glyph: 0, arity: 1, flags: {} },
|
|
271
|
+
"\\quad": { glyph: 0, arity: 0, flags: {} },
|
|
272
|
+
"\\qquad": { glyph: 0, flags: {} },
|
|
273
|
+
"\\enspace": { glyph: 0, flags: {} },
|
|
274
|
+
"\\enskip": { glyph: 0, flags: {} },
|
|
275
|
+
"\\thinspace": { glyph: 0, flags: {} },
|
|
276
|
+
"\\medspace": { glyph: 0, flags: {} },
|
|
277
|
+
"\\thickspace": { glyph: 0, flags: {} },
|
|
278
|
+
"\\negthinspace": { glyph: 0, flags: {} },
|
|
279
|
+
"\\,": { glyph: 0, arity: 0, flags: {} },
|
|
280
|
+
"\\.": { glyph: 0, arity: 0, flags: {} },
|
|
281
|
+
"\\;": { glyph: 0, arity: 0, flags: {} },
|
|
282
|
+
"\\!": { glyph: 0, arity: 0, flags: {} },
|
|
283
|
+
/* greek letters*/
|
|
284
|
+
"\\alpha": { glyph: 2127, flags: {} },
|
|
285
|
+
"\\beta": { glyph: 2128, flags: {} },
|
|
286
|
+
"\\gamma": { glyph: 2129, flags: {} },
|
|
287
|
+
"\\delta": { glyph: 2130, flags: {} },
|
|
288
|
+
"\\varepsilon": { glyph: 2131, flags: {} },
|
|
289
|
+
"\\zeta": { glyph: 2132, flags: {} },
|
|
290
|
+
"\\eta": { glyph: 2133, flags: {} },
|
|
291
|
+
"\\vartheta": { glyph: 2134, flags: {} },
|
|
292
|
+
"\\iota": { glyph: 2135, flags: {} },
|
|
293
|
+
"\\kappa": { glyph: 2136, flags: {} },
|
|
294
|
+
"\\lambda": { glyph: 2137, flags: {} },
|
|
295
|
+
"\\mu": { glyph: 2138, flags: {} },
|
|
296
|
+
"\\nu": { glyph: 2139, flags: {} },
|
|
297
|
+
"\\xi": { glyph: 2140, flags: {} },
|
|
298
|
+
"\\omicron": { glyph: 2141, flags: {} },
|
|
299
|
+
"\\pi": { glyph: 2142, flags: {} },
|
|
300
|
+
"\\rho": { glyph: 2143, flags: {} },
|
|
301
|
+
"\\sigma": { glyph: 2144, flags: {} },
|
|
302
|
+
"\\tau": { glyph: 2145, flags: {} },
|
|
303
|
+
"\\upsilon": { glyph: 2146, flags: {} },
|
|
304
|
+
"\\varphi": { glyph: 2147, flags: {} },
|
|
305
|
+
"\\chi": { glyph: 2148, flags: {} },
|
|
306
|
+
"\\psi": { glyph: 2149, flags: {} },
|
|
307
|
+
"\\omega": { glyph: 2150, flags: {} },
|
|
308
|
+
"\\epsilon": { glyph: 2184, flags: {} },
|
|
309
|
+
"\\theta": { glyph: 2185, flags: {} },
|
|
310
|
+
"\\phi": { glyph: 2186, flags: {} },
|
|
311
|
+
"\\varsigma": { glyph: 2187, flags: {} },
|
|
312
|
+
"\\Alpha": { glyph: 2027, flags: {} },
|
|
313
|
+
"\\Beta": { glyph: 2028, flags: {} },
|
|
314
|
+
"\\Gamma": { glyph: 2029, flags: {} },
|
|
315
|
+
"\\Delta": { glyph: 2030, flags: {} },
|
|
316
|
+
"\\Epsilon": { glyph: 2031, flags: {} },
|
|
317
|
+
"\\Zeta": { glyph: 2032, flags: {} },
|
|
318
|
+
"\\Eta": { glyph: 2033, flags: {} },
|
|
319
|
+
"\\Theta": { glyph: 2034, flags: {} },
|
|
320
|
+
"\\Iota": { glyph: 2035, flags: {} },
|
|
321
|
+
"\\Kappa": { glyph: 2036, flags: {} },
|
|
322
|
+
"\\Lambda": { glyph: 2037, flags: {} },
|
|
323
|
+
"\\Mu": { glyph: 2038, flags: {} },
|
|
324
|
+
"\\Nu": { glyph: 2039, flags: {} },
|
|
325
|
+
"\\Xi": { glyph: 2040, flags: {} },
|
|
326
|
+
"\\Omicron": { glyph: 2041, flags: {} },
|
|
327
|
+
"\\Pi": { glyph: 2042, flags: {} },
|
|
328
|
+
"\\Rho": { glyph: 2043, flags: {} },
|
|
329
|
+
"\\Sigma": { glyph: 2044, flags: {} },
|
|
330
|
+
"\\Tau": { glyph: 2045, flags: {} },
|
|
331
|
+
"\\Upsilon": { glyph: 2046, flags: {} },
|
|
332
|
+
"\\Phi": { glyph: 2047, flags: {} },
|
|
333
|
+
"\\Chi": { glyph: 2048, flags: {} },
|
|
334
|
+
"\\Psi": { glyph: 2049, flags: {} },
|
|
335
|
+
"\\Omega": { glyph: 2050, flags: {} }
|
|
336
|
+
};
|
|
337
|
+
function asciiMap(x, mode = "math") {
|
|
338
|
+
const c = x.charCodeAt(0);
|
|
339
|
+
if (65 <= c && c <= 90) {
|
|
340
|
+
const d = c - 65;
|
|
341
|
+
if (mode === "text" || mode === "rm") {
|
|
342
|
+
return d + 2001;
|
|
343
|
+
} else if (mode === "tt") {
|
|
344
|
+
return d + 501;
|
|
345
|
+
} else if (mode === "bf" || mode === "bb") {
|
|
346
|
+
return d + 3001;
|
|
347
|
+
} else if (mode === "sf") {
|
|
348
|
+
return d + 2501;
|
|
349
|
+
} else if (mode === "frak") {
|
|
350
|
+
return d + 3301;
|
|
351
|
+
} else if (mode === "scr" || mode === "cal") {
|
|
352
|
+
return d + 2551;
|
|
353
|
+
}
|
|
354
|
+
return d + 2051;
|
|
355
|
+
}
|
|
356
|
+
if (97 <= c && c <= 122) {
|
|
357
|
+
const d = c - 97;
|
|
358
|
+
if (mode === "text" || mode === "rm") {
|
|
359
|
+
return d + 2101;
|
|
360
|
+
} else if (mode === "tt") {
|
|
361
|
+
return d + 601;
|
|
362
|
+
} else if (mode === "bf" || mode === "bb") {
|
|
363
|
+
return d + 3101;
|
|
364
|
+
} else if (mode === "sf") {
|
|
365
|
+
return d + 2601;
|
|
366
|
+
} else if (mode === "frak") {
|
|
367
|
+
return d + 3401;
|
|
368
|
+
} else if (mode === "scr" || mode === "cal") {
|
|
369
|
+
return d + 2651;
|
|
370
|
+
}
|
|
371
|
+
return d + 2151;
|
|
372
|
+
}
|
|
373
|
+
if (48 <= c && c <= 57) {
|
|
374
|
+
const d = c - 48;
|
|
375
|
+
if (mode === "it") {
|
|
376
|
+
return d + 2750;
|
|
377
|
+
} else if (mode === "bf") {
|
|
378
|
+
return d + 3200;
|
|
379
|
+
} else if (mode === "tt") {
|
|
380
|
+
return d + 700;
|
|
381
|
+
}
|
|
382
|
+
return d + 2200;
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
".": 2210,
|
|
386
|
+
",": 2211,
|
|
387
|
+
":": 2212,
|
|
388
|
+
";": 2213,
|
|
389
|
+
"!": 2214,
|
|
390
|
+
"?": 2215,
|
|
391
|
+
"'": 2216,
|
|
392
|
+
'"': 2217,
|
|
393
|
+
"*": 2219,
|
|
394
|
+
"/": 2220,
|
|
395
|
+
"-": 2231,
|
|
396
|
+
"+": 2232,
|
|
397
|
+
"=": 2238,
|
|
398
|
+
"<": 2241,
|
|
399
|
+
">": 2242,
|
|
400
|
+
"~": 2246,
|
|
401
|
+
"@": 2273,
|
|
402
|
+
"\\": 804
|
|
403
|
+
}[x];
|
|
404
|
+
}
|
|
405
|
+
export {
|
|
406
|
+
SYMB,
|
|
407
|
+
asciiMap
|
|
408
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 浏览器专用 op 适配器:大图压缩。
|
|
3
|
+
*
|
|
4
|
+
* 不进入 core/ops 的分发器;编辑器把 `shrinkImage` 作为
|
|
5
|
+
* `ctx.media.prepareImage` 注入。Node 侧(relay/stdio)不 import 本文件。
|
|
6
|
+
*/
|
|
7
|
+
export async function shrinkImage(el) {
|
|
8
|
+
if (typeof document === 'undefined') return el
|
|
9
|
+
const src = String(el.src || '')
|
|
10
|
+
if (!/^data:image\//i.test(src) || src.length < 250000) return el
|
|
11
|
+
try {
|
|
12
|
+
const img = await new Promise((resolve, reject) => {
|
|
13
|
+
const im = new Image()
|
|
14
|
+
im.onload = () => resolve(im)
|
|
15
|
+
im.onerror = reject
|
|
16
|
+
im.src = src
|
|
17
|
+
})
|
|
18
|
+
const maxW = 1600
|
|
19
|
+
const scale = Math.min(1, maxW / (img.width || maxW))
|
|
20
|
+
if (scale >= 1 && src.length < 900000) return el
|
|
21
|
+
const cv = document.createElement('canvas')
|
|
22
|
+
cv.width = Math.max(1, Math.round((img.width || maxW) * scale))
|
|
23
|
+
cv.height = Math.max(1, Math.round((img.height || maxW) * scale))
|
|
24
|
+
cv.getContext('2d').drawImage(img, 0, 0, cv.width, cv.height)
|
|
25
|
+
el.src = cv.toDataURL('image/jpeg', 0.85)
|
|
26
|
+
} catch (e) { /* 压缩失败保留原图 */ }
|
|
27
|
+
return el
|
|
28
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** 图表 op:加图表 / 更新图表数据与样式。数据归一化在 core/chart.js。 */
|
|
2
|
+
import { makeChartElement, normalizeChartData, normalizeChartOptions, CHART_TYPES } from '../chart.js'
|
|
3
|
+
|
|
4
|
+
function clone(P, i) {
|
|
5
|
+
const slide = P.getSlides()[i]
|
|
6
|
+
if (!slide) {
|
|
7
|
+
const total = P.getSlides().length
|
|
8
|
+
throw new Error(`页号越界:第 ${i} 页不存在(共 ${total} 页)`)
|
|
9
|
+
}
|
|
10
|
+
return JSON.parse(JSON.stringify(slide))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** 取幻灯片主题色(可选,图表缺省调色兜底)。 */
|
|
14
|
+
function deckThemeColors(P) {
|
|
15
|
+
try {
|
|
16
|
+
const th = typeof P.getTheme === 'function' ? P.getTheme() : null
|
|
17
|
+
return th && Array.isArray(th.themeColors) ? th.themeColors : undefined
|
|
18
|
+
} catch {
|
|
19
|
+
return undefined
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const chartOps = {
|
|
24
|
+
'add-chart': {
|
|
25
|
+
async run(P, c) {
|
|
26
|
+
const i = Number(c.slide != null ? c.slide : 0)
|
|
27
|
+
const s = clone(P, i)
|
|
28
|
+
const el = makeChartElement(c.element || {}, deckThemeColors(P))
|
|
29
|
+
s.elements.push(el)
|
|
30
|
+
P.updateSlide(i, s)
|
|
31
|
+
return el.id
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
'update-chart': {
|
|
36
|
+
run(P, c) {
|
|
37
|
+
const i = Number(c.slide != null ? c.slide : 0)
|
|
38
|
+
const s = clone(P, i)
|
|
39
|
+
const el = s.elements.find(e => e.id === c.elementId)
|
|
40
|
+
if (!el) throw new Error('update-chart 未命中: ' + c.elementId)
|
|
41
|
+
if (el.type !== 'chart') throw new Error(`元素 ${c.elementId} 不是图表(type=${el.type})`)
|
|
42
|
+
const p = c.props || {}
|
|
43
|
+
if (p.chartType != null) {
|
|
44
|
+
const ct = String(p.chartType)
|
|
45
|
+
if (!CHART_TYPES.includes(ct)) {
|
|
46
|
+
throw new Error(`不支持的 chartType: ${ct}(支持 ${CHART_TYPES.join(' / ')})`)
|
|
47
|
+
}
|
|
48
|
+
el.chartType = ct
|
|
49
|
+
}
|
|
50
|
+
if (p.data != null) el.data = normalizeChartData(p.data, el.chartType)
|
|
51
|
+
if (p.options !== undefined) {
|
|
52
|
+
const options = normalizeChartOptions(p.options)
|
|
53
|
+
if (options) el.options = options
|
|
54
|
+
else delete el.options
|
|
55
|
+
}
|
|
56
|
+
if (Array.isArray(p.colors) && p.colors.length) el.themeColors = p.colors.map(String)
|
|
57
|
+
if (p.textColor != null) el.textColor = String(p.textColor)
|
|
58
|
+
for (const k of ['left', 'top', 'width', 'height', 'rotate']) {
|
|
59
|
+
if (p[k] != null && isFinite(Number(p[k]))) el[k] = Number(p[k])
|
|
60
|
+
}
|
|
61
|
+
P.updateSlide(i, s)
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
}
|
package/core/ops/deck.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** deck 级 op:整副替换 / 标题 / 主题。 */
|
|
2
|
+
export const deckOps = {
|
|
3
|
+
load: {
|
|
4
|
+
run(P, c) { return P.load(c.deck) },
|
|
5
|
+
},
|
|
6
|
+
title: {
|
|
7
|
+
run(P, c) { P.setTitle(String(c.title || '')) },
|
|
8
|
+
},
|
|
9
|
+
theme: {
|
|
10
|
+
run(P, c) {
|
|
11
|
+
const th = P.getTheme() || {}
|
|
12
|
+
Object.assign(th, c.theme || {})
|
|
13
|
+
P.setTheme(th)
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
/* 只压一条服务端历史快照,不改 deck。导入这类“绕过 op 内核”的
|
|
17
|
+
* 编辑器级操作前调用,保证 ppt_history undo 能回到导入前。 */
|
|
18
|
+
snapshot: {
|
|
19
|
+
run() {},
|
|
20
|
+
},
|
|
21
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** 元素 op:加/改/删元素。图片预压缩由编辑器通过 ctx.media.prepareImage 注入。 */
|
|
2
|
+
import { makeElement, patchElement } from '../text.js'
|
|
3
|
+
|
|
4
|
+
function clone(P, i) {
|
|
5
|
+
const slide = P.getSlides()[i]
|
|
6
|
+
if (!slide) {
|
|
7
|
+
const total = P.getSlides().length
|
|
8
|
+
throw new Error(`页号越界:第 ${i} 页不存在(共 ${total} 页)`)
|
|
9
|
+
}
|
|
10
|
+
return JSON.parse(JSON.stringify(slide))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const elementOps = {
|
|
14
|
+
'add-element': {
|
|
15
|
+
async run(P, c, ctx) {
|
|
16
|
+
const i = Number(c.slide != null ? c.slide : 0)
|
|
17
|
+
const s = clone(P, i)
|
|
18
|
+
const el = makeElement(c.element || {})
|
|
19
|
+
/* 完全在画布外的元素自动放回画布内(2026-10-22:曾有图片被放到
|
|
20
|
+
x=1080 / 画布宽 1000,工具报成功但用户看不到) */
|
|
21
|
+
if ((el.left != null && el.left >= 1000) || (el.top != null && el.top >= 563) ||
|
|
22
|
+
(el.left != null && el.width != null && el.left + el.width <= 0)) {
|
|
23
|
+
el.left = Math.max(0, Math.round((1000 - (el.width || 400)) / 2))
|
|
24
|
+
el.top = Math.max(0, Math.round((562.5 - (el.height || 300)) / 2))
|
|
25
|
+
}
|
|
26
|
+
if (el.type === 'image' && ctx.media && typeof ctx.media.prepareImage === 'function') {
|
|
27
|
+
await ctx.media.prepareImage(el)
|
|
28
|
+
}
|
|
29
|
+
s.elements.push(el)
|
|
30
|
+
P.updateSlide(i, s)
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
'set-element': {
|
|
35
|
+
run(P, c) {
|
|
36
|
+
const i = Number(c.slide != null ? c.slide : c.id)
|
|
37
|
+
const s = clone(P, i)
|
|
38
|
+
const el = s.elements.find(e => e.id === c.elementId)
|
|
39
|
+
if (!el) throw new Error('set-element 未命中: ' + c.elementId)
|
|
40
|
+
patchElement(el, c.props || {})
|
|
41
|
+
P.updateSlide(i, s)
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
'remove-element': {
|
|
46
|
+
run(P, c) {
|
|
47
|
+
const i = Number(c.slide != null ? c.slide : 0)
|
|
48
|
+
const s = clone(P, i)
|
|
49
|
+
const n = s.elements.length
|
|
50
|
+
s.elements = s.elements.filter(e => e.id !== c.elementId)
|
|
51
|
+
if (s.elements.length === n) throw new Error('remove-element 未命中: ' + c.elementId)
|
|
52
|
+
P.updateSlide(i, s)
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
}
|