@json-to-office/jto 2.4.0 → 3.0.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 (57) hide show
  1. package/dist/cli.js +123 -39
  2. package/dist/cli.js.map +1 -1
  3. package/dist/client/assets/HomePage-BlzZ7qG4.js +245 -0
  4. package/dist/client/assets/HomePage-BlzZ7qG4.js.map +1 -0
  5. package/dist/client/assets/{JsonEditorPage-DjLAUBv5.js → JsonEditorPage-kWuP_kL3.js} +3 -3
  6. package/dist/client/assets/{JsonEditorPage-DjLAUBv5.js.map → JsonEditorPage-kWuP_kL3.js.map} +1 -1
  7. package/dist/client/assets/{MonacoPluginProvider-D_GUFwWQ.js → MonacoPluginProvider-Dbv1PrO2.js} +6 -6
  8. package/dist/client/assets/{MonacoPluginProvider-D_GUFwWQ.js.map → MonacoPluginProvider-Dbv1PrO2.js.map} +1 -1
  9. package/dist/client/assets/{_virtual_jto-plugin-type-libs-9elxvZT2.js → _virtual_jto-plugin-type-libs-B6KyD9RL.js} +9182 -4529
  10. package/dist/client/assets/{_virtual_jto-plugin-type-libs-9elxvZT2.js.map → _virtual_jto-plugin-type-libs-B6KyD9RL.js.map} +1 -1
  11. package/dist/client/assets/_virtual_jto-sandbox-runtime-Bzo2M5U7.js +2 -0
  12. package/dist/client/assets/_virtual_jto-sandbox-runtime-Bzo2M5U7.js.map +1 -0
  13. package/dist/client/assets/editor-CwEocOY2.js +16 -0
  14. package/dist/client/assets/editor-CwEocOY2.js.map +1 -0
  15. package/dist/client/assets/editor-monaco-json-D_oiidNg.js +24 -0
  16. package/dist/client/assets/editor-monaco-json-D_oiidNg.js.map +1 -0
  17. package/dist/client/assets/index--kF4jVbp.css +1 -0
  18. package/dist/client/assets/index-DFJaEoi0.js +27 -0
  19. package/dist/client/assets/index-DFJaEoi0.js.map +1 -0
  20. package/dist/client/assets/index-UheDso2P.js +2 -0
  21. package/dist/client/assets/index-UheDso2P.js.map +1 -0
  22. package/dist/client/assets/preview-CWdUATNl.js +4 -0
  23. package/dist/client/assets/preview-CWdUATNl.js.map +1 -0
  24. package/dist/client/assets/useQualityAnalysis-Cl4QPeOT.js +6 -0
  25. package/dist/client/assets/useQualityAnalysis-Cl4QPeOT.js.map +1 -0
  26. package/dist/client/index.html +2 -2
  27. package/dist/client/templates/client-report-blocks.docx.json +791 -0
  28. package/dist/client/templates/consulting-deck-blocks.pptx.json +455 -0
  29. package/dist/client/templates/data-report-presentation.pptx.json +108 -36
  30. package/dist/client/templates/management-plan.pptx.json +100 -22
  31. package/dist/client/templates/minimalist-pitch-deck.pptx.json +172 -101
  32. package/dist/prompts/instructions-edit-document-pptx-blocks.md +77 -0
  33. package/dist/prompts/instructions-edit-document-pptx-slides.md +15 -21
  34. package/dist/prompts/instructions-edit-document-pptx.md +34 -53
  35. package/dist/prompts/instructions-edit-pptx.md +9 -8
  36. package/dist/prompts/instructions-generate-pptx.md +13 -17
  37. package/dist/prompts/pptx-core.md +104 -127
  38. package/dist/prompts/pptx-design.md +115 -109
  39. package/package.json +10 -9
  40. package/dist/client/assets/HomePage-mtUb6jxc.js +0 -251
  41. package/dist/client/assets/HomePage-mtUb6jxc.js.map +0 -1
  42. package/dist/client/assets/_virtual_jto-sandbox-runtime-Dqq17bow.js +0 -2
  43. package/dist/client/assets/_virtual_jto-sandbox-runtime-Dqq17bow.js.map +0 -1
  44. package/dist/client/assets/editor-ZbEHVEFs.js +0 -16
  45. package/dist/client/assets/editor-ZbEHVEFs.js.map +0 -1
  46. package/dist/client/assets/editor-monaco-json-FaaVfftD.js +0 -24
  47. package/dist/client/assets/editor-monaco-json-FaaVfftD.js.map +0 -1
  48. package/dist/client/assets/editor-refs-store-DAEAPqEk.js +0 -2
  49. package/dist/client/assets/editor-refs-store-DAEAPqEk.js.map +0 -1
  50. package/dist/client/assets/index-Bj6ZAKUc.css +0 -1
  51. package/dist/client/assets/index-DRbATnbJ.js +0 -5
  52. package/dist/client/assets/index-DRbATnbJ.js.map +0 -1
  53. package/dist/client/assets/preview-CM2ywF-8.js +0 -4
  54. package/dist/client/assets/preview-CM2ywF-8.js.map +0 -1
  55. package/dist/client/assets/useQualityAnalysis-ClgkaIc2.js +0 -6
  56. package/dist/client/assets/useQualityAnalysis-ClgkaIc2.js.map +0 -1
  57. package/dist/prompts/instructions-edit-document-pptx-templates.md +0 -63
@@ -1,129 +1,151 @@
1
1
  # PPTX Design Patterns & Best Practices
2
2
 
3
- ## Recommended Template Set
3
+ ## Standard slides come from blocks
4
4
 
5
- Always define at least these 2-3 templates:
5
+ Prefer the reference blocks below for standard slides: copy the definition you use into `props.blocks` verbatim, then invoke it. Define a new block yourself for any layout used more than once (a cover, a statement, a two-column comparison, a metric row): percentage frames, type-role bindings with defaults, and `$if` around every optional slot. Use a code plugin only for programmable behavior — calculations, external data, layouts that depend on logic JSON cannot express — never for a layout blocks can describe.
6
6
 
7
- 1. **TITLE_TEMPLATE** — full-bleed title slide. Placeholders: `title`, `subtitle`
8
- 2. **CONTENT_TEMPLATE** — standard content slide with heading + body. Placeholders: `heading`, `body`
9
- 3. **TWO_COLUMN_TEMPLATE** — heading + left/right columns. Placeholders: `heading`, `left`, `right`
7
+ Coordinate-authored slides (components directly in `slide.children`) are for genuinely unique, unrepeatable slides. If you have more than one such slide with the same shape, define a block instead.
10
8
 
11
- ## Custom Slides (no template) — AVOID
9
+ ## Reference blocks
12
10
 
13
- For one-off layouts, skip `template`/`placeholders` and use `children` directly. **If you have more than one custom slide, you almost certainly need another template instead.**
11
+ These definitions come from complete playground templates and validate as they are. Copy the definitions you invoke (and any block a definition itself invokes) into `props.blocks`; the names are not built into the engine.
14
12
 
15
- ```json
16
- {
17
- "name": "slide",
18
- "props": { "background": { "color": "primary" } },
19
- "children": [
20
- { "name": "text", "props": { "text": "Special Layout", "grid": { "column": 1, "row": 2, "columnSpan": 10 }, "fontSize": 36, "color": "FFFFFF", "align": "center" } }
21
- ]
22
- }
23
- ```
24
-
25
- Only use this for truly unique, unrepeatable slides. Prefer templates for any layout used more than once.
13
+ {{referenceBlocks}}
26
14
 
27
- ## Complete Minimal Example
15
+ ## Complete minimal example
28
16
 
29
17
  ```json
30
18
  {
31
19
  "name": "pptx",
32
20
  "props": {
33
- "title": "Quarterly Update",
34
- "theme": "corporate",
35
- "templates": [
36
- {
37
- "name": "TITLE_TEMPLATE",
38
- "background": { "color": "primary" },
39
- "objects": [
40
- { "name": "shape", "props": { "type": "rect", "x": 0, "y": 6.8, "w": 10, "h": 0.7, "fill": { "color": "secondary" } } }
41
- ],
42
- "placeholders": [
43
- { "name": "title", "type": "title", "style": "title", "grid": { "column": 1, "row": 1, "columnSpan": 10, "rowSpan": 2 }, "fontSize": 44, "color": "FFFFFF", "valign": "middle" },
44
- { "name": "subtitle", "type": "body", "style": "subtitle", "grid": { "column": 2, "row": 3, "columnSpan": 8 }, "color": "accent" }
45
- ]
46
- },
47
- {
48
- "name": "CONTENT_TEMPLATE",
49
- "grid": { "margin": { "top": 1.1 } },
50
- "objects": [
51
- { "name": "shape", "props": { "type": "rect", "x": 0, "y": 0, "w": 10, "h": 0.9, "fill": { "color": "primary" } } },
52
- { "name": "text", "props": { "text": "COMPANY", "x": 0.6, "y": 0.15, "w": 4, "h": 0.6, "fontSize": 14, "bold": true, "color": "FFFFFF" } }
53
- ],
54
- "slideNumber": { "x": 9, "y": 6.85, "w": 0.5, "h": 0.5, "color": "text2", "fontSize": 8 },
55
- "placeholders": [
56
- { "name": "heading", "type": "title", "style": "heading1", "grid": { "column": 0, "row": 0, "columnSpan": 12 } },
57
- { "name": "body", "type": "body", "style": "body", "grid": { "column": 0, "row": 1, "columnSpan": 12, "rowSpan": 4 } }
21
+ "title": "Quarterly update",
22
+ "theme": "consulting",
23
+ "slideWidth": 13.333,
24
+ "slideHeight": 7.5,
25
+ "blocks": {
26
+ "cover": {
27
+ "description": "Title slide: eyebrow, title, subtitle over an accent rule.",
28
+ "slots": {
29
+ "eyebrow": { "type": "string", "maxWords": 8, "oneLine": true },
30
+ "title": { "type": "string", "required": true, "maxWords": 16, "role": "actionTitle" },
31
+ "subtitle": { "type": "string", "maxWords": 16 }
32
+ },
33
+ "body": [
34
+ {
35
+ "name": "shape",
36
+ "props": {
37
+ "type": "line",
38
+ "x": "3.75%", "y": "31%", "w": "15%", "h": 0,
39
+ "line": { "color": "accent", "width": 3 }
40
+ }
41
+ },
42
+ {
43
+ "$if": "/eyebrow",
44
+ "then": {
45
+ "name": "text",
46
+ "props": {
47
+ "text": { "$slot": "/eyebrow" },
48
+ "style": "eyebrow",
49
+ "fontSize": { "$theme": "/styles/eyebrow/fontSize", "default": 10 },
50
+ "x": "3.75%", "y": "34%", "w": "90%", "h": "5%"
51
+ }
52
+ }
53
+ },
54
+ {
55
+ "name": "text",
56
+ "props": {
57
+ "text": { "$slot": "/title" },
58
+ "style": "title",
59
+ "x": "3.75%", "y": "40%", "w": "82%", "h": "23%",
60
+ "valign": "top",
61
+ "fit": { "maxLines": 2, "shrink": [28, 24] }
62
+ }
63
+ },
64
+ {
65
+ "$if": "/subtitle",
66
+ "then": {
67
+ "name": "text",
68
+ "props": {
69
+ "text": { "$slot": "/subtitle" },
70
+ "style": "subtitle",
71
+ "x": "3.75%", "y": "64%", "w": "82%", "h": "7%"
72
+ }
73
+ }
74
+ }
58
75
  ]
59
76
  }
60
- ]
77
+ }
61
78
  },
62
79
  "children": [
63
80
  {
64
81
  "name": "slide",
65
- "props": {
66
- "template": "TITLE_TEMPLATE",
67
- "placeholders": {
68
- "title": { "name": "text", "props": { "text": "Q1 2026 Update" } },
69
- "subtitle": { "name": "text", "props": { "text": "Engineering Division" } }
82
+ "props": { "meta": { "title": "Cover" } },
83
+ "children": [
84
+ {
85
+ "name": "block",
86
+ "props": {
87
+ "ref": "cover",
88
+ "slots": {
89
+ "eyebrow": "Engineering · Q1 2026",
90
+ "title": "Search v2 shipped; auth rewrite lands next quarter",
91
+ "subtitle": "Quarterly engineering update"
92
+ }
93
+ }
70
94
  }
71
- }
95
+ ]
72
96
  },
73
97
  {
74
98
  "name": "slide",
75
- "props": {
76
- "template": "CONTENT_TEMPLATE",
77
- "placeholders": {
78
- "heading": { "name": "text", "props": { "text": "Highlights" } },
79
- "body": { "name": "table", "props": { "rows": [["Feature", "Status"], ["Search v2", "Shipped"], ["Auth rewrite", "In Progress"]], "grid": { "column": 0, "row": 3, "columnSpan": 12, "rowSpan": 2 }, "fontSize": 12, "border": { "type": "solid", "pt": 0.5, "color": "E2E8F0" } } }
99
+ "props": { "meta": { "title": "Highlights" } },
100
+ "children": [
101
+ {
102
+ "name": "text",
103
+ "props": { "text": "Highlights", "style": "heading1", "x": 0.5, "y": 0.45, "w": 12.333, "h": 0.9 }
104
+ },
105
+ {
106
+ "name": "table",
107
+ "props": {
108
+ "rows": [["Feature", "Status"], ["Search v2", "Shipped"], ["Auth rewrite", "In progress"]],
109
+ "x": 0.5, "y": 1.6, "w": 12.333, "h": 1.5,
110
+ "rowH": 0.45,
111
+ "margin": [3, 6, 3, 6],
112
+ "fontSize": 12,
113
+ "border": { "type": "solid", "pt": 0.5, "color": "rule" }
114
+ }
80
115
  }
81
- }
116
+ ]
82
117
  }
83
118
  ]
84
119
  }
85
120
  ```
86
121
 
87
- ## Common Layout Pitfalls
122
+ ## Common layout pitfalls
88
123
 
89
124
  ### Text overflow
90
- PPTX does not auto-shrink text. If text is too long for its container it will clip or overflow.
91
- - Keep heading text short (≤ 6 words) or reduce `fontSize` for longer headings
92
- - Always give headings full width (`columnSpan: 12`) unless the layout genuinely needs a narrower column
93
- - For long text, prefer a smaller `fontSize` over truncation
125
+ PPTX does not auto-shrink text outside a block. Inside a block, give titles a `fit` with declared `shrink` sizes; outside, keep headings short (≤ 6 words) or reduce `fontSize`. Give headings full width unless the layout genuinely needs a narrower column.
94
126
 
95
- ### Slide number placement
96
- Never position `slideNumber` where it overlaps content. Safe defaults:
97
- - Bottom-right corner: `{ "x": 9.2, "y": 7.0, "w": 0.5, "h": 0.3, "fontSize": 8 }`
98
- - Ensure the heading placeholder's grid row does **not** share space with the slide number
127
+ ### Page numbers and chrome
128
+ Put page numbers, trackers and confidentiality footers in the block definitions (a text component with `{PAGE_NUMBER}` in the body) so every slide that invokes the block gets them in the same place — never overlapping content. A block's `slide.background` gives every invoking slide the same background.
99
129
 
100
130
  ### Element overlap
101
- Multiple text or shape components in the same region will render on top of each other. Prevent this:
102
- - Give each element its own grid row, or use explicit `y` offsets so they stack vertically
103
- - When placing a label below a title (e.g. name + role), put the title in row N and the label in row N+1, or use different `y` values with enough gap (≥ 0.35")
104
- - Never place two text components at the same `x`/`y` unless one is intentionally a background layer
131
+ Multiple text or shape components in the same region render on top of each other. Give each element its own grid row or `y` offset (≥ 0.35" gap between a title and the label under it). Inside a block, use a `group` with `direction` to distribute items rather than hand-placing each.
105
132
 
106
133
  ### Circles vs stretched ellipses
107
- An `ellipse` shape renders as a circle **only** when `w === h`. If `w ≠ h` it stretches.
108
- - For avatar circles, badges, or step indicators: always set equal `w` and `h` (e.g. `"w": 0.6, "h": 0.6`)
109
- - When using grid positioning for ellipses, ensure the grid cell is square. If not, use explicit `w`/`h` to force a 1:1 ratio — explicit dimensions override grid sizing.
134
+ An `ellipse` renders as a circle **only** when `w === h`. For avatars, badges and step indicators set equal `w` and `h`; explicit dimensions override grid sizing.
110
135
 
111
136
  ### Text inside small shapes
112
- When placing text inside a shape (initials, numbers, icons):
113
- - Keep text on a single line — never use `\n` in initials or short labels (use `"PB"` not `"P\nB"`)
114
- - Set `"align": "center"` and `"valign": "middle"` for proper centering
115
- - Ensure fontSize is small enough to fit the shape (rule of thumb: fontSize ≤ shape width in inches × 40)
137
+ Keep text on a single line (`"PB"`, not `"P\nB"`), set `"align": "center"` and `"valign": "middle"`, and keep fontSize ≤ shape width in inches × 40.
116
138
 
117
- ## Table Best Practices
139
+ ## Table best practices
118
140
 
119
141
  ### Row heights & margins
120
- Always specify `rowH` for consistent, compact rows (recommended 0.4–0.55"). Always specify `margin` for cell padding (recommended `[3, 6, 3, 6]`). Without these, rows expand unpredictably.
142
+ Always specify `rowH` (0.4–0.55") and `margin` (`[3, 6, 3, 6]`). Without them rows expand unpredictably.
121
143
 
122
144
  ### Rounded corners
123
- Use `borderRadius` (e.g. `0.15`) for polished rounded-corner tables. This renders a `roundRect` shape behind the table. When using `borderRadius`, set outer borders to `"none"` and keep internal borders only. **`borderRadius` requires explicit numeric `x`/`y` (inches, not `%` or grid-only)** — if the table is grid-positioned without explicit `x`/`y`, rounded corners are silently skipped.
145
+ `borderRadius` (e.g. `0.15`) draws a `roundRect` behind the table; set outer borders to `"none"` and keep internal borders only. It requires explicit numeric `x`/`y` (inches).
124
146
 
125
147
  ### Unicode symbols
126
- PowerPoint may render ✓✔✗✘ as color emoji. The renderer auto-appends a text variation selector to force text rendering. For best results, use `fontFace: "Arial"` on cells with Unicode symbols (✓, —, •) since Arial has reliable glyph coverage.
148
+ PowerPoint may render ✓✔✗✘ as emoji; use `fontFace: "Arial"` on cells with Unicode symbols (✓, —, •).
127
149
 
128
150
  ### Example: polished comparison table
129
151
  ```json
@@ -152,38 +174,27 @@ PowerPoint may render ✓✔✗✘ as color emoji. The renderer auto-appends a t
152
174
  "borderRadius": 0.15,
153
175
  "border": { "type": "solid", "pt": 0.5, "color": "E2E8F0" },
154
176
  "fontSize": 12,
155
- "grid": { "column": 1, "row": 2, "columnSpan": 10, "rowSpan": 3 }
177
+ "x": 1, "y": 2, "w": 11.333, "h": 1.5
156
178
  }
157
179
  }
158
180
  ```
159
181
 
160
- ## PPTX Rendering Limitations & Workarounds
182
+ ## PPTX rendering limitations & workarounds
161
183
 
162
184
  ### Character spacing (`charSpacing`)
163
- Use `charSpacing` (number, in points) on text and shape components to control letter-spacing/tracking.
164
- - Wordmarks/logos: `"charSpacing": 3` to `6`
165
- - Uppercase labels/section identifiers: `"charSpacing": 1` to `3`
166
- - Normal body text: omit (0 default)
185
+ `charSpacing` (points) controls tracking on text and shape components: wordmarks `3`–`6`, uppercase labels `1`–`3`, body text omit.
167
186
 
168
187
  ### Font weight
169
- pptxgenjs only supports `bold: true/false`, not CSS font-weight values (300/400/500/600/700). To achieve light/thin text, use font family variants in `fontFace`:
170
- - `"Inter Light"`, `"Inter Thin"`, `"Helvetica Neue Light"`, `"Montserrat Light"`
171
- - Use light font variants for elegant/refined designs rather than relying on bold alone.
188
+ Only `bold: true/false`, not numeric weights. For light text use font family variants in `fontFace` (`"Inter Light"`, `"Helvetica Neue Light"`).
172
189
 
173
190
  ### Text opacity
174
- PPTX text doesn't support opacity. To achieve semi-transparent text effects, pre-compute muted hex colors:
175
- - White at ~50% on dark bg → `"808080"`
176
- - White at ~35% on dark bg → `"595959"`
177
- - For secondary/tertiary text on dark backgrounds, use muted hex colors rather than expecting opacity support.
191
+ Not supported. Pre-compute muted hex colors (white at ~50% on dark → `"808080"`, ~35% → `"595959"`) or use the theme's `text2`.
178
192
 
179
193
  ### Decorative elements
180
- SVGs are not supported. For decorative elements:
181
- - Use `ellipse` shapes for dot patterns
182
- - Use `rect` shapes for dividers/bars
183
- - Use pre-rendered PNG images (base64) for complex decorations
194
+ SVGs are not supported as shapes. Use `ellipse` for dots, `rect` and `line` for dividers, pre-rendered PNG (base64) for complex decorations.
184
195
 
185
- ### Multi-element cards / Rich text in shapes
186
- For metric cards with per-segment formatting (large number, small label, colored indicator), use **rich text segments** in a single shape instead of overlaying multiple elements:
196
+ ### Multi-element cards / rich text in shapes
197
+ For metric cards with per-segment formatting, use **rich text segments** in a single shape:
187
198
  ```json
188
199
  {
189
200
  "name": "shape",
@@ -194,16 +205,11 @@ For metric cards with per-segment formatting (large number, small label, colored
194
205
  "valign": "middle",
195
206
  "text": [
196
207
  { "text": "124K", "fontSize": 36, "bold": true, "color": "primary" },
197
- { "text": "Active Users", "fontSize": 12, "color": "text2", "breakLine": true },
198
- { "text": "▲ 34% YoY", "fontSize": 11, "color": "22C55E", "breakLine": true }
208
+ { "text": "Active users", "fontSize": 12, "color": "text2", "breakLine": true },
209
+ { "text": "▲ 34% YoY", "fontSize": 11, "color": "positive", "breakLine": true }
199
210
  ],
200
- "grid": { "column": 0, "row": 2, "columnSpan": 4, "rowSpan": 2 }
211
+ "x": "0%", "y": "0%", "w": "100%", "h": "100%"
201
212
  }
202
213
  }
203
214
  ```
204
- Each segment can have its own `fontSize`, `fontFace`, `color`, `bold`, `italic`, `breakLine`, `spaceBefore`, and `spaceAfter`. Use `breakLine: true` to start a new line after the segment. Shape-level font props (`fontSize`, `fontColor`, `bold`) apply as defaults when segments omit them.
205
-
206
- For truly complex layouts needing independent positioning, fall back to overlaying separate components:
207
- - Use a `roundRect` shape as the card background (no text)
208
- - Overlay positioned `text` components on top with explicit x/y/w/h
209
- - All components share the same grid area but use absolute offsets within
215
+ Each segment can have its own `fontSize`, `fontFace`, `color`, `bold`, `italic`, `breakLine`, `spaceBefore` and `spaceAfter`. Inside a block, wrap such cards in a `group` with `"direction": "row"` and an `$each` over an array slot so two to four cards distribute themselves.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@json-to-office/jto",
3
- "version": "2.4.0",
3
+ "version": "3.0.0",
4
4
  "description": "JSON to Office CLI - Unified document and presentation generation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -84,13 +84,13 @@
84
84
  "vite": "6.0.5",
85
85
  "zod": "^4.0.0",
86
86
  "zustand": "5.0.2",
87
- "@json-to-office/core-docx": "^2.4.0",
88
- "@json-to-office/core-pptx": "^2.4.0",
89
- "@json-to-office/jto-cli": "^2.0.0",
90
- "@json-to-office/quality": "^2.4.0",
91
- "@json-to-office/shared": "^1.11.2",
92
- "@json-to-office/shared-docx": "^2.0.0",
93
- "@json-to-office/shared-pptx": "^2.4.0"
87
+ "@json-to-office/core-docx": "^3.0.0",
88
+ "@json-to-office/core-pptx": "^3.0.0",
89
+ "@json-to-office/jto-cli": "^3.0.0",
90
+ "@json-to-office/quality": "^3.0.0",
91
+ "@json-to-office/shared": "^3.0.0",
92
+ "@json-to-office/shared-docx": "^3.0.0",
93
+ "@json-to-office/shared-pptx": "^3.0.0"
94
94
  },
95
95
  "devDependencies": {
96
96
  "@types/lodash.debounce": "4.0.9",
@@ -101,7 +101,8 @@
101
101
  "@vitejs/plugin-react": "4.3.4",
102
102
  "esbuild": "0.24.0",
103
103
  "tsup": "8.5.0",
104
- "typescript": "5.3.3"
104
+ "typescript": "5.3.3",
105
+ "vscode-json-languageservice": "5.4.0"
105
106
  },
106
107
  "engines": {
107
108
  "node": ">=20.0.0"