@gui-chat-plugin/mulmocast 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vue.js CHANGED
@@ -1,703 +1,744 @@
1
- import { v as le, s as oe, p as ne } from "./index-BaFRLiBo.js";
2
- import { T as ft, e as yt } from "./index-BaFRLiBo.js";
3
- import { defineComponent as W, ref as b, computed as L, watch as T, createElementBlock as r, openBlock as s, Fragment as z, renderSlot as ue, withDirectives as Q, createCommentVNode as _, normalizeProps as H, guardReactiveProps as se, createElementVNode as v, createVNode as ie, mergeProps as Y, unref as X, createBlock as ee, vShow as re, renderList as te, toDisplayString as N, onMounted as Z, onUnmounted as ae, createTextVNode as D, normalizeClass as K, vModelText as de } from "vue";
4
- const G = async (o) => await new Promise((w) => setTimeout(w, o)), ce = { class: "items-center justify-center w-full" }, ve = { key: 0 }, me = ["src"], pe = {
5
- key: 1,
6
- class: "relative inline-block"
7
- }, ge = ["src"], fe = ["src"], ye = {
8
- key: 2,
9
- class: "relative inline-block"
10
- }, be = ["src"], he = ["src"], Se = {
11
- key: 3,
12
- class: "relative inline-block"
13
- }, we = ["src"], ke = { key: 4 }, xe = {
14
- key: 5,
15
- class: "mt-4 px-6 py-4 text-left"
16
- }, Pe = { class: "text-lg leading-relaxed font-sans text-gray-800" }, Re = {
17
- key: 0,
18
- class: "text-base leading-relaxed font-sans text-gray-400 mt-3 italic"
19
- }, Le = "https://github.com/receptron/mulmocast-cli/blob/main/assets/images/mulmocast_credit.png?raw=true", q = /* @__PURE__ */ W({
20
- __name: "mulmo_player",
21
- props: {
22
- index: {},
23
- videoWithAudioSource: {},
24
- soundEffectSource: {},
25
- videoSource: {},
26
- imageSource: {},
27
- audioSource: {},
28
- text: {},
29
- originalText: {},
30
- duration: {},
31
- defaultLang: {},
32
- currentLang: {},
33
- playbackSpeed: { default: 1 }
34
- },
35
- emits: ["play", "pause", "ended"],
36
- setup(o, { expose: w, emit: u }) {
37
- const n = o, h = u, m = b(), l = b(), i = b(), d = b(), y = () => {
38
- l.value && n.videoSource && (n.audioSource && n.currentLang && n.defaultLang && n.currentLang !== n.defaultLang ? l.value.volume = 0.2 : l.value.volume = 0);
39
- }, p = () => {
40
- const g = n.playbackSpeed ?? 1;
41
- m.value && (m.value.playbackRate = g), l.value && (l.value.playbackRate = g), i.value && (i.value.playbackRate = g), d.value && (d.value.playbackRate = g);
42
- };
43
- T([() => n.currentLang, () => n.defaultLang, () => n.videoSource, () => n.audioSource], () => {
44
- y();
45
- }), T(
46
- () => n.playbackSpeed,
47
- () => {
48
- p();
49
- }
50
- ), T(l, (g) => {
51
- g && (y(), p());
52
- }), T([m, i, d], () => {
53
- p();
54
- }), Z(() => {
55
- y(), p();
56
- });
57
- const U = () => {
58
- x.value = !0, i.value && l.value && (i.value.currentTime = l.value.currentTime, i.value.currentTime === l.value.currentTime && i.value.play()), h("play");
59
- }, V = (g) => {
60
- document.hidden || (x.value = !1), !l.value?.ended && i?.value && i.value?.pause(), console.log(g), C(g);
61
- }, k = () => {
62
- (!i.value || i.value.ended) && j();
63
- }, P = () => {
64
- (!l.value || l.value.ended) && j();
65
- }, f = () => {
66
- x.value = !0, h("play");
67
- }, C = (g) => {
68
- document.hidden || (x.value = !1);
69
- const t = g.target;
70
- t.duration !== t.currentTime && h("pause");
71
- }, j = () => {
72
- x.value = !1, h("ended");
73
- }, x = b(!1);
74
- let R = null;
75
- const J = async () => {
76
- x.value = !0, m.value && (p(), m.value.play()), l.value && (y(), p(), l.value.play(), i.value && (i.value.currentTime = l.value.currentTime, i.value.play())), d.value && (p(), d.value.play()), !m.value && !l.value && !d.value && (await G((n.duration ?? 0) * 1e3), x.value = !1, h("ended"));
77
- }, M = (g) => {
78
- g?.paused && !g.ended && g.play().catch(() => {
79
- });
80
- }, A = (g, t) => {
81
- t.paused && !t.ended && (g.ended || (t.currentTime = g.currentTime), t.play().catch(() => {
82
- }));
83
- }, $ = () => {
84
- x.value && (M(m.value), l.value && i.value ? (M(l.value), A(l.value, i.value)) : M(l.value), M(d.value));
85
- }, I = () => {
86
- document.hidden && x.value ? R || (R = setInterval($, 500)) : document.hidden || R && (clearInterval(R), R = null);
87
- }, E = () => {
88
- document.hidden && x.value && setTimeout($, 50);
89
- };
90
- return Z(() => {
91
- document.addEventListener("visibilitychange", I), m.value?.addEventListener("pause", E), l.value?.addEventListener("pause", E), d.value?.addEventListener("pause", E), i.value?.addEventListener("pause", E);
92
- }), ae(() => {
93
- document.removeEventListener("visibilitychange", I), m.value?.removeEventListener("pause", E), l.value?.removeEventListener("pause", E), d.value?.removeEventListener("pause", E), i.value?.removeEventListener("pause", E), R && (clearInterval(R), R = null);
94
- }), w({
95
- play: J
96
- }), (g, t) => (s(), r("div", ce, [
97
- o.videoWithAudioSource ? (s(), r("div", ve, [
98
- v("video", {
99
- ref_key: "videoWithAudioRef",
100
- ref: m,
101
- src: o.videoWithAudioSource,
102
- class: "mulmocast-video mx-auto h-auto max-h-[80vh] w-auto object-contain",
103
- controls: !0,
104
- playsinline: "true",
105
- onPlay: f,
106
- onPause: C,
107
- onEnded: j
108
- }, null, 40, me)
109
- ])) : o.soundEffectSource || o.videoSource ? (s(), r("div", pe, [
110
- v("video", {
111
- ref_key: "videoRef",
112
- ref: l,
113
- class: "mulmocast-video mx-auto h-auto max-h-[80vh] w-auto object-contain",
114
- src: o.soundEffectSource || o.videoSource,
115
- controls: !0,
116
- playsinline: "true",
117
- onPlay: U,
118
- onPause: V,
119
- onEnded: k
120
- }, null, 40, ge),
121
- o.audioSource ? (s(), r("audio", {
122
- key: 0,
123
- ref_key: "audioSyncRef",
124
- ref: i,
125
- src: o.audioSource,
126
- controls: !0,
127
- class: "hidden",
128
- onEnded: P
129
- }, null, 40, fe)) : _("", !0)
130
- ])) : o.audioSource ? (s(), r("div", ye, [
131
- o.imageSource ? (s(), r("img", {
132
- key: 0,
133
- src: o.imageSource,
134
- class: "mx-auto h-auto max-h-[80vh] w-auto object-contain",
135
- alt: "Background"
136
- }, null, 8, be)) : (s(), r("img", {
137
- key: 1,
138
- src: Le,
139
- class: "mx-auto h-auto max-h-[80vh] w-auto object-contain",
140
- alt: "Background"
141
- })),
142
- v("audio", {
143
- ref_key: "audioRef",
144
- ref: d,
145
- class: "mulmocast-audio absolute inset-0 w-full h-full",
146
- src: o.audioSource,
147
- controls: !0,
148
- onPlay: f,
149
- onPause: C,
150
- onEnded: j
151
- }, null, 40, he)
152
- ])) : o.imageSource ? (s(), r("div", Se, [
153
- v("img", {
154
- src: o.imageSource,
155
- class: "max-w-full max-h-full object-contain"
156
- }, null, 8, we)
157
- ])) : (s(), r("div", ke, "No media available")),
158
- o.text ? (s(), r("div", xe, [
159
- v("p", Pe, N(o.text), 1),
160
- o.originalText && o.originalText !== o.text ? (s(), r("p", Re, N(o.originalText), 1)) : _("", !0)
161
- ])) : _("", !0)
162
- ]));
163
- }
164
- }), Ee = ["value"], _e = ["value"], Ce = /* @__PURE__ */ W({
165
- __name: "select_language",
166
- props: {
167
- modelValue: {}
168
- },
169
- emits: ["update:modelValue"],
170
- setup(o, { emit: w }) {
171
- const u = ["en", "ja"], n = {
172
- en: "English",
173
- ja: "日本語"
174
- }, h = w, m = (l) => {
175
- const i = l.target;
176
- h("update:modelValue", i.value);
177
- };
178
- return (l, i) => (s(), r("select", {
179
- value: o.modelValue,
180
- class: "px-4 py-2 bg-white border-2 border-gray-300 rounded-lg shadow-sm hover:border-indigo-400 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 focus:outline-none transition-colors cursor-pointer text-base font-medium text-gray-700",
181
- onChange: m
182
- }, [
183
- (s(), r(z, null, te(u, (d) => v("option", {
184
- key: d,
185
- value: d
186
- }, N(n[d] || d), 9, _e)), 64))
187
- ], 40, Ee));
188
- }
189
- }), Te = { class: "w-full overflow-hidden" }, Oe = { class: "max-w-7xl mx-auto px-4" }, je = { class: "flex items-center justify-between" }, Me = ["disabled"], Ne = { class: "px-4" }, Ue = ["disabled"], Je = ["src"], $e = /* @__PURE__ */ W({
190
- __name: "mulmo_viewer",
191
- props: {
192
- dataSet: {},
193
- basePath: {},
194
- initPage: {},
195
- audioLang: { default: "en" },
196
- textLang: { default: "en" },
197
- playbackSpeed: { default: 1 }
198
- },
199
- emits: ["updatedPage", "update:audioLang", "update:textLang", "allCompleted"],
200
- setup(o, { expose: w, emit: u }) {
201
- const n = o, h = u, m = n.dataSet?.beats?.length ?? 0, l = b(n.initPage ?? 0), i = b(!0), d = b(), y = b(), p = L({
202
- get: () => n.audioLang,
203
- set: (t) => h("update:audioLang", t || "en")
204
- }), U = L({
205
- get: () => n.textLang,
206
- set: (t) => h("update:textLang", t || "en")
207
- });
208
- T(
209
- () => n.audioLang,
210
- async (t, e) => {
211
- if (t !== e && f.value) {
212
- const a = f.value;
213
- f.value = !1, await G(500), a && d.value && (f.value = !0, await d.value.play());
214
- }
215
- }
216
- ), T(
217
- () => n.textLang,
218
- async (t, e) => {
219
- t !== e && f.value && (await G(100), d.value && await d.value.play());
220
- }
221
- ), T(y, (t) => {
222
- t && (t.volume = 0.3);
223
- });
224
- const V = L(() => n.dataSet?.beats[l.value]), k = (t) => t ? n.basePath + "/" + t : "", P = L(() => k(n.dataSet?.bgmSource)), f = b(!1), C = () => {
225
- f.value = !0, y.value && (y.value.volume = 0.3, y.value.play());
226
- }, j = () => {
227
- console.log("pause"), f.value = !1, y.value && y.value.pause();
228
- }, x = async () => {
229
- await G(500), d.value && d.value.play();
230
- }, R = (t) => {
231
- l.value !== t && (l.value = t, f.value && i.value && x());
232
- }, J = (t) => {
233
- const e = l.value + t;
234
- return e > -1 && e < m ? (R(e), h("updatedPage", e), !0) : !1;
235
- }, M = () => {
236
- console.log("end"), i.value && J(1) ? x() : (f.value = !1, y.value && y.value.pause(), h("allCompleted"));
237
- }, A = {
238
- onPlay: C,
239
- onPause: j,
240
- onEnded: M
241
- }, $ = L(() => {
242
- const t = V.value, e = t?.audioSources?.[p.value], a = t?.multiLinguals?.[U.value] ?? t?.text ?? "", c = n.dataSet?.lang ? t?.multiLinguals?.[n.dataSet.lang] ?? t?.text ?? "" : "";
243
- return {
244
- videoWithAudioSource: k(t?.videoWithAudioSource),
245
- videoSource: k(t?.videoSource),
246
- soundEffectSource: k(t?.soundEffectSource),
247
- audioSource: k(e),
248
- imageSource: k(t?.imageSource),
249
- index: l.value,
250
- text: a,
251
- originalText: c,
252
- duration: t?.duration,
253
- defaultLang: n.dataSet?.lang,
254
- currentLang: p.value,
255
- playbackSpeed: n.playbackSpeed,
256
- ...A
257
- };
258
- }), I = L(() => n.dataSet?.beats[l.value + 1]), E = L(() => {
259
- if (l.value + 1 >= m) return null;
260
- const t = I.value;
261
- return {
262
- videoWithAudioSource: k(t?.videoWithAudioSource),
263
- videoSource: k(t?.videoSource),
264
- soundEffectSource: k(t?.soundEffectSource),
265
- audioSource: k(t?.audioSources?.[p.value]),
266
- imageSource: k(t?.imageSource),
267
- index: l.value + 1,
268
- text: t?.multiLinguals?.[U.value] ?? t?.text ?? "",
269
- duration: t?.duration
270
- };
271
- }), g = L(() => ({
272
- MulmoPlayer: q,
273
- pageProps: $.value,
274
- currentPage: l.value,
275
- pageCount: m,
276
- pageMove: J,
277
- isPlaying: f.value,
278
- audioLang: p,
279
- textLang: U,
280
- SelectLanguage: Ce,
281
- mediaPlayerRef: d,
282
- // Event handlers for direct access
283
- handlePlay: C,
284
- handlePause: j,
285
- handleEnded: M
286
- }));
287
- return w({
288
- updatePage: R
289
- }), (t, e) => (s(), r(z, null, [
290
- ue(t.$slots, "default", H(se(g.value)), () => [
291
- v("div", Te, [
292
- v("div", Oe, [
293
- v("div", je, [
294
- v("button", {
295
- class: "px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600 disabled:opacity-50",
296
- disabled: l.value === 0,
297
- onClick: e[0] || (e[0] = (a) => J(-1))
298
- }, " Prev ", 8, Me),
299
- v("div", Ne, [
300
- ie(q, Y({
301
- ref_key: "mediaPlayer",
302
- ref: d
303
- }, $.value), null, 16)
304
- ]),
305
- v("button", {
306
- class: "px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600 disabled:opacity-50",
307
- disabled: l.value >= X(m) - 1,
308
- onClick: e[1] || (e[1] = (a) => J(1))
309
- }, " Next ", 8, Ue)
310
- ])
311
- ])
312
- ])
313
- ]),
314
- E.value ? Q((s(), ee(q, H(Y({ key: 0 }, E.value)), null, 16)), [
315
- [re, !1]
316
- ]) : _("", !0),
317
- P.value ? (s(), r("audio", {
318
- key: 1,
319
- ref_key: "bgmRef",
320
- ref: y,
321
- src: P.value
322
- }, null, 8, Je)) : _("", !0)
323
- ], 64));
324
- }
325
- }), Ve = { class: "mulmocast-container" }, Ie = { class: "mulmocast-content-wrapper" }, Ae = { class: "p-4" }, Be = {
326
- key: 0,
327
- class: "header-row"
328
- }, We = { class: "document-title" }, Fe = { class: "button-group" }, De = ["disabled"], Ge = {
329
- key: 0,
330
- class: "error-message"
1
+ import { a as e, n as t, o as n, r, t as i } from "./samples-SOf0ey-s.js";
2
+ import { Fragment as a, computed as o, createBlock as s, createCommentVNode as c, createElementBlock as l, createElementVNode as u, createTextVNode as d, createVNode as f, defineComponent as p, guardReactiveProps as m, mergeProps as h, normalizeClass as g, normalizeProps as _, normalizeStyle as v, onMounted as y, onUnmounted as b, openBlock as x, ref as S, renderList as C, renderSlot as w, toDisplayString as T, unref as E, vModelText as D, vShow as O, watch as k, withDirectives as A } from "vue";
3
+ //#region node_modules/mulmocast-viewer/dist/mulmocast-viewer.es.js
4
+ var j = {
5
+ video: "16/9",
6
+ square: "1/1"
7
+ }, M = /^(\d+(?:\.\d+)?)\s*\/\s*(\d+(?:\.\d+)?)$/, N = (e) => {
8
+ let t = M.exec(e);
9
+ return t ? Number(t[1]) > 0 && Number(t[2]) > 0 : !1;
10
+ }, P = (e) => {
11
+ if (!e) return;
12
+ let t = j[e];
13
+ if (t) return t;
14
+ if (N(e)) return e;
15
+ }, F = async (e) => await new Promise((t) => setTimeout(t, e)), I = (e, t) => {
16
+ let n = (e) => e instanceof Error ? e : /* @__PURE__ */ Error("Aborted");
17
+ return new Promise((r, i) => {
18
+ if (t.aborted) {
19
+ i(n(t.reason));
20
+ return;
21
+ }
22
+ let a = () => {
23
+ clearTimeout(o), i(n(t.reason));
24
+ }, o = setTimeout(() => {
25
+ t.removeEventListener("abort", a), r();
26
+ }, e);
27
+ t.addEventListener("abort", a, { once: !0 });
28
+ });
29
+ }, L = 1, R = .5, z = .5, B = .2, V = (e, t) => e > t + L, H = (e) => {
30
+ if (!e || e.ended || isNaN(e.duration) || e.duration <= 0) return !0;
31
+ let t = Math.min(R, e.duration / 2);
32
+ return e.currentTime >= e.duration - t;
33
+ }, U = (e) => e.soundEffectSource ? 1 : e.videoSource && e.audioSource && e.currentLang && e.defaultLang && e.currentLang !== e.defaultLang ? B : 0, W = (e, t, n) => {
34
+ if (isNaN(e) || isNaN(t) || isNaN(n)) return null;
35
+ let r = Math.min(e, n);
36
+ return Math.abs(t - r) > z ? r : null;
37
+ }, G = (e, t, n) => e ? !1 : n ? t : !0, ee = (e, t) => e ? !1 : H(t), te = (e) => !(e.isStopping || e.videoEnded && e.audioExists && !e.audioEnded), ne = { class: "items-center justify-center w-full" }, re = {
38
+ key: 0,
39
+ class: "group relative"
40
+ }, ie = ["src"], ae = { class: "play-overlay absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none" }, oe = {
41
+ key: 0,
42
+ class: "w-8 h-8 text-white ml-1",
43
+ fill: "currentColor",
44
+ viewBox: "0 0 24 24"
45
+ }, se = {
46
+ key: 1,
47
+ class: "w-8 h-8 text-white",
48
+ fill: "currentColor",
49
+ viewBox: "0 0 24 24"
50
+ }, ce = {
51
+ key: 1,
52
+ class: "group relative inline-block"
53
+ }, le = ["src", "controls"], ue = ["src"], de = { class: "play-overlay absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none" }, fe = {
54
+ key: 0,
55
+ class: "w-8 h-8 text-white ml-1",
56
+ fill: "currentColor",
57
+ viewBox: "0 0 24 24"
58
+ }, pe = {
59
+ key: 1,
60
+ class: "w-8 h-8 text-white",
61
+ fill: "currentColor",
62
+ viewBox: "0 0 24 24"
63
+ }, me = {
64
+ key: 2,
65
+ class: "group relative inline-block"
66
+ }, he = ["src"], ge = ["src"], _e = { class: "play-overlay absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none" }, ve = {
67
+ key: 0,
68
+ class: "w-8 h-8 text-white ml-1",
69
+ fill: "currentColor",
70
+ viewBox: "0 0 24 24"
71
+ }, ye = {
72
+ key: 1,
73
+ class: "w-8 h-8 text-white",
74
+ fill: "currentColor",
75
+ viewBox: "0 0 24 24"
76
+ }, be = {
77
+ key: 3,
78
+ class: "group relative inline-block"
79
+ }, xe = ["src"], Se = { class: "play-overlay absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none" }, Ce = {
80
+ key: 0,
81
+ class: "w-8 h-8 text-white ml-1",
82
+ fill: "currentColor",
83
+ viewBox: "0 0 24 24"
84
+ }, we = {
85
+ key: 1,
86
+ class: "w-8 h-8 text-white",
87
+ fill: "currentColor",
88
+ viewBox: "0 0 24 24"
89
+ }, Te = { key: 4 }, Ee = {
90
+ key: 0,
91
+ class: "mt-4 px-6 py-4 text-left"
92
+ }, De = { class: "text-lg leading-relaxed font-sans text-gray-800" }, Oe = {
93
+ key: 0,
94
+ class: "text-base leading-relaxed font-sans text-gray-400 mt-3 italic"
95
+ }, ke = "https://github.com/receptron/mulmocast-cli/blob/main/assets/images/mulmocast_credit.png?raw=true", K = /* @__PURE__ */ p({
96
+ __name: "mulmo_player",
97
+ props: {
98
+ index: {},
99
+ videoWithAudioSource: { default: void 0 },
100
+ soundEffectSource: { default: void 0 },
101
+ videoSource: { default: void 0 },
102
+ imageSource: { default: void 0 },
103
+ audioSource: { default: void 0 },
104
+ text: { default: void 0 },
105
+ originalText: { default: void 0 },
106
+ duration: { default: void 0 },
107
+ defaultLang: { default: void 0 },
108
+ currentLang: { default: void 0 },
109
+ playbackSpeed: { default: 1 },
110
+ mediaAspectRatio: { default: void 0 }
111
+ },
112
+ emits: [
113
+ "play",
114
+ "pause",
115
+ "ended"
116
+ ],
117
+ setup(e, { expose: t, emit: n }) {
118
+ let r = o(() => {
119
+ let e = P(i.mediaAspectRatio);
120
+ return e ? { aspectRatio: e } : {};
121
+ }), i = e, a = n, s = S(), d = S(), f = S(), p = S(), m = S(!1), h = () => {
122
+ d.value && f.value && !isNaN(d.value.duration) && !isNaN(f.value.duration) && (m.value = V(f.value.duration, d.value.duration));
123
+ }, _ = () => {
124
+ d.value && (d.value.volume = U({
125
+ soundEffectSource: i.soundEffectSource,
126
+ videoSource: i.videoSource,
127
+ audioSource: i.audioSource,
128
+ currentLang: i.currentLang,
129
+ defaultLang: i.defaultLang
130
+ }));
131
+ }, C = () => {
132
+ let e = i.playbackSpeed ?? 1;
133
+ s.value && (s.value.playbackRate = e), d.value && (d.value.playbackRate = e), f.value && (f.value.playbackRate = e), p.value && (p.value.playbackRate = e);
134
+ };
135
+ k([
136
+ () => i.currentLang,
137
+ () => i.defaultLang,
138
+ () => i.videoSource,
139
+ () => i.audioSource
140
+ ], () => {
141
+ _();
142
+ }), k(() => i.playbackSpeed, () => {
143
+ C();
144
+ }), k(d, (e) => {
145
+ e && (_(), C());
146
+ }), k([
147
+ s,
148
+ f,
149
+ p
150
+ ], () => {
151
+ C();
152
+ }), y(() => {
153
+ _(), C();
154
+ });
155
+ let w = S(!1), E = S(!1), D = o(() => J.value || E.value), O = null, A = () => {
156
+ O &&= (O.abort(), null);
157
+ }, j = () => {
158
+ J.value = !0, f.value && d.value && !f.value.ended && (f.value.currentTime = d.value.currentTime, f.value.play().catch(() => {})), a("play");
159
+ }, M = (e) => {
160
+ te({
161
+ isStopping: E.value,
162
+ videoEnded: d.value?.ended ?? !1,
163
+ audioExists: !!f.value,
164
+ audioEnded: f.value?.ended ?? !0
165
+ }) && (document.hidden || (J.value = !1), !d.value?.ended && f?.value && f.value?.pause(), H(e));
166
+ }, N = () => {
167
+ G(w.value, f.value?.ended ?? !0, !!f.value) && K();
168
+ }, F = () => {
169
+ let e = d.value ? {
170
+ ended: d.value.ended,
171
+ duration: d.value.duration,
172
+ currentTime: d.value.currentTime
173
+ } : null;
174
+ ee(w.value, e) && K();
175
+ }, L = () => {
176
+ if (!d.value || !f.value) return;
177
+ let e = W(f.value.currentTime, d.value.currentTime, d.value.duration);
178
+ e !== null && (d.value.currentTime = e);
179
+ }, R = () => {
180
+ J.value = !0, d.value && !d.value.ended && d.value.play().catch(() => {}), a("play");
181
+ }, z = () => {
182
+ E.value || f.value?.ended || (document.hidden || (J.value = !1), d.value && !d.value.ended && d.value.pause(), a("pause"));
183
+ }, B = () => {
184
+ J.value = !0, a("play");
185
+ }, H = (e) => {
186
+ if (E.value) return;
187
+ document.hidden || (J.value = !1);
188
+ let t = e.target;
189
+ t.duration !== t.currentTime && a("pause");
190
+ }, K = () => {
191
+ w.value || (w.value = !0, J.value = !1, a("ended"));
192
+ }, q = () => {
193
+ s.value?.pause(), d.value?.pause(), f.value?.pause(), p.value?.pause();
194
+ }, J = S(!1), Y = null, X = async () => {
195
+ if (E.value = !1, w.value = !1, J.value = !0, s.value && (C(), s.value.play().catch(() => {})), d.value && (_(), C(), d.value.play().catch(() => {}), f.value && (f.value.currentTime = d.value.currentTime, f.value.play().catch(() => {}))), p.value && (C(), p.value.play().catch(() => {})), !s.value && !d.value && !p.value) try {
196
+ A(), O = new AbortController(), await I((i.duration ?? 0) * 1e3, O.signal), O = null, w.value || (J.value = !1, w.value = !0, a("ended"));
197
+ } catch {}
198
+ }, Ae = () => {
199
+ E.value = !0, J.value = !1, w.value = !0, A(), s.value?.pause(), d.value?.pause(), f.value?.pause(), p.value?.pause();
200
+ }, je = () => {
201
+ if (!f.value || !d.value || f.value.ended) return;
202
+ let e = W(d.value.currentTime, f.value.currentTime, f.value.duration);
203
+ e !== null && (f.value.currentTime = e);
204
+ }, Z = (e) => {
205
+ e?.paused && !e.ended && e.play().catch(() => {});
206
+ }, Me = (e, t) => {
207
+ t.paused && !t.ended && (e.ended || (t.currentTime = e.currentTime), t.play().catch(() => {}));
208
+ }, Q = () => {
209
+ J.value && (Z(s.value), d.value && f.value ? (Z(d.value), Me(d.value, f.value)) : Z(d.value), Z(p.value));
210
+ }, Ne = () => {
211
+ document.hidden && J.value ? Y ||= setInterval(Q, 500) : document.hidden || (Y &&= (clearInterval(Y), null));
212
+ }, $ = () => {
213
+ document.hidden && J.value && setTimeout(Q, 50);
214
+ };
215
+ return y(() => {
216
+ document.addEventListener("visibilitychange", Ne), s.value?.addEventListener("pause", $), d.value?.addEventListener("pause", $), p.value?.addEventListener("pause", $), f.value?.addEventListener("pause", $);
217
+ }), b(() => {
218
+ document.removeEventListener("visibilitychange", Ne), s.value?.removeEventListener("pause", $), d.value?.removeEventListener("pause", $), p.value?.removeEventListener("pause", $), f.value?.removeEventListener("pause", $), Y &&= (clearInterval(Y), null), A();
219
+ }), t({
220
+ play: X,
221
+ stop: Ae
222
+ }), (t, n) => (x(), l("div", ne, [u("div", {
223
+ class: g(["w-full flex items-center justify-center overflow-hidden", { "[&>*]:w-full [&>*]:h-full": e.mediaAspectRatio }]),
224
+ style: v(r.value)
225
+ }, [e.videoWithAudioSource ? (x(), l("div", re, [u("video", {
226
+ ref_key: "videoWithAudioRef",
227
+ ref: s,
228
+ src: e.videoWithAudioSource,
229
+ class: "mulmocast-video mx-auto h-auto max-h-[80vh] w-auto object-contain",
230
+ controls: !0,
231
+ playsinline: "true",
232
+ onPlay: B,
233
+ onPause: H,
234
+ onEnded: K
235
+ }, null, 40, ie), u("div", ae, [u("button", {
236
+ class: "pointer-events-auto w-16 h-16 bg-black/50 hover:bg-black/70 rounded-full flex items-center justify-center transition-colors cursor-pointer",
237
+ onClick: n[0] ||= (e) => D.value ? q() : X()
238
+ }, [D.value ? (x(), l("svg", se, [...n[5] ||= [u("path", { d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" }, null, -1)]])) : (x(), l("svg", oe, [...n[4] ||= [u("path", { d: "M8 5v14l11-7z" }, null, -1)]]))])])])) : e.soundEffectSource || e.videoSource ? (x(), l("div", ce, [
239
+ u("video", {
240
+ ref_key: "videoRef",
241
+ ref: d,
242
+ class: "mulmocast-video mx-auto h-auto max-h-[80vh] w-auto object-contain",
243
+ src: e.soundEffectSource || e.videoSource,
244
+ controls: !m.value,
245
+ playsinline: "true",
246
+ onPlay: j,
247
+ onPause: M,
248
+ onEnded: N,
249
+ onSeeked: je,
250
+ onLoadedmetadata: h
251
+ }, null, 40, le),
252
+ e.audioSource ? (x(), l("audio", {
253
+ key: 0,
254
+ ref_key: "audioSyncRef",
255
+ ref: f,
256
+ src: e.audioSource,
257
+ controls: !0,
258
+ class: g(m.value ? "mulmocast-audio absolute bottom-0 left-0 w-full" : "hidden"),
259
+ onEnded: F,
260
+ onSeeked: L,
261
+ onPlay: R,
262
+ onPause: z,
263
+ onLoadedmetadata: h
264
+ }, null, 42, ue)) : c("", !0),
265
+ u("div", de, [u("button", {
266
+ class: "pointer-events-auto w-16 h-16 bg-black/50 hover:bg-black/70 rounded-full flex items-center justify-center transition-colors cursor-pointer",
267
+ onClick: n[1] ||= (e) => D.value ? q() : X()
268
+ }, [D.value ? (x(), l("svg", pe, [...n[7] ||= [u("path", { d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" }, null, -1)]])) : (x(), l("svg", fe, [...n[6] ||= [u("path", { d: "M8 5v14l11-7z" }, null, -1)]]))])])
269
+ ])) : e.audioSource ? (x(), l("div", me, [
270
+ e.imageSource ? (x(), l("img", {
271
+ key: 0,
272
+ src: e.imageSource,
273
+ class: "mx-auto h-auto max-h-[80vh] w-auto object-contain",
274
+ alt: "Background"
275
+ }, null, 8, he)) : (x(), l("img", {
276
+ key: 1,
277
+ src: ke,
278
+ class: "mx-auto h-auto max-h-[80vh] w-auto object-contain",
279
+ alt: "Background"
280
+ })),
281
+ u("audio", {
282
+ ref_key: "audioRef",
283
+ ref: p,
284
+ class: "mulmocast-audio absolute inset-0 w-full h-full",
285
+ src: e.audioSource,
286
+ controls: !0,
287
+ onPlay: B,
288
+ onPause: H,
289
+ onEnded: K
290
+ }, null, 40, ge),
291
+ u("div", _e, [u("button", {
292
+ class: "pointer-events-auto w-16 h-16 bg-black/50 hover:bg-black/70 rounded-full flex items-center justify-center transition-colors cursor-pointer",
293
+ onClick: n[2] ||= (e) => D.value ? q() : X()
294
+ }, [D.value ? (x(), l("svg", ye, [...n[9] ||= [u("path", { d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" }, null, -1)]])) : (x(), l("svg", ve, [...n[8] ||= [u("path", { d: "M8 5v14l11-7z" }, null, -1)]]))])])
295
+ ])) : e.imageSource ? (x(), l("div", be, [u("img", {
296
+ src: e.imageSource,
297
+ class: "max-w-full max-h-full object-contain"
298
+ }, null, 8, xe), u("div", Se, [u("button", {
299
+ class: "pointer-events-auto w-16 h-16 bg-black/50 hover:bg-black/70 rounded-full flex items-center justify-center transition-colors cursor-pointer",
300
+ onClick: n[3] ||= (e) => D.value ? q() : X()
301
+ }, [D.value ? (x(), l("svg", we, [...n[11] ||= [u("path", { d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" }, null, -1)]])) : (x(), l("svg", Ce, [...n[10] ||= [u("path", { d: "M8 5v14l11-7z" }, null, -1)]]))])])])) : (x(), l("div", Te, "No media available"))], 6), e.text ? (x(), l("div", Ee, [u("p", De, T(e.text), 1), e.originalText && e.originalText !== e.text ? (x(), l("p", Oe, T(e.originalText), 1)) : c("", !0)])) : c("", !0)]));
302
+ }
303
+ }), q = (e, t) => {
304
+ let n = e.__vccOpts || e;
305
+ for (let [e, r] of t) n[e] = r;
306
+ return n;
307
+ }, J = /* @__PURE__ */ q(K, [["__scopeId", "data-v-0e76dd6a"]]), Y = ["value"], X = ["value"], Ae = /* @__PURE__ */ p({
308
+ __name: "select_language",
309
+ props: { modelValue: {} },
310
+ emits: ["update:modelValue"],
311
+ setup(e, { emit: t }) {
312
+ let n = ["en", "ja"], r = {
313
+ en: "English",
314
+ ja: "日本語"
315
+ }, i = t, o = (e) => {
316
+ let t = e.target;
317
+ i("update:modelValue", t.value);
318
+ };
319
+ return (t, i) => (x(), l("select", {
320
+ value: e.modelValue,
321
+ class: "px-4 py-2 bg-white border-2 border-gray-300 rounded-lg shadow-sm hover:border-indigo-400 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 focus:outline-none transition-colors cursor-pointer text-base font-medium text-gray-700",
322
+ onChange: o
323
+ }, [(x(), l(a, null, C(n, (e) => u("option", {
324
+ key: e,
325
+ value: e
326
+ }, T(r[e] || e), 9, X)), 64))], 40, Y));
327
+ }
328
+ }), je = { class: "w-full overflow-hidden" }, Z = { class: "max-w-7xl mx-auto px-4" }, Me = { class: "grid grid-cols-[auto,1fr,auto] gap-x-4 gap-y-4 max-sm:grid-cols-2" }, Q = ["disabled"], Ne = { class: "col-start-2 row-start-1 min-w-0 max-sm:col-span-2 max-sm:col-start-1" }, $ = ["disabled"], Pe = {
329
+ key: 0,
330
+ class: "mulmo-text-box col-start-2 row-start-2 min-w-0 mt-1 rounded-lg px-6 py-4 text-left max-sm:col-span-2 max-sm:col-start-1 max-sm:row-start-3"
331
+ }, Fe = { class: "mulmo-text-primary text-lg leading-relaxed font-sans" }, Ie = {
332
+ key: 0,
333
+ class: "mulmo-text-secondary text-base leading-relaxed font-sans mt-3 italic"
334
+ }, Le = ["src"], Re = /* @__PURE__ */ q(/* @__PURE__ */ p({
335
+ __name: "mulmo_viewer",
336
+ props: {
337
+ dataSet: { default: void 0 },
338
+ basePath: {},
339
+ initPage: { default: void 0 },
340
+ audioLang: { default: "en" },
341
+ textLang: { default: "en" },
342
+ playbackSpeed: { default: 1 },
343
+ mediaAspectRatio: { default: void 0 }
344
+ },
345
+ emits: [
346
+ "updatedPage",
347
+ "update:audioLang",
348
+ "update:textLang",
349
+ "allCompleted"
350
+ ],
351
+ setup(e, { expose: t, emit: n }) {
352
+ let r = e, i = n, d = r.dataSet?.beats?.length ?? 0, p = S(r.initPage ?? 0), g = S(!0), v = S(), y = S(), b = o({
353
+ get: () => r.audioLang,
354
+ set: (e) => i("update:audioLang", e || "en")
355
+ }), C = o({
356
+ get: () => r.textLang,
357
+ set: (e) => i("update:textLang", e || "en")
358
+ }), D = 0;
359
+ k(() => r.audioLang, async (e, t) => {
360
+ if (e !== t && P.value) {
361
+ D++;
362
+ let e = D;
363
+ if (v.value?.stop(), await F(500), e !== D) return;
364
+ v.value && (P.value = !0, await v.value.play());
365
+ }
366
+ }), k(() => r.textLang, async (e, t) => {
367
+ e !== t && P.value && (await F(100), v.value && await v.value.play());
368
+ }), k(y, (e) => {
369
+ e && (e.volume = .3);
370
+ });
371
+ let j = o(() => r.dataSet?.beats[p.value]), M = (e) => e ? r.basePath + "/" + e : "", N = o(() => M(r.dataSet?.bgmSource)), P = S(!1), I = () => {
372
+ P.value = !0, y.value && (y.value.volume = .3, y.value.play());
373
+ }, L = () => {
374
+ P.value = !1, y.value && y.value.pause();
375
+ }, R = async () => {
376
+ D++;
377
+ let e = D;
378
+ v.value?.stop(), await F(500), e === D && v.value && v.value.play();
379
+ }, z = (e) => {
380
+ p.value !== e && (p.value = e, P.value && g.value && R());
381
+ }, B = (e) => {
382
+ let t = p.value + e;
383
+ return t > -1 && t < d ? (z(t), i("updatedPage", t), !0) : !1;
384
+ }, V = () => {
385
+ g.value && B(1) || (P.value = !1, y.value && y.value.pause(), i("allCompleted"));
386
+ }, H = {
387
+ onPlay: I,
388
+ onPause: L,
389
+ onEnded: V
390
+ }, U = o(() => {
391
+ let e = j.value, t = e?.audioSources?.[b.value], n = e?.multiLinguals?.[C.value] ?? e?.text ?? "", i = r.dataSet?.lang ? e?.multiLinguals?.[r.dataSet.lang] ?? e?.text ?? "" : "";
392
+ return {
393
+ videoWithAudioSource: M(e?.videoWithAudioSource),
394
+ videoSource: M(e?.videoSource),
395
+ soundEffectSource: M(e?.soundEffectSource),
396
+ audioSource: M(t),
397
+ imageSource: M(e?.imageSource),
398
+ index: p.value,
399
+ text: n,
400
+ originalText: i,
401
+ duration: e?.duration,
402
+ defaultLang: r.dataSet?.lang,
403
+ currentLang: b.value,
404
+ playbackSpeed: r.playbackSpeed,
405
+ mediaAspectRatio: r.mediaAspectRatio,
406
+ ...H
407
+ };
408
+ }), W = o(() => r.dataSet?.beats[p.value + 1]), G = o(() => {
409
+ if (p.value + 1 >= d) return null;
410
+ let e = W.value;
411
+ return {
412
+ videoWithAudioSource: M(e?.videoWithAudioSource),
413
+ videoSource: M(e?.videoSource),
414
+ soundEffectSource: M(e?.soundEffectSource),
415
+ audioSource: M(e?.audioSources?.[b.value]),
416
+ imageSource: M(e?.imageSource),
417
+ index: p.value + 1,
418
+ text: e?.multiLinguals?.[C.value] ?? e?.text ?? "",
419
+ duration: e?.duration
420
+ };
421
+ }), ee = o(() => ({
422
+ MulmoPlayer: J,
423
+ pageProps: U.value,
424
+ currentPage: p.value,
425
+ pageCount: d,
426
+ pageMove: B,
427
+ isPlaying: P.value,
428
+ audioLang: b,
429
+ textLang: C,
430
+ SelectLanguage: Ae,
431
+ mediaPlayerRef: v,
432
+ mediaAspectRatio: r.mediaAspectRatio,
433
+ handlePlay: I,
434
+ handlePause: L,
435
+ handleEnded: V
436
+ }));
437
+ return t({ updatePage: z }), (e, t) => (x(), l(a, null, [
438
+ w(e.$slots, "default", _(m(ee.value)), () => [u("div", je, [u("div", Z, [u("div", Me, [
439
+ u("button", {
440
+ class: "col-start-1 row-start-1 justify-self-start w-auto px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600 disabled:opacity-50 self-center max-sm:row-start-2",
441
+ disabled: p.value === 0,
442
+ onClick: t[0] ||= (e) => B(-1)
443
+ }, " Prev ", 8, Q),
444
+ u("div", Ne, [f(J, h({
445
+ ref_key: "mediaPlayer",
446
+ ref: v
447
+ }, {
448
+ ...U.value,
449
+ text: "",
450
+ originalText: ""
451
+ }), null, 16)]),
452
+ u("button", {
453
+ class: "col-start-3 row-start-1 justify-self-end w-auto px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600 disabled:opacity-50 self-center max-sm:col-start-2 max-sm:row-start-2",
454
+ disabled: p.value >= E(d) - 1,
455
+ onClick: t[1] ||= (e) => B(1)
456
+ }, " Next ", 8, $),
457
+ U.value.text ? (x(), l("div", Pe, [u("p", Fe, T(U.value.text), 1), U.value.originalText && U.value.originalText !== U.value.text ? (x(), l("p", Ie, T(U.value.originalText), 1)) : c("", !0)])) : c("", !0)
458
+ ])])])], !0),
459
+ G.value ? A((x(), s(J, _(h({ key: 0 }, G.value)), null, 16)), [[O, !1]]) : c("", !0),
460
+ N.value ? (x(), l("audio", {
461
+ key: 1,
462
+ ref_key: "bgmRef",
463
+ ref: y,
464
+ src: N.value
465
+ }, null, 8, Le)) : c("", !0)
466
+ ], 64));
467
+ }
468
+ }), [["__scopeId", "data-v-5693d3ec"]]), ze = { class: "mulmocast-container" }, Be = { class: "mulmocast-content-wrapper" }, Ve = { class: "p-4" }, He = {
469
+ key: 0,
470
+ class: "header-row"
471
+ }, Ue = { class: "document-title" }, We = { class: "button-group" }, Ge = ["disabled"], Ke = {
472
+ key: 0,
473
+ class: "error-message"
331
474
  }, qe = {
332
- key: 1,
333
- class: "viewer-container"
334
- }, ze = ["src"], He = ["src", "alt"], Ye = { class: "beat-text" }, Ze = {
335
- key: 0,
336
- class: "script-source"
337
- }, Ke = {
338
- key: 0,
339
- class: "error"
340
- }, Qe = ["disabled"], Xe = /* @__PURE__ */ W({
341
- __name: "View",
342
- props: {
343
- selectedResult: {},
344
- setMute: { type: Function },
345
- pluginConfigs: {}
346
- },
347
- emits: ["updateResult"],
348
- setup(o, { emit: w }) {
349
- const u = o, n = L(
350
- () => u.pluginConfigs?.mulmocast ?? !0
351
- ), h = w, m = b(null), l = b(!1), i = b(null), d = b(null), y = b(
352
- JSON.stringify(u.selectedResult?.data?.mulmoScript, null, 2) || ""
353
- ), p = b(null), U = b("en"), V = b("en"), k = b(1), P = b(0), f = L(() => u.selectedResult?.data?.moviePath || null), C = L(
354
- () => u.selectedResult?.data?.viewerJsonPath || null
355
- ), j = L(() => {
356
- if (!C.value) return "";
357
- const e = C.value.indexOf("/output/");
358
- if (e !== -1) {
359
- const a = C.value.substring(e), c = a.lastIndexOf("/");
360
- return a.substring(0, c);
361
- }
362
- return "";
363
- }), x = L(() => {
364
- const e = JSON.stringify(
365
- u.selectedResult?.data?.mulmoScript,
366
- null,
367
- 2
368
- );
369
- return y.value !== e;
370
- });
371
- ae(() => {
372
- m.value && URL.revokeObjectURL(m.value);
373
- });
374
- async function R() {
375
- const e = u.selectedResult?.data?.mulmoScript;
376
- if (!(!e || l.value || !u.selectedResult)) {
377
- l.value = !0, i.value = null;
378
- try {
379
- const a = le(), c = await fetch("/api/generate-movie", {
380
- method: "POST",
381
- headers: {
382
- "Content-Type": "application/json"
383
- },
384
- body: JSON.stringify({
385
- mulmoScript: e,
386
- uuid: a,
387
- images: u.selectedResult?.data?.images || {}
388
- })
389
- });
390
- if (c.ok) {
391
- const S = await c.json(), O = {
392
- ...u.selectedResult,
393
- data: {
394
- ...u.selectedResult.data,
395
- moviePath: S.outputPath,
396
- viewerJsonPath: S.viewerJsonPath
397
- }
398
- };
399
- h("updateResult", O);
400
- } else {
401
- const S = await c.json();
402
- i.value = S.details || S.error || "Failed to generate movie";
403
- }
404
- } catch (a) {
405
- i.value = a instanceof Error ? a.message : "Unknown error";
406
- } finally {
407
- l.value = !1;
408
- }
409
- }
410
- }
411
- T(
412
- () => u.selectedResult?.data?.mulmoScript,
413
- async (e) => {
414
- !e || u.selectedResult?.data?.moviePath || l.value || !u.selectedResult || n.value === !1 || await R();
415
- },
416
- { immediate: !0 }
417
- ), T(
418
- C,
419
- async (e) => {
420
- if (!e) {
421
- p.value = null;
422
- return;
423
- }
424
- try {
425
- const a = await fetch("/api/viewer-json", {
426
- method: "POST",
427
- headers: {
428
- "Content-Type": "application/json"
429
- },
430
- body: JSON.stringify({
431
- viewerJsonPath: e
432
- })
433
- });
434
- if (!a.ok)
435
- throw new Error("Failed to load viewer JSON");
436
- p.value = await a.json();
437
- } catch (a) {
438
- console.error("Viewer JSON loading failed:", a), p.value = null;
439
- }
440
- },
441
- { immediate: !0 }
442
- ), T(
443
- f,
444
- async (e) => {
445
- if (e)
446
- try {
447
- const a = await fetch("/api/download-movie", {
448
- method: "POST",
449
- headers: {
450
- "Content-Type": "application/json"
451
- },
452
- body: JSON.stringify({
453
- moviePath: e
454
- })
455
- });
456
- if (!a.ok)
457
- throw new Error("Failed to load movie");
458
- const c = await a.blob();
459
- m.value && URL.revokeObjectURL(m.value), m.value = URL.createObjectURL(c);
460
- } catch (a) {
461
- console.error("Movie loading failed:", a);
462
- }
463
- },
464
- { immediate: !0 }
465
- );
466
- const J = () => {
467
- if (!u.selectedResult?.data?.mulmoScript) return;
468
- const e = JSON.stringify(
469
- u.selectedResult.data.mulmoScript,
470
- null,
471
- 2
472
- ), a = new Blob([e], { type: "application/json" }), c = URL.createObjectURL(a), S = document.createElement("a");
473
- S.href = c;
474
- const F = (u.selectedResult.data.mulmoScript.title || "mulmoscript").replace(/[^a-z0-9]/gi, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").toLowerCase();
475
- S.download = `${F}.json`, document.body.appendChild(S), S.click(), document.body.removeChild(S), URL.revokeObjectURL(c);
476
- }, M = async () => {
477
- if (f.value)
478
- try {
479
- const e = await fetch("/api/download-movie", {
480
- method: "POST",
481
- headers: {
482
- "Content-Type": "application/json"
483
- },
484
- body: JSON.stringify({
485
- moviePath: f.value
486
- })
487
- });
488
- if (!e.ok)
489
- throw new Error("Failed to download movie");
490
- const c = e.headers.get("Content-Disposition")?.match(/filename="(.+)"/), S = c ? c[1] : "movie.mp4", O = await e.blob(), F = URL.createObjectURL(O), B = document.createElement("a");
491
- B.href = F, B.download = S, document.body.appendChild(B), B.click(), document.body.removeChild(B), URL.revokeObjectURL(F);
492
- } catch (e) {
493
- console.error("Movie download failed:", e), alert(
494
- `Failed to download movie: ${e instanceof Error ? e.message : "Unknown error"}`
495
- );
496
- }
497
- }, A = () => {
498
- u.setMute?.(!0);
499
- }, $ = () => {
500
- u.setMute?.(!1);
501
- }, I = () => {
502
- u.setMute?.(!1);
503
- };
504
- function E() {
505
- try {
506
- const e = JSON.parse(y.value);
507
- d.value = null;
508
- const a = {
509
- ...u.selectedResult,
510
- data: {
511
- ...u.selectedResult.data,
512
- mulmoScript: e,
513
- moviePath: void 0,
514
- viewerJsonPath: void 0
515
- }
516
- };
517
- h("updateResult", a);
518
- } catch (e) {
519
- d.value = e instanceof Error ? e.message : "Invalid JSON";
520
- }
521
- }
522
- T(
523
- () => u.selectedResult?.data?.mulmoScript,
524
- (e) => {
525
- y.value = JSON.stringify(e, null, 2) || "", d.value = null;
526
- }
527
- );
528
- function g() {
529
- if (p.value && P.value < p.value.beats.length - 1) {
530
- const e = document.querySelector("video, audio"), a = e && !e.paused;
531
- P.value++, a && setTimeout(() => {
532
- const c = document.querySelector("video, audio");
533
- c && c.play().catch(() => {
534
- });
535
- }, 100);
536
- }
537
- }
538
- function t() {
539
- if (P.value > 0) {
540
- const e = document.querySelector("video, audio"), a = e && !e.paused;
541
- P.value--, a && setTimeout(() => {
542
- const c = document.querySelector("video, audio");
543
- c && c.play().catch(() => {
544
- });
545
- }, 100);
546
- }
547
- }
548
- return (e, a) => (s(), r("div", Ve, [
549
- v("div", Ie, [
550
- v("div", Ae, [
551
- o.selectedResult?.data?.mulmoScript?.title ? (s(), r("div", Be, [
552
- v("h1", We, N(o.selectedResult.data.mulmoScript.title), 1),
553
- v("div", Fe, [
554
- v("button", {
555
- onClick: J,
556
- class: "download-btn download-btn-green"
557
- }, [...a[4] || (a[4] = [
558
- v("span", { class: "material-icons" }, "download", -1),
559
- D(" Script ", -1)
560
- ])]),
561
- !f.value && !l.value && n.value === !1 ? (s(), r("button", {
562
- key: 0,
563
- onClick: R,
564
- class: "download-btn download-btn-orange"
565
- }, [...a[5] || (a[5] = [
566
- v("span", { class: "material-icons" }, "movie", -1),
567
- D(" Generate Movie ", -1)
568
- ])])) : (s(), r("button", {
569
- key: 1,
570
- onClick: M,
571
- disabled: !f.value,
572
- class: K(["download-btn", f.value ? "download-btn-blue" : "download-btn-disabled"])
573
- }, [
574
- v("span", {
575
- class: K(["material-icons", { "animate-spin": l.value }])
576
- }, N(l.value ? "hourglass_empty" : "download"), 3),
577
- a[6] || (a[6] = D(" Movie ", -1))
578
- ], 10, De))
579
- ])
580
- ])) : _("", !0),
581
- o.selectedResult?.data?.mulmoScript?.beats ? (s(!0), r(z, { key: 1 }, te(o.selectedResult.data.mulmoScript.beats, (c, S) => (s(), r("div", {
582
- key: c.id || S,
583
- class: "beat-container"
584
- }, [
585
- S === 0 && i.value ? (s(), r("div", Ge, " Movie generation failed: " + N(i.value), 1)) : S === 0 && p.value ? (s(), r("div", qe, [
586
- P.value > 0 ? (s(), r("button", {
587
- key: 0,
588
- onClick: t,
589
- class: "nav-button nav-button-prev",
590
- "aria-label": "Previous page"
591
- }, " ")) : _("", !0),
592
- (s(), ee(X($e), {
593
- ref_for: !0,
594
- ref: "viewerRef",
595
- key: `viewer-${P.value}`,
596
- "audio-lang": U.value,
597
- "onUpdate:audioLang": a[0] || (a[0] = (O) => U.value = O),
598
- "text-lang": V.value,
599
- "onUpdate:textLang": a[1] || (a[1] = (O) => V.value = O),
600
- "data-set": p.value,
601
- "base-path": j.value,
602
- "init-page": P.value,
603
- "playback-speed": k.value,
604
- onUpdatedPage: a[2] || (a[2] = (O) => P.value = O)
605
- }, null, 8, ["audio-lang", "text-lang", "data-set", "base-path", "init-page", "playback-speed"])),
606
- p.value && P.value < p.value.beats.length - 1 ? (s(), r("button", {
607
- key: 1,
608
- onClick: g,
609
- class: "nav-button nav-button-next",
610
- "aria-label": "Next page"
611
- }, " › ")) : _("", !0)
612
- ])) : S === 0 && f.value && m.value && !p.value ? (s(), r("video", {
613
- key: 2,
614
- ref_for: !0,
615
- ref: "videoEl",
616
- src: m.value,
617
- controls: "",
618
- class: "video-player",
619
- onPlay: A,
620
- onPause: $,
621
- onEnded: I
622
- }, null, 40, ze)) : c.id && o.selectedResult.data?.images?.[c.id] ? (s(), r("img", {
623
- key: 3,
624
- src: `data:image/png;base64,${o.selectedResult.data.images[c.id]}`,
625
- alt: c.text,
626
- class: "beat-image"
627
- }, null, 8, He)) : _("", !0),
628
- v("p", Ye, N(c.text), 1)
629
- ]))), 128)) : _("", !0)
630
- ])
631
- ]),
632
- o.selectedResult?.data?.mulmoScript ? (s(), r("details", Ze, [
633
- a[8] || (a[8] = v("summary", null, "Edit MulmoScript Source", -1)),
634
- d.value ? (s(), r("div", Ke, [
635
- a[7] || (a[7] = v("strong", null, "Parse Error:", -1)),
636
- D(" " + N(d.value), 1)
637
- ])) : _("", !0),
638
- Q(v("textarea", {
639
- "onUpdate:modelValue": a[3] || (a[3] = (c) => y.value = c),
640
- class: "script-editor",
641
- spellcheck: "false"
642
- }, null, 512), [
643
- [de, y.value]
644
- ]),
645
- v("button", {
646
- onClick: E,
647
- class: "apply-btn",
648
- disabled: !x.value
649
- }, " Apply Changes ", 8, Qe)
650
- ])) : _("", !0)
651
- ]));
652
- }
653
- }), et = (o, w) => {
654
- const u = o.__vccOpts || o;
655
- for (const [n, h] of w)
656
- u[n] = h;
657
- return u;
658
- }, tt = /* @__PURE__ */ et(Xe, [["__scopeId", "data-v-1e1901ce"]]), at = { class: "bg-green-100 rounded overflow-hidden" }, lt = {
659
- key: 0,
660
- class: "w-full aspect-video bg-gray-200",
661
- style: { position: "relative" }
662
- }, ot = ["src", "alt"], nt = { class: "p-2" }, ut = { class: "text-green-600 font-medium text-sm truncate" }, st = /* @__PURE__ */ W({
663
- __name: "Preview",
664
- props: {
665
- result: {}
666
- },
667
- setup(o) {
668
- const w = o, u = L(() => {
669
- const n = w.result.data?.mulmoScript?.beats?.[0];
670
- return n?.id && w.result.data?.images?.[n.id] ? w.result.data.images[n.id] : null;
671
- });
672
- return (n, h) => (s(), r("div", at, [
673
- u.value ? (s(), r("div", lt, [
674
- v("img", {
675
- src: `data:image/png;base64,${u.value}`,
676
- alt: o.result.data?.mulmoScript?.title || "Presentation",
677
- class: "w-full h-full object-cover"
678
- }, null, 8, ot)
679
- ])) : _("", !0),
680
- v("div", nt, [
681
- v("div", ut, N(o.result.data?.mulmoScript?.title || o.result.title || "Presentation"), 1)
682
- ])
683
- ]));
684
- }
685
- }), it = "showPresentation", rt = `Call the ${it} API to display presentations when the user is asking for a presentation.`, dt = {
686
- ...ne,
687
- viewComponent: tt,
688
- previewComponent: st,
689
- samples: oe,
690
- systemPrompt: rt
691
- }, mt = { plugin: dt };
692
- export {
693
- st as Preview,
694
- rt as SYSTEM_PROMPT,
695
- ft as TOOL_DEFINITION,
696
- it as TOOL_NAME,
697
- tt as View,
698
- mt as default,
699
- yt as executeMulmocast,
700
- dt as plugin,
701
- ne as pluginCore,
702
- oe as samples
703
- };
475
+ key: 1,
476
+ class: "viewer-container"
477
+ }, Je = ["src"], Ye = ["src", "alt"], Xe = { class: "beat-text" }, Ze = {
478
+ key: 0,
479
+ class: "script-source"
480
+ }, Qe = {
481
+ key: 0,
482
+ class: "error"
483
+ }, $e = ["disabled"], et = /* @__PURE__ */ ((e, t) => {
484
+ let n = e.__vccOpts || e;
485
+ for (let [e, r] of t) n[e] = r;
486
+ return n;
487
+ })(/* @__PURE__ */ p({
488
+ __name: "View",
489
+ props: {
490
+ selectedResult: {},
491
+ setMute: { type: Function },
492
+ pluginConfigs: {}
493
+ },
494
+ emits: ["updateResult"],
495
+ setup(t, { emit: n }) {
496
+ let r = t, i = o(() => r.pluginConfigs?.mulmocast ?? !0), f = n, p = S(null), m = S(!1), h = S(null), _ = S(null), v = S(JSON.stringify(r.selectedResult?.data?.mulmoScript, null, 2) || ""), y = S(null), w = S("en"), O = S("en"), j = S(1), M = S(0), N = o(() => r.selectedResult?.data?.moviePath || null), P = o(() => r.selectedResult?.data?.viewerJsonPath || null), F = o(() => {
497
+ if (!P.value) return "";
498
+ let e = P.value.indexOf("/output/");
499
+ if (e !== -1) {
500
+ let t = P.value.substring(e), n = t.lastIndexOf("/");
501
+ return t.substring(0, n);
502
+ }
503
+ return "";
504
+ }), I = o(() => {
505
+ let e = JSON.stringify(r.selectedResult?.data?.mulmoScript, null, 2);
506
+ return v.value !== e;
507
+ });
508
+ b(() => {
509
+ p.value && URL.revokeObjectURL(p.value);
510
+ });
511
+ async function L() {
512
+ let t = r.selectedResult?.data?.mulmoScript;
513
+ if (!(!t || m.value || !r.selectedResult)) {
514
+ m.value = !0, h.value = null;
515
+ try {
516
+ let n = e(), i = await fetch("/api/generate-movie", {
517
+ method: "POST",
518
+ headers: { "Content-Type": "application/json" },
519
+ body: JSON.stringify({
520
+ mulmoScript: t,
521
+ uuid: n,
522
+ images: r.selectedResult?.data?.images || {}
523
+ })
524
+ });
525
+ if (i.ok) {
526
+ let e = await i.json();
527
+ f("updateResult", {
528
+ ...r.selectedResult,
529
+ data: {
530
+ ...r.selectedResult.data,
531
+ moviePath: e.outputPath,
532
+ viewerJsonPath: e.viewerJsonPath
533
+ }
534
+ });
535
+ } else {
536
+ let e = await i.json();
537
+ h.value = e.details || e.error || "Failed to generate movie";
538
+ }
539
+ } catch (e) {
540
+ h.value = e instanceof Error ? e.message : "Unknown error";
541
+ } finally {
542
+ m.value = !1;
543
+ }
544
+ }
545
+ }
546
+ k(() => r.selectedResult?.data?.mulmoScript, async (e) => {
547
+ !e || r.selectedResult?.data?.moviePath || m.value || !r.selectedResult || i.value === !1 || await L();
548
+ }, { immediate: !0 }), k(P, async (e) => {
549
+ if (!e) {
550
+ y.value = null;
551
+ return;
552
+ }
553
+ try {
554
+ let t = await fetch("/api/viewer-json", {
555
+ method: "POST",
556
+ headers: { "Content-Type": "application/json" },
557
+ body: JSON.stringify({ viewerJsonPath: e })
558
+ });
559
+ if (!t.ok) throw Error("Failed to load viewer JSON");
560
+ y.value = await t.json();
561
+ } catch (e) {
562
+ console.error("Viewer JSON loading failed:", e), y.value = null;
563
+ }
564
+ }, { immediate: !0 }), k(N, async (e) => {
565
+ if (e) try {
566
+ let t = await fetch("/api/download-movie", {
567
+ method: "POST",
568
+ headers: { "Content-Type": "application/json" },
569
+ body: JSON.stringify({ moviePath: e })
570
+ });
571
+ if (!t.ok) throw Error("Failed to load movie");
572
+ let n = await t.blob();
573
+ p.value && URL.revokeObjectURL(p.value), p.value = URL.createObjectURL(n);
574
+ } catch (e) {
575
+ console.error("Movie loading failed:", e);
576
+ }
577
+ }, { immediate: !0 });
578
+ let R = () => {
579
+ if (!r.selectedResult?.data?.mulmoScript) return;
580
+ let e = JSON.stringify(r.selectedResult.data.mulmoScript, null, 2), t = new Blob([e], { type: "application/json" }), n = URL.createObjectURL(t), i = document.createElement("a");
581
+ i.href = n, i.download = `${(r.selectedResult.data.mulmoScript.title || "mulmoscript").replace(/[^a-z0-9]/gi, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").toLowerCase()}.json`, document.body.appendChild(i), i.click(), document.body.removeChild(i), URL.revokeObjectURL(n);
582
+ }, z = async () => {
583
+ if (N.value) try {
584
+ let e = await fetch("/api/download-movie", {
585
+ method: "POST",
586
+ headers: { "Content-Type": "application/json" },
587
+ body: JSON.stringify({ moviePath: N.value })
588
+ });
589
+ if (!e.ok) throw Error("Failed to download movie");
590
+ let t = e.headers.get("Content-Disposition")?.match(/filename="(.+)"/), n = t ? t[1] : "movie.mp4", r = await e.blob(), i = URL.createObjectURL(r), a = document.createElement("a");
591
+ a.href = i, a.download = n, document.body.appendChild(a), a.click(), document.body.removeChild(a), URL.revokeObjectURL(i);
592
+ } catch (e) {
593
+ console.error("Movie download failed:", e), alert(`Failed to download movie: ${e instanceof Error ? e.message : "Unknown error"}`);
594
+ }
595
+ }, B = () => {
596
+ r.setMute?.(!0);
597
+ }, V = () => {
598
+ r.setMute?.(!1);
599
+ }, H = () => {
600
+ r.setMute?.(!1);
601
+ };
602
+ function U() {
603
+ try {
604
+ let e = JSON.parse(v.value);
605
+ _.value = null, f("updateResult", {
606
+ ...r.selectedResult,
607
+ data: {
608
+ ...r.selectedResult.data,
609
+ mulmoScript: e,
610
+ moviePath: void 0,
611
+ viewerJsonPath: void 0
612
+ }
613
+ });
614
+ } catch (e) {
615
+ _.value = e instanceof Error ? e.message : "Invalid JSON";
616
+ }
617
+ }
618
+ k(() => r.selectedResult?.data?.mulmoScript, (e) => {
619
+ v.value = JSON.stringify(e, null, 2) || "", _.value = null;
620
+ });
621
+ function W() {
622
+ if (y.value && M.value < y.value.beats.length - 1) {
623
+ let e = document.querySelector("video, audio"), t = e && !e.paused;
624
+ M.value++, t && setTimeout(() => {
625
+ let e = document.querySelector("video, audio");
626
+ e && e.play().catch(() => {});
627
+ }, 100);
628
+ }
629
+ }
630
+ function G() {
631
+ if (M.value > 0) {
632
+ let e = document.querySelector("video, audio"), t = e && !e.paused;
633
+ M.value--, t && setTimeout(() => {
634
+ let e = document.querySelector("video, audio");
635
+ e && e.play().catch(() => {});
636
+ }, 100);
637
+ }
638
+ }
639
+ return (e, n) => (x(), l("div", ze, [u("div", Be, [u("div", Ve, [t.selectedResult?.data?.mulmoScript?.title ? (x(), l("div", He, [u("h1", Ue, T(t.selectedResult.data.mulmoScript.title), 1), u("div", We, [u("button", {
640
+ onClick: R,
641
+ class: "download-btn download-btn-green"
642
+ }, [...n[4] ||= [u("span", { class: "material-icons" }, "download", -1), d(" Script ", -1)]]), !N.value && !m.value && i.value === !1 ? (x(), l("button", {
643
+ key: 0,
644
+ onClick: L,
645
+ class: "download-btn download-btn-orange"
646
+ }, [...n[5] ||= [u("span", { class: "material-icons" }, "movie", -1), d(" Generate Movie ", -1)]])) : (x(), l("button", {
647
+ key: 1,
648
+ onClick: z,
649
+ disabled: !N.value,
650
+ class: g(["download-btn", N.value ? "download-btn-blue" : "download-btn-disabled"])
651
+ }, [u("span", { class: g(["material-icons", { "animate-spin": m.value }]) }, T(m.value ? "hourglass_empty" : "download"), 3), n[6] ||= d(" Movie ", -1)], 10, Ge))])])) : c("", !0), t.selectedResult?.data?.mulmoScript?.beats ? (x(!0), l(a, { key: 1 }, C(t.selectedResult.data.mulmoScript.beats, (e, r) => (x(), l("div", {
652
+ key: e.id || r,
653
+ class: "beat-container"
654
+ }, [r === 0 && h.value ? (x(), l("div", Ke, " Movie generation failed: " + T(h.value), 1)) : r === 0 && y.value ? (x(), l("div", qe, [
655
+ M.value > 0 ? (x(), l("button", {
656
+ key: 0,
657
+ onClick: G,
658
+ class: "nav-button nav-button-prev",
659
+ "aria-label": "Previous page"
660
+ }, " ‹ ")) : c("", !0),
661
+ (x(), s(E(Re), {
662
+ ref_for: !0,
663
+ ref: "viewerRef",
664
+ key: `viewer-${M.value}`,
665
+ "audio-lang": w.value,
666
+ "onUpdate:audioLang": n[0] ||= (e) => w.value = e,
667
+ "text-lang": O.value,
668
+ "onUpdate:textLang": n[1] ||= (e) => O.value = e,
669
+ "data-set": y.value,
670
+ "base-path": F.value,
671
+ "init-page": M.value,
672
+ "playback-speed": j.value,
673
+ onUpdatedPage: n[2] ||= (e) => M.value = e
674
+ }, null, 8, [
675
+ "audio-lang",
676
+ "text-lang",
677
+ "data-set",
678
+ "base-path",
679
+ "init-page",
680
+ "playback-speed"
681
+ ])),
682
+ y.value && M.value < y.value.beats.length - 1 ? (x(), l("button", {
683
+ key: 1,
684
+ onClick: W,
685
+ class: "nav-button nav-button-next",
686
+ "aria-label": "Next page"
687
+ }, " › ")) : c("", !0)
688
+ ])) : r === 0 && N.value && p.value && !y.value ? (x(), l("video", {
689
+ key: 2,
690
+ ref_for: !0,
691
+ ref: "videoEl",
692
+ src: p.value,
693
+ controls: "",
694
+ class: "video-player",
695
+ onPlay: B,
696
+ onPause: V,
697
+ onEnded: H
698
+ }, null, 40, Je)) : e.id && t.selectedResult.data?.images?.[e.id] ? (x(), l("img", {
699
+ key: 3,
700
+ src: `data:image/png;base64,${t.selectedResult.data.images[e.id]}`,
701
+ alt: e.text,
702
+ class: "beat-image"
703
+ }, null, 8, Ye)) : c("", !0), u("p", Xe, T(e.text), 1)]))), 128)) : c("", !0)])]), t.selectedResult?.data?.mulmoScript ? (x(), l("details", Ze, [
704
+ n[8] ||= u("summary", null, "Edit MulmoScript Source", -1),
705
+ _.value ? (x(), l("div", Qe, [n[7] ||= u("strong", null, "Parse Error:", -1), d(" " + T(_.value), 1)])) : c("", !0),
706
+ A(u("textarea", {
707
+ "onUpdate:modelValue": n[3] ||= (e) => v.value = e,
708
+ class: "script-editor",
709
+ spellcheck: "false"
710
+ }, null, 512), [[D, v.value]]),
711
+ u("button", {
712
+ onClick: U,
713
+ class: "apply-btn",
714
+ disabled: !I.value
715
+ }, " Apply Changes ", 8, $e)
716
+ ])) : c("", !0)]));
717
+ }
718
+ }), [["__scopeId", "data-v-0070ab10"]]), tt = { class: "bg-green-100 rounded overflow-hidden" }, nt = {
719
+ key: 0,
720
+ class: "w-full aspect-video bg-gray-200",
721
+ style: { position: "relative" }
722
+ }, rt = ["src", "alt"], it = { class: "p-2" }, at = { class: "text-green-600 font-medium text-sm truncate" }, ot = /* @__PURE__ */ p({
723
+ __name: "Preview",
724
+ props: { result: {} },
725
+ setup(e) {
726
+ let t = e, n = o(() => {
727
+ let e = t.result.data?.mulmoScript?.beats?.[0];
728
+ return e?.id && t.result.data?.images?.[e.id] ? t.result.data.images[e.id] : null;
729
+ });
730
+ return (t, r) => (x(), l("div", tt, [n.value ? (x(), l("div", nt, [u("img", {
731
+ src: `data:image/png;base64,${n.value}`,
732
+ alt: e.result.data?.mulmoScript?.title || "Presentation",
733
+ class: "w-full h-full object-cover"
734
+ }, null, 8, rt)])) : c("", !0), u("div", it, [u("div", at, T(e.result.data?.mulmoScript?.title || e.result.title || "Presentation"), 1)])]));
735
+ }
736
+ }), st = "showPresentation", ct = `Call the ${st} API to display presentations when the user is asking for a presentation.`, lt = {
737
+ ...r,
738
+ viewComponent: et,
739
+ previewComponent: ot,
740
+ samples: i,
741
+ systemPrompt: ct
742
+ }, ut = { plugin: lt };
743
+ //#endregion
744
+ export { ot as Preview, ct as SYSTEM_PROMPT, n as TOOL_DEFINITION, st as TOOL_NAME, et as View, ut as default, t as executeMulmocast, lt as plugin, r as pluginCore, i as samples };