@motion-script/latex 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # @motion-script/latex
2
+
3
+ Animated LaTeX math for [Motion Script](https://motionscript.dev). The `Latex`
4
+ node renders a formula to glyph paths with [MathJax](https://www.mathjax.org)
5
+ and animates between formulas token by token, so equations morph into one another
6
+ instead of cutting.
7
+
8
+ ```tsx
9
+ import { Scene, createRef } from '@motion-script/core';
10
+ import { Latex } from '@motion-script/latex';
11
+
12
+ export class MathScene extends Scene {
13
+ *build() {
14
+ const eq = createRef<Latex>();
15
+
16
+ this.add(
17
+ <Latex
18
+ ref={eq}
19
+ fontSize={64}
20
+ fill="white"
21
+ latex="a^2 + b^2 = c^2"
22
+ />,
23
+ );
24
+
25
+ yield* eq().to({ latex: 'c = \\sqrt{a^2 + b^2}' }, 1.2);
26
+ }
27
+ }
28
+ ```
29
+
30
+ ## What's in here
31
+
32
+ - **`Latex`** node, a `ShapeNode` that draws a formula as fillable, strokable
33
+ glyph paths. Set `latex` to the TeX source and `fontSize` to scale it; `fill`,
34
+ `stroke`, `shadow`, and `padding` work like any other shape.
35
+ - **Formula morphing**, `to({ latex, fontSize }, duration)` interpolates each
36
+ glyph between the current and target formula, matching tokens that persist,
37
+ fading out tokens that leave, and fading in tokens that arrive. The hugging box
38
+ resizes smoothly across the transition.
39
+ - **`buildLatexPath(latex, fontSize)`**, the underlying helper that turns TeX
40
+ into positioned `LatexToken` glyph paths plus intrinsic size and bounds, for
41
+ callers that want the geometry directly.
42
+
43
+ TeX is parsed through MathJax with the `base`, `ams`, `boldsymbol`,
44
+ `newcommand`, `cancel`, `color`, `mhchem`, `physics`, `bbox`, and `mathtools`
45
+ packages enabled. Rendering is synchronous and browser-only.
46
+
47
+ This package builds on [`@motion-script/core`](../../core) (the scene graph and
48
+ animation runtime) and renders through whatever backend draws the scene, such as
49
+ [`@motion-script/web`](../../web).
50
+
51
+ ## Usage
52
+
53
+ ```bash
54
+ npm install @motion-script/latex
55
+ ```
56
+
57
+ For a guided setup, scaffold a project instead with:
58
+
59
+ ```bash
60
+ npm create motion-script@latest
61
+ ```
62
+
63
+ See the [docs](https://motionscript.dev/docs) for the full feature set and API
64
+ reference.
65
+
66
+ ## Development
67
+
68
+ From the monorepo root:
69
+
70
+ ```bash
71
+ pnpm --filter @motion-script/latex build
72
+ pnpm --filter @motion-script/latex test
73
+ ```
@@ -0,0 +1,34 @@
1
+ import '@mathjax/src/js/input/tex/base/BaseConfiguration.js';
2
+ import '@mathjax/src/js/input/tex/ams/AmsConfiguration.js';
3
+ import '@mathjax/src/js/input/tex/boldsymbol/BoldsymbolConfiguration.js';
4
+ import '@mathjax/src/js/input/tex/newcommand/NewcommandConfiguration.js';
5
+ import '@mathjax/src/js/input/tex/cancel/CancelConfiguration.js';
6
+ import '@mathjax/src/js/input/tex/color/ColorConfiguration.js';
7
+ import '@mathjax/src/js/input/tex/mhchem/MhchemConfiguration.js';
8
+ import '@mathjax/src/js/input/tex/physics/PhysicsConfiguration.js';
9
+ import '@mathjax/src/js/input/tex/bbox/BboxConfiguration.js';
10
+ import '@mathjax/src/js/input/tex/mathtools/MathtoolsConfiguration.js';
11
+ import { PathCommand } from '@motion-script/core';
12
+ /** A single rendered glyph or shape with its character key and path commands. */
13
+ export interface LatexToken {
14
+ /** Character this token represents, or a synthetic key for non-glyph shapes. */
15
+ token: string;
16
+ path: PathCommand[];
17
+ }
18
+ export interface LatexPathResult {
19
+ /** All tokens in render order. */
20
+ tokens: LatexToken[];
21
+ /** Flat array of all path commands (for legacy single-path rendering). */
22
+ commands: PathCommand[];
23
+ width: number;
24
+ height: number;
25
+ /**
26
+ * Bounding box over every token, in token coordinate space:
27
+ * [minX, minY, maxX, maxY]. All tokens share this frame, so passing it as
28
+ * each path's center frame keeps their relative layout (instead of each
29
+ * glyph centering on its own bbox).
30
+ */
31
+ bounds: [number, number, number, number];
32
+ }
33
+ export declare function buildLatexPath(text: string, fontSize: number): LatexPathResult;
34
+ //# sourceMappingURL=geometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../src/geometry.ts"],"names":[],"mappings":"AAOA,OAAO,qDAAqD,CAAC;AAC7D,OAAO,mDAAmD,CAAC;AAC3D,OAAO,iEAAiE,CAAC;AACzE,OAAO,iEAAiE,CAAC;AACzE,OAAO,yDAAyD,CAAC;AACjE,OAAO,uDAAuD,CAAC;AAC/D,OAAO,yDAAyD,CAAC;AACjE,OAAO,2DAA2D,CAAC;AACnE,OAAO,qDAAqD,CAAC;AAC7D,OAAO,+DAA+D,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAoBlD,iFAAiF;AACjF,MAAM,WAAW,UAAU;IACvB,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC5B,kCAAkC;IAClC,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,0EAA0E;IAC1E,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,CAc9E"}
@@ -0,0 +1,417 @@
1
+ import { mathjax } from '@mathjax/src/js/mathjax.js';
2
+ import { TeX } from '@mathjax/src/js/input/tex.js';
3
+ import { SVG } from '@mathjax/src/js/output/svg.js';
4
+ import { browserAdaptor } from '@mathjax/src/js/adaptors/browserAdaptor.js';
5
+ import { RegisterHTMLHandler } from '@mathjax/src/js/handlers/html.js';
6
+ import '@mathjax/src/js/input/tex/base/BaseConfiguration.js';
7
+ import '@mathjax/src/js/input/tex/ams/AmsConfiguration.js';
8
+ import '@mathjax/src/js/input/tex/boldsymbol/BoldsymbolConfiguration.js';
9
+ import '@mathjax/src/js/input/tex/newcommand/NewcommandConfiguration.js';
10
+ import '@mathjax/src/js/input/tex/cancel/CancelConfiguration.js';
11
+ import '@mathjax/src/js/input/tex/color/ColorConfiguration.js';
12
+ import '@mathjax/src/js/input/tex/mhchem/MhchemConfiguration.js';
13
+ import '@mathjax/src/js/input/tex/physics/PhysicsConfiguration.js';
14
+ import '@mathjax/src/js/input/tex/bbox/BboxConfiguration.js';
15
+ import '@mathjax/src/js/input/tex/mathtools/MathtoolsConfiguration.js';
16
+ // --- MathJax Setup (synchronous, browser-only) ---
17
+ const adaptor = browserAdaptor();
18
+ RegisterHTMLHandler(adaptor);
19
+ const texJax = new TeX({
20
+ packages: [
21
+ 'base', 'ams', 'boldsymbol', 'newcommand',
22
+ 'cancel', 'color', 'mhchem', 'physics',
23
+ 'bbox', 'mathtools',
24
+ ],
25
+ });
26
+ const svgJax = new SVG({ fontCache: 'local' });
27
+ const mjDoc = mathjax.document('', { InputJax: texJax, OutputJax: svgJax });
28
+ export function buildLatexPath(text, fontSize) {
29
+ const node = mjDoc.convert(text, {
30
+ display: true,
31
+ em: 16,
32
+ ex: 8,
33
+ containerWidth: 80 * 16,
34
+ });
35
+ const svgEl = adaptor.firstChild(node);
36
+ const heightAttr = adaptor.getAttribute(svgEl, 'height') ?? '';
37
+ const heightEx = parseFloat(heightAttr) || 0;
38
+ const svgString = adaptor.innerHTML(node);
39
+ return fastBuildLatex(svgString, fontSize, heightEx);
40
+ }
41
+ const identityMatrix = [1, 0, 0, 1, 0, 0];
42
+ function multiplyMatrix(m1, m2) {
43
+ return [
44
+ m1[0] * m2[0] + m1[2] * m2[1],
45
+ m1[1] * m2[0] + m1[3] * m2[1],
46
+ m1[0] * m2[2] + m1[2] * m2[3],
47
+ m1[1] * m2[2] + m1[3] * m2[3],
48
+ m1[0] * m2[4] + m1[2] * m2[5] + m1[4],
49
+ m1[1] * m2[4] + m1[3] * m2[5] + m1[5],
50
+ ];
51
+ }
52
+ function parseTransform(str) {
53
+ if (!str)
54
+ return identityMatrix;
55
+ let m = [...identityMatrix];
56
+ const re = /([a-z]+)\(([^)]+)\)/g;
57
+ let match;
58
+ while ((match = re.exec(str)) !== null) {
59
+ const type = match[1];
60
+ const args = match[2].split(/[ ,]+/).map(parseFloat);
61
+ if (type === 'translate') {
62
+ m = multiplyMatrix(m, [1, 0, 0, 1, args[0] || 0, args[1] || 0]);
63
+ }
64
+ else if (type === 'scale') {
65
+ const sx = args[0] || 1;
66
+ const sy = args[1] !== undefined ? args[1] : sx;
67
+ m = multiplyMatrix(m, [sx, 0, 0, sy, 0, 0]);
68
+ }
69
+ else if (type === 'matrix') {
70
+ m = multiplyMatrix(m, [args[0], args[1], args[2], args[3], args[4], args[5]]);
71
+ }
72
+ }
73
+ return m;
74
+ }
75
+ function applyMatrix(x, y, m) {
76
+ return [
77
+ x * m[0] + y * m[2] + m[4],
78
+ x * m[1] + y * m[3] + m[5],
79
+ ];
80
+ }
81
+ // --- Glyph ID → character decoding ---
82
+ /**
83
+ * MathJax SVG glyph IDs look like "MJX-1-TEX-N-78" or "MJX-1-TEX-I-1D465".
84
+ * The last segment is the Unicode codepoint in hex.
85
+ */
86
+ function glyphIdToChar(id) {
87
+ const parts = id.split('-');
88
+ const hex = parts[parts.length - 1];
89
+ const cp = parseInt(hex, 16);
90
+ if (!isNaN(cp)) {
91
+ try {
92
+ return String.fromCodePoint(cp);
93
+ }
94
+ catch { /* fall through */ }
95
+ }
96
+ return id;
97
+ }
98
+ function fastBuildLatex(svgString, fontSize, heightEx) {
99
+ const parser = new DOMParser();
100
+ const doc = parser.parseFromString(svgString, "image/svg+xml");
101
+ // Pre-parse the glyph dictionary from <defs>
102
+ const glyphMap = new Map();
103
+ const defs = doc.getElementsByTagName("path");
104
+ for (let i = 0; i < defs.length; i++) {
105
+ const id = defs[i].getAttribute("id");
106
+ const d = defs[i].getAttribute("d");
107
+ if (id && d) {
108
+ glyphMap.set(`#${id}`, expandToAbsolute(tokenisePath(d)));
109
+ }
110
+ }
111
+ // Collect raw tokens — each <use> is one token, rects/paths are grouped as synthetic tokens
112
+ const rawTokens = [];
113
+ let synthIdx = 0;
114
+ function pushCmds(token, cmds) {
115
+ rawTokens.push({ token, cmds });
116
+ }
117
+ function traverse(node, currentMatrix) {
118
+ let nodeMatrix = currentMatrix;
119
+ const transformStr = node.getAttribute("transform");
120
+ if (transformStr) {
121
+ nodeMatrix = multiplyMatrix(nodeMatrix, parseTransform(transformStr));
122
+ }
123
+ const nodeName = node.nodeName.toLowerCase();
124
+ if (nodeName === "use") {
125
+ const href = node.getAttribute("href") || node.getAttribute("xlink:href");
126
+ const x = parseFloat(node.getAttribute("x") || "0");
127
+ const y = parseFloat(node.getAttribute("y") || "0");
128
+ if (href && glyphMap.has(href)) {
129
+ const glyphCommands = glyphMap.get(href);
130
+ const cmds = [];
131
+ for (const gc of glyphCommands) {
132
+ const shiftedArgs = [...gc.args];
133
+ for (let j = 0; j < shiftedArgs.length; j += 2) {
134
+ const [nx, ny] = applyMatrix(shiftedArgs[j] + x, shiftedArgs[j + 1] + y, nodeMatrix);
135
+ shiftedArgs[j] = nx;
136
+ shiftedArgs[j + 1] = ny;
137
+ }
138
+ cmds.push({ cmd: gc.cmd, args: shiftedArgs });
139
+ }
140
+ // Derive character from glyph ID
141
+ const rawId = href.startsWith('#') ? href.slice(1) : href;
142
+ pushCmds(glyphIdToChar(rawId), cmds);
143
+ }
144
+ }
145
+ else if (nodeName === "rect") {
146
+ const x = parseFloat(node.getAttribute("x") || "0");
147
+ const y = parseFloat(node.getAttribute("y") || "0");
148
+ const w = parseFloat(node.getAttribute("width") || "0");
149
+ const h = parseFloat(node.getAttribute("height") || "0");
150
+ if (w > 0 && h > 0) {
151
+ const pts = [[x, y], [x + w, y], [x + w, y + h], [x, y + h]];
152
+ const tp = pts.map(p => applyMatrix(p[0], p[1], nodeMatrix));
153
+ pushCmds(`__rect_${synthIdx++}`, [
154
+ { cmd: 'M', args: [tp[0][0], tp[0][1]] },
155
+ { cmd: 'L', args: [tp[1][0], tp[1][1]] },
156
+ { cmd: 'L', args: [tp[2][0], tp[2][1]] },
157
+ { cmd: 'L', args: [tp[3][0], tp[3][1]] },
158
+ { cmd: 'Z', args: [] },
159
+ ]);
160
+ }
161
+ }
162
+ else if (nodeName === "path" && node.parentNode?.nodeName.toLowerCase() !== "defs") {
163
+ const d = node.getAttribute("d");
164
+ if (d) {
165
+ const abs = expandToAbsolute(tokenisePath(d));
166
+ const cmds = [];
167
+ for (const gc of abs) {
168
+ const shiftedArgs = [...gc.args];
169
+ for (let j = 0; j < shiftedArgs.length; j += 2) {
170
+ const [nx, ny] = applyMatrix(shiftedArgs[j], shiftedArgs[j + 1], nodeMatrix);
171
+ shiftedArgs[j] = nx;
172
+ shiftedArgs[j + 1] = ny;
173
+ }
174
+ cmds.push({ cmd: gc.cmd, args: shiftedArgs });
175
+ }
176
+ pushCmds(`__path_${synthIdx++}`, cmds);
177
+ }
178
+ }
179
+ for (let i = 0; i < node.childNodes.length; i++) {
180
+ const child = node.childNodes[i];
181
+ if (child.nodeType === 1 && child.nodeName.toLowerCase() !== "defs") {
182
+ traverse(child, nodeMatrix);
183
+ }
184
+ }
185
+ }
186
+ const svg = doc.getElementsByTagName("svg")[0];
187
+ if (svg)
188
+ traverse(svg, identityMatrix);
189
+ if (rawTokens.length === 0)
190
+ return { tokens: [], commands: [], width: 0, height: 0, bounds: [0, 0, 0, 0] };
191
+ // Compute bounding box across all raw commands
192
+ const allAbs = rawTokens.flatMap(t => t.cmds);
193
+ const { minX, minY, maxX, maxY } = svgBBox(allAbs);
194
+ const svgW = maxX - minX;
195
+ const svgH = maxY - minY;
196
+ let scale;
197
+ if (heightEx > 0 && svgH > 0) {
198
+ const exInCoords = svgH / heightEx;
199
+ scale = fontSize / (2 * exInCoords);
200
+ }
201
+ else {
202
+ scale = svgH > 0 ? fontSize / svgH : 1;
203
+ }
204
+ const ocx = (minX + maxX) / 2;
205
+ const ocy = (minY + maxY) / 2;
206
+ const tx = (svgX) => (svgX - ocx) * scale;
207
+ const ty = (svgY) => (svgY - ocy) * scale;
208
+ function rawCmdsToPathCommands(cmds) {
209
+ const out = [];
210
+ for (const { cmd, args: a } of cmds) {
211
+ switch (cmd) {
212
+ case 'M':
213
+ out.push({ type: 'M', x: tx(a[0]), y: ty(a[1]) });
214
+ break;
215
+ case 'L':
216
+ out.push({ type: 'L', x: tx(a[0]), y: ty(a[1]) });
217
+ break;
218
+ case 'Q':
219
+ out.push({ type: 'Q', x1: tx(a[0]), y1: ty(a[1]), x: tx(a[2]), y: ty(a[3]) });
220
+ break;
221
+ case 'C':
222
+ out.push({ type: 'C', x1: tx(a[0]), y1: ty(a[1]), x2: tx(a[2]), y2: ty(a[3]), x: tx(a[4]), y: ty(a[5]) });
223
+ break;
224
+ case 'Z':
225
+ out.push({ type: 'Z' });
226
+ break;
227
+ }
228
+ }
229
+ return out;
230
+ }
231
+ const tokens = rawTokens.map(rt => ({
232
+ token: rt.token,
233
+ path: rawCmdsToPathCommands(rt.cmds),
234
+ }));
235
+ const commands = tokens.flatMap(t => t.path);
236
+ // Shared center frame for all tokens, in token coordinate space. tx/ty map
237
+ // the SVG bbox corners; this is the frame every token's path is laid out in.
238
+ const bounds = [
239
+ tx(minX), ty(minY), tx(maxX), ty(maxY),
240
+ ];
241
+ return { tokens, commands, width: svgW * scale, height: svgH * scale, bounds };
242
+ }
243
+ function tokenisePath(d) {
244
+ const re = /([MmLlHhVvCcSsQqTtAaZz])|([+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)/g;
245
+ const out = [];
246
+ let cur = null;
247
+ let m;
248
+ while ((m = re.exec(d)) !== null) {
249
+ if (m[1]) {
250
+ cur = { cmd: m[1], args: [] };
251
+ out.push(cur);
252
+ }
253
+ else if (cur)
254
+ cur.args.push(parseFloat(m[2]));
255
+ }
256
+ return out;
257
+ }
258
+ function argCount(cmd) {
259
+ switch (cmd.toUpperCase()) {
260
+ case 'M': return 2;
261
+ case 'L': return 2;
262
+ case 'H': return 1;
263
+ case 'V': return 1;
264
+ case 'C': return 6;
265
+ case 'S': return 4;
266
+ case 'Q': return 4;
267
+ case 'T': return 2;
268
+ case 'A': return 7;
269
+ case 'Z': return 0;
270
+ default: return 0;
271
+ }
272
+ }
273
+ function expandToAbsolute(raw) {
274
+ const out = [];
275
+ let cx = 0, cy = 0;
276
+ let mx = 0, my = 0;
277
+ let prevCmd = '';
278
+ let prevCtrl = { x: 0, y: 0 };
279
+ for (const { cmd, args } of raw) {
280
+ const up = cmd.toUpperCase();
281
+ const rel = cmd === cmd.toLowerCase() && up !== 'Z';
282
+ const n = argCount(up);
283
+ const reps = n === 0 ? 1 : Math.max(1, Math.ceil(args.length / n));
284
+ for (let r = 0; r < reps; r++) {
285
+ const a = args.slice(r * n, r * n + n);
286
+ const absX = (i) => rel ? a[i] + cx : a[i];
287
+ const absY = (i) => rel ? a[i] + cy : a[i];
288
+ switch (up) {
289
+ case 'M': {
290
+ const x = absX(0), y = absY(1);
291
+ const emitCmd = r === 0 ? 'M' : 'L';
292
+ out.push({ cmd: emitCmd, args: [x, y] });
293
+ cx = x;
294
+ cy = y;
295
+ if (r === 0) {
296
+ mx = x;
297
+ my = y;
298
+ }
299
+ prevCmd = emitCmd;
300
+ prevCtrl = { x: cx, y: cy };
301
+ break;
302
+ }
303
+ case 'Z':
304
+ out.push({ cmd: 'Z', args: [] });
305
+ cx = mx;
306
+ cy = my;
307
+ prevCmd = 'Z';
308
+ break;
309
+ case 'L': {
310
+ const x = absX(0), y = absY(1);
311
+ out.push({ cmd: 'L', args: [x, y] });
312
+ cx = x;
313
+ cy = y;
314
+ prevCmd = 'L';
315
+ prevCtrl = { x: cx, y: cy };
316
+ break;
317
+ }
318
+ case 'H': {
319
+ const x = rel ? a[0] + cx : a[0];
320
+ out.push({ cmd: 'L', args: [x, cy] });
321
+ cx = x;
322
+ prevCmd = 'L';
323
+ prevCtrl = { x: cx, y: cy };
324
+ break;
325
+ }
326
+ case 'V': {
327
+ const y = rel ? a[0] + cy : a[0];
328
+ out.push({ cmd: 'L', args: [cx, y] });
329
+ cy = y;
330
+ prevCmd = 'L';
331
+ prevCtrl = { x: cx, y: cy };
332
+ break;
333
+ }
334
+ case 'C': {
335
+ const x1 = absX(0), y1 = absY(1);
336
+ const x2 = absX(2), y2 = absY(3);
337
+ const x = absX(4), y = absY(5);
338
+ out.push({ cmd: 'C', args: [x1, y1, x2, y2, x, y] });
339
+ prevCtrl = { x: x2, y: y2 };
340
+ cx = x;
341
+ cy = y;
342
+ prevCmd = 'C';
343
+ break;
344
+ }
345
+ case 'S': {
346
+ const x1 = prevCmd === 'C' || prevCmd === 'S' ? 2 * cx - prevCtrl.x : cx;
347
+ const y1 = prevCmd === 'C' || prevCmd === 'S' ? 2 * cy - prevCtrl.y : cy;
348
+ const x2 = absX(0), y2 = absY(1);
349
+ const x = absX(2), y = absY(3);
350
+ out.push({ cmd: 'C', args: [x1, y1, x2, y2, x, y] });
351
+ prevCtrl = { x: x2, y: y2 };
352
+ cx = x;
353
+ cy = y;
354
+ prevCmd = 'S';
355
+ break;
356
+ }
357
+ case 'Q': {
358
+ const x1 = absX(0), y1 = absY(1);
359
+ const x = absX(2), y = absY(3);
360
+ out.push({ cmd: 'Q', args: [x1, y1, x, y] });
361
+ prevCtrl = { x: x1, y: y1 };
362
+ cx = x;
363
+ cy = y;
364
+ prevCmd = 'Q';
365
+ break;
366
+ }
367
+ case 'T': {
368
+ const x1 = prevCmd === 'Q' || prevCmd === 'T' ? 2 * cx - prevCtrl.x : cx;
369
+ const y1 = prevCmd === 'Q' || prevCmd === 'T' ? 2 * cy - prevCtrl.y : cy;
370
+ const x = absX(0), y = absY(1);
371
+ out.push({ cmd: 'Q', args: [x1, y1, x, y] });
372
+ prevCtrl = { x: x1, y: y1 };
373
+ cx = x;
374
+ cy = y;
375
+ prevCmd = 'T';
376
+ break;
377
+ }
378
+ }
379
+ }
380
+ }
381
+ if (out.length > 0 && out[out.length - 1].cmd !== 'Z') {
382
+ out.push({ cmd: 'Z', args: [] });
383
+ }
384
+ return out;
385
+ }
386
+ function svgBBox(abs) {
387
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
388
+ const touch = (x, y) => {
389
+ if (x < minX)
390
+ minX = x;
391
+ if (x > maxX)
392
+ maxX = x;
393
+ if (y < minY)
394
+ minY = y;
395
+ if (y > maxY)
396
+ maxY = y;
397
+ };
398
+ for (const { cmd, args } of abs) {
399
+ switch (cmd) {
400
+ case 'M':
401
+ case 'L':
402
+ touch(args[0], args[1]);
403
+ break;
404
+ case 'C':
405
+ touch(args[0], args[1]);
406
+ touch(args[2], args[3]);
407
+ touch(args[4], args[5]);
408
+ break;
409
+ case 'Q':
410
+ touch(args[0], args[1]);
411
+ touch(args[2], args[3]);
412
+ break;
413
+ }
414
+ }
415
+ return { minX, minY, maxX, maxY };
416
+ }
417
+ //# sourceMappingURL=geometry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry.js","sourceRoot":"","sources":["../src/geometry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { Latex } from './node';
2
+ export * from './geometry';
3
+ export { LatexProps } from './props';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { Latex } from './node';
2
+ export * from './geometry';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,cAAc,YAAY,CAAC"}
package/dist/node.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ import { RenderContext, EaseFunction, FrameGenerator, NodeConfig, ShapeNode, Size2D, SizeConstraints, PaddingResolved, AnimationBuilder } from "@motion-script/core";
2
+ import { LatexProps } from "./props";
3
+ export declare class Latex extends ShapeNode<LatexProps> {
4
+ getType(): string;
5
+ getName(): string;
6
+ readonly latex: string;
7
+ readonly fontSize: number;
8
+ readonly padding: PaddingResolved;
9
+ private _intrinsicWidth;
10
+ private _intrinsicHeight;
11
+ /**
12
+ * Shared center frame for all current tokens, [minX, minY, maxX, maxY] in
13
+ * token space. Passed to every per-token path so glyphs keep their relative
14
+ * layout instead of each centering on its own bbox.
15
+ */
16
+ private _bounds;
17
+ /** Current tokens to render. Each has its own opacity for tween transitions. */
18
+ private _tokens;
19
+ /** Suppresses reactive retokenization while a custom to() is driving frames. */
20
+ private _animating;
21
+ constructor(props: NodeConfig<Latex, LatexProps>);
22
+ private _updateTokens;
23
+ measure(constraints: SizeConstraints): Partial<Size2D>;
24
+ to(to: Partial<LatexProps>, duration: number, easing?: EaseFunction): AnimationBuilder<LatexProps>;
25
+ _toGen(to: Partial<LatexProps>, duration: number, easing?: EaseFunction): FrameGenerator;
26
+ protected renderSelf(ctx: RenderContext): void;
27
+ }
28
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAyB,UAAU,EAAY,SAAS,EAAE,MAAM,EAAE,eAAe,EAAuB,eAAe,EAAyD,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAElR,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAIrC,qBAAa,KAAM,SAAQ,SAAS,CAAC,UAAU,CAAC;IAC5C,OAAO,IAAI,MAAM;IACjB,OAAO,IAAI,MAAM;IAEjB,SAA4C,KAAK,EAAE,MAAM,CAAC;IAC1D,SAA4C,QAAQ,EAAE,MAAM,CAAC;IAC7D,SAAyF,OAAO,EAAE,eAAe,CAAC;IAElH,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,gBAAgB,CAAa;IAErC;;;;OAIG;IACH,OAAO,CAAC,OAAO,CAAkD;IAEjE,gFAAgF;IAChF,OAAO,CAAC,OAAO,CAAuB;IAEtC,gFAAgF;IAChF,OAAO,CAAC,UAAU,CAAkB;gBAExB,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC;IAahD,OAAO,CAAC,aAAa;IAsBZ,OAAO,CAAC,WAAW,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAoBtD,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,gBAAgB,CAAC,UAAU,CAAC;IAIjG,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,cAAc;IAmElG,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;CAyBjD"}
package/dist/node.js ADDED
@@ -0,0 +1,187 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { getSignal, lerpNumber, parallel, ShapeNode, toPathString, tween, property, resolvePadding, lerpEdgeInset, AnimationBuilder } from "@motion-script/core";
8
+ import { buildLatexPath } from "./geometry";
9
+ import { tweenLatex } from "./tween";
10
+ export class Latex extends ShapeNode {
11
+ getType() { return "latex"; }
12
+ getName() { return "Latex"; }
13
+ _intrinsicWidth = 0;
14
+ _intrinsicHeight = 0;
15
+ /**
16
+ * Shared center frame for all current tokens, [minX, minY, maxX, maxY] in
17
+ * token space. Passed to every per-token path so glyphs keep their relative
18
+ * layout instead of each centering on its own bbox.
19
+ */
20
+ _bounds = [0, 0, 0, 0];
21
+ /** Current tokens to render. Each has its own opacity for tween transitions. */
22
+ _tokens = [];
23
+ /** Suppresses reactive retokenization while a custom to() is driving frames. */
24
+ _animating = false;
25
+ constructor(props) {
26
+ super(props);
27
+ this.applyProp("width", props.width ?? "hug");
28
+ this.applyProp("height", props.height ?? "hug");
29
+ // Re-tokenize whenever latex or fontSize changes (including reactive
30
+ // bindings from upstream signals).
31
+ getSignal(this, "latex").subscribe(() => this._updateTokens());
32
+ getSignal(this, "fontSize").subscribe(() => this._updateTokens());
33
+ this._updateTokens();
34
+ }
35
+ _updateTokens() {
36
+ if (this._animating)
37
+ return;
38
+ if (this.latex) {
39
+ const result = buildLatexPath(this.latex, this.fontSize);
40
+ this._intrinsicWidth = result.width;
41
+ this._intrinsicHeight = result.height;
42
+ this._bounds = result.bounds;
43
+ this._tokens = result.tokens.map(t => ({
44
+ token: t.token,
45
+ path: t.path,
46
+ opacity: 1,
47
+ x: 0,
48
+ y: 0,
49
+ }));
50
+ }
51
+ else {
52
+ this._tokens = [];
53
+ this._intrinsicWidth = 0;
54
+ this._intrinsicHeight = 0;
55
+ this._bounds = [0, 0, 0, 0];
56
+ }
57
+ }
58
+ measure(constraints) {
59
+ const pad = this.padding;
60
+ const wm = this.width;
61
+ const hm = this.height;
62
+ const resolvedW = typeof wm === "number"
63
+ ? wm
64
+ : wm === "hug"
65
+ ? this._intrinsicWidth + pad.left + pad.right
66
+ : constraints.maxWidth ?? 0;
67
+ const resolvedH = typeof hm === "number"
68
+ ? hm
69
+ : hm === "hug"
70
+ ? this._intrinsicHeight + pad.top + pad.bottom
71
+ : constraints.maxHeight ?? 0;
72
+ return { width: resolvedW, height: resolvedH };
73
+ }
74
+ to(to, duration, easing) {
75
+ return new AnimationBuilder(this, { to, duration, easing });
76
+ }
77
+ *_toGen(to, duration, easing) {
78
+ const fromTokens = this._tokens.map(t => ({ token: t.token, path: t.path }));
79
+ const fromFontSize = this.fontSize;
80
+ const toFontSize = to.fontSize !== undefined ? to.fontSize : this.fontSize;
81
+ const toLatex = to.latex !== undefined ? to.latex : this.latex;
82
+ // Snapshot the from-frame so intrinsic size and the shared center frame
83
+ // can interpolate toward the new formula instead of snapping at the end.
84
+ const fromWidth = this._intrinsicWidth;
85
+ const fromHeight = this._intrinsicHeight;
86
+ const fromBounds = this._bounds;
87
+ const toResult = buildLatexPath(toLatex, toFontSize);
88
+ const toTokens = toResult.tokens;
89
+ const toBounds = toResult.bounds;
90
+ // Drive token interpolation directly; suppress the latex/fontSize
91
+ // subscribers so they don't retokenize each frame.
92
+ this._animating = true;
93
+ try {
94
+ yield* parallel(super._toGen(to, duration, easing), tween(duration, (rawT) => {
95
+ const t = easing ? easing(rawT) : rawT;
96
+ this.set({ fontSize: lerpNumber(fromFontSize, toFontSize, t) });
97
+ // Track the measured size so a hugging box grows/shrinks
98
+ // smoothly across the morph rather than jumping when the
99
+ // final state is committed below.
100
+ this._intrinsicWidth = lerpNumber(fromWidth, toResult.width, t);
101
+ this._intrinsicHeight = lerpNumber(fromHeight, toResult.height, t);
102
+ // Interpolate the shared center frame in lockstep so glyphs
103
+ // stay centered within the resizing box.
104
+ this._bounds = [
105
+ lerpNumber(fromBounds[0], toBounds[0], t),
106
+ lerpNumber(fromBounds[1], toBounds[1], t),
107
+ lerpNumber(fromBounds[2], toBounds[2], t),
108
+ lerpNumber(fromBounds[3], toBounds[3], t),
109
+ ];
110
+ }), tweenLatex(fromTokens, toTokens, duration, (animTokens) => {
111
+ this._tokens = animTokens;
112
+ }, easing));
113
+ }
114
+ finally {
115
+ this._animating = false;
116
+ }
117
+ // Commit final state so subsequent to() calls start from a clean baseline.
118
+ this.set({ latex: toLatex, fontSize: toFontSize });
119
+ this._tokens = toResult.tokens.map(t => ({
120
+ token: t.token,
121
+ path: t.path,
122
+ opacity: 1,
123
+ x: 0,
124
+ y: 0,
125
+ }));
126
+ this._intrinsicWidth = toResult.width;
127
+ this._intrinsicHeight = toResult.height;
128
+ this._bounds = toResult.bounds;
129
+ }
130
+ renderSelf(ctx) {
131
+ for (const token of this._tokens) {
132
+ if (token.opacity <= 0)
133
+ continue;
134
+ // Scale each token's fill opacity by the token's animated opacity
135
+ const scaledFill = scaleFillopacity(this.fill, token.opacity);
136
+ // Translate the path by token's interpolated position offset
137
+ const pathStr = token.x !== 0 || token.y !== 0
138
+ ? toPathString(offsetPath(token.path, token.x, token.y))
139
+ : toPathString(token.path);
140
+ ctx.path({
141
+ d: pathStr,
142
+ start: this.start,
143
+ end: this.end,
144
+ // All tokens share one center frame so they keep their relative
145
+ // layout — without this each glyph centers on its own bbox and
146
+ // they all stack on the origin.
147
+ centerBounds: this._bounds,
148
+ })
149
+ .fill(scaledFill)
150
+ .stroke(this.stroke).shadow(this.shadow);
151
+ }
152
+ }
153
+ }
154
+ __decorate([
155
+ property({ default: "" })
156
+ ], Latex.prototype, "latex", void 0);
157
+ __decorate([
158
+ property({ default: 16 })
159
+ ], Latex.prototype, "fontSize", void 0);
160
+ __decorate([
161
+ property({ default: 0, mapper: resolvePadding, tween: lerpEdgeInset })
162
+ ], Latex.prototype, "padding", void 0);
163
+ function scaleFillopacity(fills, opacity) {
164
+ if (opacity >= 1)
165
+ return fills;
166
+ return fills.map(f => ({ ...f, opacity: (f.opacity ?? 1) * opacity }));
167
+ }
168
+ function offsetPath(path, dx, dy) {
169
+ return path.map(cmd => {
170
+ const c = cmd;
171
+ const shifted = { ...c };
172
+ if ("x" in c)
173
+ shifted.x = c.x + dx;
174
+ if ("y" in c)
175
+ shifted.y = c.y + dy;
176
+ if ("x1" in c) {
177
+ shifted.x1 = c.x1 + dx;
178
+ shifted.y1 = c.y1 + dy;
179
+ }
180
+ if ("x2" in c) {
181
+ shifted.x2 = c.x2 + dx;
182
+ shifted.y2 = c.y2 + dy;
183
+ }
184
+ return shifted;
185
+ });
186
+ }
187
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { PaddingProps, ShapeProps } from "@motion-script/core";
2
+ export interface LatexProps extends ShapeProps {
3
+ latex: string;
4
+ fontSize: number;
5
+ padding: PaddingProps;
6
+ }
7
+ //# sourceMappingURL=props.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../src/props.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,YAAY,CAAC;CACzB"}
package/dist/props.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=props.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"props.js","sourceRoot":"","sources":["../src/props.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import { EaseFunction, FrameGenerator } from "@motion-script/core";
2
+ import { LatexToken } from "./geometry";
3
+ export interface AnimatedToken {
4
+ token: string;
5
+ path: LatexToken["path"];
6
+ /** 0 = invisible, 1 = fully visible */
7
+ opacity: number;
8
+ /** Interpolated position offset applied during morph (x, y in formula space). */
9
+ x: number;
10
+ y: number;
11
+ }
12
+ /**
13
+ * Generator that animates a formula change by:
14
+ * - Fading out deleted tokens in the first half of the duration.
15
+ * - Moving matched tokens across the full duration.
16
+ * - Fading in added tokens in the second half of the duration.
17
+ *
18
+ * `onFrame` is called each frame with the current list of AnimatedTokens to render.
19
+ */
20
+ export declare function tweenLatex(from: LatexToken[], to: LatexToken[], duration: number, onFrame: (tokens: AnimatedToken[]) => void, easing?: EaseFunction): FrameGenerator;
21
+ //# sourceMappingURL=tween.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tween.d.ts","sourceRoot":"","sources":["../src/tween.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAqB,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IACzB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACb;AAsDD;;;;;;;GAOG;AACH,wBAAiB,UAAU,CACvB,IAAI,EAAE,UAAU,EAAE,EAClB,EAAE,EAAE,UAAU,EAAE,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,IAAI,EAC1C,MAAM,CAAC,EAAE,YAAY,GACtB,cAAc,CAwDhB"}
package/dist/tween.js ADDED
@@ -0,0 +1,101 @@
1
+ import { lerpNumber, tween } from "@motion-script/core";
2
+ /**
3
+ * Compute the centroid of a token's path for position-based interpolation.
4
+ */
5
+ function centroid(path) {
6
+ let sx = 0, sy = 0, n = 0;
7
+ for (const cmd of path) {
8
+ if ("x" in cmd && "y" in cmd) {
9
+ sx += cmd.x;
10
+ sy += cmd.y;
11
+ n++;
12
+ }
13
+ }
14
+ return n > 0 ? { x: sx / n, y: sy / n } : { x: 0, y: 0 };
15
+ }
16
+ /**
17
+ * Greedily match tokens from `from` to `to` by character key.
18
+ * Returns three lists: matched pairs, deleted tokens (only in from), added tokens (only in to).
19
+ */
20
+ function matchTokens(from, to) {
21
+ const remaining = [...to];
22
+ const matched = [];
23
+ const deleted = [];
24
+ for (const ft of from) {
25
+ // Skip synthetic shapes (rects/paths) — they don't have a natural token key
26
+ if (ft.token.startsWith('__')) {
27
+ deleted.push(ft);
28
+ continue;
29
+ }
30
+ const idx = remaining.findIndex(t => t.token === ft.token && !t.token.startsWith('__'));
31
+ if (idx !== -1) {
32
+ matched.push({ from: ft, to: remaining[idx] });
33
+ remaining.splice(idx, 1);
34
+ }
35
+ else {
36
+ deleted.push(ft);
37
+ }
38
+ }
39
+ // Remaining to-tokens that weren't matched
40
+ const added = remaining;
41
+ return { matched, deleted, added };
42
+ }
43
+ /**
44
+ * Generator that animates a formula change by:
45
+ * - Fading out deleted tokens in the first half of the duration.
46
+ * - Moving matched tokens across the full duration.
47
+ * - Fading in added tokens in the second half of the duration.
48
+ *
49
+ * `onFrame` is called each frame with the current list of AnimatedTokens to render.
50
+ */
51
+ export function* tweenLatex(from, to, duration, onFrame, easing) {
52
+ const { matched, deleted, added } = matchTokens(from, to);
53
+ // Pre-compute centroids for position lerp
54
+ const matchedData = matched.map(({ from: f, to: t }) => ({
55
+ fromPath: f.path,
56
+ toPath: t.path,
57
+ token: t.token,
58
+ fromCenter: centroid(f.path),
59
+ toCenter: centroid(t.path),
60
+ }));
61
+ yield* tween(duration, (rawT) => {
62
+ const t = easing ? easing(rawT) : rawT;
63
+ const tokens = [];
64
+ // Matched tokens: slide across full duration
65
+ for (const m of matchedData) {
66
+ const dx = lerpNumber(m.fromCenter.x, m.toCenter.x, t);
67
+ const dy = lerpNumber(m.fromCenter.y, m.toCenter.y, t);
68
+ tokens.push({
69
+ token: m.token,
70
+ path: m.toPath,
71
+ opacity: 1,
72
+ x: dx - m.toCenter.x,
73
+ y: dy - m.toCenter.y,
74
+ });
75
+ }
76
+ // Deleted tokens: fade out over the first half, gone by t=0.5
77
+ for (const d of deleted) {
78
+ const fadeT = Math.min(t * 2, 1);
79
+ tokens.push({
80
+ token: d.token,
81
+ path: d.path,
82
+ opacity: lerpNumber(1, 0, fadeT),
83
+ x: 0,
84
+ y: 0,
85
+ });
86
+ }
87
+ // Added tokens: fade in over the second half, starting at t=0.5
88
+ for (const a of added) {
89
+ const fadeT = Math.max(t * 2 - 1, 0);
90
+ tokens.push({
91
+ token: a.token,
92
+ path: a.path,
93
+ opacity: lerpNumber(0, 1, fadeT),
94
+ x: 0,
95
+ y: 0,
96
+ });
97
+ }
98
+ onFrame(tokens);
99
+ });
100
+ }
101
+ //# sourceMappingURL=tween.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tween.js","sourceRoot":"","sources":["../src/tween.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@motion-script/latex",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Animated LaTeX math for Motion Script, rendering formulas to glyph paths via MathJax and morphing them token by token.",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "sideEffects": false,
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/index.js"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "build": "tsc -b && tsc-alias",
20
+ "dev": "tsc -b --watch & tsc-alias -w",
21
+ "clean": "rimraf dist .turbo && tsc -b --clean",
22
+ "test": "vitest",
23
+ "typecheck": "tsc --noEmit"
24
+ },
25
+ "keywords": [
26
+ "motion-script",
27
+ "motion script",
28
+ "latex",
29
+ "math",
30
+ "animation"
31
+ ],
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
35
+ "license": "Apache-2.0",
36
+ "peerDependencies": {
37
+ "@motion-script/core": "workspace:*"
38
+ },
39
+ "dependencies": {
40
+ "@mathjax/src": "^4.1.1"
41
+ },
42
+ "devDependencies": {
43
+ "@motion-script/core": "workspace:*",
44
+ "@types/node": "catalog:",
45
+ "tsc-alias": "catalog:",
46
+ "typescript": "catalog:",
47
+ "vitest": "catalog:"
48
+ }
49
+ }