@gui-chat-plugin/sequence 0.3.1 → 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.
@@ -1,17 +1,12 @@
1
1
  import { createSerialLock as e } from "gui-chat-protocol";
2
2
  //#region src/core/slideHtml.ts
3
3
  var t = 1280, n = 720, r = 6e4, i = "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3/dist/index.global.js", a = "sha384-2ql948lIdLcGEE0/qxNiudyTjgauA3RDJERu5xW75kFCvSl5a9odyQYCb6tEjnmB", o = [
4
- "fade-in",
5
- "fade-up",
6
- "fade-down",
7
- "slide-in-left",
8
- "slide-in-right",
9
- "zoom-in",
10
- "pop",
11
- "draw"
12
- ], s = "\n@theme {\n --animate-fade-in: fade-in 0.8s ease-out both;\n --animate-fade-up: fade-up 0.8s ease-out both;\n --animate-fade-down: fade-down 0.8s ease-out both;\n --animate-slide-in-left: slide-in-left 0.8s ease-out both;\n --animate-slide-in-right: slide-in-right 0.8s ease-out both;\n --animate-zoom-in: zoom-in 0.8s ease-out both;\n --animate-pop: pop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) both;\n --animate-draw: draw 1.5s ease-in-out both;\n @keyframes fade-in { from { opacity: 0 } to { opacity: 1 } }\n @keyframes fade-up { from { opacity: 0; transform: translateY(40px) } to { opacity: 1; transform: none } }\n @keyframes fade-down { from { opacity: 0; transform: translateY(-40px) } to { opacity: 1; transform: none } }\n @keyframes slide-in-left { from { opacity: 0; transform: translateX(-80px) } to { opacity: 1; transform: none } }\n @keyframes slide-in-right { from { opacity: 0; transform: translateX(80px) } to { opacity: 1; transform: none } }\n @keyframes zoom-in { from { opacity: 0; transform: scale(0.8) } to { opacity: 1; transform: none } }\n @keyframes pop { from { opacity: 0; transform: scale(0.5) } to { opacity: 1; transform: none } }\n @keyframes draw { from { stroke-dashoffset: var(--draw-length, 1000) } to { stroke-dashoffset: 0 } }\n}", c = "\n(() => {\n const show = () => document.documentElement.classList.add(\"ready\");\n const ready = () => requestAnimationFrame(() => requestAnimationFrame(show));\n const check = () =>\n document.querySelector(\"style:not([type]):not(#slide-base)\") ? ready() : setTimeout(check, 30);\n addEventListener(\"DOMContentLoaded\", check);\n setTimeout(show, 1000);\n addEventListener(\"click\", (event) => {\n if (event.target instanceof Element && event.target.closest(\"a, area\")) event.preventDefault();\n }, true);\n})();", l = [
4
+ "animate",
5
+ "counter",
6
+ "typewriter"
7
+ ], s = 8, c = "\n(() => {\n const EASE = {\n linear: (t) => t,\n easeIn: (t) => t * t,\n easeOut: (t) => 1 - (1 - t) * (1 - t),\n easeInOut: (t) => (t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2),\n };\n const AUTO_END = 8;\n const TRANSFORMS = [\n [\"data-translate-x\", \"translateX\", \"px\"],\n [\"data-translate-y\", \"translateY\", \"px\"],\n [\"data-scale\", \"scale\", \"\"],\n [\"data-rotate\", \"rotate\", \"deg\"],\n [\"data-rotate-x\", \"rotateX\", \"deg\"],\n [\"data-rotate-y\", \"rotateY\", \"deg\"],\n [\"data-rotate-z\", \"rotateZ\", \"deg\"],\n ];\n const STYLES = [\n [\"data-opacity\", \"opacity\", \"\"],\n [\"data-width\", \"width\", \"px\"],\n [\"data-height\", \"height\", \"px\"],\n ];\n const number = (value, fallback) => {\n const n = Number(value);\n return value !== null && value.trim() !== \"\" && Number.isFinite(n) ? n : fallback;\n };\n const range = (value, unit) => {\n if (value === null) return null;\n const parts = value.split(\",\").map((part) => part.trim());\n const from = Number(parts[0]);\n const to = Number(parts[1]);\n if (!Number.isFinite(from) || !Number.isFinite(to)) return null;\n return { from, to, unit: parts[2] || unit };\n };\n const ranges = (el, table) =>\n table\n .map(([attr, name, unit]) => [name, range(el.getAttribute(attr), unit)])\n .filter(([, r]) => r);\n let entries = [];\n const collect = () => {\n entries = [...document.querySelectorAll(\"[data-animation]\")].map((el) => {\n const kind = el.getAttribute(\"data-animation\");\n const end = el.getAttribute(\"data-end\");\n const entry = {\n el,\n kind,\n start: number(el.getAttribute(\"data-start\"), 0),\n end: end === null || end.trim() === \"auto\" ? null : number(end, null),\n ease: EASE[el.getAttribute(\"data-easing\")] || EASE.linear,\n };\n if (kind === \"animate\") {\n entry.transforms = ranges(el, TRANSFORMS);\n entry.styles = ranges(el, STYLES);\n } else if (kind === \"counter\") {\n entry.from = number(el.getAttribute(\"data-from\"), 0);\n entry.to = number(el.getAttribute(\"data-to\"), 0);\n entry.decimals = Math.max(0, Math.round(number(el.getAttribute(\"data-decimals\"), 0)));\n entry.prefix = el.getAttribute(\"data-prefix\") || \"\";\n entry.suffix = el.getAttribute(\"data-suffix\") || \"\";\n } else if (kind === \"typewriter\") {\n entry.text = el.getAttribute(\"data-text\") ?? el.textContent;\n } else {\n return null;\n }\n return entry;\n }).filter(Boolean);\n };\n const seek = (t) => {\n for (const e of entries) {\n const end = e.end ?? AUTO_END;\n const span = end - e.start;\n const p = span > 0 ? Math.min(1, Math.max(0, (t - e.start) / span)) : t >= e.start ? 1 : 0;\n const k = e.ease(p);\n const at = (r) => r.from + (r.to - r.from) * k;\n if (e.kind === \"animate\") {\n if (e.transforms.length) {\n e.el.style.transform = e.transforms.map(([name, r]) => name + \"(\" + at(r) + r.unit + \")\").join(\" \");\n }\n for (const [name, r] of e.styles) e.el.style[name] = at(r) + r.unit;\n } else if (e.kind === \"counter\") {\n e.el.textContent = e.prefix + (e.from + (e.to - e.from) * k).toFixed(e.decimals) + e.suffix;\n } else {\n e.el.textContent = e.text.slice(0, Math.floor(e.text.length * k));\n }\n }\n };\n window.__slideSeek = seek;\n const play = () => {\n const last = Math.max(0, ...entries.map((e) => e.end ?? AUTO_END));\n const begun = performance.now();\n const tick = (now) => {\n const t = (now - begun) / 1000;\n seek(t);\n if (t <= last) requestAnimationFrame(tick);\n };\n requestAnimationFrame(tick);\n };\n // Collected once the body is parsed: at DOMContentLoaded, or earlier when\n // the fallback shows the slide while a slow Tailwind still holds\n // DOMContentLoaded back (the body is parsed by then: readyState is\n // \"interactive\" before deferred scripts run). Played once both are done.\n let collected = false;\n let shown = false;\n const init = () => {\n if (collected || document.readyState === \"loading\") return;\n collected = true;\n collect();\n seek(0);\n if (shown) play();\n };\n const show = () => {\n if (shown) return;\n init();\n shown = true;\n document.documentElement.classList.add(\"ready\");\n if (collected) play();\n };\n const ready = () => requestAnimationFrame(() => requestAnimationFrame(show));\n const check = () =>\n document.querySelector(\"style:not([type]):not(#slide-base)\") ? ready() : setTimeout(check, 30);\n addEventListener(\"DOMContentLoaded\", () => {\n init();\n check();\n });\n setTimeout(show, 1000);\n addEventListener(\"click\", (event) => {\n if (event.target instanceof Element && event.target.closest(\"a, area\")) event.preventDefault();\n }, true);\n})();", l = [
13
8
  "default-src 'none'",
14
- `script-src 'sha256-MZyL5rvWmIVxl3WUuDU5BqzPJGR2/fV/YPh01MNyUoM=' ${i}`,
9
+ `script-src 'sha256-0zsqCvkCfq5Z1iJCn46NiAtSAyIr/JDkyNs/Fae1J+Y=' ${i}`,
15
10
  "style-src 'unsafe-inline' https://fonts.googleapis.com",
16
11
  "font-src https://fonts.gstatic.com data:",
17
12
  "img-src data: blob:",
@@ -19,20 +14,19 @@ var t = 1280, n = 720, r = 6e4, i = "https://cdn.jsdelivr.net/npm/@tailwindcss/b
19
14
  "connect-src 'none'",
20
15
  "form-action 'none'",
21
16
  "base-uri 'none'"
22
- ].join("; "), u = (e) => e.replace(/<(?=(meta|base|link)\b)/gi, "&lt;").replace(/shadowroot/gi, "data-no-shadow-root"), d = `
17
+ ].join("; "), u = (e) => e.replace(/<(?=(meta|base|link)\b)/gi, "&lt;").replace(/shadowroot/gi, "data-no-shadow-root"), d = "*, *::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; }", f = `
23
18
  html, body { margin: 0; width: ${t}px; height: 720px; overflow: hidden; }
24
19
  html:not(.ready) body { visibility: hidden; }
25
- html:not(.ready) body * { animation-play-state: paused !important; }`;
26
- function f(e) {
20
+ ${d}`;
21
+ function p(e) {
27
22
  return `<!doctype html>
28
23
  <html lang="en">
29
24
  <head>
30
25
  <meta charset="utf-8">
31
26
  <meta http-equiv="Content-Security-Policy" content="${l}">
32
- <style id="slide-base">${d}</style>
27
+ <style id="slide-base">${f}</style>
33
28
  <script>${c}<\/script>
34
29
  <script defer src="${i}" integrity="${a}" crossorigin="anonymous"><\/script>
35
- <style type="text/tailwindcss">${s}</style>
36
30
  </head>
37
31
  <body class="bg-white text-slate-900 font-sans antialiased">
38
32
  ${u(e)}
@@ -41,10 +35,10 @@ ${u(e)}
41
35
  }
42
36
  //#endregion
43
37
  //#region src/core/definitions.ts
44
- var p = "presentSlide", m = "defineStoryboard", h = "presentPanel", ee = 4, te = 12, ne = 3, g = /^[0-9a-f]{12}$/, _ = (e) => typeof e == "object" && !!e && !Array.isArray(e), v = (e) => typeof e == "string" ? e.trim() : "", y = (e, t) => e.toLowerCase() === t.toLowerCase(), b = (e) => typeof e == "number" && Number.isInteger(e), x = "presentSlide needs slide and totalSlides (whole numbers, slide from 1 to totalSlides), and either an imagePrompt or html", re = `presentSlide's html is too long: keep a slide under ${r} characters`;
45
- function ie(e) {
46
- let { slide: t, totalSlides: n, title: r, imagePrompt: i } = e, a = v(e.html);
47
- return !b(t) || !b(n) || t < 1 || n < t || !a && !v(i) ? x : a.length > 6e4 ? re : {
38
+ var m = "presentSlide", h = "defineStoryboard", g = "presentPanel", ee = 4, te = 12, ne = 3, _ = /^[0-9a-f]{12}$/, v = (e) => typeof e == "object" && !!e && !Array.isArray(e), y = (e) => typeof e == "string" ? e.trim() : "", b = (e, t) => e.toLowerCase() === t.toLowerCase(), x = (e) => typeof e == "number" && Number.isInteger(e), S = "presentSlide needs slide and totalSlides (whole numbers, slide from 1 to totalSlides), and either an imagePrompt or html", C = `presentSlide's html is too long: keep a slide under ${r} characters`;
39
+ function w(e) {
40
+ let { slide: t, totalSlides: n, title: r, imagePrompt: i } = e, a = y(e.html);
41
+ return !x(t) || !x(n) || t < 1 || n < t || !a && !y(i) ? S : a.length > 6e4 ? C : {
48
42
  slide: t,
49
43
  totalSlides: n,
50
44
  title: typeof r == "string" ? r : "",
@@ -53,7 +47,7 @@ function ie(e) {
53
47
  mode: e.mode === "steps" ? "steps" : "presentation"
54
48
  };
55
49
  }
56
- var S = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
50
+ var T = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
57
51
  let i = n ? ` ("${n}")` : "";
58
52
  if (r === "steps") {
59
53
  let n = `Step ${e} of ${t}${i}`;
@@ -61,10 +55,14 @@ var S = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
61
55
  }
62
56
  let a = `Slide ${e} of ${t}${i}`;
63
57
  return e < t ? `${a} is now on the screen. Explain it, then, in this same reply and without waiting for the user, call presentSlide 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, then wrap up the slideshow.`;
64
- }, ae = [`For an HTML slide, instead of imagePrompt: 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.`, `Animate it so it builds up as you explain it: these classes are defined, ${o.map((e) => `animate-${e}`).join(", ")} (an SVG path drawing itself: set stroke-dasharray and --draw-length to its length), plus Tailwind's animate-pulse, animate-bounce, animate-spin and animate-ping, and transitions. Stagger the parts with a delay, [animation-delay:600ms], so they appear one after another over a few seconds. A <style> with your own @keyframes is allowed too (and Google Fonts by @import). Scripts don't run: animate with CSS only.`].join(" "), C = "When the user asks for a slideshow (or to explain something with slides), plan four to six slides, 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. Go on to the last slide without asking whether to continue. A slide is a generated picture (imagePrompt) or a designed slide in HTML (html): use a picture for a scene, an object or a place, and HTML for words, numbers, lists, comparisons, timelines and diagrams, which a picture model draws badly; a slideshow can mix them. 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.", w = {
58
+ }, re = [
59
+ `For an HTML slide, instead of imagePrompt: 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.`,
60
+ "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).",
61
+ "CSS animations, transitions and scripts don't play: animate only with data-animation. A <style> for layout is allowed (and Google Fonts by @import)."
62
+ ].join(" "), ie = "When the user asks for a slideshow (or to explain something with slides), plan four to six slides, 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. Go on to the last slide without asking whether to continue. A slide is a generated picture (imagePrompt) or a designed slide in HTML (html): use a picture for a scene, an object or a place, and HTML for words, numbers, lists, comparisons, timelines and diagrams, which a picture model draws badly; a slideshow can mix them. 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.", E = {
65
63
  type: "function",
66
- name: p,
67
- prompt: C,
64
+ name: m,
65
+ prompt: ie,
68
66
  description: "Show one slide of a slideshow, full screen: a picture generated from imagePrompt, or a slide written in HTML (html). 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.",
69
67
  parameters: {
70
68
  type: "object",
@@ -87,7 +85,7 @@ var S = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
87
85
  },
88
86
  html: {
89
87
  type: "string",
90
- description: ae
88
+ description: re
91
89
  },
92
90
  mode: {
93
91
  type: "string",
@@ -102,49 +100,49 @@ var S = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
102
100
  ]
103
101
  }
104
102
  };
105
- function T(e) {
103
+ function D(e) {
106
104
  let { totalPanels: t } = e;
107
- if (!b(t) || t < 1 || t > 12) return "totalPanels must be a whole number from 1 to 12";
105
+ if (!x(t) || t < 1 || t > 12) return "totalPanels must be a whole number from 1 to 12";
108
106
  let n = [];
109
107
  for (let t of Array.isArray(e.characters) ? e.characters : []) {
110
- let e = _(t) ? v(t.name) : "", r = _(t) ? v(t.description) : "";
108
+ let e = v(t) ? y(t.name) : "", r = v(t) ? y(t.description) : "";
111
109
  if (!e || !r) return "every character needs a name and a description";
112
- if (n.some((t) => y(t.name, e))) return `two characters are named ${e}`;
110
+ if (n.some((t) => b(t.name, e))) return `two characters are named ${e}`;
113
111
  n.push({
114
112
  name: e,
115
113
  description: r
116
114
  });
117
115
  }
118
116
  return n.length < 1 || n.length > 4 ? "a storyboard has 1 to 4 characters" : {
119
- title: v(e.title),
120
- style: v(e.style),
117
+ title: y(e.title),
118
+ style: y(e.style),
121
119
  totalPanels: t,
122
120
  characters: n,
123
121
  interactive: e.interactive === !0
124
122
  };
125
123
  }
126
- var E = ({ title: e, id: t }) => `The cast of "${e}" is now on the screen. Introduce the characters briefly, then, in this same reply and without waiting for the user, call presentPanel for panel 1 with storyboardId "${t}". If the user has asked you to stop, or asked something else, answer them instead of going on.`, D = "presentPanel needs a storyboardId, a panel number (from 1) and an imagePrompt";
127
- function O(e) {
128
- let { panel: t } = e, n = v(e.storyboardId), r = v(e.imagePrompt);
129
- if (!n || !r || !b(t) || t < 1) return null;
130
- let i = (e) => (Array.isArray(e) ? e : []).map(v).filter(Boolean);
124
+ var O = ({ title: e, id: t }) => `The cast of "${e}" is now on the screen. Introduce the characters briefly, then, in this same reply and without waiting for the user, call presentPanel for panel 1 with storyboardId "${t}". If the user has asked you to stop, or asked something else, answer them instead of going on.`, k = "presentPanel needs a storyboardId, a panel number (from 1) and an imagePrompt";
125
+ function A(e) {
126
+ let { panel: t } = e, n = y(e.storyboardId), r = y(e.imagePrompt);
127
+ if (!n || !r || !x(t) || t < 1) return null;
128
+ let i = (e) => (Array.isArray(e) ? e : []).map(y).filter(Boolean);
131
129
  return {
132
130
  storyboardId: n,
133
131
  panel: t,
134
132
  characters: i(e.characters),
135
133
  imagePrompt: r,
136
- caption: v(e.caption),
134
+ caption: y(e.caption),
137
135
  choices: i(e.choices).slice(0, 3)
138
136
  };
139
137
  }
140
- function k(e, t, n) {
138
+ function j(e, t, n) {
141
139
  let { id: r, totalPanels: i } = e;
142
140
  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, then, in this same reply and without waiting for the user, call presentPanel for panel ${t + 1} with storyboardId "${r}". 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.`;
143
141
  }
144
- var A = "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.", j = {
142
+ var M = "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.", N = {
145
143
  type: "function",
146
- name: m,
147
- prompt: A,
144
+ name: h,
145
+ prompt: M,
148
146
  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.",
149
147
  parameters: {
150
148
  type: "object",
@@ -191,9 +189,9 @@ var A = "When the user asks for a story, a picture book, a comic or a storyboard
191
189
  "characters"
192
190
  ]
193
191
  }
194
- }, M = {
192
+ }, P = {
195
193
  type: "function",
196
- name: h,
194
+ name: g,
197
195
  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.",
198
196
  parameters: {
199
197
  type: "object",
@@ -232,54 +230,54 @@ var A = "When the user asks for a story, a picture book, a comic or a storyboard
232
230
  "imagePrompt"
233
231
  ]
234
232
  }
235
- }, N = (e) => typeof e == "object" && !!e && !Array.isArray(e), oe = (e) => N(e) && typeof e.message == "string";
236
- function P(e) {
237
- let t = N(e?.data) ? e.data : {};
233
+ }, F = (e) => typeof e == "object" && !!e && !Array.isArray(e), ae = (e) => F(e) && typeof e.message == "string";
234
+ function I(e) {
235
+ let t = F(e?.data) ? e.data : {};
238
236
  return {
239
237
  ...typeof t.imageData == "string" && { imageData: t.imageData },
240
238
  ...typeof t.imagePath == "string" && { imagePath: t.imagePath }
241
239
  };
242
240
  }
243
- function F(e) {
244
- let t = N(e?.data) ? e.data : {};
241
+ function L(e) {
242
+ let t = F(e?.data) ? e.data : {};
245
243
  return typeof t.html == "string" ? t.html : "";
246
244
  }
247
- var se = (e) => !!P(e).imageData || !!F(e);
248
- function ce(e, t) {
249
- let n = P(e), r = P(t);
245
+ var oe = (e) => !!I(e).imageData || !!L(e);
246
+ function se(e, t) {
247
+ let n = I(e), r = I(t);
250
248
  if (n.imagePath && r.imagePath) return n.imagePath === r.imagePath;
251
249
  if (n.imageData) return n.imageData === r.imageData;
252
- let i = F(e);
253
- return !!i && i === F(t);
250
+ let i = L(e);
251
+ return !!i && i === L(t);
254
252
  }
255
- var I = (e, t) => e.userSpokeAt === void 0 || e.userSpokeAt > t, L = () => crypto.randomUUID().replace(/-/g, "").slice(0, 12), le = "artifacts/";
256
- async function R(e, t) {
253
+ var R = (e, t) => e.userSpokeAt === void 0 || e.userSpokeAt > t, z = () => crypto.randomUUID().replace(/-/g, "").slice(0, 12), ce = "artifacts/";
254
+ async function B(e, t) {
257
255
  let n = e.files?.artifacts;
258
256
  if (!e.app?.editImages || !n) return [];
259
257
  let r = [];
260
- for (let e of t) if (e.startsWith(le)) try {
258
+ for (let e of t) if (e.startsWith(ce)) try {
261
259
  await n.exists(e.slice(10)) && r.push(e);
262
260
  } catch {}
263
261
  return r;
264
262
  }
265
- async function z(e, t, n = []) {
263
+ async function V(e, t, n = []) {
266
264
  let r = e.app, i = r?.editImages, a = r?.generateImage;
267
265
  try {
268
266
  let e;
269
267
  if (n.length && i) e = await i(t, [...n]);
270
268
  else if (a) e = await a(t);
271
269
  else return { message: "image generation isn't available" };
272
- return oe(e) ? e : { message: "image generation returned an unrecognized result" };
270
+ return ae(e) ? e : { message: "image generation returned an unrecognized result" };
273
271
  } catch (e) {
274
272
  return { message: `image generation failed: ${e instanceof Error ? e.message : String(e)}` };
275
273
  }
276
274
  }
277
- var ue = 50;
278
- function B(e) {
275
+ var le = 50;
276
+ function ue(e) {
279
277
  let t = /* @__PURE__ */ new Map();
280
278
  return (n) => {
281
279
  let r = n.conversationId ?? "", i = t.get(r);
282
- if (i === void 0 ? i = e() : t.delete(r), t.set(r, i), t.size > ue) {
280
+ if (i === void 0 ? i = e() : t.delete(r), t.set(r, i), t.size > le) {
283
281
  let e = t.keys().next().value;
284
282
  e !== void 0 && t.delete(e);
285
283
  }
@@ -288,20 +286,20 @@ function B(e) {
288
286
  }
289
287
  //#endregion
290
288
  //#region src/core/records.ts
291
- var V = "slideshows", H = "storyboards", U = {}, W = /* @__PURE__ */ new WeakMap(), G = /* @__PURE__ */ new WeakMap();
292
- function K(e) {
293
- let t = W.get(e);
294
- return t || W.set(e, t = /* @__PURE__ */ new Map()), t;
289
+ var H = "slideshows", U = "storyboards", W = {}, G = /* @__PURE__ */ new WeakMap(), K = /* @__PURE__ */ new WeakMap();
290
+ function q(e) {
291
+ let t = G.get(e);
292
+ return t || G.set(e, t = /* @__PURE__ */ new Map()), t;
295
293
  }
296
294
  function de(t, n) {
297
- let r = G.get(t);
298
- r || G.set(t, r = /* @__PURE__ */ new Map());
295
+ let r = K.get(t);
296
+ r || K.set(t, r = /* @__PURE__ */ new Map());
299
297
  let i = r.get(n);
300
298
  return i || r.set(n, i = e()), i;
301
299
  }
302
- var q = (e, t) => `${e}/${t}.json`;
303
- async function J(e, t) {
304
- let n = K(e ?? U), r = n.get(t);
300
+ var J = (e, t) => `${e}/${t}.json`;
301
+ async function Y(e, t) {
302
+ let n = q(e ?? W), r = n.get(t);
305
303
  if (r) return r;
306
304
  if (!e) return null;
307
305
  try {
@@ -311,14 +309,14 @@ async function J(e, t) {
311
309
  return null;
312
310
  }
313
311
  }
314
- async function Y(e, t, n) {
315
- return g.test(n) ? J(e, q(t, n)) : null;
312
+ async function X(e, t, n) {
313
+ return _.test(n) ? Y(e, J(t, n)) : null;
316
314
  }
317
- async function X(e, t, n, r) {
318
- let i = q(t, n), a = e ?? U;
315
+ async function Z(e, t, n, r) {
316
+ let i = J(t, n), a = e ?? W;
319
317
  return de(a, i)(async () => {
320
- let t = r(await J(e, i));
321
- if (K(a).set(i, t), !e) return !1;
318
+ let t = r(await Y(e, i));
319
+ if (q(a).set(i, t), !e) return !1;
322
320
  try {
323
321
  return await e.write(i, JSON.stringify(t, null, 2)), !0;
324
322
  } catch (e) {
@@ -326,8 +324,8 @@ async function X(e, t, n, r) {
326
324
  }
327
325
  });
328
326
  }
329
- var Z = (e) => `the ${e} could not be saved, so it lasts only until the app or server restarts`, fe = 6e4;
330
- function pe() {
327
+ var Q = (e) => `the ${e} could not be saved, so it lasts only until the app or server restarts`, fe = 6e4;
328
+ function $() {
331
329
  let e = /* @__PURE__ */ new Map();
332
330
  return { claim: (t) => {
333
331
  let n = Date.now();
@@ -345,7 +343,7 @@ function pe() {
345
343
  }
346
344
  //#endregion
347
345
  //#region src/core/presentSlide.ts
348
- function me({ slide: e, totalSlides: t, mode: n }) {
346
+ function pe({ slide: e, totalSlides: t, mode: n }) {
349
347
  return n === "steps" ? {
350
348
  step: e,
351
349
  total: t,
@@ -363,26 +361,26 @@ function me({ slide: e, totalSlides: t, mode: n }) {
363
361
  nextCall: `call presentSlide for slide ${e + 1} of ${t}`
364
362
  };
365
363
  }
366
- var he = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, html: a }) => JSON.stringify([
364
+ var me = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, html: a }) => JSON.stringify([
367
365
  e,
368
366
  t,
369
367
  n,
370
368
  r,
371
369
  i,
372
370
  a
373
- ]), ge = B(() => ({
371
+ ]), he = ue(() => ({
374
372
  latest: {
375
373
  presentation: null,
376
374
  steps: null
377
375
  },
378
376
  lastShown: null,
379
- repeats: pe()
377
+ repeats: $()
380
378
  }));
381
- function _e(e, t) {
379
+ function ge(e, t) {
382
380
  let n = e.latest[t.mode], r = n?.totalSlides === t.totalSlides && (t.slide !== 1 || n.firstTitle === t.title);
383
381
  if (n && r) return n;
384
382
  let i = {
385
- id: L(),
383
+ id: z(),
386
384
  mode: t.mode,
387
385
  totalSlides: t.totalSlides,
388
386
  firstTitle: t.slide === 1 ? t.title : "",
@@ -392,18 +390,18 @@ function _e(e, t) {
392
390
  };
393
391
  return e.latest[t.mode] = i, i;
394
392
  }
395
- function ve(e, t, n, r) {
393
+ function _e(e, t, n, r) {
396
394
  t.current = n.slide, t.shownAt = Date.now(), e.lastShown = t;
397
395
  let i = n.mode === "steps" ? "step" : "slide", { uuid: a, ...o } = r;
398
396
  return {
399
397
  ...o,
400
398
  message: `${i} ${n.slide} of ${n.totalSlides} is on the screen again, as it was`,
401
- instructions: S(n),
399
+ instructions: T(n),
402
400
  instructionsRequired: !0,
403
- sequence: me(n)
401
+ sequence: pe(n)
404
402
  };
405
403
  }
406
- function ye(e, t) {
404
+ function ve(e, t) {
407
405
  if (e.mode !== "steps") return e.title ? `A presentation slide titled "${e.title}". ${e.imagePrompt}` : e.imagePrompt;
408
406
  let n = e.title ? `, "${e.title}"` : "";
409
407
  return [
@@ -412,12 +410,12 @@ function ye(e, t) {
412
410
  "Show the action clearly, with little or no text."
413
411
  ].filter(Boolean).join(" ");
414
412
  }
415
- async function be(e, t, n) {
413
+ async function ye(e, t, n) {
416
414
  if (n.html) return {
417
415
  html: n.html,
418
416
  prompt: ""
419
417
  };
420
- let r = t.slides.get(n.slide - 1), i = n.mode === "steps" ? P(r).imagePath : void 0, a = i ? await R(e, [i]) : [], o = ye(n, a.length > 0), s = await z(e, o, a), { imageData: c, imagePath: l } = P(s);
418
+ let r = t.slides.get(n.slide - 1), i = n.mode === "steps" ? I(r).imagePath : void 0, a = i ? await B(e, [i]) : [], o = ve(n, a.length > 0), s = await V(e, o, a), { imageData: c, imagePath: l } = I(s);
421
419
  return c ? {
422
420
  imageData: c,
423
421
  ...l && { imagePath: l },
@@ -427,10 +425,10 @@ async function be(e, t, n) {
427
425
  sequence: null
428
426
  } };
429
427
  }
430
- async function xe(e, t, n) {
431
- let r = await be(e, t, n);
428
+ async function be(e, t, n) {
429
+ let r = await ye(e, t, n);
432
430
  if ("failed" in r) return r.failed;
433
- let { imageData: i, imagePath: a, html: o, prompt: s } = r, c = t.id, l = await X(e.files?.artifacts, V, c, (e) => {
431
+ let { imageData: i, imagePath: a, html: o, prompt: s } = r, c = t.id, l = await Z(e.files?.artifacts, H, c, (e) => {
434
432
  let t = e ?? {
435
433
  id: c,
436
434
  title: "",
@@ -461,21 +459,21 @@ async function xe(e, t, n) {
461
459
  message: [
462
460
  `${d} ${n.slide} of ${n.totalSlides} of slideshow "${c}" is on the screen`,
463
461
  a ? `saved to ${a}` : "",
464
- l ? "" : Z("slideshow")
462
+ l ? "" : Q("slideshow")
465
463
  ].filter(Boolean).join("; "),
466
- instructions: S(n),
464
+ instructions: T(n),
467
465
  instructionsRequired: !0,
468
- sequence: me(n)
466
+ sequence: pe(n)
469
467
  };
470
468
  }
471
- async function Q(e, t) {
472
- let n = ie(t);
469
+ async function xe(e, t) {
470
+ let n = w(t);
473
471
  if (typeof n == "string") return {
474
472
  message: n,
475
473
  sequence: null
476
474
  };
477
- let r = ge(e), i = _e(r, n), a = n.mode === "steps";
478
- if (a && n.slide > i.current && i.current > 0 && !I(e, i.shownAt)) {
475
+ let r = he(e), i = ge(r, n), a = n.mode === "steps";
476
+ if (a && n.slide > i.current && i.current > 0 && !R(e, i.shownAt)) {
479
477
  console.info(`[sequence] holding step ${n.slide} for the user`);
480
478
  let e = i.shownAt === Infinity ? "is still being drawn" : "is still on the screen";
481
479
  return {
@@ -484,15 +482,15 @@ async function Q(e, t) {
484
482
  };
485
483
  }
486
484
  let o = a ? i.slides.get(n.slide) : void 0;
487
- if (o) return ce(e.currentResult, o) ? {
485
+ if (o) return se(e.currentResult, o) ? {
488
486
  message: `step ${n.slide} of ${n.totalSlides} is already on the screen`,
489
487
  cancelled: !0
490
- } : ve(r, i, n, o);
491
- let s = r.repeats.claim(he(i.id, n));
488
+ } : _e(r, i, n, o);
489
+ let s = r.repeats.claim(me(i.id, n));
492
490
  if ("earlier" in s) {
493
- if (!await s.earlier) return Q(e, t);
491
+ if (!await s.earlier) return xe(e, t);
494
492
  let a = i.slides.get(n.slide);
495
- return a && r.lastShown !== i ? ve(r, i, n, a) : {
493
+ return a && r.lastShown !== i ? _e(r, i, n, a) : {
496
494
  message: `slide ${n.slide} of ${n.totalSlides} is already on the screen`,
497
495
  cancelled: !0
498
496
  };
@@ -504,8 +502,8 @@ async function Q(e, t) {
504
502
  i.current = n.slide, i.shownAt = Infinity;
505
503
  let u = !1;
506
504
  try {
507
- let t = await xe(e, i, n);
508
- return u = se(t), u && (i.slides.set(n.slide, t), i.current = n.slide, i.shownAt = Date.now(), r.lastShown = i), t;
505
+ let t = await be(e, i, n);
506
+ return u = oe(t), u && (i.slides.set(n.slide, t), i.current = n.slide, i.shownAt = Date.now(), r.lastShown = i), t;
509
507
  } finally {
510
508
  c(u), !u && i.current === n.slide && (i.current = l.current, i.shownAt = l.shownAt);
511
509
  }
@@ -529,19 +527,19 @@ var Se = ({ id: e, title: t, totalPanels: n }) => ({
529
527
  ...r.length > 0 && { waitsForUser: !0 }
530
528
  }), we = (e, t) => e ? `${e}. ${t}` : t, Te = (e, { name: t, description: n }) => we(e, `Character reference sheet of ${t}: ${n}. Full body, front, side and back views, on a plain white background. No text or labels.`);
531
529
  async function Ee(e, t) {
532
- let n = T(t);
530
+ let n = D(t);
533
531
  if (typeof n == "string") return {
534
532
  message: n,
535
533
  sequence: null
536
534
  };
537
- let r = await Promise.all(n.characters.map((t) => z(e, Te(n.style, t)))), i = r.map(P), a = r.find((e, t) => !i[t]?.imageData);
535
+ let r = await Promise.all(n.characters.map((t) => V(e, Te(n.style, t)))), i = r.map(I), a = r.find((e, t) => !i[t]?.imageData);
538
536
  if (i.every(({ imageData: e }) => !e) && a) return {
539
537
  ...a,
540
538
  message: `the character sheets couldn't be made: ${a.message}`,
541
539
  sequence: null
542
540
  };
543
541
  let o = {
544
- id: L(),
542
+ id: z(),
545
543
  ...n,
546
544
  characters: n.characters.map((e, t) => {
547
545
  let n = i[t]?.imagePath;
@@ -551,7 +549,7 @@ async function Ee(e, t) {
551
549
  };
552
550
  }),
553
551
  panels: {}
554
- }, s = await X(e.files?.artifacts, H, 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;
552
+ }, s = await Z(e.files?.artifacts, U, 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;
555
553
  return {
556
554
  data: {
557
555
  storyboardId: o.id,
@@ -572,9 +570,9 @@ async function Ee(e, t) {
572
570
  `storyboard "${o.id}" is ready with ${o.totalPanels} panels; the cast is on the screen`,
573
571
  c.length ? `character sheets saved to ${c.join(", ")}` : "",
574
572
  l.length ? `no sheet for ${l.join("; ")}: they will be drawn from their description` : "",
575
- s ? "" : Z("storyboard")
573
+ s ? "" : Q("storyboard")
576
574
  ].filter(Boolean).join("; "),
577
- instructions: E(o),
575
+ instructions: O(o),
578
576
  instructionsRequired: !0,
579
577
  sequence: Se(o)
580
578
  };
@@ -586,10 +584,10 @@ function De(e, t, n) {
586
584
  async function Oe(e, t, n) {
587
585
  let r = [], i = [];
588
586
  for (let a of n.characters) {
589
- let n = t.characters.find((e) => y(e.name, a));
587
+ let n = t.characters.find((e) => b(e.name, a));
590
588
  if (!n) r.push(a);
591
589
  else if (!i.some((e) => e.character === n)) {
592
- let [t] = n.imagePath ? await R(e, [n.imagePath]) : [];
590
+ let [t] = n.imagePath ? await B(e, [n.imagePath]) : [];
593
591
  i.push({
594
592
  character: n,
595
593
  sheet: t ?? null
@@ -599,12 +597,12 @@ async function Oe(e, t, n) {
599
597
  let a = i.map(({ sheet: e }) => e).filter((e) => !!e), o = De(t, n, i.map(({ character: e, sheet: t }) => ({
600
598
  character: e,
601
599
  hasSheet: !!t
602
- }))), s = await z(e, o, a), { imageData: c, imagePath: l } = P(s);
600
+ }))), s = await V(e, o, a), { imageData: c, imagePath: l } = I(s);
603
601
  if (!c) return {
604
602
  ...s,
605
603
  sequence: null
606
604
  };
607
- let u = n.panel < t.totalPanels && n.choices.length >= 2 ? n.choices : [], d = await X(e.files?.artifacts, H, t.id, (e) => {
605
+ let u = n.panel < t.totalPanels && n.choices.length >= 2 ? n.choices : [], d = await Z(e.files?.artifacts, U, t.id, (e) => {
608
606
  let r = e ?? t;
609
607
  return u.length && (r.interactive = !0), r.panels[String(n.panel)] = {
610
608
  caption: n.caption,
@@ -630,25 +628,25 @@ async function Oe(e, t, n) {
630
628
  `panel ${n.panel} of ${t.totalPanels} is on the screen`,
631
629
  l ? `saved to ${l}` : "",
632
630
  r.length ? `not in the cast, so drawn from the prompt alone: ${r.join(", ")}` : "",
633
- d ? "" : Z("storyboard")
631
+ d ? "" : Q("storyboard")
634
632
  ].filter(Boolean).join("; "),
635
- instructions: k(t, n.panel, u),
633
+ instructions: j(t, n.panel, u),
636
634
  instructionsRequired: !0,
637
635
  sequence: Ce(t, n.panel, u)
638
636
  };
639
637
  }
640
- var ke = B(() => ({
641
- repeats: pe(),
638
+ var ke = ue(() => ({
639
+ repeats: $(),
642
640
  awaitingChoice: /* @__PURE__ */ new Map()
643
641
  }));
644
- async function $(e, t) {
645
- let n = O(t);
642
+ async function Ae(e, t) {
643
+ let n = A(t);
646
644
  if (!n) return {
647
- message: D,
645
+ message: k,
648
646
  sequence: null
649
647
  };
650
648
  let { storyboardId: r, panel: i } = n, { repeats: a, awaitingChoice: o } = ke(e), s = o.get(r);
651
- if (s && i > s.panel && !I(e, s.shownAt)) return console.info(`[sequence] holding panel ${i} for the user`), {
649
+ if (s && i > s.panel && !R(e, s.shownAt)) return console.info(`[sequence] holding panel ${i} for the user`), {
652
650
  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.`,
653
651
  cancelled: !0
654
652
  };
@@ -656,7 +654,7 @@ async function $(e, t) {
656
654
  if ("earlier" in c) return await c.earlier ? {
657
655
  message: `panel ${i} is already on the screen`,
658
656
  cancelled: !0
659
- } : $(e, t);
657
+ } : Ae(e, t);
660
658
  let { settle: l } = c, u = {
661
659
  panel: i,
662
660
  shownAt: Infinity
@@ -664,7 +662,7 @@ async function $(e, t) {
664
662
  o.set(r, u);
665
663
  let f = () => o.get(r) === u, p = !1;
666
664
  try {
667
- let t = await Y(e.files?.artifacts, H, r);
665
+ let t = await X(e.files?.artifacts, U, r);
668
666
  if (!t) return {
669
667
  message: `there is no storyboard "${r}"; call defineStoryboard first`,
670
668
  sequence: null
@@ -674,7 +672,7 @@ async function $(e, t) {
674
672
  sequence: null
675
673
  };
676
674
  let a = await Oe(e, t, n);
677
- p = !!P(a).imageData;
675
+ p = !!I(a).imageData;
678
676
  let s = a.data;
679
677
  return p && f() && (s?.choices?.length ? o.set(r, {
680
678
  panel: i,
@@ -686,21 +684,21 @@ async function $(e, t) {
686
684
  }
687
685
  //#endregion
688
686
  //#region src/core/index.ts
689
- var Ae = {
690
- toolDefinition: w,
687
+ var je = {
688
+ toolDefinition: E,
691
689
  generatingMessage: "Making the slide...",
692
690
  isEnabled: () => !0,
693
- execute: (e, t) => Q(e, t)
694
- }, je = {
695
- toolDefinition: j,
691
+ execute: (e, t) => xe(e, t)
692
+ }, Me = {
693
+ toolDefinition: N,
696
694
  generatingMessage: "Drawing the characters...",
697
695
  isEnabled: () => !0,
698
696
  execute: (e, t) => Ee(e, t)
699
- }, Me = {
700
- toolDefinition: M,
697
+ }, Ne = {
698
+ toolDefinition: P,
701
699
  generatingMessage: "Drawing the panel...",
702
700
  isEnabled: () => !0,
703
- execute: (e, t) => $(e, t)
701
+ execute: (e, t) => Ae(e, t)
704
702
  };
705
703
  //#endregion
706
- export { o as A, k as C, y as D, T as E, t as M, f as N, S as O, E as S, ie as T, C as _, H as a, re as b, j as c, te as d, D as f, w as g, p as h, V as i, n as j, r as k, ee as l, M as m, Me as n, Y as o, h as p, Ae as r, m as s, je as t, ne as u, g as v, O as w, A as x, x as y };
704
+ export { o as A, j as C, b as D, D as E, p as F, d as M, n as N, T as O, t as P, O as S, w as T, ie as _, U as a, C as b, N as c, te as d, k as f, E as g, m as h, H as i, s as j, r as k, ee as l, P as m, Ne as n, X as o, g as p, je as r, h as s, Me as t, ne as u, _ as v, A as w, M as x, S as y };