@excalimate/mcp-server 0.3.0 → 0.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.
Files changed (41) hide show
  1. package/dist/httpServer.d.ts +1 -1
  2. package/dist/httpServer.d.ts.map +1 -1
  3. package/dist/httpServer.js +6 -25
  4. package/dist/httpServer.js.map +1 -1
  5. package/dist/index.js +12 -7
  6. package/dist/index.js.map +1 -1
  7. package/dist/server/animationTools.d.ts.map +1 -1
  8. package/dist/server/animationTools.js +43 -63
  9. package/dist/server/animationTools.js.map +1 -1
  10. package/dist/server/compositeTools.d.ts +18 -0
  11. package/dist/server/compositeTools.d.ts.map +1 -0
  12. package/dist/server/compositeTools.js +209 -0
  13. package/dist/server/compositeTools.js.map +1 -0
  14. package/dist/server/referenceText.d.ts +2 -2
  15. package/dist/server/referenceText.d.ts.map +1 -1
  16. package/dist/server/referenceText.js +83 -254
  17. package/dist/server/referenceText.js.map +1 -1
  18. package/dist/server/sceneTools.d.ts.map +1 -1
  19. package/dist/server/sceneTools.js +2 -1
  20. package/dist/server/sceneTools.js.map +1 -1
  21. package/dist/server/shareTools.d.ts +6 -3
  22. package/dist/server/shareTools.d.ts.map +1 -1
  23. package/dist/server/shareTools.js +17 -17
  24. package/dist/server/shareTools.js.map +1 -1
  25. package/dist/server/stateContext.d.ts +36 -1
  26. package/dist/server/stateContext.d.ts.map +1 -1
  27. package/dist/server/stateContext.js +157 -13
  28. package/dist/server/stateContext.js.map +1 -1
  29. package/dist/server.d.ts +3 -3
  30. package/dist/server.d.ts.map +1 -1
  31. package/dist/server.js +6 -4
  32. package/dist/server.js.map +1 -1
  33. package/dist/state.d.ts +14 -0
  34. package/dist/state.d.ts.map +1 -1
  35. package/dist/state.js +57 -0
  36. package/dist/state.js.map +1 -1
  37. package/package.json +4 -2
  38. package/dist/shareRoutes.d.ts +0 -4
  39. package/dist/shareRoutes.d.ts.map +0 -1
  40. package/dist/shareRoutes.js +0 -44
  41. package/dist/shareRoutes.js.map +0 -1
@@ -1,268 +1,97 @@
1
- export const REFERENCE_TEXT = `# Excalimate MCP Reference
1
+ export const REFERENCE_TEXT = `# Excalimate Reference
2
2
 
3
- ## Excalidraw Element Format
3
+ ## Element Format (base properties)
4
+ { id, type, x, y, width, height, strokeColor, backgroundColor, fillStyle, strokeWidth, opacity, groupIds, angle }
4
5
 
5
- Every element has these base properties:
6
- \`\`\`json
7
- {
8
- "id": "unique-id",
9
- "type": "rectangle|ellipse|diamond|arrow|line|text|freedraw|image",
10
- "x": 100, "y": 200,
11
- "width": 300, "height": 150,
12
- "angle": 0,
13
- "strokeColor": "#1e1e1e",
14
- "backgroundColor": "transparent",
15
- "fillStyle": "solid",
16
- "strokeWidth": 2,
17
- "roughness": 1,
18
- "opacity": 100,
19
- "groupIds": [],
20
- "isDeleted": false
21
- }
22
- \`\`\`
6
+ Types: rectangle, ellipse, diamond, arrow, line, text, freedraw, image
23
7
 
24
- ### Text Elements
25
- \`\`\`json
26
- {
27
- "type": "text",
28
- "text": "Hello World",
29
- "fontSize": 20,
30
- "fontFamily": 5,
31
- "textAlign": "center",
32
- "verticalAlign": "middle"
33
- }
34
- \`\`\`
8
+ Text extra: { text, fontSize, fontFamily: 5, textAlign, verticalAlign }
9
+ Arrow/Line extra: { points: [[0,0],[dx,dy]], endArrowhead: "arrow"|null }
10
+ Bound text: text with containerId → shape with boundElements:[{id,type:"text"}]
35
11
 
36
- ### Arrow/Line Elements
37
- \`\`\`json
38
- {
39
- "type": "arrow",
40
- "points": [[0, 0], [200, 100]],
41
- "startArrowhead": null,
42
- "endArrowhead": "arrow",
43
- "startBinding": null,
44
- "endBinding": null
45
- }
46
- \`\`\`
12
+ ## Colors
13
+ Stroke: #1e1e1e #e03131 #2f9e44 #1971c2 #f08c00 #6741d9 #0c8599 #e8590c
14
+ Fill: transparent #ffc9c9 #b2f2bb #a5d8ff #ffec99 #d0bfff #99e9f2 #ffd8a8
47
15
 
48
- ### Bound Text (Label on Shape)
49
- Create a text element with \`containerId\` pointing to the shape:
50
- \`\`\`json
51
- { "type": "text", "containerId": "shape-id", ... }
52
- \`\`\`
53
- And add to the shape: \`"boundElements": [{"id": "text-id", "type": "text"}]\`
54
-
55
- ## Color Palettes
56
-
57
- **Stroke**: #1e1e1e, #e03131, #2f9e44, #1971c2, #f08c00, #6741d9, #0c8599, #e8590c
58
- **Background**: transparent, #ffc9c9, #b2f2bb, #a5d8ff, #ffec99, #d0bfff, #99e9f2, #ffd8a8
59
-
60
- ## Animatable Properties
61
-
62
- | Property | Range | Description |
63
- |----------|-------|-------------|
64
- | opacity | 0–1 | Element visibility (0=hidden, 1=visible) |
65
- | translateX | px | Horizontal position offset |
66
- | translateY | px | Vertical position offset |
67
- | scaleX | 0.1+ | Horizontal scale (1=normal) |
68
- | scaleY | 0.1+ | Vertical scale (1=normal) |
69
- | rotation | degrees | Rotation angle |
70
- | drawProgress | 0–1 | Stroke draw-on progress (for lines/arrows) |
71
-
72
- ## Easing Types
16
+ ## Animation Properties
17
+ opacity (0–1), translateX/Y (px), scaleX/Y (0.1+), rotation (deg), drawProgress (0–1, lines/arrows only)
73
18
 
19
+ ## Easings
74
20
  linear, easeIn, easeOut, easeInOut, easeInQuad, easeOutQuad, easeInOutQuad,
75
21
  easeInCubic, easeOutCubic, easeInOutCubic, easeInBack, easeOutBack, easeInOutBack,
76
22
  easeInElastic, easeOutElastic, easeInBounce, easeOutBounce, step
77
23
 
78
- ## Workflow
79
-
80
- 1. Call \`read_me\` (this tool) to get the reference
81
- 2. Call \`create_scene\` with Excalidraw elements JSON (or \`clear_scene\` to start fresh)
82
- 3. Call \`add_keyframe\` or \`add_keyframes_batch\` to animate elements
83
- 4. Use \`create_sequence\` for reveal animations
84
- 5. Call \`set_clip_range\` to set export bounds
85
- 6. Call \`save_checkpoint\` to persist
86
- 7. User opens the checkpoint in the Excalimate web app for preview/export
87
-
88
- Use \`clear_scene\` to reset everything (elements + animations) or \`clear_animation\` to keep elements but remove all keyframes.
89
-
90
- ## Example: Fade-in Rectangle
91
-
92
- \`\`\`
93
- 1. create_scene: [{"id":"rect1","type":"rectangle","x":100,"y":100,"width":200,"height":100,...}]
94
- 2. add_keyframe: {targetId:"rect1", property:"opacity", time:0, value:0}
95
- 3. add_keyframe: {targetId:"rect1", property:"opacity", time:1000, value:1, easing:"easeOut"}
96
- \`\`\`
24
+ ## Preferred Workflow
25
+ 1. Use **create_animated_scene** — one call for elements + keyframes + sequences + camera + clip range
26
+ 2. Use add_keyframes_batch or create_sequence for incremental changes
27
+ 3. Use save_checkpoint to persist
28
+ 4. Verify with animations_of_item, items_visible_in_camera, is_camera_centered
29
+
30
+ ## Key Tips
31
+ - Set opacity 0 at time 0 for elements that appear later
32
+ - Bound text inherits container animation
33
+ - drawProgress only works on arrows/lines
34
+ - easeOutBack = nice bounce; easeInOutCubic = best general-purpose
35
+ - Camera: scale > 1 = zoomed out, < 1 = zoomed in
36
+ - Set clip range before saving
97
37
  `;
98
- export const EXAMPLES_TEXT = `# Excalimate Few-Shot Examples
99
-
100
- ## Example 1: Single Rectangle
101
- \`\`\`
102
- create_scene({ elements: '[{"id":"box1","type":"rectangle","x":200,"y":150,"width":250,"height":120,"strokeColor":"#1971c2","backgroundColor":"#a5d8ff","fillStyle":"solid"}]' })
103
- \`\`\`
104
-
105
- ## Example 2: Rectangle with Bound Text Label
106
- \`\`\`
107
- create_scene({ elements: '[{"id":"server","type":"rectangle","x":100,"y":100,"width":200,"height":80,"strokeColor":"#1e1e1e","backgroundColor":"#a5d8ff","fillStyle":"solid","boundElements":[{"id":"server-label","type":"text"}]},{"id":"server-label","type":"text","x":140,"y":125,"width":120,"height":30,"text":"API Server","fontSize":20,"fontFamily":5,"textAlign":"center","verticalAlign":"middle","containerId":"server"}]' })
108
- \`\`\`
109
-
110
- ## Example 3: Two Shapes Connected by Arrow
111
- \`\`\`
112
- create_scene({ elements: '[{"id":"A","type":"rectangle","x":100,"y":200,"width":150,"height":80,"strokeColor":"#1e1e1e","backgroundColor":"#b2f2bb","fillStyle":"solid"},{"id":"B","type":"rectangle","x":500,"y":200,"width":150,"height":80,"strokeColor":"#1e1e1e","backgroundColor":"#a5d8ff","fillStyle":"solid"},{"id":"arrow1","type":"arrow","x":250,"y":240,"width":250,"height":0,"points":[[0,0],[250,0]],"endArrowhead":"arrow","startBinding":{"elementId":"A","focus":0,"gap":1},"endBinding":{"elementId":"B","focus":0,"gap":1}}]' })
113
- \`\`\`
114
-
115
- ## Example 4: Ellipse and Diamond
116
- \`\`\`
117
- add_elements({ elements: '[{"id":"circle1","type":"ellipse","x":300,"y":100,"width":120,"height":120,"strokeColor":"#e03131","backgroundColor":"#ffc9c9","fillStyle":"solid"},{"id":"diamond1","type":"diamond","x":500,"y":90,"width":140,"height":140,"strokeColor":"#6741d9","backgroundColor":"#d0bfff","fillStyle":"solid"}]' })
118
- \`\`\`
119
-
120
- ## Example 5: Multi-Point Line
121
- \`\`\`
122
- add_elements({ elements: '[{"id":"line1","type":"line","x":100,"y":300,"width":400,"height":80,"points":[[0,0],[200,-80],[400,0]],"strokeColor":"#e03131","strokeWidth":3}]' })
123
- \`\`\`
124
-
125
- ## Example 6: Standalone Text
126
- \`\`\`
127
- add_elements({ elements: '[{"id":"title","type":"text","x":200,"y":50,"width":300,"height":50,"text":"Architecture Overview","fontSize":36,"fontFamily":5,"textAlign":"center","strokeColor":"#1e1e1e"}]' })
128
- \`\`\`
129
-
130
- ---
131
-
132
- # Animation Examples
133
-
134
- ## Example 7: Fade In
135
- \`\`\`
136
- add_keyframe({ targetId: "box1", property: "opacity", time: 0, value: 0 })
137
- add_keyframe({ targetId: "box1", property: "opacity", time: 800, value: 1, easing: "easeOut" })
138
- \`\`\`
139
-
140
- ## Example 8: Slide In from Left
141
- \`\`\`
142
- add_keyframes_batch({ keyframes: '[{"targetId":"box1","property":"translateX","time":0,"value":-300},{"targetId":"box1","property":"translateX","time":1000,"value":0,"easing":"easeOutCubic"},{"targetId":"box1","property":"opacity","time":0,"value":0},{"targetId":"box1","property":"opacity","time":500,"value":1,"easing":"easeOut"}]' })
143
- \`\`\`
144
-
145
- ## Example 9: Pop In from Center (Scale Up with Bounce)
146
- \`\`\`
147
- add_keyframes_batch({ keyframes: '[{"targetId":"box1","property":"scaleX","time":0,"value":0.3,"scaleOrigin":"center"},{"targetId":"box1","property":"scaleY","time":0,"value":0.3,"scaleOrigin":"center"},{"targetId":"box1","property":"scaleX","time":600,"value":1,"easing":"easeOutBack","scaleOrigin":"center"},{"targetId":"box1","property":"scaleY","time":600,"value":1,"easing":"easeOutBack","scaleOrigin":"center"},{"targetId":"box1","property":"opacity","time":0,"value":0},{"targetId":"box1","property":"opacity","time":300,"value":1}]' })
148
- \`\`\`
149
-
150
- ## Example 9b: Scale from Bottom Edge
151
- \`\`\`
152
- add_scale_animation({ targetId: "box1", origin: "bottom", keyframes: '[{"time":0,"scaleX":1,"scaleY":0},{"time":800,"scaleX":1,"scaleY":1,"easing":"easeOutCubic"}]' })
153
- \`\`\`
154
- Scale origins: center, top-left, top-right, bottom-left, bottom-right, top, bottom, left, right.
155
- Add "scaleOrigin" per scaleX/scaleY keyframe in add_keyframes_batch, or use add_scale_animation for a single element.
156
-
157
- ## Example 10: Draw In an Arrow (Stroke Animation)
158
- \`\`\`
159
- add_keyframe({ targetId: "arrow1", property: "drawProgress", time: 0, value: 0 })
160
- add_keyframe({ targetId: "arrow1", property: "drawProgress", time: 1200, value: 1, easing: "easeInOut" })
161
- \`\`\`
162
-
163
- ## Example 11: Sequential Reveal — A → Arrow → B (Most Common Pattern)
164
- \`\`\`
165
- add_keyframes_batch({ keyframes: '[
166
- {"targetId":"A","property":"opacity","time":0,"value":0},
167
- {"targetId":"A","property":"opacity","time":600,"value":1,"easing":"easeOut"},
168
- {"targetId":"arrow1","property":"opacity","time":0,"value":0},
169
- {"targetId":"arrow1","property":"opacity","time":600,"value":0},
170
- {"targetId":"arrow1","property":"opacity","time":700,"value":1},
171
- {"targetId":"arrow1","property":"drawProgress","time":600,"value":0},
172
- {"targetId":"arrow1","property":"drawProgress","time":1800,"value":1,"easing":"easeInOut"},
173
- {"targetId":"B","property":"opacity","time":0,"value":0},
174
- {"targetId":"B","property":"opacity","time":1800,"value":0},
175
- {"targetId":"B","property":"opacity","time":2400,"value":1,"easing":"easeOut"}
176
- ]' })
177
- \`\`\`
178
-
179
- ## Example 12: Bidirectional Flow — A ↔ B
180
- \`\`\`
181
- add_keyframes_batch({ keyframes: '[
182
- {"targetId":"A","property":"opacity","time":0,"value":0},
183
- {"targetId":"A","property":"opacity","time":500,"value":1,"easing":"easeOut"},
184
- {"targetId":"arrowAB","property":"opacity","time":0,"value":0},
185
- {"targetId":"arrowAB","property":"opacity","time":500,"value":1},
186
- {"targetId":"arrowAB","property":"drawProgress","time":500,"value":0},
187
- {"targetId":"arrowAB","property":"drawProgress","time":1500,"value":1,"easing":"easeInOut"},
188
- {"targetId":"B","property":"opacity","time":0,"value":0},
189
- {"targetId":"B","property":"opacity","time":1500,"value":0},
190
- {"targetId":"B","property":"opacity","time":2000,"value":1,"easing":"easeOut"},
191
- {"targetId":"arrowBA","property":"opacity","time":0,"value":0},
192
- {"targetId":"arrowBA","property":"opacity","time":2000,"value":1},
193
- {"targetId":"arrowBA","property":"drawProgress","time":2000,"value":0},
194
- {"targetId":"arrowBA","property":"drawProgress","time":3000,"value":1,"easing":"easeInOut"}
38
+ // Use string concatenation for EXAMPLES_TEXT to avoid backtick escaping issues
39
+ const CB = '```'; // code block delimiter
40
+ export const EXAMPLES_TEXT = `# Excalimate Examples
41
+
42
+ ## Complete Scene (preferred one call)
43
+ ${CB}
44
+ create_animated_scene({
45
+ elements: '[
46
+ {"id":"A","type":"rectangle","x":100,"y":200,"width":150,"height":80,"strokeColor":"#1e1e1e","backgroundColor":"#b2f2bb","fillStyle":"solid","boundElements":[{"id":"A-label","type":"text"}]},
47
+ {"id":"A-label","type":"text","x":120,"y":225,"width":110,"height":30,"text":"Service A","fontSize":20,"fontFamily":5,"textAlign":"center","verticalAlign":"middle","containerId":"A"},
48
+ {"id":"B","type":"rectangle","x":500,"y":200,"width":150,"height":80,"strokeColor":"#1e1e1e","backgroundColor":"#a5d8ff","fillStyle":"solid","boundElements":[{"id":"B-label","type":"text"}]},
49
+ {"id":"B-label","type":"text","x":520,"y":225,"width":110,"height":30,"text":"Service B","fontSize":20,"fontFamily":5,"textAlign":"center","verticalAlign":"middle","containerId":"B"},
50
+ {"id":"arrow1","type":"arrow","x":250,"y":240,"width":250,"height":0,"points":[[0,0],[250,0]],"endArrowhead":"arrow"}
51
+ ]',
52
+ keyframes: '[
53
+ {"targetId":"A","property":"opacity","time":0,"value":0},
54
+ {"targetId":"A","property":"opacity","time":600,"value":1,"easing":"easeOut"},
55
+ {"targetId":"arrow1","property":"opacity","time":0,"value":0},
56
+ {"targetId":"arrow1","property":"opacity","time":600,"value":0},
57
+ {"targetId":"arrow1","property":"opacity","time":700,"value":1},
58
+ {"targetId":"arrow1","property":"drawProgress","time":600,"value":0},
59
+ {"targetId":"arrow1","property":"drawProgress","time":1800,"value":1,"easing":"easeInOut"},
60
+ {"targetId":"B","property":"opacity","time":0,"value":0},
61
+ {"targetId":"B","property":"opacity","time":1800,"value":0},
62
+ {"targetId":"B","property":"opacity","time":2400,"value":1,"easing":"easeOut"}
63
+ ]',
64
+ clipEnd: 3000,
65
+ cameraFrame: { x: 375, y: 240, width: 800 }
66
+ })
67
+ ${CB}
68
+
69
+ ## Staggered Reveal (simpler alternative)
70
+ ${CB}
71
+ create_animated_scene({
72
+ elements: '[...elements...]',
73
+ sequences: '[{"elementIds":["title","box1","arrow1","box2"],"delay":400,"duration":600}]',
74
+ clipEnd: 3500
75
+ })
76
+ ${CB}
77
+
78
+ ## Scale Animation (pop-in from center)
79
+ ${CB}
80
+ add_scale_animation({ targetId: "box1", origin: "center", keyframes: '[{"time":0,"scaleX":0.3,"scaleY":0.3},{"time":600,"scaleX":1,"scaleY":1,"easing":"easeOutBack"}]' })
81
+ ${CB}
82
+ Origins: center, top-left, top-right, bottom-left, bottom-right, top, bottom, left, right
83
+
84
+ ## Camera Pan + Zoom
85
+ ${CB}
86
+ set_camera_frame({ x: 300, y: 200, width: 800 })
87
+ add_camera_keyframes_batch({ keyframes: '[
88
+ {"property":"translateX","time":0,"value":-200},
89
+ {"property":"translateX","time":3000,"value":200,"easing":"easeInOut"},
90
+ {"property":"scaleX","time":0,"value":1.5},
91
+ {"property":"scaleY","time":0,"value":1.5},
92
+ {"property":"scaleX","time":3000,"value":1,"easing":"easeInOutCubic"},
93
+ {"property":"scaleY","time":3000,"value":1,"easing":"easeInOutCubic"}
195
94
  ]' })
196
- \`\`\`
197
-
198
- ## Example 13: Staggered Reveal via create_sequence
199
- \`\`\`
200
- create_sequence({ elementIds: ["title","box1","arrow1","box2","arrow2","box3"], property: "opacity", startTime: 0, delay: 400, duration: 600 })
201
- \`\`\`
202
- Result: title at 0ms, box1 at 400ms, arrow1 at 800ms, box2 at 1200ms, arrow2 at 1600ms, box3 at 2000ms.
203
-
204
- ## Example 14: Camera Pan
205
- \`\`\`
206
- set_camera_frame({ x: 300, y: 200, width: 800, aspectRatio: "16:9" })
207
- add_camera_keyframe({ property: "translateX", time: 0, value: -200 })
208
- add_camera_keyframe({ property: "translateX", time: 3000, value: 200, easing: "easeInOut" })
209
- \`\`\`
210
-
211
- ## Example 15: Camera Zoom In
212
- \`\`\`
213
- add_camera_keyframe({ property: "scaleX", time: 0, value: 2 })
214
- add_camera_keyframe({ property: "scaleY", time: 0, value: 2 })
215
- add_camera_keyframe({ property: "scaleX", time: 2000, value: 1, easing: "easeInOutCubic" })
216
- add_camera_keyframe({ property: "scaleY", time: 2000, value: 1, easing: "easeInOutCubic" })
217
- \`\`\`
218
-
219
- ## Example 16: Clip Range + Save
220
- \`\`\`
221
- set_clip_range({ start: 0, end: 5000 })
222
- save_checkpoint({ id: "my-animation" })
223
- \`\`\`
224
-
225
- ---
226
-
227
- # Tips
228
-
229
- 1. Always call create_scene first (or clear_scene to start fresh), then animate.
230
- 2. Use add_keyframes_batch for efficiency — one call for many keyframes.
231
- 3. Use create_sequence for simple staggered reveals.
232
- 4. Bound text inherits container animation — animating arrow opacity also hides its label.
233
- 5. drawProgress only works on arrows and lines.
234
- 6. easeOutBack gives a nice bounce for pop-in effects.
235
- 7. easeInOutCubic is the best general-purpose easing.
236
- 8. Set elements to opacity 0 at time 0 if they should appear later.
237
- 9. Set clip range before saving — it defines what gets exported.
238
- 10. Camera scale > 1 = zoomed out, < 1 = zoomed in.
239
- 11. Use delete_items to remove elements AND their animation tracks in one call.
240
- 12. Verify your work with animations_of_item, items_visible_in_camera, are_items_in_line, is_camera_centered.
241
-
242
- ## Example 17: Verify Animation
243
- \`\`\`
244
- animations_of_item({ targetId: "box1" })
245
- // Returns:
246
- // opacity:
247
- // 0ms 0% ↑ 100% 600ms (easeOut)
248
-
249
- items_visible_in_camera({ time: 1000 })
250
- // Returns: 5/8 items visible (62%) at 1000ms
251
-
252
- are_items_in_line({ ids: ["box1","box2","box3"], axis: "horizontal" })
253
- // Returns: ✅ Aligned (max deviation: 3px)
254
-
255
- is_camera_centered({ axis: "both", time: 0 })
256
- // Returns: ✅ Centered (offsets: dx=5 dy=2)
257
- \`\`\`
258
-
259
- ## Example 18: Delete and Rebuild
260
- \`\`\`
261
- delete_items({ ids: ["old_box", "old_arrow"] })
262
- // Removes elements + all their animation tracks
263
-
264
- clear_scene()
265
- // Nuclear option: removes everything
266
- \`\`\`
95
+ ${CB}
267
96
  `;
268
97
  //# sourceMappingURL=referenceText.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"referenceText.js","sourceRoot":"","sources":["../../src/server/referenceText.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgG7B,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyK5B,CAAC"}
1
+ {"version":3,"file":"referenceText.js","sourceRoot":"","sources":["../../src/server/referenceText.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoC7B,CAAC;AAEF,+EAA+E;AAC/E,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,uBAAuB;AACzC,MAAM,CAAC,MAAM,aAAa,GAAG;;;EAG3B,EAAE;;;;;;;;;;;;;;;;;;;;;;;;EAwBF,EAAE;;;EAGF,EAAE;;;;;;EAMF,EAAE;;;EAGF,EAAE;;EAEF,EAAE;;;;EAIF,EAAE;;;;;;;;;;EAUF,EAAE;CACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"sceneTools.d.ts","sourceRoot":"","sources":["../../src/server/sceneTools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,YAAY,EACjB,iBAAiB,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,GAC5C,IAAI,CAsHN"}
1
+ {"version":3,"file":"sceneTools.d.ts","sourceRoot":"","sources":["../../src/server/sceneTools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,YAAY,EACjB,iBAAiB,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,GAC5C,IAAI,CAsHN"}
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { getSceneElementsJSON } from './stateContext.js';
2
3
  export function registerSceneTools(server, ctx, normalizeElements) {
3
4
  ctx.mutatingTool('create_scene', 'Create or replace the Excalidraw scene with the given elements.', { elements: z.string().describe('JSON string of Excalidraw elements array') }, async ({ elements }) => {
4
5
  try {
@@ -60,7 +61,7 @@ export function registerSceneTools(server, ctx, normalizeElements) {
60
61
  }
61
62
  });
62
63
  server.tool('get_scene', 'Return the current scene elements as JSON.', {}, async () => ({
63
- content: [{ type: 'text', text: JSON.stringify(ctx.getState().scene.elements, null, 2) }],
64
+ content: [{ type: 'text', text: getSceneElementsJSON() }],
64
65
  }));
65
66
  ctx.mutatingTool('clear_scene', 'Clear all elements and all animation tracks. Resets the scene to a blank canvas.', {}, async () => {
66
67
  const state = ctx.getState();
@@ -1 +1 @@
1
- {"version":3,"file":"sceneTools.js","sourceRoot":"","sources":["../../src/server/sceneTools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sceneTools.js","sourceRoot":"","sources":["../../src/server/sceneTools.ts"],"names":[],"mappings":"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"}
@@ -2,10 +2,13 @@
2
2
  * MCP tool: share_project
3
3
  *
4
4
  * Creates an E2E encrypted share URL containing the complete project state.
5
- * Uses AES-256-GCM encryption — the key is returned to the AI in the URL
6
- * hash fragment and never stored on the server.
5
+ * Uploads to the Excalimate cloud share service (Cloudflare Worker + R2)
6
+ * so links persist even after the MCP server restarts.
7
+ *
8
+ * Uses AES-256-GCM encryption — the key is returned in the URL hash
9
+ * fragment and never stored on any server.
7
10
  */
8
11
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
9
12
  import type { StateContext } from './stateContext.js';
10
- export declare function registerShareTools(server: McpServer, ctx: StateContext, serverPort: number): void;
13
+ export declare function registerShareTools(server: McpServer, ctx: StateContext): void;
11
14
  //# sourceMappingURL=shareTools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shareTools.d.ts","sourceRoot":"","sources":["../../src/server/shareTools.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAwBtD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,YAAY,EACjB,UAAU,EAAE,MAAM,GACjB,IAAI,CA6DN"}
1
+ {"version":3,"file":"shareTools.d.ts","sourceRoot":"","sources":["../../src/server/shareTools.ts"],"names":[],"mappings":"AACA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAqBtD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,YAAY,GAChB,IAAI,CA2DN"}
@@ -3,40 +3,42 @@
3
3
  * MCP tool: share_project
4
4
  *
5
5
  * Creates an E2E encrypted share URL containing the complete project state.
6
- * Uses AES-256-GCM encryption — the key is returned to the AI in the URL
7
- * hash fragment and never stored on the server.
6
+ * Uploads to the Excalimate cloud share service (Cloudflare Worker + R2)
7
+ * so links persist even after the MCP server restarts.
8
+ *
9
+ * Uses AES-256-GCM encryption — the key is returned in the URL hash
10
+ * fragment and never stored on any server.
8
11
  */
9
12
  import crypto from 'node:crypto';
10
13
  import { z } from 'zod';
11
14
  import { promisify } from 'node:util';
12
15
  import { gzip } from 'node:zlib';
13
16
  const gzipAsync = promisify(gzip);
17
+ const DEFAULT_SHARE_API = 'https://share.excalimate.com';
14
18
  /**
15
19
  * Encrypt data with AES-256-GCM.
16
20
  * Returns: [IV (12 bytes)] [ciphertext + GCM auth tag]
17
21
  */
18
22
  function encrypt(plaintext) {
19
- const key = crypto.randomBytes(32); // 256-bit key
20
- const iv = crypto.randomBytes(12); // 96-bit IV for GCM
23
+ const key = crypto.randomBytes(32);
24
+ const iv = crypto.randomBytes(12);
21
25
  const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
22
26
  const enc = Buffer.concat([cipher.update(plaintext), cipher.final()]);
23
- const tag = cipher.getAuthTag(); // 16 bytes
24
- // Layout: [IV (12)] [ciphertext] [GCM tag (16)]
27
+ const tag = cipher.getAuthTag();
25
28
  const result = Buffer.concat([iv, enc, tag]);
26
- // Export key as base64url (no padding) for shortest URL
27
29
  const keyBase64url = key.toString('base64url');
28
30
  return { encrypted: result, keyBase64url };
29
31
  }
30
- export function registerShareTools(server, ctx, serverPort) {
31
- server.tool('share_project', 'Create an E2E encrypted share URL for the current project. The URL contains the encryption key in the hash fragment (never sent to the server). Returns the shareable URL.', {
32
+ export function registerShareTools(server, ctx) {
33
+ server.tool('share_project', 'Create an E2E encrypted share URL for the current project. Uploads to the Excalimate cloud share service so links persist permanently (30 days). The encryption key is in the URL hash fragment (never sent to any server). Returns the shareable URL.', {
32
34
  baseUrl: z.string().optional().describe('Base URL for the share link (default: https://excalimate.com)'),
33
- }, async ({ baseUrl }) => {
35
+ shareApi: z.string().optional().describe('Share service API URL (default: https://share.excalimate.com)'),
36
+ }, async ({ baseUrl, shareApi }) => {
34
37
  const state = ctx.getState();
35
38
  if (!state.scene.elements || state.scene.elements.length === 0) {
36
39
  return { content: [{ type: 'text', text: 'Error: No elements in the scene. Create a scene first.' }] };
37
40
  }
38
41
  try {
39
- // Build the full project payload
40
42
  const payload = JSON.stringify({
41
43
  scene: state.scene,
42
44
  timeline: state.timeline,
@@ -44,12 +46,11 @@ export function registerShareTools(server, ctx, serverPort) {
44
46
  clipEnd: state.clipEnd,
45
47
  cameraFrame: state.cameraFrame,
46
48
  });
47
- // Compress + encrypt
48
49
  const compressed = await gzipAsync(Buffer.from(payload, 'utf-8'));
49
50
  const { encrypted, keyBase64url } = encrypt(compressed);
50
- // Upload to the local share endpoint
51
- const shareUrl = `http://localhost:${serverPort}/share`;
52
- const response = await fetch(shareUrl, {
51
+ // Upload to the cloud share service (persists across MCP server restarts)
52
+ const apiUrl = shareApi ?? process.env.EXCALIMATE_SHARE_API ?? DEFAULT_SHARE_API;
53
+ const response = await fetch(`${apiUrl}/share`, {
53
54
  method: 'POST',
54
55
  headers: { 'Content-Type': 'application/octet-stream' },
55
56
  body: new Uint8Array(encrypted),
@@ -59,7 +60,6 @@ export function registerShareTools(server, ctx, serverPort) {
59
60
  return { content: [{ type: 'text', text: `Error uploading share: ${err}` }] };
60
61
  }
61
62
  const { id } = await response.json();
62
- // Build the shareable URL — key in hash fragment (never sent to server)
63
63
  const appBase = baseUrl ?? 'https://excalimate.com';
64
64
  const fullUrl = `${appBase}/#share=${id},${keyBase64url}`;
65
65
  return {
@@ -69,7 +69,7 @@ export function registerShareTools(server, ctx, serverPort) {
69
69
  `Elements: ${state.scene.elements.length}, ` +
70
70
  `Tracks: ${state.timeline.tracks.length}, ` +
71
71
  `Encrypted size: ${(encrypted.length / 1024).toFixed(1)} KB\n\n` +
72
- `The encryption key is in the URL hash — the server only stores an encrypted blob it cannot read.`,
72
+ `Link is valid for 30 days. The encryption key is in the URL hash — no server can read the content.`,
73
73
  }],
74
74
  };
75
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"shareTools.js","sourceRoot":"","sources":["../../src/server/shareTools.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD;;;;;;GAMG;AAGH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC;;;GAGG;AACH,SAAS,OAAO,CAAC,SAAiB;IAChC,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc;IAClD,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAE,oBAAoB;IACxD,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC7D,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACtE,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,WAAW;IAE5C,gDAAgD;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAE7C,wDAAwD;IACxD,MAAM,YAAY,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAE/C,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,MAAiB,EACjB,GAAiB,EACjB,UAAkB;IAElB,MAAM,CAAC,IAAI,CACT,eAAe,EACf,4KAA4K,EAC5K;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+DAA+D,CAAC;KACzG,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/D,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,wDAAwD,EAAE,CAAC,EAAE,CAAC;QACzG,CAAC;QAED,IAAI,CAAC;YACH,iCAAiC;YACjC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;gBAC7B,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B,CAAC,CAAC;YAEH,qBAAqB;YACrB,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;YAClE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;YAExD,qCAAqC;YACrC,MAAM,QAAQ,GAAG,oBAAoB,UAAU,QAAQ,CAAC;YACxD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;gBACrC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE;gBACvD,IAAI,EAAE,IAAI,UAAU,CAAC,SAAS,CAAC;aAChC,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAClC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,0BAA0B,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC;YAChF,CAAC;YAED,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAoB,CAAC;YAEvD,wEAAwE;YACxE,MAAM,OAAO,GAAG,OAAO,IAAI,wBAAwB,CAAC;YACpD,MAAM,OAAO,GAAG,GAAG,OAAO,WAAW,EAAE,IAAI,YAAY,EAAE,CAAC;YAE1D,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,uBAAuB,OAAO,MAAM;4BACxC,aAAa,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,IAAI;4BAC5C,WAAW,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,IAAI;4BAC3C,mBAAmB,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;4BAChE,kGAAkG;qBACrG,CAAC;aACH,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAC7E,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"shareTools.js","sourceRoot":"","sources":["../../src/server/shareTools.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,42 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { ServerState } from '../types.js';
3
- export type StateChangeListener = (delta: Partial<ServerState>) => void;
3
+ /**
4
+ * Delta message format sent over SSE.
5
+ * Instead of full state areas, we send fine-grained changes:
6
+ * - Scene: only added/updated/removed elements
7
+ * - Timeline: only upserted/removed tracks
8
+ * - Clip and cameraFrame: sent as-is (small payloads)
9
+ */
10
+ export interface StateDelta {
11
+ scene?: {
12
+ /** Elements that were added or have changed properties */
13
+ upsert: any[];
14
+ /** Element IDs that were removed */
15
+ removed: string[];
16
+ };
17
+ timeline?: {
18
+ /** Tracks that were added or have changed keyframes */
19
+ upsertedTracks: any[];
20
+ /** Track IDs that were removed */
21
+ removedTrackIds: string[];
22
+ /** Timeline metadata (duration, fps) — only sent if changed */
23
+ meta?: {
24
+ duration: number;
25
+ fps: number;
26
+ };
27
+ };
28
+ clipStart?: number;
29
+ clipEnd?: number;
30
+ cameraFrame?: ServerState['cameraFrame'];
31
+ }
32
+ export type StateChangeListener = (delta: StateDelta) => void;
4
33
  export declare function getSharedState(): ServerState;
34
+ /** Get the full state as a JSON string, using cache when unchanged. */
35
+ export declare function getSharedStateJSON(): string;
36
+ /** Get scene elements as a pretty JSON string, using cache when unchanged. */
37
+ export declare function getSceneElementsJSON(): string;
38
+ /** Get timeline + clip + camera as a pretty JSON string, using cache when unchanged. */
39
+ export declare function getTimelineJSON(): string;
5
40
  export interface StateContext {
6
41
  getState: () => ServerState;
7
42
  updateState: (newState: ServerState) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"stateContext.d.ts","sourceRoot":"","sources":["../../src/server/stateContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;AAKxE,wBAAgB,cAAc,IAAI,WAAW,CAAyB;AAEtE,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,WAAW,CAAC;IAC5B,WAAW,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7C,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,yDAAyD;IACzD,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,aAAa,GAAG,KAAK,KAAK,IAAI,CAAC;IACjF,YAAY,EAAE,CACZ,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,GAAG,EACX,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAAE,CAAC;IAC9E,wFAAwF;IACxF,UAAU,CAAC,EAAE,KAAK,CAAC,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,aAAa,CAAC,KAC9D,IAAI,CAAC;CACX;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,EACjB,aAAa,CAAC,EAAE,mBAAmB,GAClC,YAAY,CAgFd"}
1
+ {"version":3,"file":"stateContext.d.ts","sourceRoot":"","sources":["../../src/server/stateContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE;QACN,0DAA0D;QAC1D,MAAM,EAAE,GAAG,EAAE,CAAC;QACd,oCAAoC;QACpC,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,uDAAuD;QACvD,cAAc,EAAE,GAAG,EAAE,CAAC;QACtB,kCAAkC;QAClC,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,+DAA+D;QAC/D,IAAI,CAAC,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC;KAC1C,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;CAC1C;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AAM9D,wBAAgB,cAAc,IAAI,WAAW,CAAyB;AAatE,uEAAuE;AACvE,wBAAgB,kBAAkB,IAAI,MAAM,CAK3C;AAED,8EAA8E;AAC9E,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AAED,wFAAwF;AACxF,wBAAgB,eAAe,IAAI,MAAM,CAUxC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,WAAW,CAAC;IAC5B,WAAW,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7C,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,yDAAyD;IACzD,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,aAAa,GAAG,KAAK,KAAK,IAAI,CAAC;IACjF,YAAY,EAAE,CACZ,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,GAAG,EACX,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAAE,CAAC;IAC9E,wFAAwF;IACxF,UAAU,CAAC,EAAE,KAAK,CAAC,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,aAAa,CAAC,KAC9D,IAAI,CAAC;CACX;AAqGD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,EACjB,aAAa,CAAC,EAAE,mBAAmB,GAClC,YAAY,CA+Gd"}