@doodle-engine/react 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/GameProvider.d.ts +38 -0
  2. package/dist/GameProvider.d.ts.map +1 -0
  3. package/dist/GameRenderer.d.ts +8 -0
  4. package/dist/GameRenderer.d.ts.map +1 -0
  5. package/dist/GameShell.d.ts +41 -0
  6. package/dist/GameShell.d.ts.map +1 -0
  7. package/dist/components/CharacterList.d.ts +11 -0
  8. package/dist/components/CharacterList.d.ts.map +1 -0
  9. package/dist/components/ChoiceList.d.ts +11 -0
  10. package/dist/components/ChoiceList.d.ts.map +1 -0
  11. package/dist/components/DialogueBox.d.ts +10 -0
  12. package/dist/components/DialogueBox.d.ts.map +1 -0
  13. package/dist/components/Inventory.d.ts +10 -0
  14. package/dist/components/Inventory.d.ts.map +1 -0
  15. package/dist/components/Journal.d.ts +11 -0
  16. package/dist/components/Journal.d.ts.map +1 -0
  17. package/dist/components/LocationView.d.ts +10 -0
  18. package/dist/components/LocationView.d.ts.map +1 -0
  19. package/dist/components/MapView.d.ts +11 -0
  20. package/dist/components/MapView.d.ts.map +1 -0
  21. package/dist/components/NotificationArea.d.ts +12 -0
  22. package/dist/components/NotificationArea.d.ts.map +1 -0
  23. package/dist/components/PauseMenu.d.ts +19 -0
  24. package/dist/components/PauseMenu.d.ts.map +1 -0
  25. package/dist/components/SaveLoadPanel.d.ts +12 -0
  26. package/dist/components/SaveLoadPanel.d.ts.map +1 -0
  27. package/dist/components/SettingsPanel.d.ts +26 -0
  28. package/dist/components/SettingsPanel.d.ts.map +1 -0
  29. package/dist/components/SplashScreen.d.ts +19 -0
  30. package/dist/components/SplashScreen.d.ts.map +1 -0
  31. package/dist/components/TitleScreen.d.ts +23 -0
  32. package/dist/components/TitleScreen.d.ts.map +1 -0
  33. package/dist/components/VideoPlayer.d.ts +18 -0
  34. package/dist/components/VideoPlayer.d.ts.map +1 -0
  35. package/dist/hooks/useAudioManager.d.ts +43 -0
  36. package/dist/hooks/useAudioManager.d.ts.map +1 -0
  37. package/dist/hooks/useGame.d.ts +13 -0
  38. package/dist/hooks/useGame.d.ts.map +1 -0
  39. package/dist/hooks/useUISounds.d.ts +40 -0
  40. package/dist/hooks/useUISounds.d.ts.map +1 -0
  41. package/dist/index.d.ts +46 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/react.cjs +22 -0
  44. package/dist/react.js +1063 -0
  45. package/dist/tsconfig.tsbuildinfo +1 -0
  46. package/package.json +52 -0
package/dist/react.js ADDED
@@ -0,0 +1,1063 @@
1
+ import { Engine as ie } from "@doodle-engine/core";
2
+ import { VERSION as De } from "@doodle-engine/core";
3
+ import ue, { createContext as de, useState as C, useCallback as N, useContext as me, useRef as q, useEffect as D } from "react";
4
+ var Z = { exports: {} }, z = {};
5
+ /**
6
+ * @license React
7
+ * react-jsx-runtime.production.js
8
+ *
9
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
10
+ *
11
+ * This source code is licensed under the MIT license found in the
12
+ * LICENSE file in the root directory of this source tree.
13
+ */
14
+ var ne;
15
+ function he() {
16
+ if (ne) return z;
17
+ ne = 1;
18
+ var t = Symbol.for("react.transitional.element"), s = Symbol.for("react.fragment");
19
+ function r(a, l, o) {
20
+ var m = null;
21
+ if (o !== void 0 && (m = "" + o), l.key !== void 0 && (m = "" + l.key), "key" in l) {
22
+ o = {};
23
+ for (var h in l)
24
+ h !== "key" && (o[h] = l[h]);
25
+ } else o = l;
26
+ return l = o.ref, {
27
+ $$typeof: t,
28
+ type: a,
29
+ key: m,
30
+ ref: l !== void 0 ? l : null,
31
+ props: o
32
+ };
33
+ }
34
+ return z.Fragment = s, z.jsx = r, z.jsxs = r, z;
35
+ }
36
+ var B = {};
37
+ /**
38
+ * @license React
39
+ * react-jsx-runtime.development.js
40
+ *
41
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
42
+ *
43
+ * This source code is licensed under the MIT license found in the
44
+ * LICENSE file in the root directory of this source tree.
45
+ */
46
+ var te;
47
+ function ve() {
48
+ return te || (te = 1, process.env.NODE_ENV !== "production" && (function() {
49
+ function t(n) {
50
+ if (n == null) return null;
51
+ if (typeof n == "function")
52
+ return n.$$typeof === y ? null : n.displayName || n.name || null;
53
+ if (typeof n == "string") return n;
54
+ switch (n) {
55
+ case u:
56
+ return "Fragment";
57
+ case G:
58
+ return "Profiler";
59
+ case _:
60
+ return "StrictMode";
61
+ case A:
62
+ return "Suspense";
63
+ case F:
64
+ return "SuspenseList";
65
+ case v:
66
+ return "Activity";
67
+ }
68
+ if (typeof n == "object")
69
+ switch (typeof n.tag == "number" && console.error(
70
+ "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
71
+ ), n.$$typeof) {
72
+ case i:
73
+ return "Portal";
74
+ case W:
75
+ return n.displayName || "Context";
76
+ case L:
77
+ return (n._context.displayName || "Context") + ".Consumer";
78
+ case J:
79
+ var c = n.render;
80
+ return n = n.displayName, n || (n = c.displayName || c.name || "", n = n !== "" ? "ForwardRef(" + n + ")" : "ForwardRef"), n;
81
+ case p:
82
+ return c = n.displayName || null, c !== null ? c : t(n.type) || "Memo";
83
+ case d:
84
+ c = n._payload, n = n._init;
85
+ try {
86
+ return t(n(c));
87
+ } catch {
88
+ }
89
+ }
90
+ return null;
91
+ }
92
+ function s(n) {
93
+ return "" + n;
94
+ }
95
+ function r(n) {
96
+ try {
97
+ s(n);
98
+ var c = !1;
99
+ } catch {
100
+ c = !0;
101
+ }
102
+ if (c) {
103
+ c = console;
104
+ var j = c.error, S = typeof Symbol == "function" && Symbol.toStringTag && n[Symbol.toStringTag] || n.constructor.name || "Object";
105
+ return j.call(
106
+ c,
107
+ "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
108
+ S
109
+ ), s(n);
110
+ }
111
+ }
112
+ function a(n) {
113
+ if (n === u) return "<>";
114
+ if (typeof n == "object" && n !== null && n.$$typeof === d)
115
+ return "<...>";
116
+ try {
117
+ var c = t(n);
118
+ return c ? "<" + c + ">" : "<...>";
119
+ } catch {
120
+ return "<...>";
121
+ }
122
+ }
123
+ function l() {
124
+ var n = O.A;
125
+ return n === null ? null : n.getOwner();
126
+ }
127
+ function o() {
128
+ return Error("react-stack-top-frame");
129
+ }
130
+ function m(n) {
131
+ if (M.call(n, "key")) {
132
+ var c = Object.getOwnPropertyDescriptor(n, "key").get;
133
+ if (c && c.isReactWarning) return !1;
134
+ }
135
+ return n.key !== void 0;
136
+ }
137
+ function h(n, c) {
138
+ function j() {
139
+ P || (P = !0, console.error(
140
+ "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
141
+ c
142
+ ));
143
+ }
144
+ j.isReactWarning = !0, Object.defineProperty(n, "key", {
145
+ get: j,
146
+ configurable: !0
147
+ });
148
+ }
149
+ function f() {
150
+ var n = t(this.type);
151
+ return I[n] || (I[n] = !0, console.error(
152
+ "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
153
+ )), n = this.props.ref, n !== void 0 ? n : null;
154
+ }
155
+ function b(n, c, j, S, H, K) {
156
+ var k = j.ref;
157
+ return n = {
158
+ $$typeof: w,
159
+ type: n,
160
+ key: c,
161
+ props: j,
162
+ _owner: S
163
+ }, (k !== void 0 ? k : null) !== null ? Object.defineProperty(n, "ref", {
164
+ enumerable: !1,
165
+ get: f
166
+ }) : Object.defineProperty(n, "ref", { enumerable: !1, value: null }), n._store = {}, Object.defineProperty(n._store, "validated", {
167
+ configurable: !1,
168
+ enumerable: !1,
169
+ writable: !0,
170
+ value: 0
171
+ }), Object.defineProperty(n, "_debugInfo", {
172
+ configurable: !1,
173
+ enumerable: !1,
174
+ writable: !0,
175
+ value: null
176
+ }), Object.defineProperty(n, "_debugStack", {
177
+ configurable: !1,
178
+ enumerable: !1,
179
+ writable: !0,
180
+ value: H
181
+ }), Object.defineProperty(n, "_debugTask", {
182
+ configurable: !1,
183
+ enumerable: !1,
184
+ writable: !0,
185
+ value: K
186
+ }), Object.freeze && (Object.freeze(n.props), Object.freeze(n)), n;
187
+ }
188
+ function x(n, c, j, S, H, K) {
189
+ var k = c.children;
190
+ if (k !== void 0)
191
+ if (S)
192
+ if (Y(k)) {
193
+ for (S = 0; S < k.length; S++)
194
+ R(k[S]);
195
+ Object.freeze && Object.freeze(k);
196
+ } else
197
+ console.error(
198
+ "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
199
+ );
200
+ else R(k);
201
+ if (M.call(c, "key")) {
202
+ k = t(n);
203
+ var U = Object.keys(c).filter(function(ce) {
204
+ return ce !== "key";
205
+ });
206
+ S = 0 < U.length ? "{key: someKey, " + U.join(": ..., ") + ": ...}" : "{key: someKey}", V[k + S] || (U = 0 < U.length ? "{" + U.join(": ..., ") + ": ...}" : "{}", console.error(
207
+ `A props object containing a "key" prop is being spread into JSX:
208
+ let props = %s;
209
+ <%s {...props} />
210
+ React keys must be passed directly to JSX without using spread:
211
+ let props = %s;
212
+ <%s key={someKey} {...props} />`,
213
+ S,
214
+ k,
215
+ U,
216
+ k
217
+ ), V[k + S] = !0);
218
+ }
219
+ if (k = null, j !== void 0 && (r(j), k = "" + j), m(c) && (r(c.key), k = "" + c.key), "key" in c) {
220
+ j = {};
221
+ for (var ee in c)
222
+ ee !== "key" && (j[ee] = c[ee]);
223
+ } else j = c;
224
+ return k && h(
225
+ j,
226
+ typeof n == "function" ? n.displayName || n.name || "Unknown" : n
227
+ ), b(
228
+ n,
229
+ k,
230
+ j,
231
+ l(),
232
+ H,
233
+ K
234
+ );
235
+ }
236
+ function R(n) {
237
+ T(n) ? n._store && (n._store.validated = 1) : typeof n == "object" && n !== null && n.$$typeof === d && (n._payload.status === "fulfilled" ? T(n._payload.value) && n._payload.value._store && (n._payload.value._store.validated = 1) : n._store && (n._store.validated = 1));
238
+ }
239
+ function T(n) {
240
+ return typeof n == "object" && n !== null && n.$$typeof === w;
241
+ }
242
+ var E = ue, w = Symbol.for("react.transitional.element"), i = Symbol.for("react.portal"), u = Symbol.for("react.fragment"), _ = Symbol.for("react.strict_mode"), G = Symbol.for("react.profiler"), L = Symbol.for("react.consumer"), W = Symbol.for("react.context"), J = Symbol.for("react.forward_ref"), A = Symbol.for("react.suspense"), F = Symbol.for("react.suspense_list"), p = Symbol.for("react.memo"), d = Symbol.for("react.lazy"), v = Symbol.for("react.activity"), y = Symbol.for("react.client.reference"), O = E.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, M = Object.prototype.hasOwnProperty, Y = Array.isArray, $ = console.createTask ? console.createTask : function() {
243
+ return null;
244
+ };
245
+ E = {
246
+ react_stack_bottom_frame: function(n) {
247
+ return n();
248
+ }
249
+ };
250
+ var P, I = {}, X = E.react_stack_bottom_frame.bind(
251
+ E,
252
+ o
253
+ )(), g = $(a(o)), V = {};
254
+ B.Fragment = u, B.jsx = function(n, c, j) {
255
+ var S = 1e4 > O.recentlyCreatedOwnerStacks++;
256
+ return x(
257
+ n,
258
+ c,
259
+ j,
260
+ !1,
261
+ S ? Error("react-stack-top-frame") : X,
262
+ S ? $(a(n)) : g
263
+ );
264
+ }, B.jsxs = function(n, c, j) {
265
+ var S = 1e4 > O.recentlyCreatedOwnerStacks++;
266
+ return x(
267
+ n,
268
+ c,
269
+ j,
270
+ !0,
271
+ S ? Error("react-stack-top-frame") : X,
272
+ S ? $(a(n)) : g
273
+ );
274
+ };
275
+ })()), B;
276
+ }
277
+ var se;
278
+ function pe() {
279
+ return se || (se = 1, process.env.NODE_ENV === "production" ? Z.exports = he() : Z.exports = ve()), Z.exports;
280
+ }
281
+ var e = pe();
282
+ const ae = de(null);
283
+ function fe({ engine: t, initialSnapshot: s, children: r }) {
284
+ const [a, l] = C(s), o = N(
285
+ (i) => {
286
+ const u = t.selectChoice(i);
287
+ l(u);
288
+ },
289
+ [t]
290
+ ), m = N(
291
+ (i) => {
292
+ const u = t.talkTo(i);
293
+ l(u);
294
+ },
295
+ [t]
296
+ ), h = N(
297
+ (i) => {
298
+ const u = t.takeItem(i);
299
+ l(u);
300
+ },
301
+ [t]
302
+ ), f = N(
303
+ (i) => {
304
+ const u = t.travelTo(i);
305
+ l(u);
306
+ },
307
+ [t]
308
+ ), b = N(
309
+ (i, u) => {
310
+ const _ = t.writeNote(i, u);
311
+ l(_);
312
+ },
313
+ [t]
314
+ ), x = N(
315
+ (i) => {
316
+ const u = t.deleteNote(i);
317
+ l(u);
318
+ },
319
+ [t]
320
+ ), R = N(
321
+ (i) => {
322
+ const u = t.setLocale(i);
323
+ l(u);
324
+ },
325
+ [t]
326
+ ), T = N(() => t.saveGame(), [t]), E = N(
327
+ (i) => {
328
+ const u = t.loadGame(i);
329
+ l(u);
330
+ },
331
+ [t]
332
+ ), w = {
333
+ snapshot: a,
334
+ actions: {
335
+ selectChoice: o,
336
+ talkTo: m,
337
+ takeItem: h,
338
+ travelTo: f,
339
+ writeNote: b,
340
+ deleteNote: x,
341
+ setLocale: R,
342
+ saveGame: T,
343
+ loadGame: E
344
+ }
345
+ };
346
+ return /* @__PURE__ */ e.jsx(ae.Provider, { value: w, children: r });
347
+ }
348
+ function re() {
349
+ const t = me(ae);
350
+ if (!t)
351
+ throw new Error("useGame must be used within a GameProvider");
352
+ return t;
353
+ }
354
+ function le(t, s = {}) {
355
+ var p;
356
+ const {
357
+ audioBasePath: r = "/audio",
358
+ masterVolume: a = 1,
359
+ musicVolume: l = 0.7,
360
+ soundVolume: o = 0.8,
361
+ voiceVolume: m = 1,
362
+ crossfadeDuration: h = 1e3
363
+ } = s, [f, b] = C(a), [x, R] = C(l), [T, E] = C(o), [w, i] = C(m), u = q(null), _ = q(null), G = q(null), L = q(null);
364
+ D(() => {
365
+ const d = new Audio();
366
+ d.loop = !0, u.current = d;
367
+ const v = new Audio();
368
+ return _.current = v, () => {
369
+ L.current && clearInterval(L.current), d.pause(), v.pause(), d.src = "", v.src = "";
370
+ };
371
+ }, []), D(() => {
372
+ const d = u.current;
373
+ if (!d) return;
374
+ const v = t.music;
375
+ if (v !== G.current)
376
+ if (G.current = v, !v)
377
+ J(d, h);
378
+ else {
379
+ const y = `${r}/music/${v}`;
380
+ W(d, y, h);
381
+ }
382
+ d.volume = f * x;
383
+ }, [t.music, f, x, r, h]), D(() => {
384
+ var y;
385
+ const d = _.current;
386
+ if (!d) return;
387
+ const v = (y = t.dialogue) == null ? void 0 : y.voice;
388
+ v && (d.pause(), d.currentTime = 0, d.src = `${r}/voice/${v}`, d.volume = f * w, d.play().catch((O) => {
389
+ console.warn("Voice playback failed:", O);
390
+ }));
391
+ }, [(p = t.dialogue) == null ? void 0 : p.voice, f, w, r]), D(() => {
392
+ t.pendingSounds.length !== 0 && t.pendingSounds.forEach((d) => {
393
+ const v = new Audio(`${r}/sfx/${d}`);
394
+ v.volume = f * T, v.play().catch((y) => {
395
+ console.warn("Sound playback failed:", y);
396
+ });
397
+ });
398
+ }, [t.pendingSounds, f, T, r]);
399
+ const W = (d, v, y) => {
400
+ J(d, y / 2).then(() => {
401
+ d.src = v, d.load(), d.volume = 0, d.play().then(() => {
402
+ A(d, y / 2, f * x);
403
+ }).catch((O) => {
404
+ console.warn("Music playback failed:", O);
405
+ });
406
+ });
407
+ }, J = (d, v) => new Promise((y) => {
408
+ const O = d.volume, M = 20, Y = v / M, $ = O / M;
409
+ let P = 0;
410
+ const I = setInterval(() => {
411
+ P++, d.volume = Math.max(0, O - $ * P), P >= M && (clearInterval(I), d.pause(), d.currentTime = 0, y());
412
+ }, Y);
413
+ L.current = I;
414
+ }), A = (d, v, y) => {
415
+ const M = v / 20, Y = y / 20;
416
+ let $ = 0;
417
+ const P = setInterval(() => {
418
+ $++, d.volume = Math.min(y, Y * $), $ >= 20 && clearInterval(P);
419
+ }, M);
420
+ L.current = P;
421
+ };
422
+ return {
423
+ setMasterVolume: b,
424
+ setMusicVolume: R,
425
+ setSoundVolume: E,
426
+ setVoiceVolume: i,
427
+ stopAll: () => {
428
+ u.current && (u.current.pause(), u.current.currentTime = 0), _.current && (_.current.pause(), _.current.currentTime = 0);
429
+ }
430
+ };
431
+ }
432
+ const xe = {
433
+ click: "click.ogg",
434
+ menuOpen: "menu_open.ogg",
435
+ menuClose: "menu_close.ogg"
436
+ };
437
+ function je(t = {}) {
438
+ const {
439
+ enabled: s = !0,
440
+ basePath: r = "/audio/ui",
441
+ volume: a = 0.5,
442
+ sounds: l = {}
443
+ } = t, [o, m] = C(s), [h, f] = C(a), b = q({ ...xe, ...l }), x = N(
444
+ (i) => {
445
+ if (!o || !i) return;
446
+ const u = new Audio(`${r}/${i}`);
447
+ u.volume = h, u.play().catch(() => {
448
+ });
449
+ },
450
+ [o, h, r]
451
+ ), R = N(
452
+ (i) => {
453
+ const u = b.current[i];
454
+ u && x(u);
455
+ },
456
+ [x]
457
+ ), T = N(() => x(b.current.click), [x]), E = N(() => x(b.current.menuOpen), [x]), w = N(() => x(b.current.menuClose), [x]);
458
+ return {
459
+ playClick: T,
460
+ playMenuOpen: E,
461
+ playMenuClose: w,
462
+ playSound: R,
463
+ setEnabled: m,
464
+ setVolume: f,
465
+ enabled: o,
466
+ volume: h
467
+ };
468
+ }
469
+ function Ne({ dialogue: t, className: s = "" }) {
470
+ return /* @__PURE__ */ e.jsxs("div", { className: `dialogue-box ${s}`, children: [
471
+ t.portrait && /* @__PURE__ */ e.jsx("div", { className: "dialogue-portrait", children: /* @__PURE__ */ e.jsx("img", { src: t.portrait, alt: t.speakerName }) }),
472
+ /* @__PURE__ */ e.jsxs("div", { className: "dialogue-content", children: [
473
+ /* @__PURE__ */ e.jsx("div", { className: "dialogue-speaker", children: t.speakerName }),
474
+ /* @__PURE__ */ e.jsx("div", { className: "dialogue-text", children: t.text })
475
+ ] })
476
+ ] });
477
+ }
478
+ function ge({ choices: t, onSelectChoice: s, className: r = "" }) {
479
+ return t.length === 0 ? null : /* @__PURE__ */ e.jsx("div", { className: `choice-list ${r}`, children: t.map((a) => /* @__PURE__ */ e.jsx(
480
+ "button",
481
+ {
482
+ className: "choice-button",
483
+ onClick: () => s(a.id),
484
+ children: a.text
485
+ },
486
+ a.id
487
+ )) });
488
+ }
489
+ function be({ location: t, className: s = "" }) {
490
+ return /* @__PURE__ */ e.jsxs("div", { className: `location-view ${s}`, children: [
491
+ t.banner && /* @__PURE__ */ e.jsx("div", { className: "location-banner", children: /* @__PURE__ */ e.jsx("img", { src: t.banner, alt: t.name }) }),
492
+ /* @__PURE__ */ e.jsxs("div", { className: "location-content", children: [
493
+ /* @__PURE__ */ e.jsx("h1", { className: "location-name", children: t.name }),
494
+ /* @__PURE__ */ e.jsx("p", { className: "location-description", children: t.description })
495
+ ] })
496
+ ] });
497
+ }
498
+ function Se({
499
+ characters: t,
500
+ onTalkTo: s,
501
+ className: r = ""
502
+ }) {
503
+ return t.length === 0 ? null : /* @__PURE__ */ e.jsxs("div", { className: `character-list ${r}`, children: [
504
+ /* @__PURE__ */ e.jsx("h2", { children: "Characters" }),
505
+ /* @__PURE__ */ e.jsx("div", { className: "character-grid", children: t.map((a) => /* @__PURE__ */ e.jsxs(
506
+ "button",
507
+ {
508
+ className: "character-card",
509
+ onClick: () => s(a.id),
510
+ children: [
511
+ a.portrait && /* @__PURE__ */ e.jsx(
512
+ "img",
513
+ {
514
+ src: a.portrait,
515
+ alt: a.name,
516
+ className: "character-portrait"
517
+ }
518
+ ),
519
+ /* @__PURE__ */ e.jsx("div", { className: "character-name", children: a.name })
520
+ ]
521
+ },
522
+ a.id
523
+ )) })
524
+ ] });
525
+ }
526
+ function ke({ items: t, className: s = "" }) {
527
+ const [r, a] = C(null);
528
+ return /* @__PURE__ */ e.jsxs("div", { className: `inventory ${s}`, children: [
529
+ /* @__PURE__ */ e.jsx("h2", { children: "Inventory" }),
530
+ t.length === 0 ? /* @__PURE__ */ e.jsx("p", { className: "inventory-empty", children: "No items" }) : /* @__PURE__ */ e.jsx("div", { className: "inventory-grid", children: t.map((l) => /* @__PURE__ */ e.jsxs(
531
+ "div",
532
+ {
533
+ className: "inventory-item",
534
+ onClick: () => a(l),
535
+ children: [
536
+ l.icon && /* @__PURE__ */ e.jsx("img", { src: l.icon, alt: l.name, className: "item-icon" }),
537
+ /* @__PURE__ */ e.jsx("div", { className: "item-name", children: l.name })
538
+ ]
539
+ },
540
+ l.id
541
+ )) }),
542
+ r && /* @__PURE__ */ e.jsx("div", { className: "item-modal-overlay", onClick: () => a(null), children: /* @__PURE__ */ e.jsxs("div", { className: "item-modal", onClick: (l) => l.stopPropagation(), children: [
543
+ r.image && /* @__PURE__ */ e.jsx("img", { src: r.image, alt: r.name, className: "item-modal-image" }),
544
+ /* @__PURE__ */ e.jsx("h3", { className: "item-modal-name", children: r.name }),
545
+ /* @__PURE__ */ e.jsx("p", { className: "item-modal-description", children: r.description }),
546
+ /* @__PURE__ */ e.jsx("button", { className: "item-modal-close", onClick: () => a(null), children: "Close" })
547
+ ] }) })
548
+ ] });
549
+ }
550
+ function ye({ quests: t, entries: s, className: r = "" }) {
551
+ return /* @__PURE__ */ e.jsxs("div", { className: `journal ${r}`, children: [
552
+ /* @__PURE__ */ e.jsx("h2", { children: "Journal" }),
553
+ t.length > 0 && /* @__PURE__ */ e.jsxs("div", { className: "journal-quests", children: [
554
+ /* @__PURE__ */ e.jsx("h3", { children: "Active Quests" }),
555
+ t.map((a) => /* @__PURE__ */ e.jsxs("div", { className: "quest-entry", children: [
556
+ /* @__PURE__ */ e.jsx("div", { className: "quest-name", children: a.name }),
557
+ /* @__PURE__ */ e.jsx("div", { className: "quest-description", children: a.description }),
558
+ /* @__PURE__ */ e.jsx("div", { className: "quest-stage", children: a.currentStageDescription })
559
+ ] }, a.id))
560
+ ] }),
561
+ s.length > 0 && /* @__PURE__ */ e.jsxs("div", { className: "journal-entries", children: [
562
+ /* @__PURE__ */ e.jsx("h3", { children: "Entries" }),
563
+ s.map((a) => /* @__PURE__ */ e.jsxs("div", { className: `journal-entry journal-category-${a.category}`, children: [
564
+ /* @__PURE__ */ e.jsx("div", { className: "entry-title", children: a.title }),
565
+ /* @__PURE__ */ e.jsx("div", { className: "entry-text", children: a.text })
566
+ ] }, a.id))
567
+ ] }),
568
+ t.length === 0 && s.length === 0 && /* @__PURE__ */ e.jsx("p", { className: "journal-empty", children: "No entries yet" })
569
+ ] });
570
+ }
571
+ function Ee({ map: t, onTravelTo: s, className: r = "" }) {
572
+ return t ? /* @__PURE__ */ e.jsxs("div", { className: `map-view ${r}`, children: [
573
+ /* @__PURE__ */ e.jsx("h2", { children: t.name }),
574
+ /* @__PURE__ */ e.jsxs("div", { className: "map-container", style: { position: "relative" }, children: [
575
+ t.image && /* @__PURE__ */ e.jsx("img", { src: t.image, alt: t.name, className: "map-image" }),
576
+ t.locations.map((a) => /* @__PURE__ */ e.jsx(
577
+ "button",
578
+ {
579
+ className: `map-marker ${a.isCurrent ? "current" : ""}`,
580
+ style: {
581
+ position: "absolute",
582
+ left: `${a.x}px`,
583
+ top: `${a.y}px`
584
+ },
585
+ onClick: () => !a.isCurrent && s(a.id),
586
+ disabled: a.isCurrent,
587
+ title: a.name,
588
+ children: a.name
589
+ },
590
+ a.id
591
+ ))
592
+ ] })
593
+ ] }) : null;
594
+ }
595
+ function Te({
596
+ notifications: t,
597
+ className: s = ""
598
+ }) {
599
+ return t.length === 0 ? null : /* @__PURE__ */ e.jsx("div", { className: `notification-area ${s}`, children: t.map((r, a) => /* @__PURE__ */ e.jsx("div", { className: "notification", children: r }, a)) });
600
+ }
601
+ function we({
602
+ onSave: t,
603
+ onLoad: s,
604
+ storageKey: r = "doodle-engine-save",
605
+ className: a = ""
606
+ }) {
607
+ const [l, o] = C(""), m = () => {
608
+ const b = t();
609
+ localStorage.setItem(r, JSON.stringify(b)), o("Saved!"), setTimeout(() => o(""), 2e3);
610
+ }, h = () => {
611
+ const b = localStorage.getItem(r);
612
+ if (!b) {
613
+ o("No save found"), setTimeout(() => o(""), 2e3);
614
+ return;
615
+ }
616
+ const x = JSON.parse(b);
617
+ s(x), o("Loaded!"), setTimeout(() => o(""), 2e3);
618
+ }, f = localStorage.getItem(r) !== null;
619
+ return /* @__PURE__ */ e.jsxs("div", { className: `save-load-panel ${a}`, children: [
620
+ /* @__PURE__ */ e.jsx("button", { className: "save-button", onClick: m, children: "Save" }),
621
+ /* @__PURE__ */ e.jsx("button", { className: "load-button", onClick: h, disabled: !f, children: "Load" }),
622
+ l && /* @__PURE__ */ e.jsx("span", { className: "save-load-message", children: l })
623
+ ] });
624
+ }
625
+ function _e({ className: t = "" }) {
626
+ const { snapshot: s, actions: r } = re();
627
+ le(s);
628
+ const a = Object.entries(s.variables).filter(([l]) => !l.startsWith("_"));
629
+ return /* @__PURE__ */ e.jsxs("div", { className: `game-renderer ${t}`, children: [
630
+ /* @__PURE__ */ e.jsx(Te, { notifications: s.notifications }),
631
+ /* @__PURE__ */ e.jsxs("div", { className: "game-main", children: [
632
+ /* @__PURE__ */ e.jsx(be, { location: s.location }),
633
+ s.dialogue && /* @__PURE__ */ e.jsxs("div", { className: "dialogue-container", children: [
634
+ /* @__PURE__ */ e.jsx(Ne, { dialogue: s.dialogue }),
635
+ /* @__PURE__ */ e.jsx(ge, { choices: s.choices, onSelectChoice: r.selectChoice })
636
+ ] }),
637
+ !s.dialogue && /* @__PURE__ */ e.jsx(
638
+ Se,
639
+ {
640
+ characters: s.charactersHere,
641
+ onTalkTo: r.talkTo
642
+ }
643
+ )
644
+ ] }),
645
+ /* @__PURE__ */ e.jsxs("div", { className: "game-sidebar", children: [
646
+ /* @__PURE__ */ e.jsx(we, { onSave: r.saveGame, onLoad: r.loadGame }),
647
+ a.length > 0 && /* @__PURE__ */ e.jsxs("div", { className: "resources", children: [
648
+ /* @__PURE__ */ e.jsx("h2", { children: "Resources" }),
649
+ /* @__PURE__ */ e.jsx("ul", { className: "resources-list", children: a.map(([l, o]) => /* @__PURE__ */ e.jsxs("li", { className: "resource-entry", children: [
650
+ /* @__PURE__ */ e.jsx("span", { className: "resource-name", children: l }),
651
+ /* @__PURE__ */ e.jsx("span", { className: "resource-value", children: o })
652
+ ] }, l)) })
653
+ ] }),
654
+ s.party.length > 0 && /* @__PURE__ */ e.jsxs("div", { className: "party", children: [
655
+ /* @__PURE__ */ e.jsx("h2", { children: "Party" }),
656
+ /* @__PURE__ */ e.jsx("ul", { className: "party-list", children: s.party.map((l) => /* @__PURE__ */ e.jsx("li", { className: "party-member", children: /* @__PURE__ */ e.jsx("span", { className: "party-member-name", children: l.name }) }, l.id)) })
657
+ ] }),
658
+ /* @__PURE__ */ e.jsx(ke, { items: s.inventory }),
659
+ /* @__PURE__ */ e.jsx(ye, { quests: s.quests, entries: s.journal }),
660
+ s.map && /* @__PURE__ */ e.jsx(Ee, { map: s.map, onTravelTo: r.travelTo })
661
+ ] })
662
+ ] });
663
+ }
664
+ function Ce({
665
+ logoSrc: t,
666
+ title: s,
667
+ onComplete: r,
668
+ duration: a = 2e3,
669
+ className: l = ""
670
+ }) {
671
+ return D(() => {
672
+ const o = setTimeout(r, a);
673
+ return () => clearTimeout(o);
674
+ }, [r, a]), /* @__PURE__ */ e.jsxs("div", { className: `splash-screen ${l}`, onClick: r, children: [
675
+ t && /* @__PURE__ */ e.jsx("img", { src: t, alt: s || "", className: "splash-logo" }),
676
+ s && /* @__PURE__ */ e.jsx("h1", { className: "splash-title", children: s }),
677
+ /* @__PURE__ */ e.jsx("div", { className: "splash-loading", children: "Loading..." })
678
+ ] });
679
+ }
680
+ function Re({
681
+ title: t = "Doodle Engine",
682
+ subtitle: s,
683
+ logoSrc: r,
684
+ hasSaveData: a,
685
+ onNewGame: l,
686
+ onContinue: o,
687
+ onSettings: m,
688
+ className: h = ""
689
+ }) {
690
+ return /* @__PURE__ */ e.jsxs("div", { className: `title-screen ${h}`, children: [
691
+ r && /* @__PURE__ */ e.jsx("img", { src: r, alt: t, className: "title-logo" }),
692
+ /* @__PURE__ */ e.jsx("h1", { className: "title-heading", children: t }),
693
+ s && /* @__PURE__ */ e.jsx("p", { className: "title-subtitle", children: s }),
694
+ /* @__PURE__ */ e.jsxs("div", { className: "title-menu", children: [
695
+ /* @__PURE__ */ e.jsx("button", { className: "title-button", onClick: l, children: "New Game" }),
696
+ a && /* @__PURE__ */ e.jsx("button", { className: "title-button", onClick: o, children: "Continue" }),
697
+ /* @__PURE__ */ e.jsx("button", { className: "title-button", onClick: m, children: "Settings" })
698
+ ] })
699
+ ] });
700
+ }
701
+ function Ae({
702
+ onResume: t,
703
+ onSave: s,
704
+ onLoad: r,
705
+ onSettings: a,
706
+ onQuitToTitle: l,
707
+ className: o = ""
708
+ }) {
709
+ return /* @__PURE__ */ e.jsx("div", { className: `pause-menu-overlay ${o}`, children: /* @__PURE__ */ e.jsxs("div", { className: "pause-menu", children: [
710
+ /* @__PURE__ */ e.jsx("h2", { className: "pause-title", children: "Paused" }),
711
+ /* @__PURE__ */ e.jsxs("div", { className: "pause-buttons", children: [
712
+ /* @__PURE__ */ e.jsx("button", { className: "pause-button", onClick: t, children: "Resume" }),
713
+ /* @__PURE__ */ e.jsx("button", { className: "pause-button", onClick: s, children: "Save" }),
714
+ /* @__PURE__ */ e.jsx("button", { className: "pause-button", onClick: r, children: "Load" }),
715
+ /* @__PURE__ */ e.jsx("button", { className: "pause-button", onClick: a, children: "Settings" }),
716
+ /* @__PURE__ */ e.jsx("button", { className: "pause-button pause-button-quit", onClick: l, children: "Quit to Title" })
717
+ ] })
718
+ ] }) });
719
+ }
720
+ function oe({
721
+ audioControls: t,
722
+ uiSoundControls: s,
723
+ availableLocales: r,
724
+ currentLocale: a,
725
+ onLocaleChange: l,
726
+ onBack: o,
727
+ className: m = ""
728
+ }) {
729
+ return /* @__PURE__ */ e.jsxs("div", { className: `settings-panel ${m}`, children: [
730
+ /* @__PURE__ */ e.jsx("h2", { className: "settings-title", children: "Settings" }),
731
+ /* @__PURE__ */ e.jsxs("div", { className: "settings-section", children: [
732
+ /* @__PURE__ */ e.jsx("h3", { children: "Audio" }),
733
+ /* @__PURE__ */ e.jsx(
734
+ Q,
735
+ {
736
+ label: "Master",
737
+ value: 1,
738
+ onChange: t.setMasterVolume
739
+ }
740
+ ),
741
+ /* @__PURE__ */ e.jsx(
742
+ Q,
743
+ {
744
+ label: "Music",
745
+ value: 0.7,
746
+ onChange: t.setMusicVolume
747
+ }
748
+ ),
749
+ /* @__PURE__ */ e.jsx(
750
+ Q,
751
+ {
752
+ label: "Sound Effects",
753
+ value: 0.8,
754
+ onChange: t.setSoundVolume
755
+ }
756
+ ),
757
+ /* @__PURE__ */ e.jsx(
758
+ Q,
759
+ {
760
+ label: "Voice",
761
+ value: 1,
762
+ onChange: t.setVoiceVolume
763
+ }
764
+ ),
765
+ s && /* @__PURE__ */ e.jsx(
766
+ Q,
767
+ {
768
+ label: "UI Sounds",
769
+ value: s.volume,
770
+ onChange: s.setVolume
771
+ }
772
+ )
773
+ ] }),
774
+ r && r.length > 1 && l && /* @__PURE__ */ e.jsxs("div", { className: "settings-section", children: [
775
+ /* @__PURE__ */ e.jsx("h3", { children: "Language" }),
776
+ /* @__PURE__ */ e.jsx(
777
+ "select",
778
+ {
779
+ className: "settings-locale-select",
780
+ value: a,
781
+ onChange: (h) => l(h.target.value),
782
+ children: r.map((h) => /* @__PURE__ */ e.jsx("option", { value: h.code, children: h.label }, h.code))
783
+ }
784
+ )
785
+ ] }),
786
+ /* @__PURE__ */ e.jsx("button", { className: "settings-back-button", onClick: o, children: "Back" })
787
+ ] });
788
+ }
789
+ function Q({
790
+ label: t,
791
+ value: s,
792
+ onChange: r
793
+ }) {
794
+ return /* @__PURE__ */ e.jsxs("div", { className: "volume-slider", children: [
795
+ /* @__PURE__ */ e.jsx("label", { className: "volume-label", children: t }),
796
+ /* @__PURE__ */ e.jsx(
797
+ "input",
798
+ {
799
+ type: "range",
800
+ min: "0",
801
+ max: "1",
802
+ step: "0.05",
803
+ defaultValue: s,
804
+ onChange: (a) => r(parseFloat(a.target.value)),
805
+ className: "volume-input"
806
+ }
807
+ )
808
+ ] });
809
+ }
810
+ function Oe({
811
+ src: t,
812
+ basePath: s = "/video",
813
+ onComplete: r,
814
+ className: a = ""
815
+ }) {
816
+ const l = q(null);
817
+ return D(() => {
818
+ const o = (m) => {
819
+ (m.key === "Escape" || m.key === " " || m.key === "Enter") && (m.preventDefault(), r());
820
+ };
821
+ return window.addEventListener("keydown", o), () => window.removeEventListener("keydown", o);
822
+ }, [r]), /* @__PURE__ */ e.jsxs("div", { className: `video-player-overlay ${a}`, children: [
823
+ /* @__PURE__ */ e.jsx(
824
+ "video",
825
+ {
826
+ ref: l,
827
+ src: `${s}/${t}`,
828
+ autoPlay: !0,
829
+ onEnded: r,
830
+ className: "video-player-video"
831
+ }
832
+ ),
833
+ /* @__PURE__ */ e.jsx(
834
+ "button",
835
+ {
836
+ className: "video-player-skip-button",
837
+ onClick: r,
838
+ children: "Skip"
839
+ }
840
+ )
841
+ ] });
842
+ }
843
+ function Me({
844
+ registry: t,
845
+ config: s,
846
+ title: r = "Doodle Engine",
847
+ subtitle: a,
848
+ logoSrc: l,
849
+ splashDuration: o = 2e3,
850
+ uiSounds: m,
851
+ audioOptions: h,
852
+ storageKey: f = "doodle-engine-save",
853
+ availableLocales: b,
854
+ videoBasePath: x = "/video",
855
+ className: R = ""
856
+ }) {
857
+ const [T, E] = C(o > 0 ? "splash" : "title"), [w, i] = C(!1), [u, _] = C(!1), [G, L] = C("title"), [W, J] = C(null), [A, F] = C(null), p = je(
858
+ m === !1 ? { enabled: !1 } : m
859
+ ), d = localStorage.getItem(f) !== null, v = N(() => {
860
+ const g = {
861
+ currentLocation: s.startLocation,
862
+ currentTime: { ...s.startTime },
863
+ flags: { ...s.startFlags },
864
+ variables: { ...s.startVariables },
865
+ inventory: [...s.startInventory],
866
+ questProgress: {},
867
+ unlockedJournalEntries: [],
868
+ playerNotes: [],
869
+ dialogueState: null,
870
+ characterState: {},
871
+ itemLocations: {},
872
+ mapEnabled: !0,
873
+ notifications: [],
874
+ pendingSounds: [],
875
+ pendingVideo: null,
876
+ currentLocale: "en"
877
+ };
878
+ return new ie(t, g);
879
+ }, [t, s]), y = N(() => {
880
+ p.playClick();
881
+ const g = v(), V = g.newGame(s);
882
+ F({ engine: g, snapshot: V }), E("playing");
883
+ }, [v, s, p]), O = N(() => {
884
+ p.playClick();
885
+ const g = localStorage.getItem(f);
886
+ if (!g) return;
887
+ const V = JSON.parse(g), n = v(), c = n.loadGame(V);
888
+ F({ engine: n, snapshot: c }), E("playing");
889
+ }, [v, f, p]), M = N(() => {
890
+ if (!A) return;
891
+ p.playClick();
892
+ const g = A.engine.saveGame();
893
+ localStorage.setItem(f, JSON.stringify(g)), i(!1);
894
+ }, [A, f, p]), Y = N(() => {
895
+ const g = localStorage.getItem(f);
896
+ if (!g || !A) return;
897
+ p.playClick();
898
+ const V = JSON.parse(g), n = A.engine.loadGame(V);
899
+ F({ engine: A.engine, snapshot: n }), i(!1);
900
+ }, [A, f, p]), $ = N(() => {
901
+ p.playClick(), i(!1), _(!1), F(null), E("title");
902
+ }, [p]), P = N((g) => {
903
+ p.playMenuOpen(), L(g), _(!0), g === "pause" && i(!1);
904
+ }, [p]), I = N(() => {
905
+ p.playMenuClose(), _(!1), G === "pause" && i(!0);
906
+ }, [G, p]);
907
+ D(() => {
908
+ if (T !== "playing") return;
909
+ const g = (V) => {
910
+ V.key === "Escape" && (V.preventDefault(), u ? I() : (w ? p.playMenuClose() : p.playMenuOpen(), i((n) => !n)));
911
+ };
912
+ return window.addEventListener("keydown", g), () => window.removeEventListener("keydown", g);
913
+ }, [T, w, u, I, p]);
914
+ const X = {
915
+ setMasterVolume: () => {
916
+ },
917
+ setMusicVolume: () => {
918
+ },
919
+ setSoundVolume: () => {
920
+ },
921
+ setVoiceVolume: () => {
922
+ },
923
+ stopAll: () => {
924
+ }
925
+ };
926
+ return T === "splash" ? /* @__PURE__ */ e.jsx("div", { className: `game-shell ${R}`, children: /* @__PURE__ */ e.jsx(
927
+ Ce,
928
+ {
929
+ logoSrc: l,
930
+ title: r,
931
+ onComplete: () => E("title"),
932
+ duration: o
933
+ }
934
+ ) }) : T === "title" ? /* @__PURE__ */ e.jsx("div", { className: `game-shell ${R}`, children: u ? /* @__PURE__ */ e.jsx(
935
+ oe,
936
+ {
937
+ audioControls: X,
938
+ uiSoundControls: m !== !1 ? p : void 0,
939
+ availableLocales: b,
940
+ onBack: I
941
+ }
942
+ ) : /* @__PURE__ */ e.jsx(
943
+ Re,
944
+ {
945
+ title: r,
946
+ subtitle: a,
947
+ logoSrc: l,
948
+ hasSaveData: d,
949
+ onNewGame: y,
950
+ onContinue: O,
951
+ onSettings: () => P("title")
952
+ }
953
+ ) }) : A ? /* @__PURE__ */ e.jsx("div", { className: `game-shell ${R}`, children: /* @__PURE__ */ e.jsx(fe, { engine: A.engine, initialSnapshot: A.snapshot, children: /* @__PURE__ */ e.jsx(
954
+ Pe,
955
+ {
956
+ audioOptions: h,
957
+ uiSoundControls: m !== !1 ? p : void 0,
958
+ showPauseMenu: w,
959
+ showSettings: u,
960
+ availableLocales: b,
961
+ videoBasePath: x,
962
+ pendingVideo: W,
963
+ setPendingVideo: J,
964
+ onPause: () => {
965
+ p.playMenuOpen(), i(!0);
966
+ },
967
+ onResume: () => {
968
+ p.playMenuClose(), i(!1);
969
+ },
970
+ onSave: M,
971
+ onLoad: Y,
972
+ onSettings: () => P("pause"),
973
+ onQuitToTitle: $,
974
+ onCloseSettings: I
975
+ }
976
+ ) }) }) : null;
977
+ }
978
+ function Pe({
979
+ audioOptions: t,
980
+ uiSoundControls: s,
981
+ showPauseMenu: r,
982
+ showSettings: a,
983
+ availableLocales: l,
984
+ videoBasePath: o,
985
+ pendingVideo: m,
986
+ setPendingVideo: h,
987
+ onPause: f,
988
+ onResume: b,
989
+ onSave: x,
990
+ onLoad: R,
991
+ onSettings: T,
992
+ onQuitToTitle: E,
993
+ onCloseSettings: w
994
+ }) {
995
+ const { snapshot: i, actions: u } = re(), _ = le(i, t);
996
+ return D(() => {
997
+ i.pendingVideo && h(i.pendingVideo);
998
+ }, [i.pendingVideo, h]), /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
999
+ m && /* @__PURE__ */ e.jsx(
1000
+ Oe,
1001
+ {
1002
+ src: m,
1003
+ basePath: o,
1004
+ onComplete: () => h(null)
1005
+ }
1006
+ ),
1007
+ /* @__PURE__ */ e.jsx(_e, {}),
1008
+ !r && !a && !m && /* @__PURE__ */ e.jsx(
1009
+ "button",
1010
+ {
1011
+ className: "game-shell-menu-button",
1012
+ onClick: f,
1013
+ "aria-label": "Menu",
1014
+ children: "Menu"
1015
+ }
1016
+ ),
1017
+ r && /* @__PURE__ */ e.jsx(
1018
+ Ae,
1019
+ {
1020
+ onResume: b,
1021
+ onSave: x,
1022
+ onLoad: R,
1023
+ onSettings: T,
1024
+ onQuitToTitle: E
1025
+ }
1026
+ ),
1027
+ a && /* @__PURE__ */ e.jsx(
1028
+ oe,
1029
+ {
1030
+ audioControls: _,
1031
+ uiSoundControls: s,
1032
+ availableLocales: l,
1033
+ currentLocale: (i.time, void 0),
1034
+ onLocaleChange: u.setLocale,
1035
+ onBack: w
1036
+ }
1037
+ )
1038
+ ] });
1039
+ }
1040
+ export {
1041
+ Se as CharacterList,
1042
+ ge as ChoiceList,
1043
+ Ne as DialogueBox,
1044
+ ae as GameContext,
1045
+ fe as GameProvider,
1046
+ _e as GameRenderer,
1047
+ Me as GameShell,
1048
+ ke as Inventory,
1049
+ ye as Journal,
1050
+ be as LocationView,
1051
+ Ee as MapView,
1052
+ Te as NotificationArea,
1053
+ Ae as PauseMenu,
1054
+ we as SaveLoadPanel,
1055
+ oe as SettingsPanel,
1056
+ Ce as SplashScreen,
1057
+ Re as TitleScreen,
1058
+ De as VERSION,
1059
+ Oe as VideoPlayer,
1060
+ le as useAudioManager,
1061
+ re as useGame,
1062
+ je as useUISounds
1063
+ };