@gui-chat-plugin/sequence 0.5.4 → 0.6.1
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/CHANGELOG.md +21 -0
- package/README.md +16 -1
- package/dist/core/definitions.d.ts +8 -4
- package/dist/core/index.d.ts +1 -1
- package/dist/core/slideHtml.d.ts +10 -0
- package/dist/core-9tYquYlg.cjs +245 -0
- package/dist/{core-BYk8F8Fi.js → core-CAot6uC8.js} +288 -235
- package/dist/index.cjs +1 -1
- package/dist/index.js +2 -2
- package/dist/style.css +1 -1
- package/dist/vue.cjs +1 -1
- package/dist/vue.js +43 -43
- package/package.json +1 -1
- package/dist/core-DlvNLaFp.cjs +0 -236
|
@@ -154,28 +154,31 @@ var t = 1280, n = 720, r = 6e4, i = "https://cdn.jsdelivr.net/npm/@tailwindcss/b
|
|
|
154
154
|
"<": "<",
|
|
155
155
|
">": ">",
|
|
156
156
|
"\"": """
|
|
157
|
-
}, p = (e) => e.replace(/[&<>"]/g, (e) => f[e] ?? e),
|
|
157
|
+
}, p = (e) => e.replace(/[&<>"]/g, (e) => f[e] ?? e), m = (e) => e.replace(/<(?=(meta|base|link)\b)/gi, "<").replace(/shadowroot/gi, "data-no-shadow-root"), h = "*, *::before, *::after { animation-play-state: paused !important; animation-duration: 0s !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; animation-fill-mode: both !important; transition: none !important; }", ee = `
|
|
158
158
|
html, body { margin: 0; width: ${t}px; height: 720px; overflow: hidden; }
|
|
159
159
|
html:not(.ready) body { visibility: hidden; }
|
|
160
|
-
${
|
|
161
|
-
|
|
160
|
+
${h}`, g = "{{image}}", _ = /(\bsrc\s*=\s*["']?|\burl\(\s*["']?)(?:\{\{image\}\}|%7B%7Bimage%7D%7D)/gi, te = /^data:image\/[a-z0-9.+-]+;base64,[a-z0-9+/=]+$/i, ne = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7", v = /(<pre\b[\s\S]*?<\/pre>|<code\b[\s\S]*?<\/code>)/gi, y = (e) => e.split(v).some((e, t) => t % 2 == 0 && new RegExp(_.source, "i").test(e)), re = (e, t) => {
|
|
161
|
+
let n = t && te.test(t) ? t : ne;
|
|
162
|
+
return e.split(v).map((e, t) => t % 2 == 1 ? e : e.replace(_, (e, t) => t + n)).join("");
|
|
163
|
+
};
|
|
164
|
+
function ie(e) {
|
|
162
165
|
return `<!doctype html>
|
|
163
166
|
<html lang="en">
|
|
164
167
|
<head>
|
|
165
168
|
<meta charset="utf-8">
|
|
166
169
|
<meta http-equiv="Content-Security-Policy" content="${d}">
|
|
167
|
-
<style id="slide-base">${
|
|
170
|
+
<style id="slide-base">${ee}</style>
|
|
168
171
|
<script>${u}<\/script>
|
|
169
172
|
<script defer src="${i}" integrity="${a}" crossorigin="anonymous"><\/script>
|
|
170
173
|
</head>
|
|
171
174
|
<body class="bg-white text-slate-900 font-sans antialiased">
|
|
172
|
-
${
|
|
175
|
+
${m(e)}
|
|
173
176
|
</body>
|
|
174
177
|
</html>`;
|
|
175
178
|
}
|
|
176
179
|
//#endregion
|
|
177
180
|
//#region src/core/chartSlide.ts
|
|
178
|
-
var
|
|
181
|
+
var b = [
|
|
179
182
|
"bar",
|
|
180
183
|
"line",
|
|
181
184
|
"pie",
|
|
@@ -184,32 +187,32 @@ var h = [
|
|
|
184
187
|
"polarArea",
|
|
185
188
|
"scatter",
|
|
186
189
|
"bubble"
|
|
187
|
-
],
|
|
190
|
+
], ae = "https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js", oe = "sha384-jb8JQMbMoBUzgWatfe6COACi2ljcDdZQ2OxczGA3bGNeWe+6DChMTBJemed7ZnvJ", se = "\n(() => {\n const fail = (why) => {\n document.getElementById(\"chart-error\").textContent = why;\n document.documentElement.classList.add(\"failed\");\n };\n addEventListener(\"DOMContentLoaded\", () => {\n if (!window.Chart) return fail(\"The chart couldn't be drawn: Chart.js didn't load.\");\n let config;\n try {\n config = JSON.parse(document.getElementById(\"chart-config\").textContent);\n } catch {\n return fail(\"The chart couldn't be drawn: its configuration isn't valid.\");\n }\n Chart.defaults.font.size = 22;\n Chart.defaults.color = \"#334155\";\n Chart.defaults.animation.duration = 1200;\n config.options = { ...config.options, responsive: true, maintainAspectRatio: false };\n try {\n new Chart(document.getElementById(\"chart\"), config);\n } catch (error) {\n fail(\"The chart couldn't be drawn: \" + (error && error.message ? error.message : error));\n }\n });\n})();", ce = [
|
|
188
191
|
"default-src 'none'",
|
|
189
|
-
`script-src 'sha256-TfZZxJX+yWgzYLy7zqsMa85OJEaC+zNLIpKLDZVnUqA=' ${
|
|
192
|
+
`script-src 'sha256-TfZZxJX+yWgzYLy7zqsMa85OJEaC+zNLIpKLDZVnUqA=' ${ae}`,
|
|
190
193
|
"style-src 'unsafe-inline'",
|
|
191
194
|
"img-src data: blob:",
|
|
192
195
|
"connect-src 'none'",
|
|
193
196
|
"form-action 'none'",
|
|
194
197
|
"base-uri 'none'"
|
|
195
|
-
].join("; "),
|
|
198
|
+
].join("; "), le = `
|
|
196
199
|
html, body { margin: 0; width: ${t}px; height: 720px; overflow: hidden; background: #ffffff; color: #0f172a; font-family: ui-sans-serif, system-ui, sans-serif; }
|
|
197
200
|
body { box-sizing: border-box; padding: 40px 64px 48px; display: flex; flex-direction: column; gap: 24px; }
|
|
198
201
|
h1 { margin: 0; font-size: 52px; font-weight: 800; color: #1e3a8a; line-height: 1.15; text-align: center; }
|
|
199
202
|
.chart { position: relative; flex: 1; min-height: 0; }
|
|
200
203
|
#chart-error { display: none; margin: auto; font-size: 28px; color: #b91c1c; }
|
|
201
204
|
.failed .chart { display: none; }
|
|
202
|
-
.failed #chart-error { display: block; }`,
|
|
203
|
-
function
|
|
205
|
+
.failed #chart-error { display: block; }`, ue = (e) => JSON.stringify(e).replace(/</g, "\\u003c");
|
|
206
|
+
function de(e, t) {
|
|
204
207
|
return `<!doctype html>
|
|
205
208
|
<html lang="en">
|
|
206
209
|
<head>
|
|
207
210
|
<meta charset="utf-8">
|
|
208
|
-
<meta http-equiv="Content-Security-Policy" content="${
|
|
209
|
-
<style>${
|
|
210
|
-
<script>${
|
|
211
|
-
<script defer src="${
|
|
212
|
-
<script type="application/json" id="chart-config">${
|
|
211
|
+
<meta http-equiv="Content-Security-Policy" content="${ce}">
|
|
212
|
+
<style>${le}</style>
|
|
213
|
+
<script>${se}<\/script>
|
|
214
|
+
<script defer src="${ae}" integrity="${oe}" crossorigin="anonymous"><\/script>
|
|
215
|
+
<script type="application/json" id="chart-config">${ue(t)}<\/script>
|
|
213
216
|
</head>
|
|
214
217
|
<body>
|
|
215
218
|
${e ? `<h1>${p(e)}</h1>` : ""}
|
|
@@ -220,50 +223,53 @@ ${e ? `<h1>${p(e)}</h1>` : ""}
|
|
|
220
223
|
}
|
|
221
224
|
//#endregion
|
|
222
225
|
//#region src/core/definitions.ts
|
|
223
|
-
var
|
|
224
|
-
function
|
|
226
|
+
var fe = "presentSlide", pe = "defineStoryboard", me = "presentPanel", he = 4, ge = 12, _e = 3, x = /^[0-9a-f]{12}$/, S = (e) => typeof e == "object" && !!e && !Array.isArray(e), C = (e) => typeof e == "string" ? e.trim() : "", w = (e, t) => e.toLowerCase() === t.toLowerCase(), T = (e) => typeof e == "number" && Number.isInteger(e), E = "presentSlide needs slide and totalSlides (whole numbers, slide from 1 to totalSlides), and one of imagePrompt, html, markdown or chart", D = `presentSlide's slide is too long: keep its html, markdown or chart under ${r} characters`, O = `presentSlide's slide has ${g} but no imagePrompt: give imagePrompt for the picture that goes there, or take ${g} out`, k = `presentSlide's chart must be a Chart.js configuration: an object with type (${b.join(", ")}), data ({ labels, datasets }) and optionally options`;
|
|
227
|
+
function ve(e) {
|
|
225
228
|
let t = e;
|
|
226
229
|
if (typeof t == "string") try {
|
|
227
230
|
t = JSON.parse(t);
|
|
228
231
|
} catch {
|
|
229
232
|
return null;
|
|
230
233
|
}
|
|
231
|
-
if (!
|
|
234
|
+
if (!S(t) || !S(t.data)) return null;
|
|
232
235
|
let n = t.type;
|
|
233
|
-
return !
|
|
236
|
+
return !b.some((e) => e === n) || t.options !== void 0 && !S(t.options) ? null : t;
|
|
234
237
|
}
|
|
235
|
-
function
|
|
236
|
-
let { slide: t, totalSlides: n, title: r, imagePrompt: i } = e, a =
|
|
237
|
-
if (!
|
|
238
|
-
let c = s ?
|
|
239
|
-
|
|
238
|
+
function A(e) {
|
|
239
|
+
let { slide: t, totalSlides: n, title: r, imagePrompt: i } = e, a = C(e.html), o = a ? "" : C(e.markdown), s = !a && !o && e.chart !== void 0 && e.chart !== null;
|
|
240
|
+
if (!T(t) || !T(n) || t < 1 || n < t || !a && !o && !s && !C(i)) return E;
|
|
241
|
+
let c = s ? ve(e.chart) : null;
|
|
242
|
+
if (s && !c) return k;
|
|
243
|
+
if (Math.max(a.length, o.length, c ? JSON.stringify(c).length : 0) > 6e4) return D;
|
|
244
|
+
let l = !a && !o && !c, u = !!a && y(a);
|
|
245
|
+
return u && !C(i) ? O : {
|
|
240
246
|
slide: t,
|
|
241
247
|
totalSlides: n,
|
|
242
248
|
title: typeof r == "string" ? r : "",
|
|
243
|
-
imagePrompt:
|
|
249
|
+
imagePrompt: l || u || o && C(i) ? String(i) : "",
|
|
244
250
|
...a && { html: a },
|
|
245
251
|
...o && { markdown: o },
|
|
246
252
|
...c && { chart: c },
|
|
247
253
|
mode: e.mode === "steps" ? "steps" : "presentation"
|
|
248
254
|
};
|
|
249
255
|
}
|
|
250
|
-
var
|
|
256
|
+
var j = "teach its subject as a presenter speaking to the audience, and cover everything on it: every section, point and number, in order, each in a sentence or more. The slide is replaced by the next one as soon as you stop talking, so a point you leave out is never explained. Begin with the content itself, never with the slide or your plan: no \"This slide is about…\", \"The first slide shows…\", \"Let's unpack this one\", \"Next, I'll…\". A line about the slide is not an explanation.", M = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
|
|
251
257
|
let i = n ? ` ("${n}")` : "";
|
|
252
258
|
if (r === "steps") {
|
|
253
259
|
let n = `Step ${e} of ${t}${i}`;
|
|
254
260
|
return e < t ? `${n} is now on the screen. Say what to do in this step, directly ("Crack two eggs into a bowl…", not "This step is about eggs"), then stop and wait while the user does it. When they say they're ready (next, done, go on), call presentSlide for step ${e + 1} with mode "steps". If they ask to go back or to see a step again, call presentSlide for that step.` : `${n}, the last one, is now on the screen. Say what to do, directly, then wrap up the guide once the user is done.`;
|
|
255
261
|
}
|
|
256
262
|
let a = `Slide ${e} of ${t}${i}`;
|
|
257
|
-
return e < t ? `${a} is now on the screen. Explain it: ${
|
|
258
|
-
},
|
|
259
|
-
`For an HTML slide
|
|
263
|
+
return e < t ? `${a} is now on the screen. Explain it: ${j} This reply is only the explanation: don't call presentSlide in it. When you have finished, you will be asked for slide ${e + 1}. If the user has asked you to stop, or asked something else, since the slideshow began, answer them instead of going on.` : `${a}, the last one, is now on the screen. Explain it: ${j} Then wrap up the slideshow.`;
|
|
264
|
+
}, ye = [
|
|
265
|
+
`For an HTML slide: the slide's content, the inside of <body> only (no <html>, <head> or <body> tags), for a ${t}x720 px canvas, which it should fill (start with a <div class="w-full h-full ...">). Style it with Tailwind CSS v4 classes, which are loaded for you: a clear layout, a large title (text-6xl or so), few words in large type, a color scheme, and inline SVG or emoji for icons and diagrams. There is no network: no <img> from URLs, no links to follow. For one generated picture on the slide (a photo, a scene, an object beside the text), give imagePrompt too and put <img src="${g}" alt="..." class="..."> where it goes, sized by its classes (for example class="w-1/2 h-full object-cover rounded-2xl").`,
|
|
260
266
|
"Animate it so it builds up as you explain it, with MulmoCast's data-animation attributes (the same ones make it move in a movie of the slideshow): data-animation=\"animate\" with data-opacity=\"0,1\", data-translate-x, data-translate-y (px), data-scale, data-rotate (deg), data-width or data-height (\"0,80,%\"), each \"from,to\"; data-animation=\"counter\" with data-from, data-to, data-decimals, data-prefix, data-suffix; data-animation=\"typewriter\" (its text, or data-text). Give every one data-start and data-end in seconds, and optionally data-easing (linear, easeIn, easeOut, easeInOut); stagger the parts with later data-start values so they appear one after another over a few seconds (for example 0, 0.6, 1.2). Set the first frame inline too (style=\"opacity:0\" on an element that fades in).",
|
|
261
267
|
"CSS animations, transitions and scripts don't play: animate only with data-animation. A <style> for layout is allowed (and Google Fonts by @import)."
|
|
262
|
-
].join(" "),
|
|
268
|
+
].join(" "), be = `For a Markdown slide: the slide in Markdown (GitHub's: headings, lists, bold, tables, code), with math in TeX between $...$ inline or $$...$$ for a displayed equation (on lines of its own). Start with a # heading, and keep it to what fits on one slide: a heading and a few lines, a list or an equation or two. Write a dollar sign that isn't math as \\$. For one generated picture on the slide, give imagePrompt too and put  on a line of its own: the slide is then two columns, the text on the left and the picture on the right.`, xe = `For a chart slide, instead of imagePrompt (for numbers: real figures you have, never a picture of a chart): a Chart.js configuration as JSON text, {"type": ..., "data": ...}: { type, data: { labels, datasets: [{ label, data, backgroundColor }] }, options }. type is one of ${b.join(", ")}. It is drawn under the slide's title, so leave out options.plugins.title; give the datasets colors, and the axes titles (options.scales.x.title) when their units aren't obvious. JSON values only: no functions.`, N = "When the user asks for a slideshow (or to explain something with slides), plan four to six slides (more when the subject or your instructions need them), then show them one at a time with presentSlide: slide 1 first, and each next slide only after you have explained the one on the screen. Explain the subject, not the slides: say what the slide teaches, not that a slide is about it, and explain everything on a slide before showing the next; put on a slide only what you will explain. Go on to the last slide without asking whether to continue. A slide is a generated picture (imagePrompt), a chart (chart), a text slide in Markdown (markdown) or a designed slide in HTML (html): use a picture for a scene, an object or a place; a chart for numbers to compare, a trend or proportions; Markdown for equations and formulas (TeX math), definitions, short lists and small tables; and HTML for designed layouts, comparisons, timelines and diagrams. A picture model draws words, numbers and math badly, so they go on the other kinds; a slideshow can mix them. When a picture helps the text (the thing being explained, beside its key points), make an HTML or Markdown slide with one generated picture on it: imagePrompt for the picture, and {{image}} where it goes. Numbers go on a chart slide: when you have figures (from a search, a document or the user: revenue, market share, growth, prices, counts over time), show them in a chart with those exact values, labelled with their units and the year or period, and say where they come from. Figures over time, shares of a whole or values side by side are a chart, not a list or table on a Markdown or HTML slide. Never make a chart, graph or table a picture (imagePrompt): a picture of a chart has made-up bars and no real numbers. A slideshow about a business, a market or a comparison of companies has its figures on chart slides, not only in text. Never invent figures; with none to show, leave the chart out. A slide holds only its subject, never notes about your work (what you searched for, that a search succeeded). When the user asks for HTML slides (slides in HTML, an HTML presentation), this is the tool: make them HTML slides with presentSlide, one call per slide, not one HTML page. When the user wants to be shown how to do something they will do along with you (cooking, folding, fixing, an exercise), make it a step-by-step guide instead: mode \"steps\", one slide per step, and after each step wait for the user to say they are ready. Use generateImage for a single picture, not for slides.", P = {
|
|
263
269
|
type: "function",
|
|
264
|
-
name:
|
|
265
|
-
prompt:
|
|
266
|
-
description: "Show one slide of a slideshow, full screen: a picture generated from imagePrompt, a chart (chart), a slide written in Markdown with TeX math (markdown), or a slide written in HTML (html). Give one of the four. Call it once per slide, in order, starting with slide 1. With mode \"steps\" it is a step-by-step guide: one slide per step, and the next step waits for the user.",
|
|
270
|
+
name: fe,
|
|
271
|
+
prompt: N,
|
|
272
|
+
description: "Show one slide of a slideshow, full screen: a picture generated from imagePrompt, a chart (chart), a slide written in Markdown with TeX math (markdown), or a slide written in HTML (html). Give one of the four; an HTML or Markdown slide can also hold one generated picture (imagePrompt, placed at {{image}}). Call it once per slide, in order, starting with slide 1. With mode \"steps\" it is a step-by-step guide: one slide per step, and the next step waits for the user.",
|
|
267
273
|
parameters: {
|
|
268
274
|
type: "object",
|
|
269
275
|
properties: {
|
|
@@ -281,19 +287,19 @@ var D = "teach its subject as a presenter speaking to the audience, and cover ev
|
|
|
281
287
|
},
|
|
282
288
|
imagePrompt: {
|
|
283
289
|
type: "string",
|
|
284
|
-
description: "For a picture slide: the picture, a clear illustration of its point, with the title as its only large text. Be concrete. Never a chart, graph, table, dashboard, infographic, key figures or anything with numbers: those are chart, Markdown or HTML slides. For a step, show the action: hands, tools and the object.
|
|
290
|
+
description: "For a picture slide: the picture, a clear illustration of its point, with the title as its only large text. Be concrete. Never a chart, graph, table, dashboard, infographic, key figures or anything with numbers: those are chart, Markdown or HTML slides. For a step, show the action: hands, tools and the object. With html or markdown, it is the one picture placed where the slide has {{image}}; leave it out for a chart, and for an HTML or Markdown slide without {{image}}."
|
|
285
291
|
},
|
|
286
292
|
html: {
|
|
287
293
|
type: "string",
|
|
288
|
-
description:
|
|
294
|
+
description: ye
|
|
289
295
|
},
|
|
290
296
|
markdown: {
|
|
291
297
|
type: "string",
|
|
292
|
-
description:
|
|
298
|
+
description: be
|
|
293
299
|
},
|
|
294
300
|
chart: {
|
|
295
301
|
type: "string",
|
|
296
|
-
description:
|
|
302
|
+
description: xe
|
|
297
303
|
},
|
|
298
304
|
mode: {
|
|
299
305
|
type: "string",
|
|
@@ -308,49 +314,49 @@ var D = "teach its subject as a presenter speaking to the audience, and cover ev
|
|
|
308
314
|
]
|
|
309
315
|
}
|
|
310
316
|
};
|
|
311
|
-
function
|
|
317
|
+
function F(e) {
|
|
312
318
|
let { totalPanels: t } = e;
|
|
313
|
-
if (!
|
|
319
|
+
if (!T(t) || t < 1 || t > 12) return "totalPanels must be a whole number from 1 to 12";
|
|
314
320
|
let n = [];
|
|
315
321
|
for (let t of Array.isArray(e.characters) ? e.characters : []) {
|
|
316
|
-
let e =
|
|
322
|
+
let e = S(t) ? C(t.name) : "", r = S(t) ? C(t.description) : "";
|
|
317
323
|
if (!e || !r) return "every character needs a name and a description";
|
|
318
|
-
if (n.some((t) =>
|
|
324
|
+
if (n.some((t) => w(t.name, e))) return `two characters are named ${e}`;
|
|
319
325
|
n.push({
|
|
320
326
|
name: e,
|
|
321
327
|
description: r
|
|
322
328
|
});
|
|
323
329
|
}
|
|
324
330
|
return n.length < 1 || n.length > 4 ? "a storyboard has 1 to 4 characters" : {
|
|
325
|
-
title:
|
|
326
|
-
style:
|
|
331
|
+
title: C(e.title),
|
|
332
|
+
style: C(e.style),
|
|
327
333
|
totalPanels: t,
|
|
328
334
|
characters: n,
|
|
329
335
|
interactive: e.interactive === !0
|
|
330
336
|
};
|
|
331
337
|
}
|
|
332
|
-
var
|
|
333
|
-
function
|
|
334
|
-
let { panel: t } = e, n =
|
|
335
|
-
if (!n || !r || !
|
|
336
|
-
let i = (e) => (Array.isArray(e) ? e : []).map(
|
|
338
|
+
var I = ({ title: e }) => `The cast of "${e}" is now on the screen. Introduce the characters briefly. This reply is only the introduction: don't call presentPanel in it. When you have finished, you will be asked for panel 1. If the user has asked you to stop, or asked something else, answer them instead of going on.`, L = "presentPanel needs a storyboardId, a panel number (from 1) and an imagePrompt";
|
|
339
|
+
function R(e) {
|
|
340
|
+
let { panel: t } = e, n = C(e.storyboardId), r = C(e.imagePrompt);
|
|
341
|
+
if (!n || !r || !T(t) || t < 1) return null;
|
|
342
|
+
let i = (e) => (Array.isArray(e) ? e : []).map(C).filter(Boolean);
|
|
337
343
|
return {
|
|
338
344
|
storyboardId: n,
|
|
339
345
|
panel: t,
|
|
340
346
|
characters: i(e.characters),
|
|
341
347
|
imagePrompt: r,
|
|
342
|
-
caption:
|
|
348
|
+
caption: C(e.caption),
|
|
343
349
|
choices: i(e.choices).slice(0, 3)
|
|
344
350
|
};
|
|
345
351
|
}
|
|
346
|
-
function
|
|
352
|
+
function z(e, t, n) {
|
|
347
353
|
let { id: r, totalPanels: i } = e;
|
|
348
354
|
return n.length ? `Panel ${t} of ${i} is now on the screen, with the user's choices: ${n.map((e, t) => `${t + 1}. ${e}`).join(" ")} Tell this part of the story, then read the choices out and ask the user which one they pick, and wait for their answer. Then call presentPanel for panel ${t + 1} with storyboardId "${r}", going on the way they chose.` : t < i ? `Panel ${t} of ${i} is now on the screen. Tell this part of the story, aloud, as a storyteller. This reply is only the telling: don't call presentPanel in it. When you have finished, you will be asked for panel ${t + 1}. If the user has asked you to stop, or asked something else, since the story began, answer them instead of going on.` : `Panel ${t} of ${i}, the last one, is now on the screen. Tell this part of the story, then bring it to an end.`;
|
|
349
355
|
}
|
|
350
|
-
var
|
|
356
|
+
var B = "When the user asks for a story, a picture book, a comic or a storyboard, tell it in pictures: first call defineStoryboard with the art style and the characters who appear more than once (it draws a reference sheet for each, so they look the same in every panel), then show the panels one at a time with presentPanel, naming the characters in each, and tell each part of the story when its panel appears. Go on to the last panel without asking whether to continue, unless the story is interactive. When the user wants to decide what happens (an adventure, a story for a child who wants to choose), set interactive, and give two or three choices on two or three of the panels: the story waits there for the user's pick and goes on their way; it still ends at the last panel whichever way it goes. Use presentSlide to explain a topic, not to tell a story.", V = {
|
|
351
357
|
type: "function",
|
|
352
|
-
name:
|
|
353
|
-
prompt:
|
|
358
|
+
name: pe,
|
|
359
|
+
prompt: B,
|
|
354
360
|
description: "Start a story told in pictures: set its art style and draw a reference sheet for each recurring character, shown as the cast. Then call presentPanel for each panel, in order.",
|
|
355
361
|
parameters: {
|
|
356
362
|
type: "object",
|
|
@@ -397,9 +403,9 @@ var ve = "When the user asks for a story, a picture book, a comic or a storyboar
|
|
|
397
403
|
"characters"
|
|
398
404
|
]
|
|
399
405
|
}
|
|
400
|
-
},
|
|
406
|
+
}, H = {
|
|
401
407
|
type: "function",
|
|
402
|
-
name:
|
|
408
|
+
name: me,
|
|
403
409
|
description: "Show one panel of a storyboard made with defineStoryboard: a picture of the scene with its characters drawn as in their reference sheets, and a caption. Call it once per panel, in order, starting with panel 1.",
|
|
404
410
|
parameters: {
|
|
405
411
|
type: "object",
|
|
@@ -438,60 +444,60 @@ var ve = "When the user asks for a story, a picture book, a comic or a storyboar
|
|
|
438
444
|
"imagePrompt"
|
|
439
445
|
]
|
|
440
446
|
}
|
|
441
|
-
},
|
|
442
|
-
function
|
|
443
|
-
let t =
|
|
447
|
+
}, U = (e) => typeof e == "object" && !!e && !Array.isArray(e), Se = (e) => U(e) && typeof e.message == "string";
|
|
448
|
+
function W(e) {
|
|
449
|
+
let t = U(e?.data) ? e.data : {};
|
|
444
450
|
return {
|
|
445
451
|
...typeof t.imageData == "string" && { imageData: t.imageData },
|
|
446
452
|
...typeof t.imagePath == "string" && { imagePath: t.imagePath }
|
|
447
453
|
};
|
|
448
454
|
}
|
|
449
|
-
function
|
|
450
|
-
let t =
|
|
455
|
+
function G(e) {
|
|
456
|
+
let t = U(e?.data) ? e.data : {};
|
|
451
457
|
return typeof t.html == "string" ? t.html : "";
|
|
452
458
|
}
|
|
453
|
-
function
|
|
454
|
-
let t =
|
|
455
|
-
return
|
|
459
|
+
function K(e) {
|
|
460
|
+
let t = U(e?.data) ? e.data : {};
|
|
461
|
+
return U(t.chart) ? JSON.stringify(t.chart) : "";
|
|
456
462
|
}
|
|
457
|
-
var
|
|
458
|
-
function
|
|
459
|
-
let n =
|
|
463
|
+
var Ce = (e) => !!W(e).imageData || !!G(e) || !!K(e);
|
|
464
|
+
function we(e, t) {
|
|
465
|
+
let n = W(e), r = W(t);
|
|
460
466
|
if (n.imagePath && r.imagePath) return n.imagePath === r.imagePath;
|
|
461
467
|
if (n.imageData) return n.imageData === r.imageData;
|
|
462
|
-
let i =
|
|
463
|
-
if (i) return i ===
|
|
464
|
-
let a =
|
|
465
|
-
return !!a && a ===
|
|
468
|
+
let i = G(e);
|
|
469
|
+
if (i) return i === G(t);
|
|
470
|
+
let a = K(e);
|
|
471
|
+
return !!a && a === K(t);
|
|
466
472
|
}
|
|
467
|
-
var
|
|
468
|
-
async function
|
|
473
|
+
var q = (e, t) => e.userSpokeAt === void 0 || e.userSpokeAt > t, Te = () => crypto.randomUUID().replace(/-/g, "").slice(0, 12), Ee = "artifacts/";
|
|
474
|
+
async function De(e, t) {
|
|
469
475
|
let n = e.files?.artifacts;
|
|
470
476
|
if (!e.app?.editImages || !n) return [];
|
|
471
477
|
let r = [];
|
|
472
|
-
for (let e of t) if (e.startsWith(
|
|
478
|
+
for (let e of t) if (e.startsWith(Ee)) try {
|
|
473
479
|
await n.exists(e.slice(10)) && r.push(e);
|
|
474
480
|
} catch {}
|
|
475
481
|
return r;
|
|
476
482
|
}
|
|
477
|
-
async function
|
|
483
|
+
async function J(e, t, n = []) {
|
|
478
484
|
let r = e.app, i = r?.editImages, a = r?.generateImage;
|
|
479
485
|
try {
|
|
480
486
|
let e;
|
|
481
487
|
if (n.length && i) e = await i(t, [...n]);
|
|
482
488
|
else if (a) e = await a(t);
|
|
483
489
|
else return { message: "image generation isn't available" };
|
|
484
|
-
return
|
|
490
|
+
return Se(e) ? e : { message: "image generation returned an unrecognized result" };
|
|
485
491
|
} catch (e) {
|
|
486
492
|
return { message: `image generation failed: ${e instanceof Error ? e.message : String(e)}` };
|
|
487
493
|
}
|
|
488
494
|
}
|
|
489
|
-
var
|
|
490
|
-
function
|
|
495
|
+
var Oe = 50;
|
|
496
|
+
function ke(e) {
|
|
491
497
|
let t = /* @__PURE__ */ new Map();
|
|
492
498
|
return (n) => {
|
|
493
499
|
let r = n.conversationId ?? "", i = t.get(r);
|
|
494
|
-
if (i === void 0 ? i = e() : t.delete(r), t.set(r, i), t.size >
|
|
500
|
+
if (i === void 0 ? i = e() : t.delete(r), t.set(r, i), t.size > Oe) {
|
|
495
501
|
let e = t.keys().next().value;
|
|
496
502
|
e !== void 0 && t.delete(e);
|
|
497
503
|
}
|
|
@@ -500,41 +506,45 @@ function K(e) {
|
|
|
500
506
|
}
|
|
501
507
|
//#endregion
|
|
502
508
|
//#region src/core/markdownSlide.ts
|
|
503
|
-
var
|
|
504
|
-
.${
|
|
505
|
-
.${
|
|
506
|
-
.${
|
|
507
|
-
.${
|
|
508
|
-
.${
|
|
509
|
-
.${
|
|
510
|
-
.${
|
|
511
|
-
.${
|
|
512
|
-
.${
|
|
513
|
-
.${
|
|
514
|
-
.${
|
|
515
|
-
.${
|
|
516
|
-
.${
|
|
517
|
-
.${
|
|
518
|
-
.${
|
|
519
|
-
.${
|
|
520
|
-
.${
|
|
521
|
-
.${
|
|
522
|
-
.${
|
|
523
|
-
.${
|
|
524
|
-
.${
|
|
525
|
-
.${
|
|
526
|
-
.${
|
|
527
|
-
.${
|
|
528
|
-
.${
|
|
529
|
-
.${
|
|
530
|
-
.${
|
|
531
|
-
.${
|
|
532
|
-
|
|
509
|
+
var Y = "slide-md", Ae = "slide-md-split", X = "slide-md-text", je = "slide-md-picture", Me = .8, Ne = `
|
|
510
|
+
.${Y} { box-sizing: border-box; flex-shrink: 0; width: ${t}px; height: 720px; padding: 56px 80px; overflow: hidden; display: flex; flex-direction: column; justify-content: center; gap: 0.5em; background: #ffffff; color: #0f172a; font-family: ui-sans-serif, system-ui, sans-serif; line-height: 1.35; }
|
|
511
|
+
.${Y} > * { margin: 0; }
|
|
512
|
+
.${Y} h1 { font-size: 1.9em; font-weight: 800; color: #1e3a8a; line-height: 1.15; }
|
|
513
|
+
.${Y} h2 { font-size: 1.5em; font-weight: 700; color: #1e40af; line-height: 1.2; }
|
|
514
|
+
.${Y} h3 { font-size: 1.2em; font-weight: 700; color: #334155; }
|
|
515
|
+
.${Y} ul, .${Y} ol { padding-left: 1.3em; display: flex; flex-direction: column; gap: 0.3em; }
|
|
516
|
+
.${Y} ul { list-style: disc; }
|
|
517
|
+
.${Y} ol { list-style: decimal; }
|
|
518
|
+
.${Y} li > ul, .${Y} li > ol { margin-top: 0.3em; font-size: 0.9em; }
|
|
519
|
+
.${Y} li::marker { color: #2563eb; }
|
|
520
|
+
.${Y} strong { font-weight: 700; color: #1e3a8a; }
|
|
521
|
+
.${Y} em { font-style: italic; }
|
|
522
|
+
.${Y} a { color: #2563eb; text-decoration: underline; }
|
|
523
|
+
.${Y} code { font-family: ui-monospace, monospace; font-size: 0.85em; background: #f1f5f9; border-radius: 0.2em; padding: 0.05em 0.3em; }
|
|
524
|
+
.${Y} pre { background: #0f172a; color: #e2e8f0; border-radius: 0.4em; padding: 0.6em 0.8em; font-size: 0.75em; overflow: hidden; }
|
|
525
|
+
.${Y} pre code { background: none; padding: 0; color: inherit; }
|
|
526
|
+
.${Y} blockquote { border-left: 0.2em solid #93c5fd; padding-left: 0.8em; color: #475569; font-style: italic; }
|
|
527
|
+
.${Y} table { border-collapse: collapse; font-size: 0.85em; align-self: flex-start; }
|
|
528
|
+
.${Y} th, .${Y} td { border: 1px solid #cbd5e1; padding: 0.25em 0.7em; text-align: left; }
|
|
529
|
+
.${Y} th { background: #eff6ff; font-weight: 700; }
|
|
530
|
+
.${Y} hr { border: 0; border-top: 2px solid #e2e8f0; }
|
|
531
|
+
.${Y} img { max-width: 100%; max-height: 60%; }
|
|
532
|
+
.${Y}.${Ae} { flex-direction: row; align-items: center; gap: 48px; }
|
|
533
|
+
.${Y} .${X} { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 0.5em; }
|
|
534
|
+
.${Y} .${X} > * { margin: 0; }
|
|
535
|
+
.${Y} .${je} { flex: 0 0 44%; width: 44%; height: 100%; max-width: none; max-height: 100%; object-fit: cover; border-radius: 0.6em; box-shadow: 0 10px 30px rgba(15, 23, 42, 0.18); }
|
|
536
|
+
.${Y} .math-display { display: block; text-align: center; font-size: 1.15em; }
|
|
537
|
+
.${Y} math { font-family: "Latin Modern Math", "STIX Two Math", "Cambria Math", math; }
|
|
538
|
+
.${Y} mtd { padding: 0.1em 0.4em; }
|
|
539
|
+
.${Y} mtd:first-child { padding-left: 0; }
|
|
540
|
+
.${Y} mtd:last-child { padding-right: 0; }
|
|
541
|
+
.${Y} .math-error { color: #b91c1c; font-family: ui-monospace, monospace; }`;
|
|
542
|
+
function Pe(e) {
|
|
533
543
|
let t = e.split("\n").filter((e) => e.trim()).length, n = e.length;
|
|
534
544
|
return t <= 5 && n <= 250 ? 40 : t <= 8 && n <= 450 ? 34 : t <= 12 && n <= 700 ? 28 : 24;
|
|
535
545
|
}
|
|
536
|
-
var
|
|
537
|
-
function
|
|
546
|
+
var Fe = /^[ \t]*(?:\$\$([\s\S]+?)\$\$|\\\[([\s\S]+?)\\\])[ \t]*(?:\n|$)/, Ie = /^(?:\$\$(.+?)\$\$|\$(?!\s)((?:\\.|[^\\$\n])+?)(?<!\s)\$(?!\d)|\\\((.+?)\\\))/;
|
|
547
|
+
function Le(e) {
|
|
538
548
|
return [{
|
|
539
549
|
name: "blockMath",
|
|
540
550
|
level: "block",
|
|
@@ -543,7 +553,7 @@ function Oe(e) {
|
|
|
543
553
|
return t ? t.index + (t[1] ?? "").length : void 0;
|
|
544
554
|
},
|
|
545
555
|
tokenizer(e) {
|
|
546
|
-
let t =
|
|
556
|
+
let t = Fe.exec(e);
|
|
547
557
|
if (t) return {
|
|
548
558
|
type: "blockMath",
|
|
549
559
|
raw: t[0],
|
|
@@ -556,7 +566,7 @@ function Oe(e) {
|
|
|
556
566
|
level: "inline",
|
|
557
567
|
start: (e) => e.match(/(?<!\\)\$|\\\(/)?.index,
|
|
558
568
|
tokenizer(e) {
|
|
559
|
-
let t =
|
|
569
|
+
let t = Ie.exec(e);
|
|
560
570
|
if (t) return {
|
|
561
571
|
type: "inlineMath",
|
|
562
572
|
raw: t[0],
|
|
@@ -567,11 +577,11 @@ function Oe(e) {
|
|
|
567
577
|
renderer: (t) => e(String(t.text), t.display === !0)
|
|
568
578
|
}];
|
|
569
579
|
}
|
|
570
|
-
var
|
|
571
|
-
async function
|
|
580
|
+
var Re = /(<\/mi>|<\/mn>|<\/mrow>|<mo[^>]*>[)\]]<\/mo>)?(<mi(?: mathvariant="normal")?>[A-Za-z]{2,}<\/mi>)<mo>\u2061<\/mo>/g, ze = "<mspace width=\"0.1667em\"></mspace>", Be = (e) => e.replace(Re, (e, t, n) => `${t ? t + ze : ""}${n}<mo lspace="0" rspace="0.1667em">\u2061</mo>`);
|
|
581
|
+
async function Ve(e) {
|
|
572
582
|
let [{ Marked: t }, { default: n }] = await Promise.all([import("marked"), import("katex")]), r = (e, t) => {
|
|
573
583
|
try {
|
|
574
|
-
return
|
|
584
|
+
return Be(n.renderToString(e, {
|
|
575
585
|
output: "mathml",
|
|
576
586
|
displayMode: t,
|
|
577
587
|
throwOnError: !0
|
|
@@ -583,28 +593,42 @@ async function J(e) {
|
|
|
583
593
|
gfm: !0,
|
|
584
594
|
breaks: !1
|
|
585
595
|
});
|
|
586
|
-
i.use({ extensions:
|
|
587
|
-
let a =
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
596
|
+
i.use({ extensions: Le(r) });
|
|
597
|
+
let a = i.lexer(e), o = a.findIndex((e) => {
|
|
598
|
+
if (e.type !== "paragraph" || e.tokens?.length !== 1) return !1;
|
|
599
|
+
let t = e.tokens[0];
|
|
600
|
+
return t?.type === "image" ? t.href.trim() === g : t?.type === "text" && t.text.trim() === "{{image}}";
|
|
601
|
+
});
|
|
602
|
+
if (o >= 0) {
|
|
603
|
+
let [t] = a.splice(o, 1), n = t?.type === "paragraph" ? t.tokens?.[0] : void 0, r = n?.type === "image" ? n.text : "", s = i.parser(a), c = e.replace(t?.raw ?? "", "");
|
|
604
|
+
return `<style>${Ne}</style>
|
|
605
|
+
<div class="${Y} ${Ae}" data-fit style="font-size: ${Math.round(Pe(c) * Me)}px">
|
|
606
|
+
<div class="${X}">
|
|
607
|
+
${s}</div>
|
|
608
|
+
<img class="${je}" src="${g}" alt="${p(r)}">
|
|
609
|
+
</div>`;
|
|
610
|
+
}
|
|
611
|
+
let s = await i.parse(e);
|
|
612
|
+
return `<style>${Ne}</style>
|
|
613
|
+
<div class="${Y}" data-fit style="font-size: ${Pe(e)}px">
|
|
614
|
+
${s}</div>`;
|
|
591
615
|
}
|
|
592
616
|
//#endregion
|
|
593
617
|
//#region src/core/records.ts
|
|
594
|
-
var
|
|
595
|
-
function
|
|
596
|
-
let t =
|
|
597
|
-
return t ||
|
|
618
|
+
var He = "slideshows", Z = "storyboards", Ue = {}, We = /* @__PURE__ */ new WeakMap(), Ge = /* @__PURE__ */ new WeakMap();
|
|
619
|
+
function Ke(e) {
|
|
620
|
+
let t = We.get(e);
|
|
621
|
+
return t || We.set(e, t = /* @__PURE__ */ new Map()), t;
|
|
598
622
|
}
|
|
599
|
-
function
|
|
600
|
-
let r =
|
|
601
|
-
r ||
|
|
623
|
+
function qe(t, n) {
|
|
624
|
+
let r = Ge.get(t);
|
|
625
|
+
r || Ge.set(t, r = /* @__PURE__ */ new Map());
|
|
602
626
|
let i = r.get(n);
|
|
603
627
|
return i || r.set(n, i = e()), i;
|
|
604
628
|
}
|
|
605
|
-
var
|
|
606
|
-
async function
|
|
607
|
-
let n =
|
|
629
|
+
var Je = (e, t) => `${e}/${t}.json`;
|
|
630
|
+
async function Ye(e, t) {
|
|
631
|
+
let n = Ke(e ?? Ue), r = n.get(t);
|
|
608
632
|
if (r) return r;
|
|
609
633
|
if (!e) return null;
|
|
610
634
|
try {
|
|
@@ -614,14 +638,14 @@ async function Re(e, t) {
|
|
|
614
638
|
return null;
|
|
615
639
|
}
|
|
616
640
|
}
|
|
617
|
-
async function
|
|
618
|
-
return
|
|
641
|
+
async function Xe(e, t, n) {
|
|
642
|
+
return x.test(n) ? Ye(e, Je(t, n)) : null;
|
|
619
643
|
}
|
|
620
|
-
async function
|
|
621
|
-
let i =
|
|
622
|
-
return
|
|
623
|
-
let t = r(await
|
|
624
|
-
if (
|
|
644
|
+
async function Q(e, t, n, r) {
|
|
645
|
+
let i = Je(t, n), a = e ?? Ue;
|
|
646
|
+
return qe(a, i)(async () => {
|
|
647
|
+
let t = r(await Ye(e, i));
|
|
648
|
+
if (Ke(a).set(i, t), !e) return !1;
|
|
625
649
|
try {
|
|
626
650
|
return await e.write(i, JSON.stringify(t, null, 2)), !0;
|
|
627
651
|
} catch (e) {
|
|
@@ -629,12 +653,12 @@ async function Z(e, t, n, r) {
|
|
|
629
653
|
}
|
|
630
654
|
});
|
|
631
655
|
}
|
|
632
|
-
var
|
|
633
|
-
function
|
|
656
|
+
var $ = (e) => `the ${e} could not be saved, so it lasts only until the app or server restarts`, Ze = 6e4;
|
|
657
|
+
function Qe() {
|
|
634
658
|
let e = /* @__PURE__ */ new Map();
|
|
635
659
|
return { claim: (t) => {
|
|
636
660
|
let n = Date.now();
|
|
637
|
-
for (let [t, r] of e) n - r.at >
|
|
661
|
+
for (let [t, r] of e) n - r.at > Ze && e.delete(t);
|
|
638
662
|
let r = e.get(t);
|
|
639
663
|
if (r) return { earlier: r.shown };
|
|
640
664
|
let i = () => void 0, a = new Promise((e) => i = e);
|
|
@@ -648,7 +672,7 @@ function Ve() {
|
|
|
648
672
|
}
|
|
649
673
|
//#endregion
|
|
650
674
|
//#region src/core/presentSlide.ts
|
|
651
|
-
function
|
|
675
|
+
function $e({ slide: e, totalSlides: t, mode: n }) {
|
|
652
676
|
return n === "steps" ? {
|
|
653
677
|
step: e,
|
|
654
678
|
total: t,
|
|
@@ -666,7 +690,7 @@ function He({ slide: e, totalSlides: t, mode: n }) {
|
|
|
666
690
|
nextCall: `call presentSlide for slide ${e + 1} of ${t}`
|
|
667
691
|
};
|
|
668
692
|
}
|
|
669
|
-
var
|
|
693
|
+
var et = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, html: a, markdown: o, chart: s }) => JSON.stringify([
|
|
670
694
|
e,
|
|
671
695
|
t,
|
|
672
696
|
n,
|
|
@@ -675,19 +699,19 @@ var Ue = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, html: a, mark
|
|
|
675
699
|
a,
|
|
676
700
|
o,
|
|
677
701
|
s
|
|
678
|
-
]),
|
|
702
|
+
]), tt = ke(() => ({
|
|
679
703
|
latest: {
|
|
680
704
|
presentation: null,
|
|
681
705
|
steps: null
|
|
682
706
|
},
|
|
683
707
|
lastShown: null,
|
|
684
|
-
repeats:
|
|
708
|
+
repeats: Qe()
|
|
685
709
|
}));
|
|
686
|
-
function
|
|
710
|
+
function nt(e, t) {
|
|
687
711
|
let n = e.latest[t.mode], r = n?.totalSlides === t.totalSlides && (t.slide !== 1 || n.firstTitle === t.title);
|
|
688
712
|
if (n && r) return n;
|
|
689
713
|
let i = {
|
|
690
|
-
id:
|
|
714
|
+
id: Te(),
|
|
691
715
|
mode: t.mode,
|
|
692
716
|
totalSlides: t.totalSlides,
|
|
693
717
|
firstTitle: t.slide === 1 ? t.title : "",
|
|
@@ -697,56 +721,84 @@ function Ge(e, t) {
|
|
|
697
721
|
};
|
|
698
722
|
return e.latest[t.mode] = i, i;
|
|
699
723
|
}
|
|
700
|
-
function
|
|
724
|
+
function rt(e, t, n, r) {
|
|
701
725
|
t.current = n.slide, t.shownAt = Date.now(), e.lastShown = t;
|
|
702
726
|
let i = n.mode === "steps" ? "step" : "slide", { uuid: a, ...o } = r;
|
|
703
727
|
return {
|
|
704
728
|
...o,
|
|
705
729
|
message: `${i} ${n.slide} of ${n.totalSlides} is on the screen again, as it was`,
|
|
706
|
-
instructions:
|
|
730
|
+
instructions: M(n),
|
|
707
731
|
instructionsRequired: !0,
|
|
708
|
-
sequence:
|
|
732
|
+
sequence: $e(n)
|
|
709
733
|
};
|
|
710
734
|
}
|
|
711
|
-
function
|
|
735
|
+
function it(e, t) {
|
|
712
736
|
if (e.mode !== "steps") return e.title ? `A presentation slide titled "${e.title}". ${e.imagePrompt}` : e.imagePrompt;
|
|
713
737
|
let n = e.title ? `, "${e.title}"` : "";
|
|
714
738
|
return [
|
|
715
739
|
`An instructional illustration of step ${e.slide} of ${e.totalSlides}${n}. ${e.imagePrompt}`,
|
|
716
|
-
t ?
|
|
740
|
+
t ? at : "",
|
|
717
741
|
"Show the action clearly, with little or no text."
|
|
718
742
|
].filter(Boolean).join(" ");
|
|
719
743
|
}
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
744
|
+
var at = "The reference image is the previous step: keep the same objects, hands, tools and setting, and show what this step changes.";
|
|
745
|
+
async function ot(e, t, n) {
|
|
746
|
+
if (n.mode !== "steps") return [];
|
|
747
|
+
let r = W(t.slides.get(n.slide - 1)).imagePath;
|
|
748
|
+
return r ? await De(e, [r]) : [];
|
|
749
|
+
}
|
|
750
|
+
var st = (e, t) => [
|
|
751
|
+
e.mode === "steps" ? `An instructional illustration for step ${e.slide} of ${e.totalSlides}${e.title ? `, "${e.title}"` : ""}. ${e.imagePrompt}` : `A picture for a presentation slide${e.title ? ` titled "${e.title}"` : ""}. ${e.imagePrompt}`,
|
|
752
|
+
t ? at : "",
|
|
753
|
+
e.markdown ? "Keep the subject in the middle: the picture is cropped to a tall frame." : "",
|
|
754
|
+
"No text, letters or numbers in the picture."
|
|
755
|
+
].filter(Boolean).join(" ");
|
|
756
|
+
async function ct(e, t, n) {
|
|
725
757
|
if (n.chart) return {
|
|
726
758
|
chart: n.chart,
|
|
727
759
|
prompt: ""
|
|
728
760
|
};
|
|
729
|
-
if (n.markdown)
|
|
730
|
-
html:
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
761
|
+
if (n.html || n.markdown) {
|
|
762
|
+
let r = n.html ? { html: n.html } : {
|
|
763
|
+
html: await Ve(n.markdown ?? ""),
|
|
764
|
+
markdown: n.markdown ?? ""
|
|
765
|
+
}, i = y(r.html);
|
|
766
|
+
if (i && !n.imagePrompt) return { failed: {
|
|
767
|
+
message: O,
|
|
768
|
+
sequence: null
|
|
769
|
+
} };
|
|
770
|
+
if (!i) return {
|
|
771
|
+
...r,
|
|
772
|
+
prompt: ""
|
|
773
|
+
};
|
|
774
|
+
let a = await ot(e, t, n), o = st(n, a.length > 0), s = await J(e, o, a), { imageData: c, imagePath: l } = W(s);
|
|
775
|
+
return c ? {
|
|
776
|
+
...r,
|
|
777
|
+
imageData: c,
|
|
778
|
+
...l && { imagePath: l },
|
|
779
|
+
prompt: o
|
|
780
|
+
} : {
|
|
781
|
+
...r,
|
|
782
|
+
prompt: o,
|
|
783
|
+
pictureFailed: s.message
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
let r = await ot(e, t, n), i = it(n, r.length > 0), a = await J(e, i, r), { imageData: o, imagePath: s } = W(a);
|
|
787
|
+
return o ? {
|
|
788
|
+
imageData: o,
|
|
789
|
+
...s && { imagePath: s },
|
|
790
|
+
prompt: i
|
|
739
791
|
} : { failed: {
|
|
740
|
-
...
|
|
792
|
+
...a,
|
|
741
793
|
sequence: null
|
|
742
794
|
} };
|
|
743
795
|
}
|
|
744
|
-
async function
|
|
745
|
-
let r = await
|
|
796
|
+
async function lt(e, t, n) {
|
|
797
|
+
let r = await ct(e, t, n);
|
|
746
798
|
if ("failed" in r) return r.failed;
|
|
747
|
-
let { imageData: i, imagePath: a, html: o, markdown: s, chart: c, prompt: l } = r,
|
|
799
|
+
let { imageData: i, imagePath: a, html: o, markdown: s, chart: c, prompt: l, pictureFailed: u } = r, d = t.id, f = await Q(e.files?.artifacts, He, d, (e) => {
|
|
748
800
|
let t = e ?? {
|
|
749
|
-
id:
|
|
801
|
+
id: d,
|
|
750
802
|
title: "",
|
|
751
803
|
mode: n.mode,
|
|
752
804
|
totalSlides: n.totalSlides,
|
|
@@ -754,46 +806,47 @@ async function Ye(e, t, n) {
|
|
|
754
806
|
};
|
|
755
807
|
return n.slide === 1 && (t.title = n.title), t.slides[String(n.slide)] = {
|
|
756
808
|
title: n.title,
|
|
757
|
-
imagePrompt: n.imagePrompt,
|
|
809
|
+
imagePrompt: o && !l ? "" : n.imagePrompt,
|
|
758
810
|
...a && { imagePath: a },
|
|
759
811
|
...o && { html: o },
|
|
760
812
|
...s && { markdown: s },
|
|
761
813
|
...c && { chart: c }
|
|
762
814
|
}, t;
|
|
763
|
-
}),
|
|
815
|
+
}), p = {
|
|
764
816
|
...i && { imageData: i },
|
|
765
817
|
...a && { imagePath: a },
|
|
766
818
|
...o && { html: o },
|
|
767
819
|
...s && { markdown: s },
|
|
768
820
|
...c && { chart: c },
|
|
769
821
|
prompt: l,
|
|
770
|
-
slideshowId:
|
|
822
|
+
slideshowId: d,
|
|
771
823
|
slide: n.slide,
|
|
772
824
|
totalSlides: n.totalSlides,
|
|
773
825
|
title: n.title,
|
|
774
826
|
mode: n.mode
|
|
775
|
-
},
|
|
827
|
+
}, m = n.mode === "steps" ? "step" : "slide";
|
|
776
828
|
return {
|
|
777
|
-
data:
|
|
829
|
+
data: p,
|
|
778
830
|
title: n.title || `Slide ${n.slide}`,
|
|
779
831
|
message: [
|
|
780
|
-
`${
|
|
832
|
+
`${m} ${n.slide} of ${n.totalSlides} of slideshow "${d}" is on the screen`,
|
|
781
833
|
a ? `saved to ${a}` : "",
|
|
782
|
-
|
|
834
|
+
u ? `its picture couldn't be drawn (${u}), so the slide is shown without it` : "",
|
|
835
|
+
f ? "" : $("slideshow")
|
|
783
836
|
].filter(Boolean).join("; "),
|
|
784
|
-
instructions:
|
|
837
|
+
instructions: M(n),
|
|
785
838
|
instructionsRequired: !0,
|
|
786
|
-
sequence:
|
|
839
|
+
sequence: $e(n)
|
|
787
840
|
};
|
|
788
841
|
}
|
|
789
|
-
async function
|
|
790
|
-
let n =
|
|
842
|
+
async function ut(e, t) {
|
|
843
|
+
let n = A(t);
|
|
791
844
|
if (typeof n == "string") return {
|
|
792
845
|
message: n,
|
|
793
846
|
sequence: null
|
|
794
847
|
};
|
|
795
|
-
let r =
|
|
796
|
-
if (a && n.slide > i.current && i.current > 0 && !
|
|
848
|
+
let r = tt(e), i = nt(r, n), a = n.mode === "steps";
|
|
849
|
+
if (a && n.slide > i.current && i.current > 0 && !q(e, i.shownAt)) {
|
|
797
850
|
console.info(`[sequence] holding step ${n.slide} for the user`);
|
|
798
851
|
let e = i.shownAt === Infinity ? "is still being drawn" : "is still on the screen";
|
|
799
852
|
return {
|
|
@@ -802,15 +855,15 @@ async function Xe(e, t) {
|
|
|
802
855
|
};
|
|
803
856
|
}
|
|
804
857
|
let o = a ? i.slides.get(n.slide) : void 0;
|
|
805
|
-
if (o) return
|
|
858
|
+
if (o) return we(e.currentResult, o) ? {
|
|
806
859
|
message: `step ${n.slide} of ${n.totalSlides} is already on the screen`,
|
|
807
860
|
cancelled: !0
|
|
808
|
-
} :
|
|
809
|
-
let s = r.repeats.claim(
|
|
861
|
+
} : rt(r, i, n, o);
|
|
862
|
+
let s = r.repeats.claim(et(i.id, n));
|
|
810
863
|
if ("earlier" in s) {
|
|
811
|
-
if (!await s.earlier) return
|
|
864
|
+
if (!await s.earlier) return ut(e, t);
|
|
812
865
|
let a = i.slides.get(n.slide);
|
|
813
|
-
return a && r.lastShown !== i ?
|
|
866
|
+
return a && r.lastShown !== i ? rt(r, i, n, a) : {
|
|
814
867
|
message: `slide ${n.slide} of ${n.totalSlides} is already on the screen`,
|
|
815
868
|
cancelled: !0
|
|
816
869
|
};
|
|
@@ -822,22 +875,22 @@ async function Xe(e, t) {
|
|
|
822
875
|
i.current = n.slide, i.shownAt = Infinity;
|
|
823
876
|
let u = !1;
|
|
824
877
|
try {
|
|
825
|
-
let t = await
|
|
826
|
-
return u =
|
|
878
|
+
let t = await lt(e, i, n);
|
|
879
|
+
return u = Ce(t), u && (i.slides.set(n.slide, t), i.current = n.slide, i.shownAt = Date.now(), r.lastShown = i), t;
|
|
827
880
|
} finally {
|
|
828
881
|
c(u), !u && i.current === n.slide && (i.current = l.current, i.shownAt = l.shownAt);
|
|
829
882
|
}
|
|
830
883
|
}
|
|
831
884
|
//#endregion
|
|
832
885
|
//#region src/core/storyboard.ts
|
|
833
|
-
var
|
|
886
|
+
var dt = ({ id: e, title: t, totalPanels: n }) => ({
|
|
834
887
|
step: 0,
|
|
835
888
|
total: n,
|
|
836
889
|
kind: "story",
|
|
837
890
|
label: `The cast of "${t}"`,
|
|
838
891
|
onShown: "introduce the characters",
|
|
839
892
|
nextCall: `call presentPanel for panel 1 of ${n} with storyboardId "${e}"`
|
|
840
|
-
}),
|
|
893
|
+
}), ft = ({ id: e, totalPanels: t }, n, r) => ({
|
|
841
894
|
step: n,
|
|
842
895
|
total: t,
|
|
843
896
|
kind: "story",
|
|
@@ -845,21 +898,21 @@ var Ze = ({ id: e, title: t, totalPanels: n }) => ({
|
|
|
845
898
|
onShown: "tell that part of the story",
|
|
846
899
|
nextCall: `call presentPanel for panel ${n + 1} of ${t} with storyboardId "${e}"`,
|
|
847
900
|
...r.length > 0 && { waitsForUser: !0 }
|
|
848
|
-
}),
|
|
849
|
-
async function
|
|
850
|
-
let n =
|
|
901
|
+
}), pt = (e, t) => e ? `${e}. ${t}` : t, mt = (e, { name: t, description: n }) => pt(e, `Character reference sheet of ${t}: ${n}. Full body, front, side and back views, on a plain white background. No text or labels.`);
|
|
902
|
+
async function ht(e, t) {
|
|
903
|
+
let n = F(t);
|
|
851
904
|
if (typeof n == "string") return {
|
|
852
905
|
message: n,
|
|
853
906
|
sequence: null
|
|
854
907
|
};
|
|
855
|
-
let r = await Promise.all(n.characters.map((t) =>
|
|
908
|
+
let r = await Promise.all(n.characters.map((t) => J(e, mt(n.style, t)))), i = r.map(W), a = r.find((e, t) => !i[t]?.imageData);
|
|
856
909
|
if (i.every(({ imageData: e }) => !e) && a) return {
|
|
857
910
|
...a,
|
|
858
911
|
message: `the character sheets couldn't be made: ${a.message}`,
|
|
859
912
|
sequence: null
|
|
860
913
|
};
|
|
861
914
|
let o = {
|
|
862
|
-
id:
|
|
915
|
+
id: Te(),
|
|
863
916
|
...n,
|
|
864
917
|
characters: n.characters.map((e, t) => {
|
|
865
918
|
let n = i[t]?.imagePath;
|
|
@@ -869,7 +922,7 @@ async function tt(e, t) {
|
|
|
869
922
|
};
|
|
870
923
|
}),
|
|
871
924
|
panels: {}
|
|
872
|
-
}, s = await
|
|
925
|
+
}, s = await Q(e.files?.artifacts, Z, o.id, () => o), c = o.characters.filter((e) => e.imagePath).map((e) => `${e.name}: ${e.imagePath}`), l = n.characters.map(({ name: e }, t) => i[t]?.imageData ? null : `${e} (${r[t]?.message ?? ""})`).filter((e) => !!e), u = i.find((e) => e.imageData)?.imageData;
|
|
873
926
|
return {
|
|
874
927
|
data: {
|
|
875
928
|
storyboardId: o.id,
|
|
@@ -890,39 +943,39 @@ async function tt(e, t) {
|
|
|
890
943
|
`storyboard "${o.id}" is ready with ${o.totalPanels} panels; the cast is on the screen`,
|
|
891
944
|
c.length ? `character sheets saved to ${c.join(", ")}` : "",
|
|
892
945
|
l.length ? `no sheet for ${l.join("; ")}: they will be drawn from their description` : "",
|
|
893
|
-
s ? "" :
|
|
946
|
+
s ? "" : $("storyboard")
|
|
894
947
|
].filter(Boolean).join("; "),
|
|
895
|
-
instructions:
|
|
948
|
+
instructions: I(o),
|
|
896
949
|
instructionsRequired: !0,
|
|
897
|
-
sequence:
|
|
950
|
+
sequence: dt(o)
|
|
898
951
|
};
|
|
899
952
|
}
|
|
900
|
-
function
|
|
901
|
-
let r = [
|
|
953
|
+
function gt(e, t, n) {
|
|
954
|
+
let r = [pt(e.style, `Panel ${t.panel} of ${e.totalPanels} of the illustrated story "${e.title}". ${t.imagePrompt}`)], i = 0, a = n.map(({ character: e, hasSheet: t }) => t ? `${e.name} is the character in reference image ${++i}` : `${e.name}: ${e.description}`);
|
|
902
955
|
return a.length && r.push(`${a.join(". ")}.`), i && r.push("Draw each character exactly as in their reference image: the same face, hair, clothes and colors. Use the reference images only for how the characters look, not for their pose or the background."), r.push("No captions, speech bubbles or other text in the picture."), r.join(" ");
|
|
903
956
|
}
|
|
904
|
-
async function
|
|
957
|
+
async function _t(e, t, n) {
|
|
905
958
|
let r = [], i = [];
|
|
906
959
|
for (let a of n.characters) {
|
|
907
|
-
let n = t.characters.find((e) =>
|
|
960
|
+
let n = t.characters.find((e) => w(e.name, a));
|
|
908
961
|
if (!n) r.push(a);
|
|
909
962
|
else if (!i.some((e) => e.character === n)) {
|
|
910
|
-
let [t] = n.imagePath ? await
|
|
963
|
+
let [t] = n.imagePath ? await De(e, [n.imagePath]) : [];
|
|
911
964
|
i.push({
|
|
912
965
|
character: n,
|
|
913
966
|
sheet: t ?? null
|
|
914
967
|
});
|
|
915
968
|
}
|
|
916
969
|
}
|
|
917
|
-
let a = i.map(({ sheet: e }) => e).filter((e) => !!e), o =
|
|
970
|
+
let a = i.map(({ sheet: e }) => e).filter((e) => !!e), o = gt(t, n, i.map(({ character: e, sheet: t }) => ({
|
|
918
971
|
character: e,
|
|
919
972
|
hasSheet: !!t
|
|
920
|
-
}))), s = await
|
|
973
|
+
}))), s = await J(e, o, a), { imageData: c, imagePath: l } = W(s);
|
|
921
974
|
if (!c) return {
|
|
922
975
|
...s,
|
|
923
976
|
sequence: null
|
|
924
977
|
};
|
|
925
|
-
let u = n.panel < t.totalPanels && n.choices.length >= 2 ? n.choices : [], d = await
|
|
978
|
+
let u = n.panel < t.totalPanels && n.choices.length >= 2 ? n.choices : [], d = await Q(e.files?.artifacts, Z, t.id, (e) => {
|
|
926
979
|
let r = e ?? t;
|
|
927
980
|
return u.length && (r.interactive = !0), r.panels[String(n.panel)] = {
|
|
928
981
|
caption: n.caption,
|
|
@@ -948,25 +1001,25 @@ async function rt(e, t, n) {
|
|
|
948
1001
|
`panel ${n.panel} of ${t.totalPanels} is on the screen`,
|
|
949
1002
|
l ? `saved to ${l}` : "",
|
|
950
1003
|
r.length ? `not in the cast, so drawn from the prompt alone: ${r.join(", ")}` : "",
|
|
951
|
-
d ? "" :
|
|
1004
|
+
d ? "" : $("storyboard")
|
|
952
1005
|
].filter(Boolean).join("; "),
|
|
953
|
-
instructions:
|
|
1006
|
+
instructions: z(t, n.panel, u),
|
|
954
1007
|
instructionsRequired: !0,
|
|
955
|
-
sequence:
|
|
1008
|
+
sequence: ft(t, n.panel, u)
|
|
956
1009
|
};
|
|
957
1010
|
}
|
|
958
|
-
var
|
|
959
|
-
repeats:
|
|
1011
|
+
var vt = ke(() => ({
|
|
1012
|
+
repeats: Qe(),
|
|
960
1013
|
awaitingChoice: /* @__PURE__ */ new Map()
|
|
961
1014
|
}));
|
|
962
|
-
async function
|
|
963
|
-
let n =
|
|
1015
|
+
async function yt(e, t) {
|
|
1016
|
+
let n = R(t);
|
|
964
1017
|
if (!n) return {
|
|
965
|
-
message:
|
|
1018
|
+
message: L,
|
|
966
1019
|
sequence: null
|
|
967
1020
|
};
|
|
968
|
-
let { storyboardId: r, panel: i } = n, { repeats: a, awaitingChoice: o } =
|
|
969
|
-
if (s && i > s.panel && !
|
|
1021
|
+
let { storyboardId: r, panel: i } = n, { repeats: a, awaitingChoice: o } = vt(e), s = o.get(r);
|
|
1022
|
+
if (s && i > s.panel && !q(e, s.shownAt)) return console.info(`[sequence] holding panel ${i} for the user`), {
|
|
970
1023
|
message: s.shownAt === Infinity ? `panel ${i} was not shown: panel ${s.panel} is still being drawn. Wait for it before going on.` : `panel ${i} was not shown: the user hasn't picked a choice yet, and panel ${s.panel} is still on the screen. Wait for their answer.`,
|
|
971
1024
|
cancelled: !0
|
|
972
1025
|
};
|
|
@@ -974,7 +1027,7 @@ async function $(e, t) {
|
|
|
974
1027
|
if ("earlier" in c) return await c.earlier ? {
|
|
975
1028
|
message: `panel ${i} is already on the screen`,
|
|
976
1029
|
cancelled: !0
|
|
977
|
-
} :
|
|
1030
|
+
} : yt(e, t);
|
|
978
1031
|
let { settle: l } = c, u = {
|
|
979
1032
|
panel: i,
|
|
980
1033
|
shownAt: Infinity
|
|
@@ -982,7 +1035,7 @@ async function $(e, t) {
|
|
|
982
1035
|
o.set(r, u);
|
|
983
1036
|
let f = () => o.get(r) === u, p = !1;
|
|
984
1037
|
try {
|
|
985
|
-
let t = await
|
|
1038
|
+
let t = await Xe(e.files?.artifacts, Z, r);
|
|
986
1039
|
if (!t) return {
|
|
987
1040
|
message: `there is no storyboard "${r}"; call defineStoryboard first`,
|
|
988
1041
|
sequence: null
|
|
@@ -991,8 +1044,8 @@ async function $(e, t) {
|
|
|
991
1044
|
message: `storyboard "${t.id}" has ${t.totalPanels} panels`,
|
|
992
1045
|
sequence: null
|
|
993
1046
|
};
|
|
994
|
-
let a = await
|
|
995
|
-
p = !!
|
|
1047
|
+
let a = await _t(e, t, n);
|
|
1048
|
+
p = !!W(a).imageData;
|
|
996
1049
|
let s = a.data;
|
|
997
1050
|
return p && f() && (s?.choices?.length ? o.set(r, {
|
|
998
1051
|
panel: i,
|
|
@@ -1004,21 +1057,21 @@ async function $(e, t) {
|
|
|
1004
1057
|
}
|
|
1005
1058
|
//#endregion
|
|
1006
1059
|
//#region src/core/index.ts
|
|
1007
|
-
var
|
|
1008
|
-
toolDefinition:
|
|
1060
|
+
var bt = {
|
|
1061
|
+
toolDefinition: P,
|
|
1009
1062
|
generatingMessage: "Making the slide...",
|
|
1010
1063
|
isEnabled: () => !0,
|
|
1011
|
-
execute: (e, t) =>
|
|
1012
|
-
},
|
|
1013
|
-
toolDefinition:
|
|
1064
|
+
execute: (e, t) => ut(e, t)
|
|
1065
|
+
}, xt = {
|
|
1066
|
+
toolDefinition: V,
|
|
1014
1067
|
generatingMessage: "Drawing the characters...",
|
|
1015
1068
|
isEnabled: () => !0,
|
|
1016
|
-
execute: (e, t) =>
|
|
1017
|
-
},
|
|
1018
|
-
toolDefinition:
|
|
1069
|
+
execute: (e, t) => ht(e, t)
|
|
1070
|
+
}, St = {
|
|
1071
|
+
toolDefinition: H,
|
|
1019
1072
|
generatingMessage: "Drawing the panel...",
|
|
1020
1073
|
isEnabled: () => !0,
|
|
1021
|
-
execute: (e, t) =>
|
|
1074
|
+
execute: (e, t) => yt(e, t)
|
|
1022
1075
|
};
|
|
1023
1076
|
//#endregion
|
|
1024
|
-
export {
|
|
1077
|
+
export { w as A, g as B, O as C, R as D, z as E, o as F, y as H, s as I, h as L, b as M, de as N, A as O, r as P, l as R, D as S, I as T, ie as U, t as V, re as W, P as _, Z as a, E as b, pe as c, _e as d, ge as f, fe as g, H as h, He as i, M as j, F as k, V as l, me as m, St as n, Xe as o, L as p, bt as r, Ve as s, xt as t, he as u, N as v, B as w, k as x, x as y, n as z };
|