@pixerate/editor 0.133.0 → 0.134.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.
Files changed (61) hide show
  1. package/dist/animation-editor/index.cjs +55 -55
  2. package/dist/animation-editor/index.d.cts +4 -4
  3. package/dist/animation-editor/index.d.ts +4 -4
  4. package/dist/animation-editor/index.js +2 -2
  5. package/dist/{bezier-DL2wPsFf.d.cts → bezier-J8i4uqSH.d.cts} +1 -1
  6. package/dist/{bezier-BAGdL89w.d.ts → bezier-lNEOp0Jx.d.ts} +1 -1
  7. package/dist/canvas/index.d.cts +7 -7
  8. package/dist/canvas/index.d.ts +7 -7
  9. package/dist/{chunk-VGZSIXX3.js → chunk-7RJ6P7MI.js} +2 -2
  10. package/dist/{chunk-AOCFL7L7.js → chunk-ESIWZMMK.js} +2 -2
  11. package/dist/{chunk-FOBB6AIO.js → chunk-HHTCDFZC.js} +97 -5
  12. package/dist/chunk-HHTCDFZC.js.map +1 -0
  13. package/dist/{chunk-2QKUD3E2.cjs → chunk-T6TV6HY6.cjs} +36 -36
  14. package/dist/{chunk-2QKUD3E2.cjs.map → chunk-T6TV6HY6.cjs.map} +1 -1
  15. package/dist/{chunk-65GNHOD4.cjs → chunk-YAFS2QFZ.cjs} +82 -82
  16. package/dist/{chunk-65GNHOD4.cjs.map → chunk-YAFS2QFZ.cjs.map} +1 -1
  17. package/dist/{chunk-F7GGEAO2.cjs → chunk-Z2H7KECK.cjs} +151 -59
  18. package/dist/chunk-Z2H7KECK.cjs.map +1 -0
  19. package/dist/effects/index.d.cts +4 -4
  20. package/dist/effects/index.d.ts +4 -4
  21. package/dist/{export-BICOEM9d.d.cts → export-BGdT02aL.d.cts} +3 -3
  22. package/dist/{export-zB4HITwP.d.ts → export-DMeG6E06.d.ts} +1 -1
  23. package/dist/{export-XnuX8FZ2.d.ts → export-Dng22YB8.d.ts} +3 -3
  24. package/dist/{export-CeFplzAW.d.cts → export-KzubBKo7.d.cts} +1 -1
  25. package/dist/{helpers-cssRNUzH.d.ts → helpers-Coa4e2j_.d.ts} +12 -0
  26. package/dist/{helpers-BuKdqUlM.d.cts → helpers-DHl28yLO.d.cts} +12 -0
  27. package/dist/image-editor/index.cjs +610 -610
  28. package/dist/image-editor/index.d.cts +8 -8
  29. package/dist/image-editor/index.d.ts +8 -8
  30. package/dist/image-editor/index.js +2 -2
  31. package/dist/{opentype-C3iyIFRx.d.cts → opentype-BWR7Qv8W.d.cts} +1 -1
  32. package/dist/{opentype-DG5Lkwul.d.ts → opentype-Dfcx6wFx.d.ts} +1 -1
  33. package/dist/paint-editor/index.cjs +7 -7
  34. package/dist/paint-editor/index.d.cts +5 -5
  35. package/dist/paint-editor/index.d.ts +5 -5
  36. package/dist/paint-editor/index.js +2 -2
  37. package/dist/{pathfinder-DKLt4UDG.d.ts → pathfinder-Celbi3e6.d.ts} +1 -1
  38. package/dist/{pathfinder-8vXik95z.d.cts → pathfinder-D8KQ6blQ.d.cts} +1 -1
  39. package/dist/{pool-C69pkWRz.d.ts → pool-8JZGWHvR.d.ts} +1 -1
  40. package/dist/{pool-VAWcYUbs.d.cts → pool-BfuxBKTd.d.cts} +1 -1
  41. package/dist/{svg-CEYpvsgH.d.ts → svg-CxxqG3_W.d.ts} +2 -2
  42. package/dist/{svg-BThlZmja.d.cts → svg-pwXWq6s2.d.cts} +2 -2
  43. package/dist/{tools-CRnZJXXr.d.cts → tools-3EBjR91b.d.cts} +1 -1
  44. package/dist/{tools-CVGqEpO8.d.ts → tools-y1M6O3UT.d.ts} +1 -1
  45. package/dist/vector/index.cjs +1292 -1035
  46. package/dist/vector/index.cjs.map +1 -1
  47. package/dist/vector/index.d.cts +183 -91
  48. package/dist/vector/index.d.ts +183 -91
  49. package/dist/vector/index.js +267 -10
  50. package/dist/vector/index.js.map +1 -1
  51. package/dist/video-editor/index.d.cts +4 -4
  52. package/dist/video-editor/index.d.ts +4 -4
  53. package/dist/{warp-mKylbLiF.d.ts → warp-C1gwu2G_.d.ts} +1 -1
  54. package/dist/{warp-ChcFDdlT.d.cts → warp-Ceqdz7kj.d.cts} +1 -1
  55. package/package.json +1 -1
  56. package/skills/pixerate-vector/SKILL.md +12 -53
  57. package/skills/pixerate-vector/references/pitfalls.md +62 -0
  58. package/dist/chunk-F7GGEAO2.cjs.map +0 -1
  59. package/dist/chunk-FOBB6AIO.js.map +0 -1
  60. /package/dist/{chunk-VGZSIXX3.js.map → chunk-7RJ6P7MI.js.map} +0 -0
  61. /package/dist/{chunk-AOCFL7L7.js.map → chunk-ESIWZMMK.js.map} +0 -0
@@ -43,7 +43,7 @@ import {
43
43
  reverseMorphContour,
44
44
  subpathToMorphContour,
45
45
  turnMorphContour
46
- } from "../chunk-VGZSIXX3.js";
46
+ } from "../chunk-7RJ6P7MI.js";
47
47
  import {
48
48
  DEFAULT_VECTOR_FONT,
49
49
  IDENTITY_MATRIX,
@@ -208,6 +208,7 @@ import {
208
208
  isVectorMaskActive,
209
209
  isVectorMaskGroup,
210
210
  isVectorMaskType,
211
+ isVectorMasterPage,
211
212
  isVectorMeshGradient,
212
213
  isVectorShadedPaint,
213
214
  isVectorSymmetryGroup,
@@ -273,6 +274,7 @@ import {
273
274
  rerouteVectorConnectors,
274
275
  resizeWarpMesh,
275
276
  resolveVectorLenses,
277
+ resolveVectorMasterPages,
276
278
  resolveVectorSymbols,
277
279
  reverseSubpath,
278
280
  reverseVectorGradient,
@@ -319,6 +321,7 @@ import {
319
321
  splitWarpMeshV,
320
322
  starSubpath,
321
323
  stripVectorLensViews,
324
+ stripVectorMasterArt,
322
325
  stripVectorSymbolArt,
323
326
  strokePositionPoint,
324
327
  strokeWidthProfileOf,
@@ -413,6 +416,8 @@ import {
413
416
  vectorMaskedGeometry,
414
417
  vectorMaskedLocalBounds,
415
418
  vectorMaskedShapes,
419
+ vectorMasterArt,
420
+ vectorMasterPages,
416
421
  vectorMeshColorAt,
417
422
  vectorMeshFromOutline,
418
423
  vectorMeshLines,
@@ -427,6 +432,7 @@ import {
427
432
  vectorNodeToBezier,
428
433
  vectorNodesNear,
429
434
  vectorOperandOperation,
435
+ vectorPages,
430
436
  vectorPaintLayerNodes,
431
437
  vectorPaintSolid,
432
438
  vectorPaintToSvg,
@@ -495,7 +501,7 @@ import {
495
501
  withVectorStrokes,
496
502
  withVectorTargetPaint,
497
503
  zigzagPaths
498
- } from "../chunk-FOBB6AIO.js";
504
+ } from "../chunk-HHTCDFZC.js";
499
505
  import {
500
506
  bezierPathBounds,
501
507
  bezierPathToSvg,
@@ -2437,7 +2443,7 @@ var lensResolved = /* @__PURE__ */ new WeakMap();
2437
2443
  function resolvedLensNodes(doc) {
2438
2444
  const hit = lensResolved.get(doc.nodes);
2439
2445
  if (hit) return hit;
2440
- const nodes = resolveVectorLenses(doc).nodes;
2446
+ const nodes = resolveVectorLenses(resolveVectorMasterPages(doc)).nodes;
2441
2447
  lensResolved.set(doc.nodes, nodes);
2442
2448
  return nodes;
2443
2449
  }
@@ -3678,10 +3684,10 @@ ${offset}
3678
3684
  var pdfString = (s) => `(${s.replace(/[\\()]/g, (c) => `\\${c}`).replace(/[^\x20-\x7e]/g, "?")})`;
3679
3685
  function vectorDocumentToPdf(doc, options = {}) {
3680
3686
  const notes = /* @__PURE__ */ new Set();
3681
- doc = resolveVectorLenses(doc);
3687
+ doc = resolveVectorLenses(resolveVectorMasterPages(doc));
3682
3688
  const scale = options.scale ?? 1;
3683
3689
  const compress = options.compress !== false;
3684
- const frames = options.pages === "artboards" ? vectorArtboards(doc) : [];
3690
+ const frames = options.pages === "artboards" ? vectorPages(doc) : [];
3685
3691
  if (options.pages === "artboards" && !frames.length) notes.add("There are no artboards (top-level frames): the whole drawing is one page.");
3686
3692
  const docs = frames.length ? frames.map((f) => vectorFrameDocument(doc, f.id, findVectorNode)) : [doc];
3687
3693
  const w = new PdfWriter();
@@ -3948,7 +3954,7 @@ function vectorDocumentToLottie(doc, options = {}) {
3948
3954
  const fps = options.fps ?? 30;
3949
3955
  const op = Math.max(1, Math.round(options.frames ?? 1));
3950
3956
  const shapes = [];
3951
- if (!options.nodes) doc = resolveVectorLenses(doc);
3957
+ if (!options.nodes) doc = resolveVectorLenses(resolveVectorMasterPages(doc));
3952
3958
  for (const n2 of [...options.nodes ?? doc.nodes].reverse()) {
3953
3959
  const g = nodeGroup(n2, notes);
3954
3960
  if (g) shapes.push(g);
@@ -7147,7 +7153,7 @@ var VectorEditorController = class _VectorEditorController {
7147
7153
  out = { ...out, symbols: out.symbols.map((s) => s.id === edit.symbolId ? { ...s, nodes: out.nodes } : s) };
7148
7154
  }
7149
7155
  out = resolveVectorSymbols(out);
7150
- return resolveVectorLenses(rerouteVectorConnectors(this.solved(out)));
7156
+ return resolveVectorLenses(resolveVectorMasterPages(rerouteVectorConnectors(this.solved(out))));
7151
7157
  }
7152
7158
  /**
7153
7159
  * `doc` with its constraints solved (geometry edited since the last solve moving least) and
@@ -7641,7 +7647,7 @@ var VectorEditorController = class _VectorEditorController {
7641
7647
  return vectorDocumentToSvg(this.storedDocument(), options);
7642
7648
  }
7643
7649
  toJSON() {
7644
- return cloneVectorDocument(stripVectorLensViews(stripVectorSymbolArt(this.storedDocument())));
7650
+ return cloneVectorDocument(stripVectorMasterArt(stripVectorLensViews(stripVectorSymbolArt(this.storedDocument()))));
7645
7651
  }
7646
7652
  /** Adds a node (ids are kept unless taken). Returns its id. */
7647
7653
  addNode(node, options = {}) {
@@ -10559,6 +10565,146 @@ var VectorEditorController = class _VectorEditorController {
10559
10565
  });
10560
10566
  return { ok: true, id };
10561
10567
  }
10568
+ // -----------------------------------------------------------------------------------------
10569
+ // Pages and master pages
10570
+ /**
10571
+ * The document's pages (top-level frames that are not master pages, in order: `number` from 1)
10572
+ * with the master each uses, and its master pages.
10573
+ */
10574
+ getPages() {
10575
+ const pages = vectorPages(this.doc);
10576
+ const masters = vectorMasterPages(this.doc);
10577
+ const box = (f) => ({ x: f.frame.x, y: f.frame.y, width: f.frame.width, height: f.frame.height });
10578
+ return {
10579
+ pages: pages.map((p, i) => ({ id: p.id, name: p.name ?? `Page ${i + 1}`, number: i + 1, masterId: p.frame.masterId && masters.some((m) => m.id === p.frame.masterId) ? p.frame.masterId : null, bounds: box(p) })),
10580
+ masters: masters.map((m) => ({ id: m.id, name: m.name ?? "Master", usedBy: pages.filter((p) => p.frame.masterId === m.id).map((p) => p.id), bounds: box(m) }))
10581
+ };
10582
+ }
10583
+ /** Where a new page or master goes: right of every top-level frame, or below them for a master. */
10584
+ nextPageRect(master) {
10585
+ const frames = this.doc.nodes.filter(isVectorFrame);
10586
+ const pages = vectorPages(this.doc);
10587
+ const like = pages[pages.length - 1]?.frame ?? frames[frames.length - 1]?.frame;
10588
+ const width = like?.width ?? this.doc.width;
10589
+ const height = like?.height ?? this.doc.height;
10590
+ if (!frames.length) return { x: 0, y: 0, width, height };
10591
+ const gap = Math.max(20, Math.round(width * 0.1));
10592
+ if (master) {
10593
+ const bottom = Math.max(...frames.map((f) => f.frame.y + f.frame.height));
10594
+ const left = Math.min(...frames.map((f) => f.frame.x));
10595
+ return { x: left, y: bottom + gap * 2, width, height };
10596
+ }
10597
+ const right = Math.max(...pages.map((f) => f.frame.x + f.frame.width), ...pages.length ? [] : frames.map((f) => f.frame.x + f.frame.width));
10598
+ const top = pages.length ? Math.min(...pages.map((f) => f.frame.y)) : Math.min(...frames.map((f) => f.frame.y));
10599
+ return { x: right + gap, y: top, width, height };
10600
+ }
10601
+ /**
10602
+ * Adds a page: a frame the size of the last page (or the document), to the right of the others,
10603
+ * after page `after` in the page order (default last), using master page `masterId` (default:
10604
+ * the master the last page uses). The first page added to a document without frames covers the
10605
+ * artboard and takes the existing top-level art in. One undo step; selects it. Returns its id.
10606
+ */
10607
+ addPage(input = {}) {
10608
+ const pages = vectorPages(this.doc);
10609
+ if (input.masterId && !isVectorMasterPage(this.doc.nodes.find((n2) => n2.id === input.masterId))) return { ok: false, message: `"${input.masterId}" is not a master page (add one with vector.addMasterPage).` };
10610
+ if (input.after !== void 0 && !pages.some((p) => p.id === input.after)) return { ok: false, message: `"${input.after}" is not a page.` };
10611
+ const first = !this.doc.nodes.some(isVectorFrame);
10612
+ const rect = this.nextPageRect(false);
10613
+ const id = this.newId();
10614
+ const masterId = input.masterId === void 0 ? pages[pages.length - 1]?.frame.masterId ?? null : input.masterId;
10615
+ const adopted = first ? this.doc.nodes.filter((n2) => !n2.locked && n2.visible !== false && !n2.blendStep) : [];
10616
+ const page = {
10617
+ id,
10618
+ type: "group",
10619
+ name: input.name ?? `Page ${pages.length + 1}`,
10620
+ frame: { ...rect, fill: "#ffffff", ...masterId ? { masterId } : {} },
10621
+ children: adopted
10622
+ };
10623
+ const taken = new Set(adopted.map((n2) => n2.id));
10624
+ this.change("Add Page", () => {
10625
+ const rest = this.doc.nodes.filter((n2) => !taken.has(n2.id));
10626
+ const at = input.after ? rest.findIndex((n2) => n2.id === input.after) + 1 : rest.length;
10627
+ this.setDoc([...rest.slice(0, at), page, ...rest.slice(at)]);
10628
+ this.selection = [id];
10629
+ this.anchors = [];
10630
+ this.editingId = null;
10631
+ });
10632
+ return { ok: true, id };
10633
+ }
10634
+ /**
10635
+ * Adds an empty master page (a frame with `master` set, the size of the last page) below the
10636
+ * pages. Art drawn in it shows on every page that uses it; text can show `{page}` and `{pages}`.
10637
+ * With `assignTo` (page ids, or `all`), those pages use it. One undo step; selects it.
10638
+ */
10639
+ addMasterPage(input = {}) {
10640
+ const pages = vectorPages(this.doc);
10641
+ const assign = input.assignTo === "all" ? pages.map((p) => p.id) : input.assignTo ?? [];
10642
+ for (const pid of assign) if (!pages.some((p) => p.id === pid)) return { ok: false, message: `"${pid}" is not a page.` };
10643
+ const rect = this.nextPageRect(true);
10644
+ const id = this.newId();
10645
+ const master = { id, type: "group", name: input.name ?? `Master ${String.fromCharCode(65 + vectorMasterPages(this.doc).length % 26)}`, frame: { ...rect, master: true }, children: [] };
10646
+ const set = new Set(assign);
10647
+ this.change("Add Master Page", () => {
10648
+ this.setDoc([...this.doc.nodes.map((n2) => set.has(n2.id) && isVectorFrame(n2) ? { ...n2, frame: { ...n2.frame, masterId: id } } : n2), master]);
10649
+ this.selection = [id];
10650
+ this.anchors = [];
10651
+ this.editingId = null;
10652
+ });
10653
+ return { ok: true, id };
10654
+ }
10655
+ /** Makes pages use master page `masterId`, or none with null. One undo step. */
10656
+ setPageMaster(masterId, options = {}) {
10657
+ const pages = vectorPages(this.doc);
10658
+ const ids = options.ids ?? this.selection.filter((id) => pages.some((p) => p.id === id));
10659
+ if (!ids.length) return { ok: false, message: "Select a page (a top-level frame) first." };
10660
+ for (const id of ids) if (!pages.some((p) => p.id === id)) return { ok: false, message: `"${id}" is not a page${isVectorMasterPage(this.getNode(id)) ? " (it is a master page)" : ""}.` };
10661
+ if (masterId !== null && !isVectorMasterPage(this.doc.nodes.find((n2) => n2.id === masterId))) return { ok: false, message: `"${masterId}" is not a master page.` };
10662
+ const set = new Set(ids);
10663
+ this.change(masterId ? "Apply Master Page" : "Remove Master Page", () => {
10664
+ this.setDoc(
10665
+ this.doc.nodes.map((n2) => {
10666
+ if (!set.has(n2.id) || !isVectorFrame(n2)) return n2;
10667
+ const { masterId: _m, ...frame } = n2.frame;
10668
+ return { ...n2, frame: masterId ? { ...frame, masterId } : frame };
10669
+ })
10670
+ );
10671
+ });
10672
+ return { ok: true, ids: [...ids] };
10673
+ }
10674
+ /** Moves page `id` to position `index` (0-based) in the page order. One undo step. Returns the new order. */
10675
+ movePage(id, index) {
10676
+ const pages = vectorPages(this.doc);
10677
+ const from = pages.findIndex((p) => p.id === id);
10678
+ if (from < 0) return { ok: false, message: `"${id}" is not a page.` };
10679
+ if (!Number.isInteger(index) || index < 0 || index >= pages.length) return { ok: false, message: `index must be from 0 to ${pages.length - 1}.` };
10680
+ if (index === from) return { ok: true, order: pages.map((p) => p.id) };
10681
+ const order = pages.map((p) => p.id);
10682
+ order.splice(index, 0, ...order.splice(from, 1));
10683
+ const slots = this.doc.nodes.map((n2, i) => pages.some((p) => p.id === n2.id) ? i : -1).filter((i) => i >= 0);
10684
+ const byId = new Map(pages.map((p) => [p.id, p]));
10685
+ this.change("Move Page", () => {
10686
+ const nodes = this.doc.nodes.slice();
10687
+ slots.forEach((slot, k) => nodes[slot] = byId.get(order[k]));
10688
+ this.setDoc(nodes);
10689
+ });
10690
+ return { ok: true, order };
10691
+ }
10692
+ /**
10693
+ * Goes to a page (or master page): selects it and brings it into view, fitted to a canvas of
10694
+ * `size` screen pixels when given, otherwise at the current zoom with its corner near the
10695
+ * canvas's top-left. Not an undo step.
10696
+ */
10697
+ goToPage(id, options = {}) {
10698
+ const n2 = this.doc.nodes.find((x) => x.id === id);
10699
+ if (!isVectorFrame(n2)) return { ok: false, message: `"${id}" is not a page or master page.` };
10700
+ const b = vectorNodeBounds(n2) ?? { x: n2.frame.x, y: n2.frame.y, width: n2.frame.width, height: n2.frame.height };
10701
+ this.selection = [id];
10702
+ this.anchors = [];
10703
+ if (options.size) this.zoomToFit(options.size, { bounds: b });
10704
+ else this.setViewport({ x: 40 - b.x * this.viewport.zoom, y: 40 - b.y * this.viewport.zoom });
10705
+ this.notify();
10706
+ return { ok: true };
10707
+ }
10562
10708
  /**
10563
10709
  * Frame Selection: puts the selected (or given) objects, which must share a parent, into a new
10564
10710
  * frame fitted to their bounds plus `padding` (document units, default 0), in their place in the
@@ -14883,7 +15029,8 @@ function createVectorCommands(controller, options = {}) {
14883
15029
  name: { type: "string", description: "Layer name (default the text's start)." },
14884
15030
  fill: PAINT,
14885
15031
  stroke: PAINT,
14886
- strokeWidth: { type: "number", minimum: 0, description: "Stroke width (default 1)." }
15032
+ strokeWidth: { type: "number", minimum: 0, description: "Stroke width (default 1)." },
15033
+ parentId: { type: "string", description: "A group (frame, master page, symmetry group) to add it into, on top of its children (default: the top of the document). On a master page, {page} and {pages} show each page's number and the page count." }
14887
15034
  },
14888
15035
  required: ["text"],
14889
15036
  additionalProperties: false
@@ -14903,7 +15050,7 @@ function createVectorCommands(controller, options = {}) {
14903
15050
  ...params.paragraph ? { paragraph: params.paragraph } : {},
14904
15051
  ...params.fill !== void 0 ? { fill: checkPaint(params.fill, "fill") } : {},
14905
15052
  ...params.stroke !== void 0 ? { stroke: checkPaint(params.stroke, "stroke") } : {}
14906
- });
15053
+ }, parentOf(params.parentId));
14907
15054
  } catch (e) {
14908
15055
  fail(e instanceof Error ? e.message : String(e));
14909
15056
  }
@@ -15975,6 +16122,109 @@ function createVectorCommands(controller, options = {}) {
15975
16122
  ];
15976
16123
  const frameResult = (id) => controller.getFrames().find((f) => f.id === id) ?? fail(`"${id}" is not a frame.`);
15977
16124
  const FRAME_PAINT = { ...PAINT, description: `The frame's background, drawn below its children. ${PAINT.description}` };
16125
+ const pagesResult = () => controller.getPages();
16126
+ const pageCommands = () => [
16127
+ {
16128
+ ...base,
16129
+ id: `${prefix}listPages`,
16130
+ label: "Pages",
16131
+ keywords: ["pages", "master page", "multipage", "page numbers", "document pages"],
16132
+ description: "Lists the document's pages (top-level frames that are not master pages, in order) and its master pages: { pages: [{ id, name, number, masterId, bounds }], masters: [{ id, name, usedBy, bounds }] }. Place master art inside the master bounds.",
16133
+ params: { type: "object", properties: {}, additionalProperties: false },
16134
+ run: () => pagesResult()
16135
+ },
16136
+ {
16137
+ ...base,
16138
+ id: `${prefix}addPage`,
16139
+ label: "Add Page",
16140
+ keywords: ["page", "add page", "new page", "insert page", "multipage"],
16141
+ description: "Adds a page: a frame the size of the last page (or the document) right of the others, after page `after` (default last), using master `masterId` (default: the last page's master; null for none). The first page of a document without frames covers the artboard and takes its art in. Add art to it with parentId. One undo step. Returns { id } and the pages.",
16142
+ params: {
16143
+ type: "object",
16144
+ properties: {
16145
+ name: { type: "string", description: 'Page name (default "Page n").' },
16146
+ masterId: { type: ["string", "null"], description: "Master page id, or null for none (default: the last page's master)." },
16147
+ after: { type: "string", description: "Page id to insert after (default: at the end)." }
16148
+ },
16149
+ additionalProperties: false
16150
+ },
16151
+ undoable: true,
16152
+ run: (_ctx, params) => {
16153
+ const r = controller.addPage(params ?? {});
16154
+ check(r);
16155
+ return { id: r.id, ...pagesResult() };
16156
+ }
16157
+ },
16158
+ {
16159
+ ...base,
16160
+ id: `${prefix}addMasterPage`,
16161
+ label: "Add Master Page",
16162
+ keywords: ["master page", "template page", "header", "footer", "page numbers"],
16163
+ description: 'Adds an empty master page (a frame below the pages, not a page itself). Art added to it (parentId: its id) shows on every page using it, laid out by each object\'s resizing constraints; text there can show {page} and {pages}. `assignTo` page ids or "all" make pages use it. One undo step. Returns { id } and the pages.',
16164
+ params: {
16165
+ type: "object",
16166
+ properties: {
16167
+ name: { type: "string", description: 'Master name (default "Master A", "Master B", \u2026).' },
16168
+ assignTo: { anyOf: [{ type: "string", enum: ["all"] }, { ...IDS }], description: 'Pages that use it: "all" or page ids (default none).' }
16169
+ },
16170
+ additionalProperties: false
16171
+ },
16172
+ undoable: true,
16173
+ run: (_ctx, params) => {
16174
+ const r = controller.addMasterPage(params ?? {});
16175
+ check(r);
16176
+ return { id: r.id, ...pagesResult() };
16177
+ }
16178
+ },
16179
+ {
16180
+ ...base,
16181
+ id: `${prefix}setPageMaster`,
16182
+ label: "Apply Master Page",
16183
+ keywords: ["master page", "apply master", "page template"],
16184
+ description: "Makes pages (`ids`, default the selected pages) use master page `masterId`, or none with null. One undo step. Returns the pages.",
16185
+ params: { type: "object", properties: { ids: { ...IDS, description: "Page ids (default: the selected pages)." }, masterId: { type: ["string", "null"], description: "Master page id, or null for none." } }, required: ["masterId"], additionalProperties: false },
16186
+ undoable: true,
16187
+ run: (_ctx, params) => {
16188
+ check(controller.setPageMaster(params.masterId, params.ids ? { ids: params.ids } : {}));
16189
+ return pagesResult();
16190
+ }
16191
+ },
16192
+ {
16193
+ ...base,
16194
+ id: `${prefix}movePage`,
16195
+ label: "Move Page",
16196
+ keywords: ["page order", "reorder pages", "move page"],
16197
+ description: "Moves page `id` to position `index` (0-based) in the page order; page numbers follow. One undo step. Returns the pages.",
16198
+ params: { type: "object", properties: { id: { type: "string", description: "The page." }, index: { type: "integer", minimum: 0, description: "New position, 0 for first." } }, required: ["id", "index"], additionalProperties: false },
16199
+ undoable: true,
16200
+ run: (_ctx, params) => {
16201
+ check(controller.movePage(params.id, params.index));
16202
+ return pagesResult();
16203
+ }
16204
+ },
16205
+ {
16206
+ ...base,
16207
+ id: `${prefix}goToPage`,
16208
+ label: "Go to Page",
16209
+ keywords: ["go to page", "navigate", "show page", "zoom to page"],
16210
+ description: "Selects a page or master page and brings it into view for the user (fitted when the canvas size is given). Not an undo step. Returns { id }.",
16211
+ params: {
16212
+ type: "object",
16213
+ properties: {
16214
+ id: { type: "string", description: "Page or master page id." },
16215
+ canvasWidth: { type: "number", exclusiveMinimum: 0, description: "Canvas width in screen pixels, to fit the page (optional)." },
16216
+ canvasHeight: { type: "number", exclusiveMinimum: 0, description: "Canvas height in screen pixels, to fit the page (optional)." }
16217
+ },
16218
+ required: ["id"],
16219
+ additionalProperties: false
16220
+ },
16221
+ run: (_ctx, params) => {
16222
+ const size = params.canvasWidth && params.canvasHeight ? { width: params.canvasWidth, height: params.canvasHeight } : void 0;
16223
+ check(controller.goToPage(params.id, size ? { size } : {}));
16224
+ return { id: params.id };
16225
+ }
16226
+ }
16227
+ ];
15978
16228
  const frameCommands = () => [
15979
16229
  {
15980
16230
  ...base,
@@ -16324,6 +16574,7 @@ function createVectorCommands(controller, options = {}) {
16324
16574
  ...symbolCommands(),
16325
16575
  ...constraintCommands(),
16326
16576
  ...frameCommands(),
16577
+ ...pageCommands(),
16327
16578
  ...connectorCommands(),
16328
16579
  ...trackingCommands(),
16329
16580
  ...shadingCommands(),
@@ -17579,6 +17830,7 @@ export {
17579
17830
  isVectorMaskActive,
17580
17831
  isVectorMaskGroup,
17581
17832
  isVectorMaskType,
17833
+ isVectorMasterPage,
17582
17834
  isVectorMeshGradient,
17583
17835
  isVectorShadedPaint,
17584
17836
  isVectorSymmetryGroup,
@@ -17666,6 +17918,7 @@ export {
17666
17918
  resizeWarpMesh as resizeVectorMesh,
17667
17919
  resolveVectorBlendOptions,
17668
17920
  resolveVectorLenses,
17921
+ resolveVectorMasterPages,
17669
17922
  resolveVectorSymbols,
17670
17923
  reverseMorphContour,
17671
17924
  reverseSubpath,
@@ -17719,6 +17972,7 @@ export {
17719
17972
  splitWarpMeshV as splitVectorMeshV,
17720
17973
  starSubpath,
17721
17974
  stripVectorLensViews,
17975
+ stripVectorMasterArt,
17722
17976
  stripVectorSymbolArt,
17723
17977
  strokePositionPoint,
17724
17978
  strokeWidthProfileOf,
@@ -17851,6 +18105,8 @@ export {
17851
18105
  vectorMaskedGeometry,
17852
18106
  vectorMaskedLocalBounds,
17853
18107
  vectorMaskedShapes,
18108
+ vectorMasterArt,
18109
+ vectorMasterPages,
17854
18110
  vectorMeshColorAt,
17855
18111
  warpMeshColumns as vectorMeshColumns,
17856
18112
  warpMeshControlBounds as vectorMeshControlBounds,
@@ -17871,6 +18127,7 @@ export {
17871
18127
  vectorNodeToBezier,
17872
18128
  vectorNodesNear,
17873
18129
  vectorOperandOperation,
18130
+ vectorPages,
17874
18131
  vectorPaintLayerNodes,
17875
18132
  vectorPaintSolid,
17876
18133
  vectorPaintSwatch,