@clipform/mcp-server 1.0.0 → 1.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/dist/lib/api-client.d.ts +5 -0
- package/dist/lib/api-client.js +47 -0
- package/dist/lib/api-client.js.map +1 -1
- package/dist/lib/config.d.ts +1 -0
- package/dist/lib/config.js +63 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/prompts.d.ts +2 -0
- package/dist/prompts.js +123 -0
- package/dist/prompts.js.map +1 -0
- package/dist/server.js +45 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/attach-question-audio.d.ts +2 -0
- package/dist/tools/attach-question-audio.js +37 -0
- package/dist/tools/attach-question-audio.js.map +1 -0
- package/dist/tools/delete-question-media.d.ts +2 -0
- package/dist/tools/delete-question-media.js +29 -0
- package/dist/tools/delete-question-media.js.map +1 -0
- package/dist/tools/generate-slideshow.d.ts +2 -0
- package/dist/tools/generate-slideshow.js +52 -0
- package/dist/tools/generate-slideshow.js.map +1 -0
- package/dist/tools/generate-tts.d.ts +2 -0
- package/dist/tools/generate-tts.js +48 -0
- package/dist/tools/generate-tts.js.map +1 -0
- package/dist/tools/get-daily-content.d.ts +2 -0
- package/dist/tools/get-daily-content.js +66 -0
- package/dist/tools/get-daily-content.js.map +1 -0
- package/dist/tools/get-question-media.d.ts +2 -0
- package/dist/tools/get-question-media.js +39 -0
- package/dist/tools/get-question-media.js.map +1 -0
- package/dist/tools/get-trivia.d.ts +2 -0
- package/dist/tools/get-trivia.js +49 -0
- package/dist/tools/get-trivia.js.map +1 -0
- package/dist/tools/log-generation.d.ts +2 -0
- package/dist/tools/log-generation.js +34 -0
- package/dist/tools/log-generation.js.map +1 -0
- package/dist/tools/lookup-country.d.ts +2 -0
- package/dist/tools/lookup-country.js +38 -0
- package/dist/tools/lookup-country.js.map +1 -0
- package/dist/tools/search-images.d.ts +2 -0
- package/dist/tools/search-images.js +36 -0
- package/dist/tools/search-images.js.map +1 -0
- package/dist/tools/search-knowledge.d.ts +2 -0
- package/dist/tools/search-knowledge.js +40 -0
- package/dist/tools/search-knowledge.js.map +1 -0
- package/dist/tools/search-news.d.ts +2 -0
- package/dist/tools/search-news.js +38 -0
- package/dist/tools/search-news.js.map +1 -0
- package/dist/tools/search-videos.d.ts +2 -0
- package/dist/tools/search-videos.js +37 -0
- package/dist/tools/search-videos.js.map +1 -0
- package/dist/tools/set-question-logic.d.ts +2 -0
- package/dist/tools/set-question-logic.js +54 -0
- package/dist/tools/set-question-logic.js.map +1 -0
- package/dist/tools/upload-question-media.d.ts +2 -0
- package/dist/tools/upload-question-media.js +41 -0
- package/dist/tools/upload-question-media.js.map +1 -0
- package/package.json +5 -1
package/dist/lib/api-client.d.ts
CHANGED
|
@@ -13,6 +13,11 @@ type ApiResult = {
|
|
|
13
13
|
error: string;
|
|
14
14
|
};
|
|
15
15
|
export declare function callApi(path: string, options?: ApiOptions): Promise<ApiResult>;
|
|
16
|
+
/**
|
|
17
|
+
* Call an internal API endpoint (formgen, media, etc.)
|
|
18
|
+
* Uses INTERNAL_API_KEY for auth and INTERNAL_API_URL as base.
|
|
19
|
+
*/
|
|
20
|
+
export declare function callInternalApi(path: string, options?: Omit<ApiOptions, "token">): Promise<ApiResult>;
|
|
16
21
|
export declare function errorResult(message: string): {
|
|
17
22
|
content: {
|
|
18
23
|
type: "text";
|
package/dist/lib/api-client.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const DASHBOARD_URL = process.env.SERVER_URL || process.env.DASHBOARD_URL || "https://api.clipform.io";
|
|
2
2
|
const API_VERSION = "v1";
|
|
3
|
+
const INTERNAL_API_URL = process.env.INTERNAL_API_URL || DASHBOARD_URL;
|
|
4
|
+
const INTERNAL_API_KEY = process.env.INTERNAL_API_KEY || "";
|
|
3
5
|
export async function callApi(path, options = {}) {
|
|
4
6
|
const { method = "GET", body, params, token } = options;
|
|
5
7
|
let url = `${DASHBOARD_URL}/${API_VERSION}${path}`;
|
|
@@ -42,6 +44,51 @@ export async function callApi(path, options = {}) {
|
|
|
42
44
|
}
|
|
43
45
|
return { ok: true, data };
|
|
44
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Call an internal API endpoint (formgen, media, etc.)
|
|
49
|
+
* Uses INTERNAL_API_KEY for auth and INTERNAL_API_URL as base.
|
|
50
|
+
*/
|
|
51
|
+
export async function callInternalApi(path, options = {}) {
|
|
52
|
+
const { method = "POST", body, params } = options;
|
|
53
|
+
let url = `${INTERNAL_API_URL}${path}`;
|
|
54
|
+
if (params) {
|
|
55
|
+
const searchParams = new URLSearchParams(params);
|
|
56
|
+
url += `?${searchParams.toString()}`;
|
|
57
|
+
}
|
|
58
|
+
const headers = {
|
|
59
|
+
"Content-Type": "application/json",
|
|
60
|
+
};
|
|
61
|
+
if (INTERNAL_API_KEY) {
|
|
62
|
+
headers["Authorization"] = `Bearer ${INTERNAL_API_KEY}`;
|
|
63
|
+
}
|
|
64
|
+
const fetchOptions = { method, headers };
|
|
65
|
+
if (body && method !== "GET") {
|
|
66
|
+
fetchOptions.body = JSON.stringify(body);
|
|
67
|
+
}
|
|
68
|
+
let response;
|
|
69
|
+
try {
|
|
70
|
+
response = await fetch(url, fetchOptions);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
return {
|
|
74
|
+
ok: false,
|
|
75
|
+
status: 0,
|
|
76
|
+
error: `Failed to connect to internal API at ${url}.\n\nError: ${err instanceof Error ? err.message : String(err)}`,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (response.status === 204) {
|
|
80
|
+
return { ok: true, data: {} };
|
|
81
|
+
}
|
|
82
|
+
const data = await response.json();
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
return {
|
|
85
|
+
ok: false,
|
|
86
|
+
status: response.status,
|
|
87
|
+
error: data.error || `Internal API error (${response.status})`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return { ok: true, data };
|
|
91
|
+
}
|
|
45
92
|
export function errorResult(message) {
|
|
46
93
|
return {
|
|
47
94
|
content: [{ type: "text", text: message }],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAAA,MAAM,aAAa,GACjB,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,yBAAyB,CAAC;AACnF,MAAM,WAAW,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.d.ts
CHANGED
package/dist/lib/config.js
CHANGED
|
@@ -12,6 +12,7 @@ export const ANSWER_TYPES = {
|
|
|
12
12
|
is_active: true,
|
|
13
13
|
is_system: false,
|
|
14
14
|
has_options: true,
|
|
15
|
+
max_option_length: 36,
|
|
15
16
|
config_schema: {
|
|
16
17
|
type: "object",
|
|
17
18
|
properties: {
|
|
@@ -137,12 +138,43 @@ export const ANSWER_TYPES = {
|
|
|
137
138
|
},
|
|
138
139
|
},
|
|
139
140
|
},
|
|
141
|
+
binary: {
|
|
142
|
+
label: "Binary",
|
|
143
|
+
description: "Two-option choice - yes/no, true/false, or this vs that",
|
|
144
|
+
is_active: true,
|
|
145
|
+
is_system: false,
|
|
146
|
+
has_options: true,
|
|
147
|
+
max_option_length: 12,
|
|
148
|
+
config_schema: {
|
|
149
|
+
type: "object",
|
|
150
|
+
properties: {
|
|
151
|
+
choice: {
|
|
152
|
+
type: "object",
|
|
153
|
+
properties: {
|
|
154
|
+
enable_branching: {
|
|
155
|
+
type: "boolean",
|
|
156
|
+
label: "Enable branching logic",
|
|
157
|
+
default: true,
|
|
158
|
+
description: "Allow each option to have its own logic path.",
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
content_media_type: {
|
|
163
|
+
enum: ["upload", "recorded"],
|
|
164
|
+
type: "string",
|
|
165
|
+
label: "Content media type",
|
|
166
|
+
description: "How the question media was provided",
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
140
171
|
button: {
|
|
141
172
|
label: "Button",
|
|
142
173
|
description: "Simple button for acknowledgment or navigation",
|
|
143
174
|
is_active: true,
|
|
144
175
|
is_system: false,
|
|
145
176
|
has_options: true,
|
|
177
|
+
max_option_length: 28,
|
|
146
178
|
config_schema: {
|
|
147
179
|
type: "object",
|
|
148
180
|
properties: {
|
|
@@ -248,6 +280,37 @@ export const ANSWER_TYPES = {
|
|
|
248
280
|
label: "Restart button text",
|
|
249
281
|
default: "Start over",
|
|
250
282
|
},
|
|
283
|
+
score_ranges: {
|
|
284
|
+
type: "array",
|
|
285
|
+
label: "Score-based content",
|
|
286
|
+
description: "Show different content based on cumulative score. First matching range wins.",
|
|
287
|
+
items: {
|
|
288
|
+
type: "object",
|
|
289
|
+
required: ["min", "max", "title"],
|
|
290
|
+
properties: {
|
|
291
|
+
min: { type: "integer", label: "Minimum score (inclusive)" },
|
|
292
|
+
max: { type: "integer", label: "Maximum score (inclusive)" },
|
|
293
|
+
title: { type: "string", label: "Title" },
|
|
294
|
+
message: { type: "string", label: "Message" },
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
scoring_results: {
|
|
299
|
+
type: "array",
|
|
300
|
+
label: "Category-based results",
|
|
301
|
+
description: "Results keyed by scoring category. The winning category (highest non-knocked-out score) determines which result is shown.",
|
|
302
|
+
items: {
|
|
303
|
+
type: "object",
|
|
304
|
+
required: ["category", "title"],
|
|
305
|
+
properties: {
|
|
306
|
+
category: { type: "string", label: "Category key (must match keys used in option scores)" },
|
|
307
|
+
title: { type: "string", label: "Title" },
|
|
308
|
+
message: { type: "string", label: "Message" },
|
|
309
|
+
cta_url: { type: "string", label: "CTA URL", format: "uri" },
|
|
310
|
+
cta_text: { type: "string", label: "CTA button text" },
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
},
|
|
251
314
|
},
|
|
252
315
|
},
|
|
253
316
|
},
|
package/dist/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
package/dist/prompts.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
export function registerPrompts(server) {
|
|
2
|
+
server.registerPrompt("create-quiz", {
|
|
3
|
+
title: "Quiz Creation Guide",
|
|
4
|
+
description: "Best practices and defaults for creating a quiz with Clipform",
|
|
5
|
+
}, async () => ({
|
|
6
|
+
messages: [
|
|
7
|
+
{
|
|
8
|
+
role: "user",
|
|
9
|
+
content: { type: "text", text: "How should I create a quiz?" },
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
role: "assistant",
|
|
13
|
+
content: {
|
|
14
|
+
type: "text",
|
|
15
|
+
text: `When creating a quiz (knowledge questions with correct/wrong answers):
|
|
16
|
+
|
|
17
|
+
**Form settings** (set via clipform_update_form after creation):
|
|
18
|
+
- show_step_counter: true (shows "1/5" progress)
|
|
19
|
+
- disable_back_navigation: true (no going back to change answers)
|
|
20
|
+
|
|
21
|
+
**Question defaults:**
|
|
22
|
+
- Randomise answer options (set randomise_options: true in config)
|
|
23
|
+
- 3-4 wrong answers per question for good difficulty
|
|
24
|
+
- One clearly correct answer
|
|
25
|
+
|
|
26
|
+
**Scoring:**
|
|
27
|
+
- Set score: 1 on the correct answer option, score: 0 on wrong answers
|
|
28
|
+
- This enables automatic score tracking throughout the quiz
|
|
29
|
+
|
|
30
|
+
**Media workflow (if the user wants video):**
|
|
31
|
+
1. clipform_generate_tts - generate narration audio for each question
|
|
32
|
+
2. formgen_search_images - find 3 images per question
|
|
33
|
+
3. clipform_generate_slideshow - create Ken Burns video from images + audio
|
|
34
|
+
4. clipform_upload_media - attach video to question (include captions from TTS for subtitles)
|
|
35
|
+
|
|
36
|
+
**Image selection:**
|
|
37
|
+
- ONLY use image URLs from formgen_search_images results. These are quality-filtered and high-res.
|
|
38
|
+
|
|
39
|
+
**Narration style:**
|
|
40
|
+
- The TTS narration should only read the question - do NOT repeat the answer options verbally. The options are displayed on screen for the user to read and tap.
|
|
41
|
+
- Keep narration concise and conversational. Add a brief interesting fact or context if it fits naturally.
|
|
42
|
+
|
|
43
|
+
**Audit log (final step):**
|
|
44
|
+
After building the quiz, call clipform_log_generation with:
|
|
45
|
+
- summary of what was built
|
|
46
|
+
- sources used for research (Wikipedia articles, URLs)
|
|
47
|
+
- images used with attribution and license
|
|
48
|
+
|
|
49
|
+
**Before building, ask the user:**
|
|
50
|
+
1. How many questions?
|
|
51
|
+
2. Media style: text only, still images, or slideshow video with narration?
|
|
52
|
+
3. Any topic or style preferences?`,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
}));
|
|
57
|
+
server.registerPrompt("create-form", {
|
|
58
|
+
title: "Form Creation Guide",
|
|
59
|
+
description: "Best practices for creating a standard form or survey with Clipform",
|
|
60
|
+
}, async () => ({
|
|
61
|
+
messages: [
|
|
62
|
+
{
|
|
63
|
+
role: "user",
|
|
64
|
+
content: { type: "text", text: "How should I create a form?" },
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
role: "assistant",
|
|
68
|
+
content: {
|
|
69
|
+
type: "text",
|
|
70
|
+
text: `When creating a standard form or survey:
|
|
71
|
+
|
|
72
|
+
**Form settings:**
|
|
73
|
+
- Back navigation is enabled by default (respondents can review answers)
|
|
74
|
+
- Step counter is off by default (optional, enable for longer forms)
|
|
75
|
+
|
|
76
|
+
**Common patterns:**
|
|
77
|
+
- Use "contact" type for collecting user details (name, email, etc.)
|
|
78
|
+
- Use "open" type for free-text responses
|
|
79
|
+
- Use "choice" type for multiple choice / single select
|
|
80
|
+
- End with an "end_screen" type for a thank you message
|
|
81
|
+
|
|
82
|
+
**Media:** Forms can have video or image backgrounds on each question. Use clipform_upload_media to attach media after creation.`,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
}));
|
|
87
|
+
server.registerPrompt("create-journo-request", {
|
|
88
|
+
title: "Journalist Request Guide",
|
|
89
|
+
description: "Best practices for turning a journalist's callout into a Clipform",
|
|
90
|
+
}, async () => ({
|
|
91
|
+
messages: [
|
|
92
|
+
{
|
|
93
|
+
role: "user",
|
|
94
|
+
content: { type: "text", text: "How should I create a journalist request form?" },
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
role: "assistant",
|
|
98
|
+
content: {
|
|
99
|
+
type: "text",
|
|
100
|
+
text: `When a journalist pastes their callout/request text, turn it into a Clipform. The form replaces "DM me" or "email me" with a shareable link.
|
|
101
|
+
|
|
102
|
+
**Form structure (in order):**
|
|
103
|
+
1. **Open question** - The core ask from the journalist's text. Use "open" type. Default to text + audio + video responses.
|
|
104
|
+
2. **Additional short questions** (optional) - Only for distinct secondary asks. Don't over-split.
|
|
105
|
+
3. **Contact collection** - Always include. Minimum: first_name and email.
|
|
106
|
+
4. **Consent checkbox** - "I agree that my response may be used in published media coverage."
|
|
107
|
+
5. **End screen** - "Thanks for your response. The journalist will be in touch if they'd like to take things further."
|
|
108
|
+
|
|
109
|
+
**Form settings:**
|
|
110
|
+
- disable_back_navigation: false
|
|
111
|
+
- show_step_counter: true
|
|
112
|
+
|
|
113
|
+
**Two modes:**
|
|
114
|
+
- One-shot: build immediately with sensible defaults when asked directly
|
|
115
|
+
- Dialogue: ask about video-only/format and extra fields, show wireframe preview first
|
|
116
|
+
|
|
117
|
+
Default to dialogue mode unless explicitly asked for one-shot.`,
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,MAAM,CAAC,cAAc,CACnB,aAAa,EACb;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,+DAA+D;KAC7E,EACD,KAAK,IAAI,EAAE,CAAC,CAAC;QACX,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,6BAA6B,EAAE;aACxE;YACD;gBACE,IAAI,EAAE,WAAoB;gBAC1B,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAqCiB;iBACxB;aACF;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,aAAa,EACb;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,qEAAqE;KACnF,EACD,KAAK,IAAI,EAAE,CAAC,CAAC;QACX,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,6BAA6B,EAAE;aACxE;YACD;gBACE,IAAI,EAAE,WAAoB;gBAC1B,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE;;;;;;;;;;;;iIAY+G;iBACtH;aACF;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,uBAAuB,EACvB;QACE,KAAK,EAAE,0BAA0B;QACjC,WAAW,EAAE,mEAAmE;KACjF,EACD,KAAK,IAAI,EAAE,CAAC,CAAC;QACX,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,gDAAgD,EAAE;aAC3F;YACD;gBACE,IAAI,EAAE,WAAoB;gBAC1B,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE;;;;;;;;;;;;;;;;;+DAiB6C;iBACpD;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -1,23 +1,67 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
// Form CRUD tools
|
|
2
3
|
import { registerCreateFormTool } from "./tools/create-form.js";
|
|
3
4
|
import { registerGetFormTool } from "./tools/get-form.js";
|
|
4
5
|
import { registerUpdateFormTool } from "./tools/update-form.js";
|
|
5
6
|
import { registerDeleteFormTool } from "./tools/delete-form.js";
|
|
7
|
+
// Question CRUD tools
|
|
6
8
|
import { registerAddQuestionTool } from "./tools/add-question.js";
|
|
7
9
|
import { registerUpdateQuestionTool } from "./tools/update-question.js";
|
|
8
10
|
import { registerDeleteQuestionTool } from "./tools/delete-question.js";
|
|
11
|
+
// Media management tools
|
|
12
|
+
import { registerUploadQuestionMediaTool } from "./tools/upload-question-media.js";
|
|
13
|
+
import { registerGetQuestionMediaTool } from "./tools/get-question-media.js";
|
|
14
|
+
import { registerDeleteQuestionMediaTool } from "./tools/delete-question-media.js";
|
|
15
|
+
import { registerSetQuestionLogicTool } from "./tools/set-question-logic.js";
|
|
16
|
+
import { registerAttachQuestionAudioTool } from "./tools/attach-question-audio.js";
|
|
17
|
+
// Core media generation tools
|
|
18
|
+
import { registerGenerateTtsTool } from "./tools/generate-tts.js";
|
|
19
|
+
import { registerGenerateSlideshowTool } from "./tools/generate-slideshow.js";
|
|
20
|
+
import { registerLogGenerationTool } from "./tools/log-generation.js";
|
|
21
|
+
// FormGen content research tools
|
|
22
|
+
import { registerSearchImagesTool } from "./tools/search-images.js";
|
|
23
|
+
import { registerSearchVideosTool } from "./tools/search-videos.js";
|
|
24
|
+
import { registerSearchKnowledgeTool } from "./tools/search-knowledge.js";
|
|
25
|
+
import { registerSearchNewsTool } from "./tools/search-news.js";
|
|
26
|
+
import { registerGetTriviaTool } from "./tools/get-trivia.js";
|
|
27
|
+
import { registerLookupCountryTool } from "./tools/lookup-country.js";
|
|
28
|
+
import { registerGetDailyContentTool } from "./tools/get-daily-content.js";
|
|
29
|
+
// Prompts
|
|
30
|
+
import { registerPrompts } from "./prompts.js";
|
|
9
31
|
export function createServer() {
|
|
10
32
|
const server = new McpServer({
|
|
11
33
|
name: "clipform-mcp-server",
|
|
12
|
-
version: "1.
|
|
34
|
+
version: "1.1.0",
|
|
13
35
|
});
|
|
36
|
+
// Form CRUD
|
|
14
37
|
registerCreateFormTool(server);
|
|
15
38
|
registerGetFormTool(server);
|
|
16
39
|
registerUpdateFormTool(server);
|
|
17
40
|
registerDeleteFormTool(server);
|
|
41
|
+
// Question CRUD
|
|
18
42
|
registerAddQuestionTool(server);
|
|
19
43
|
registerUpdateQuestionTool(server);
|
|
20
44
|
registerDeleteQuestionTool(server);
|
|
45
|
+
// Media management
|
|
46
|
+
registerUploadQuestionMediaTool(server);
|
|
47
|
+
registerGetQuestionMediaTool(server);
|
|
48
|
+
registerDeleteQuestionMediaTool(server);
|
|
49
|
+
registerSetQuestionLogicTool(server);
|
|
50
|
+
registerAttachQuestionAudioTool(server);
|
|
51
|
+
// Core media generation
|
|
52
|
+
registerGenerateTtsTool(server);
|
|
53
|
+
registerGenerateSlideshowTool(server);
|
|
54
|
+
registerLogGenerationTool(server);
|
|
55
|
+
// FormGen content research
|
|
56
|
+
registerSearchImagesTool(server);
|
|
57
|
+
registerSearchVideosTool(server);
|
|
58
|
+
registerSearchKnowledgeTool(server);
|
|
59
|
+
registerSearchNewsTool(server);
|
|
60
|
+
registerGetTriviaTool(server);
|
|
61
|
+
registerLookupCountryTool(server);
|
|
62
|
+
registerGetDailyContentTool(server);
|
|
63
|
+
// Prompts
|
|
64
|
+
registerPrompts(server);
|
|
21
65
|
return server;
|
|
22
66
|
}
|
|
23
67
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { callApi, errorResult, textResult } from "../lib/api-client.js";
|
|
3
|
+
export function registerAttachQuestionAudioTool(server) {
|
|
4
|
+
server.registerTool("clipform_attach_audio", {
|
|
5
|
+
title: "Attach Audio to Question",
|
|
6
|
+
description: `Attach a sound effect or audio file to a question with existing media (stills only). The audio auto-plays once when a respondent reaches this question. Provide a public URL to the audio file (WAV, MP3, or OGG). The question must already have media uploaded (use clipform_upload_question_media first).`,
|
|
7
|
+
inputSchema: {
|
|
8
|
+
form_id: z.string().describe("The form ID"),
|
|
9
|
+
edit_token: z.string().describe("The edit token"),
|
|
10
|
+
question_id: z
|
|
11
|
+
.string()
|
|
12
|
+
.describe("The question ID (must already have media attached)"),
|
|
13
|
+
url: z
|
|
14
|
+
.string()
|
|
15
|
+
.url()
|
|
16
|
+
.describe("Public URL to the audio file (WAV, MP3, or OGG)"),
|
|
17
|
+
},
|
|
18
|
+
annotations: {
|
|
19
|
+
readOnlyHint: false,
|
|
20
|
+
destructiveHint: false,
|
|
21
|
+
idempotentHint: true,
|
|
22
|
+
openWorldHint: true,
|
|
23
|
+
},
|
|
24
|
+
}, async ({ form_id, edit_token, question_id, url }) => {
|
|
25
|
+
const result = await callApi(`/forms/${form_id}/questions/${question_id}/audio`, {
|
|
26
|
+
method: "PUT",
|
|
27
|
+
token: edit_token,
|
|
28
|
+
body: { url },
|
|
29
|
+
});
|
|
30
|
+
if (!result.ok) {
|
|
31
|
+
return errorResult(result.error);
|
|
32
|
+
}
|
|
33
|
+
return textResult(`Audio attached to question ${question_id}.\n` +
|
|
34
|
+
`Audio path: ${result.data.audio_storage_path}`);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=attach-question-audio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attach-question-audio.js","sourceRoot":"","sources":["../../src/tools/attach-question-audio.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAExE,MAAM,UAAU,+BAA+B,CAAC,MAAiB;IAC/D,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,0BAA0B;QACjC,WAAW,EAAE,8SAA8S;QAC3T,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;YAC3C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;YACjD,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,CAAC,oDAAoD,CAAC;YACjE,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,QAAQ,CAAC,iDAAiD,CAAC;SAC/D;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,EAAE,EAAE,EAAE;QAClD,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,UAAU,OAAO,cAAc,WAAW,QAAQ,EAClD;YACE,MAAM,EAAE,KAAK;YACb,KAAK,EAAE,UAAU;YACjB,IAAI,EAAE,EAAE,GAAG,EAAE;SACd,CACF,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,UAAU,CACf,8BAA8B,WAAW,KAAK;YAC5C,eAAe,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAClD,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { callApi, errorResult, textResult } from "../lib/api-client.js";
|
|
3
|
+
export function registerDeleteQuestionMediaTool(server) {
|
|
4
|
+
server.registerTool("clipform_delete_question_media", {
|
|
5
|
+
title: "Delete Question Media",
|
|
6
|
+
description: `Remove media from a question. Deletes the media record and cleans up external resources (Mux video asset, storage file).`,
|
|
7
|
+
inputSchema: {
|
|
8
|
+
form_id: z.string().describe("The form ID"),
|
|
9
|
+
edit_token: z.string().describe("The edit token"),
|
|
10
|
+
question_id: z.string().describe("The question ID"),
|
|
11
|
+
},
|
|
12
|
+
annotations: {
|
|
13
|
+
readOnlyHint: false,
|
|
14
|
+
destructiveHint: true,
|
|
15
|
+
idempotentHint: false,
|
|
16
|
+
openWorldHint: true,
|
|
17
|
+
},
|
|
18
|
+
}, async ({ form_id, edit_token, question_id }) => {
|
|
19
|
+
const result = await callApi(`/forms/${form_id}/questions/${question_id}/media`, {
|
|
20
|
+
method: "DELETE",
|
|
21
|
+
token: edit_token,
|
|
22
|
+
});
|
|
23
|
+
if (!result.ok) {
|
|
24
|
+
return errorResult(result.error);
|
|
25
|
+
}
|
|
26
|
+
return textResult("Media removed from question.");
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=delete-question-media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete-question-media.js","sourceRoot":"","sources":["../../src/tools/delete-question-media.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAExE,MAAM,UAAU,+BAA+B,CAAC,MAAiB;IAC/D,MAAM,CAAC,YAAY,CACjB,gCAAgC,EAChC;QACE,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EAAE,0HAA0H;QACvI,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;YAC3C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;YACjD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;SACpD;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,EAAE;QAC7C,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,UAAU,OAAO,cAAc,WAAW,QAAQ,EAClD;YACE,MAAM,EAAE,QAAQ;YAChB,KAAK,EAAE,UAAU;SAClB,CACF,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,UAAU,CAAC,8BAA8B,CAAC,CAAC;IACpD,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { callInternalApi, errorResult, textResult } from "../lib/api-client.js";
|
|
3
|
+
export function registerGenerateSlideshowTool(server) {
|
|
4
|
+
server.registerTool("clipform_generate_slideshow", {
|
|
5
|
+
title: "Generate Ken Burns Slideshow",
|
|
6
|
+
description: `Generate a Ken Burns slideshow video from images and audio. Uses FFmpeg to create a video with pan/zoom effects and crossfade transitions. The video is uploaded to storage and a public URL is returned.
|
|
7
|
+
|
|
8
|
+
Workflow:
|
|
9
|
+
1. Find images (use formgen_search_images or provide URLs)
|
|
10
|
+
2. Provide an audio track URL (e.g. TTS narration from clipform_generate_tts)
|
|
11
|
+
3. This tool creates a video with Ken Burns pan/zoom effects over the images, synced to the audio duration
|
|
12
|
+
4. Attach the resulting public URL to a question using clipform_upload_media with media_type "video"
|
|
13
|
+
|
|
14
|
+
Effects: zoom-in, zoom-out, pan-left, pan-right, pan-up, pan-down, zoom-in-pan-left, zoom-in-pan-right, random, static.
|
|
15
|
+
Transitions: fade, fadeblack, fadewhite, slideleft, slideright, circlecrop, circleopen, circleclose, dissolve, pixelize, radial, smoothleft, smoothright.`,
|
|
16
|
+
inputSchema: {
|
|
17
|
+
images: z.array(z.object({
|
|
18
|
+
url: z.string().url().describe("Image URL"),
|
|
19
|
+
effect: z.string().optional().describe("Ken Burns effect (e.g. 'zoom-in', 'pan-left', 'random'). Default: random"),
|
|
20
|
+
})).min(1).max(20).describe("Images for the slideshow (1-20)"),
|
|
21
|
+
audio_url: z.string().url().describe("URL of the audio track (mp3/wav)"),
|
|
22
|
+
random_effects: z.boolean().optional().default(true).describe("Randomise effects (default: true)"),
|
|
23
|
+
transition: z.object({
|
|
24
|
+
type: z.string().optional().default("fade").describe("Transition type (default: 'fade')"),
|
|
25
|
+
duration: z.number().optional().default(1).describe("Transition duration in seconds (default: 1)"),
|
|
26
|
+
}).optional().describe("Transition settings"),
|
|
27
|
+
},
|
|
28
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
29
|
+
}, async ({ images, audio_url, random_effects, transition }) => {
|
|
30
|
+
const result = await callInternalApi("/internal/media/slideshow", {
|
|
31
|
+
body: {
|
|
32
|
+
images,
|
|
33
|
+
audio_url,
|
|
34
|
+
random_effects: random_effects ?? true,
|
|
35
|
+
transition: transition ?? { type: "fade", duration: 1 },
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
if (!result.ok)
|
|
39
|
+
return errorResult(result.error);
|
|
40
|
+
const data = result.data;
|
|
41
|
+
return textResult([
|
|
42
|
+
`Slideshow generated successfully!`,
|
|
43
|
+
``,
|
|
44
|
+
`Storage path: ${data.storage_path}`,
|
|
45
|
+
`Public URL: ${data.public_url}`,
|
|
46
|
+
`Duration: ${data.duration_seconds}s`,
|
|
47
|
+
``,
|
|
48
|
+
`Use clipform_upload_media with the public URL to attach this video to a question.`,
|
|
49
|
+
].join("\n"));
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=generate-slideshow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-slideshow.js","sourceRoot":"","sources":["../../src/tools/generate-slideshow.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEhF,MAAM,UAAU,6BAA6B,CAAC,MAAiB;IAC7D,MAAM,CAAC,YAAY,CACjB,6BAA6B,EAC7B;QACE,KAAK,EAAE,8BAA8B;QACrC,WAAW,EAAE;;;;;;;;;0JASuI;QACpJ,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,KAAK,CACb,CAAC,CAAC,MAAM,CAAC;gBACP,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAC3C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0EAA0E,CAAC;aACnH,CAAC,CACH,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,iCAAiC,CAAC;YAC5D,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;YACxE,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YAClG,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;gBACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,mCAAmC,CAAC;gBACzF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,6CAA6C,CAAC;aACnG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;SAC9C;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;KACzG,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,EAAE,EAAE;QAC1D,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,2BAA2B,EAAE;YAChE,IAAI,EAAE;gBACJ,MAAM;gBACN,SAAS;gBACT,cAAc,EAAE,cAAc,IAAI,IAAI;gBACtC,UAAU,EAAE,UAAU,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE;aACxD;SACF,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEjD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAW,CAAC;QAChC,OAAO,UAAU,CACf;YACE,mCAAmC;YACnC,EAAE;YACF,iBAAiB,IAAI,CAAC,YAAY,EAAE;YACpC,eAAe,IAAI,CAAC,UAAU,EAAE;YAChC,aAAa,IAAI,CAAC,gBAAgB,GAAG;YACrC,EAAE;YACF,mFAAmF;SACpF,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { callInternalApi, errorResult, textResult } from "../lib/api-client.js";
|
|
3
|
+
export function registerGenerateTtsTool(server) {
|
|
4
|
+
server.registerTool("clipform_generate_tts", {
|
|
5
|
+
title: "Generate Text-to-Speech",
|
|
6
|
+
description: `Generate narration audio from text using Edge TTS (free) with ElevenLabs fallback. The audio is uploaded to storage and a public URL is returned.
|
|
7
|
+
|
|
8
|
+
Use this to create narration for slideshow videos. Workflow:
|
|
9
|
+
1. Generate TTS audio with this tool
|
|
10
|
+
2. Search for images with formgen_search_images
|
|
11
|
+
3. Create a slideshow with clipform_generate_slideshow (pass the audio URL + image URLs)
|
|
12
|
+
4. Attach the video to a question with clipform_upload_media
|
|
13
|
+
|
|
14
|
+
Available voices:
|
|
15
|
+
- ryan: British male (default)
|
|
16
|
+
- sonia: British female
|
|
17
|
+
- andrew: American male
|
|
18
|
+
- ava: American female
|
|
19
|
+
- guy: American male (casual)
|
|
20
|
+
|
|
21
|
+
Returns the audio public URL and word-level captions for subtitle display.`,
|
|
22
|
+
inputSchema: {
|
|
23
|
+
text: z.string().min(1).max(5000).describe("The narration text to convert to speech"),
|
|
24
|
+
voice: z.enum(["ryan", "sonia", "andrew", "ava", "guy"]).optional().default("ryan").describe("TTS voice (default: ryan)"),
|
|
25
|
+
},
|
|
26
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
27
|
+
}, async ({ text, voice }) => {
|
|
28
|
+
const result = await callInternalApi("/internal/formgen/generate-tts", {
|
|
29
|
+
body: { text, voice },
|
|
30
|
+
});
|
|
31
|
+
if (!result.ok)
|
|
32
|
+
return errorResult(result.error);
|
|
33
|
+
const data = result.data;
|
|
34
|
+
return textResult([
|
|
35
|
+
`TTS audio generated successfully!`,
|
|
36
|
+
``,
|
|
37
|
+
`Voice: ${data.voice}`,
|
|
38
|
+
`Audio URL: ${data.audioUrl}`,
|
|
39
|
+
`Storage path: ${data.storagePath}`,
|
|
40
|
+
`Captions: ${data.captions.length} segments`,
|
|
41
|
+
`Captions JSON: ${JSON.stringify(data.captions)}`,
|
|
42
|
+
``,
|
|
43
|
+
`Use the Audio URL with clipform_generate_slideshow to create a video.`,
|
|
44
|
+
`Pass the Captions JSON to clipform_upload_media to enable subtitles.`,
|
|
45
|
+
].join("\n"));
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=generate-tts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-tts.js","sourceRoot":"","sources":["../../src/tools/generate-tts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEhF,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE;;;;;;;;;;;;;;;2EAewD;QACrE,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,yCAAyC,CAAC;YACrF,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC;SAC1H;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;KACzG,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,gCAAgC,EAAE;YACrE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;SACtB,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEjD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAW,CAAC;QAChC,OAAO,UAAU,CACf;YACE,mCAAmC;YACnC,EAAE;YACF,UAAU,IAAI,CAAC,KAAK,EAAE;YACtB,cAAc,IAAI,CAAC,QAAQ,EAAE;YAC7B,iBAAiB,IAAI,CAAC,WAAW,EAAE;YACnC,aAAa,IAAI,CAAC,QAAQ,CAAC,MAAM,WAAW;YAC5C,kBAAkB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;YACjD,EAAE;YACF,uEAAuE;YACvE,sEAAsE;SACvE,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|