@doodle-engine/react 0.0.8 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @doodle-engine/react
2
2
 
3
+ ## 0.0.10
4
+
5
+ ### Patch Changes
6
+
7
+ - ecfe7ba: Added Interludes
8
+ - Updated dependencies [ecfe7ba]
9
+ - @doodle-engine/core@0.0.10
10
+
11
+ ## 0.0.9
12
+
13
+ ### Patch Changes
14
+
15
+ - 90cd5a7: Update validator and dev tools, added loading screen
16
+ - Updated dependencies [90cd5a7]
17
+ - @doodle-engine/core@0.0.9
18
+
3
19
  ## 0.0.8
4
20
 
5
21
  ### Patch Changes
@@ -4,7 +4,7 @@
4
4
  * Holds the engine instance and current snapshot state.
5
5
  * Provides action methods that update the snapshot when called.
6
6
  */
7
- import React, { type ReactNode } from 'react';
7
+ import { type ReactNode } from 'react';
8
8
  import { Engine } from '@doodle-engine/core';
9
9
  import type { Snapshot, SaveData } from '@doodle-engine/core';
10
10
  export interface GameContextValue {
@@ -19,9 +19,10 @@ export interface GameContextValue {
19
19
  setLocale: (locale: string) => void;
20
20
  saveGame: () => SaveData;
21
21
  loadGame: (saveData: SaveData) => void;
22
+ dismissInterlude: () => void;
22
23
  };
23
24
  }
24
- export declare const GameContext: React.Context<GameContextValue | null>;
25
+ export declare const GameContext: import("react").Context<GameContextValue | null>;
25
26
  export interface GameProviderProps {
26
27
  /** Engine instance (already initialized with registry) */
27
28
  engine: Engine;
@@ -29,10 +30,20 @@ export interface GameProviderProps {
29
30
  initialSnapshot: Snapshot;
30
31
  /** Children components */
31
32
  children: ReactNode;
33
+ /**
34
+ * Enable the browser console debugging API (window.doodle).
35
+ * When true, you can type doodle.setFlag(), doodle.teleport(), etc.
36
+ * in the browser DevTools console while testing your game.
37
+ *
38
+ * Pass import.meta.env.DEV to automatically enable in development
39
+ * and disable in production builds:
40
+ * <GameProvider devTools={import.meta.env.DEV} ...>
41
+ */
42
+ devTools?: boolean;
32
43
  }
33
44
  /**
34
45
  * Provider component that wraps the game UI
35
46
  * Manages engine state and provides actions to child components
36
47
  */
37
- export declare function GameProvider({ engine, initialSnapshot, children }: GameProviderProps): import("react/jsx-runtime").JSX.Element;
48
+ export declare function GameProvider({ engine, initialSnapshot, children, devTools }: GameProviderProps): import("react/jsx-runtime").JSX.Element;
38
49
  //# sourceMappingURL=GameProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GameProvider.d.ts","sourceRoot":"","sources":["../src/GameProvider.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,EAAmD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAC9F,OAAO,EAAE,MAAM,EAAkB,MAAM,qBAAqB,CAAA;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,QAAQ,CAAA;IAClB,OAAO,EAAE;QACP,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;QACxC,MAAM,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAA;QACrC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;QAClC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;QACtC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;QAChD,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;QACpC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;QACnC,QAAQ,EAAE,MAAM,QAAQ,CAAA;QACxB,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAA;KACvC,CAAA;CACF;AAED,eAAO,MAAM,WAAW,wCAA+C,CAAA;AAEvE,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAA;IACd,kDAAkD;IAClD,eAAe,EAAE,QAAQ,CAAA;IACzB,0BAA0B;IAC1B,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,EAAE,iBAAiB,2CA4GpF"}
1
+ {"version":3,"file":"GameProvider.d.ts","sourceRoot":"","sources":["../src/GameProvider.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAmD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACvF,OAAO,EAAE,MAAM,EAAkB,MAAM,qBAAqB,CAAA;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,QAAQ,CAAA;IAClB,OAAO,EAAE;QACP,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;QACxC,MAAM,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAA;QACrC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;QAClC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;QACtC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;QAChD,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;QACpC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;QACnC,QAAQ,EAAE,MAAM,QAAQ,CAAA;QACxB,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAA;QACtC,gBAAgB,EAAE,MAAM,IAAI,CAAA;KAC7B,CAAA;CACF;AAED,eAAO,MAAM,WAAW,kDAA+C,CAAA;AAEvE,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAA;IACd,kDAAkD;IAClD,eAAe,EAAE,QAAQ,CAAA;IACzB,0BAA0B;IAC1B,QAAQ,EAAE,SAAS,CAAA;IACnB;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAgB,EAAE,EAAE,iBAAiB,2CA+GtG"}
@@ -1 +1 @@
1
- {"version":3,"file":"GameRenderer.d.ts","sourceRoot":"","sources":["../src/GameRenderer.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAcH,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,YAAY,CAAC,EAAE,SAAc,EAAE,EAAE,iBAAiB,2CAgEjE"}
1
+ {"version":3,"file":"GameRenderer.d.ts","sourceRoot":"","sources":["../src/GameRenderer.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAeH,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,YAAY,CAAC,EAAE,SAAc,EAAE,EAAE,iBAAiB,2CAuEjE"}
@@ -36,6 +36,16 @@ export interface GameShellProps {
36
36
  videoBasePath?: string;
37
37
  /** CSS class */
38
38
  className?: string;
39
+ /**
40
+ * Enable the browser console debugging API (window.doodle).
41
+ * When true, you can type doodle.setFlag(), doodle.teleport(), etc.
42
+ * in the browser DevTools console while testing your game.
43
+ *
44
+ * Pass import.meta.env.DEV to automatically enable in development
45
+ * and disable in production builds:
46
+ * <GameShell devTools={import.meta.env.DEV} ...>
47
+ */
48
+ devTools?: boolean;
39
49
  }
40
- export declare function GameShell({ registry, config, title, subtitle, logoSrc, splashDuration, uiSounds: uiSoundsConfig, audioOptions, storageKey, availableLocales, videoBasePath, className, }: GameShellProps): import("react/jsx-runtime").JSX.Element | null;
50
+ export declare function GameShell({ registry, config, title, subtitle, logoSrc, splashDuration, uiSounds: uiSoundsConfig, audioOptions, storageKey, availableLocales, videoBasePath, className, devTools, }: GameShellProps): import("react/jsx-runtime").JSX.Element | null;
41
51
  //# sourceMappingURL=GameShell.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GameShell.d.ts","sourceRoot":"","sources":["../src/GameShell.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAiC,MAAM,qBAAqB,CAAA;AAKrG,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,qBAAqB,CAAA;AACzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AASlE,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,QAAQ,EAAE,eAAe,CAAA;IACzB,sCAAsC;IACtC,MAAM,EAAE,UAAU,CAAA;IAClB,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oBAAoB;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,aAAa,GAAG,KAAK,CAAA;IAChC,4BAA4B;IAC5B,YAAY,CAAC,EAAE,mBAAmB,CAAA;IAClC,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACpD,sBAAsB;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,gBAAgB;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,MAAM,EACN,KAAuB,EACvB,QAAQ,EACR,OAAO,EACP,cAAqB,EACrB,QAAQ,EAAE,cAAc,EACxB,YAAY,EACZ,UAAiC,EACjC,gBAAgB,EAChB,aAAwB,EACxB,SAAc,GACf,EAAE,cAAc,kDA0MhB"}
1
+ {"version":3,"file":"GameShell.d.ts","sourceRoot":"","sources":["../src/GameShell.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAiC,MAAM,qBAAqB,CAAA;AAKrG,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,qBAAqB,CAAA;AACzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AASlE,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,QAAQ,EAAE,eAAe,CAAA;IACzB,sCAAsC;IACtC,MAAM,EAAE,UAAU,CAAA;IAClB,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oBAAoB;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,aAAa,GAAG,KAAK,CAAA;IAChC,4BAA4B;IAC5B,YAAY,CAAC,EAAE,mBAAmB,CAAA;IAClC,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACpD,sBAAsB;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,gBAAgB;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,MAAM,EACN,KAAuB,EACvB,QAAQ,EACR,OAAO,EACP,cAAqB,EACrB,QAAQ,EAAE,cAAc,EACxB,YAAY,EACZ,UAAiC,EACjC,gBAAgB,EAChB,aAAwB,EACxB,SAAc,EACd,QAAgB,GACjB,EAAE,cAAc,kDA2MhB"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Interlude - Full-screen narrative text scene
3
+ *
4
+ * Displays a background image with scrolling text, like chapter cards
5
+ * in Baldur's Gate. The player can skip at any time.
6
+ */
7
+ import type { SnapshotInterlude } from '@doodle-engine/core';
8
+ export interface InterludeProps {
9
+ interlude: SnapshotInterlude;
10
+ onDismiss: () => void;
11
+ }
12
+ export declare function Interlude({ interlude, onDismiss }: InterludeProps): import("react/jsx-runtime").JSX.Element;
13
+ //# sourceMappingURL=Interlude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Interlude.d.ts","sourceRoot":"","sources":["../../src/components/Interlude.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAE5D,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,iBAAiB,CAAA;IAC5B,SAAS,EAAE,MAAM,IAAI,CAAA;CACtB;AAED,wBAAgB,SAAS,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,cAAc,2CA8GjE"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * LoadingScreen - Displayed while game content is loading
3
+ *
4
+ * Simple default loading state. Replace with your own component or
5
+ * style it with CSS using the className prop.
6
+ */
7
+ export interface LoadingScreenProps {
8
+ /** Optional message to display */
9
+ message?: string;
10
+ /** CSS class for custom styling */
11
+ className?: string;
12
+ }
13
+ export declare function LoadingScreen({ message, className }: LoadingScreenProps): import("react/jsx-runtime").JSX.Element;
14
+ //# sourceMappingURL=LoadingScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoadingScreen.d.ts","sourceRoot":"","sources":["../../src/components/LoadingScreen.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,kBAAkB;IACjC,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mCAAmC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,aAAa,CAAC,EAAE,OAAsB,EAAE,SAAc,EAAE,EAAE,kBAAkB,2CAS3F"}
package/dist/index.d.ts CHANGED
@@ -35,6 +35,10 @@ export { SaveLoadPanel } from './components/SaveLoadPanel';
35
35
  export type { SaveLoadPanelProps } from './components/SaveLoadPanel';
36
36
  export { VideoPlayer } from './components/VideoPlayer';
37
37
  export type { VideoPlayerProps } from './components/VideoPlayer';
38
+ export { Interlude } from './components/Interlude';
39
+ export type { InterludeProps } from './components/Interlude';
40
+ export { LoadingScreen } from './components/LoadingScreen';
41
+ export type { LoadingScreenProps } from './components/LoadingScreen';
38
42
  export { SplashScreen } from './components/SplashScreen';
39
43
  export type { SplashScreenProps } from './components/SplashScreen';
40
44
  export { TitleScreen } from './components/TitleScreen';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAG7C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC1D,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAGzE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AACxF,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAGzE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAGvD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGjD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAE9D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAElE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAC9C,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAExD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAC9C,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAExD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AAE1E,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAElE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAG7C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC1D,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAGzE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AACxF,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAGzE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAGvD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGjD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAE9D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAElE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAC9C,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAExD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAC9C,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAExD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AAE1E,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAEpE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAElE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA"}
package/dist/react.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const re=require("@doodle-engine/core"),o=require("react");var Q={exports:{}},U={};/**
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Z=require("@doodle-engine/core"),l=require("react");var H={exports:{}},q={};/**
2
2
  * @license React
3
3
  * react-jsx-runtime.production.js
4
4
  *
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * This source code is licensed under the MIT license found in the
8
8
  * LICENSE file in the root directory of this source tree.
9
- */var te;function ke(){if(te)return U;te=1;var t=Symbol.for("react.transitional.element"),n=Symbol.for("react.fragment");function r(a,l,c){var f=null;if(c!==void 0&&(f=""+c),l.key!==void 0&&(f=""+l.key),"key"in l){c={};for(var h in l)h!=="key"&&(c[h]=l[h])}else c=l;return l=c.ref,{$$typeof:t,type:a,key:f,ref:l!==void 0?l:null,props:c}}return U.Fragment=n,U.jsx=r,U.jsxs=r,U}var q={};/**
9
+ */var se;function ye(){if(se)return q;se=1;var t=Symbol.for("react.transitional.element"),s=Symbol.for("react.fragment");function r(a,o,c){var m=null;if(c!==void 0&&(m=""+c),o.key!==void 0&&(m=""+o.key),"key"in o){c={};for(var f in o)f!=="key"&&(c[f]=o[f])}else c=o;return o=c.ref,{$$typeof:t,type:a,key:m,ref:o!==void 0?o:null,props:c}}return q.Fragment=s,q.jsx=r,q.jsxs=r,q}var U={};/**
10
10
  * @license React
11
11
  * react-jsx-runtime.development.js
12
12
  *
@@ -14,9 +14,10 @@
14
14
  *
15
15
  * This source code is licensed under the MIT license found in the
16
16
  * LICENSE file in the root directory of this source tree.
17
- */var ne;function Ee(){return ne||(ne=1,process.env.NODE_ENV!=="production"&&(function(){function t(s){if(s==null)return null;if(typeof s=="function")return s.$$typeof===E?null:s.displayName||s.name||null;if(typeof s=="string")return s;switch(s){case d:return"Fragment";case L:return"Profiler";case w:return"StrictMode";case _:return"Suspense";case D:return"SuspenseList";case v:return"Activity"}if(typeof s=="object")switch(typeof s.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),s.$$typeof){case u:return"Portal";case J:return s.displayName||"Context";case I:return(s._context.displayName||"Context")+".Consumer";case F:var i=s.render;return s=s.displayName,s||(s=i.displayName||i.name||"",s=s!==""?"ForwardRef("+s+")":"ForwardRef"),s;case p:return i=s.displayName||null,i!==null?i:t(s.type)||"Memo";case m:i=s._payload,s=s._init;try{return t(s(i))}catch{}}return null}function n(s){return""+s}function r(s){try{n(s);var i=!1}catch{i=!0}if(i){i=console;var b=i.error,S=typeof Symbol=="function"&&Symbol.toStringTag&&s[Symbol.toStringTag]||s.constructor.name||"Object";return b.call(i,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",S),n(s)}}function a(s){if(s===d)return"<>";if(typeof s=="object"&&s!==null&&s.$$typeof===m)return"<...>";try{var i=t(s);return i?"<"+i+">":"<...>"}catch{return"<...>"}}function l(){var s=P.A;return s===null?null:s.getOwner()}function c(){return Error("react-stack-top-frame")}function f(s){if($.call(s,"key")){var i=Object.getOwnPropertyDescriptor(s,"key").get;if(i&&i.isReactWarning)return!1}return s.key!==void 0}function h(s,i){function b(){A||(A=!0,console.error("%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)",i))}b.isReactWarning=!0,Object.defineProperty(s,"key",{get:b,configurable:!0})}function x(){var s=t(this.type);return M[s]||(M[s]=!0,console.error("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.")),s=this.props.ref,s!==void 0?s:null}function g(s,i,b,S,z,X){var k=b.ref;return s={$$typeof:T,type:s,key:i,props:b,_owner:S},(k!==void 0?k:null)!==null?Object.defineProperty(s,"ref",{enumerable:!1,get:x}):Object.defineProperty(s,"ref",{enumerable:!1,value:null}),s._store={},Object.defineProperty(s._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(s,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(s,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:z}),Object.defineProperty(s,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:X}),Object.freeze&&(Object.freeze(s.props),Object.freeze(s)),s}function j(s,i,b,S,z,X){var k=i.children;if(k!==void 0)if(S)if(G(k)){for(S=0;S<k.length;S++)R(k[S]);Object.freeze&&Object.freeze(k)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else R(k);if($.call(i,"key")){k=t(s);var Y=Object.keys(i).filter(function(Se){return Se!=="key"});S=0<Y.length?"{key: someKey, "+Y.join(": ..., ")+": ...}":"{key: someKey}",V[k+S]||(Y=0<Y.length?"{"+Y.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
17
+ */var ae;function Ee(){return ae||(ae=1,process.env.NODE_ENV!=="production"&&(function(){function t(n){if(n==null)return null;if(typeof n=="function")return n.$$typeof===y?null:n.displayName||n.name||null;if(typeof n=="string")return n;switch(n){case v:return"Fragment";case j:return"Profiler";case d:return"StrictMode";case J:return"Suspense";case A:return"SuspenseList";case g:return"Activity"}if(typeof n=="object")switch(typeof n.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),n.$$typeof){case p:return"Portal";case L:return n.displayName||"Context";case _:return(n._context.displayName||"Context")+".Consumer";case F:var u=n.render;return n=n.displayName,n||(n=u.displayName||u.name||"",n=n!==""?"ForwardRef("+n+")":"ForwardRef"),n;case I:return u=n.displayName||null,u!==null?u:t(n.type)||"Memo";case i:u=n._payload,n=n._init;try{return t(n(u))}catch{}}return null}function s(n){return""+n}function r(n){try{s(n);var u=!1}catch{u=!0}if(u){u=console;var S=u.error,C=typeof Symbol=="function"&&Symbol.toStringTag&&n[Symbol.toStringTag]||n.constructor.name||"Object";return S.call(u,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",C),s(n)}}function a(n){if(n===v)return"<>";if(typeof n=="object"&&n!==null&&n.$$typeof===i)return"<...>";try{var u=t(n);return u?"<"+u+">":"<...>"}catch{return"<...>"}}function o(){var n=P.A;return n===null?null:n.getOwner()}function c(){return Error("react-stack-top-frame")}function m(n){if($.call(n,"key")){var u=Object.getOwnPropertyDescriptor(n,"key").get;if(u&&u.isReactWarning)return!1}return n.key!==void 0}function f(n,u){function S(){V||(V=!0,console.error("%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)",u))}S.isReactWarning=!0,Object.defineProperty(n,"key",{get:S,configurable:!0})}function x(){var n=t(this.type);return M[n]||(M[n]=!0,console.error("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.")),n=this.props.ref,n!==void 0?n:null}function N(n,u,S,C,z,Q){var w=S.ref;return n={$$typeof:h,type:n,key:u,props:S,_owner:C},(w!==void 0?w:null)!==null?Object.defineProperty(n,"ref",{enumerable:!1,get:x}):Object.defineProperty(n,"ref",{enumerable:!1,value:null}),n._store={},Object.defineProperty(n._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(n,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(n,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:z}),Object.defineProperty(n,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:Q}),Object.freeze&&(Object.freeze(n.props),Object.freeze(n)),n}function b(n,u,S,C,z,Q){var w=u.children;if(w!==void 0)if(C)if(D(w)){for(C=0;C<w.length;C++)R(w[C]);Object.freeze&&Object.freeze(w)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else R(w);if($.call(u,"key")){w=t(n);var Y=Object.keys(u).filter(function(ke){return ke!=="key"});C=0<Y.length?"{key: someKey, "+Y.join(": ..., ")+": ...}":"{key: someKey}",E[w+C]||(Y=0<Y.length?"{"+Y.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
18
18
  let props = %s;
19
19
  <%s {...props} />
20
20
  React keys must be passed directly to JSX without using spread:
21
21
  let props = %s;
22
- <%s key={someKey} {...props} />`,S,k,Y,k),V[k+S]=!0)}if(k=null,b!==void 0&&(r(b),k=""+b),f(i)&&(r(i.key),k=""+i.key),"key"in i){b={};for(var H in i)H!=="key"&&(b[H]=i[H])}else b=i;return k&&h(b,typeof s=="function"?s.displayName||s.name||"Unknown":s),g(s,k,b,l(),z,X)}function R(s){C(s)?s._store&&(s._store.validated=1):typeof s=="object"&&s!==null&&s.$$typeof===m&&(s._payload.status==="fulfilled"?C(s._payload.value)&&s._payload.value._store&&(s._payload.value._store.validated=1):s._store&&(s._store.validated=1))}function C(s){return typeof s=="object"&&s!==null&&s.$$typeof===T}var y=o,T=Symbol.for("react.transitional.element"),u=Symbol.for("react.portal"),d=Symbol.for("react.fragment"),w=Symbol.for("react.strict_mode"),L=Symbol.for("react.profiler"),I=Symbol.for("react.consumer"),J=Symbol.for("react.context"),F=Symbol.for("react.forward_ref"),_=Symbol.for("react.suspense"),D=Symbol.for("react.suspense_list"),p=Symbol.for("react.memo"),m=Symbol.for("react.lazy"),v=Symbol.for("react.activity"),E=Symbol.for("react.client.reference"),P=y.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,$=Object.prototype.hasOwnProperty,G=Array.isArray,O=console.createTask?console.createTask:function(){return null};y={react_stack_bottom_frame:function(s){return s()}};var A,M={},B=y.react_stack_bottom_frame.bind(y,c)(),N=O(a(c)),V={};q.Fragment=d,q.jsx=function(s,i,b){var S=1e4>P.recentlyCreatedOwnerStacks++;return j(s,i,b,!1,S?Error("react-stack-top-frame"):B,S?O(a(s)):N)},q.jsxs=function(s,i,b){var S=1e4>P.recentlyCreatedOwnerStacks++;return j(s,i,b,!0,S?Error("react-stack-top-frame"):B,S?O(a(s)):N)}})()),q}var ae;function ye(){return ae||(ae=1,process.env.NODE_ENV==="production"?Q.exports=ke():Q.exports=Ee()),Q.exports}var e=ye();const Z=o.createContext(null);function le({engine:t,initialSnapshot:n,children:r}){const[a,l]=o.useState(n);o.useEffect(()=>{},[t]);const c=o.useCallback(u=>{const d=t.selectChoice(u);l(d)},[t]),f=o.useCallback(u=>{const d=t.talkTo(u);l(d)},[t]),h=o.useCallback(u=>{const d=t.takeItem(u);l(d)},[t]),x=o.useCallback(u=>{const d=t.travelTo(u);l(d)},[t]),g=o.useCallback((u,d)=>{const w=t.writeNote(u,d);l(w)},[t]),j=o.useCallback(u=>{const d=t.deleteNote(u);l(d)},[t]),R=o.useCallback(u=>{const d=t.setLocale(u);l(d)},[t]),C=o.useCallback(()=>t.saveGame(),[t]),y=o.useCallback(u=>{const d=t.loadGame(u);l(d)},[t]),T={snapshot:a,actions:{selectChoice:c,talkTo:f,takeItem:h,travelTo:x,writeNote:g,deleteNote:j,setLocale:R,saveGame:C,loadGame:y}};return e.jsx(Z.Provider,{value:T,children:r})}function K(){const t=o.useContext(Z);if(!t)throw new Error("useGame must be used within a GameProvider");return t}function ee(t,n={}){var p;const{audioBasePath:r="/audio",masterVolume:a=1,musicVolume:l=.7,soundVolume:c=.8,voiceVolume:f=1,crossfadeDuration:h=1e3}=n,[x,g]=o.useState(a),[j,R]=o.useState(l),[C,y]=o.useState(c),[T,u]=o.useState(f),d=o.useRef(null),w=o.useRef(null),L=o.useRef(null),I=o.useRef(null);o.useEffect(()=>{const m=new Audio;m.loop=!0,d.current=m;const v=new Audio;return w.current=v,()=>{I.current&&clearInterval(I.current),m.pause(),v.pause(),m.src="",v.src=""}},[]),o.useEffect(()=>{const m=d.current;if(!m)return;const v=t.music;if(v!==L.current)if(L.current=v,!v)F(m,h);else{const E=`${r}/music/${v}`;J(m,E,h)}m.volume=x*j},[t.music,x,j,r,h]),o.useEffect(()=>{var E;const m=w.current;if(!m)return;const v=(E=t.dialogue)==null?void 0:E.voice;v&&(m.pause(),m.currentTime=0,m.src=`${r}/voice/${v}`,m.volume=x*T,m.play().catch(P=>{console.warn("Voice playback failed:",P)}))},[(p=t.dialogue)==null?void 0:p.voice,x,T,r]),o.useEffect(()=>{t.pendingSounds.length!==0&&t.pendingSounds.forEach(m=>{const v=new Audio(`${r}/sfx/${m}`);v.volume=x*C,v.play().catch(E=>{console.warn("Sound playback failed:",E)})})},[t.pendingSounds,x,C,r]);const J=(m,v,E)=>{F(m,E/2).then(()=>{m.src=v,m.load(),m.volume=0,m.play().then(()=>{_(m,E/2,x*j)}).catch(P=>{console.warn("Music playback failed:",P)})})},F=(m,v)=>new Promise(E=>{const P=m.volume,$=20,G=v/$,O=P/$;let A=0;const M=setInterval(()=>{A++,m.volume=Math.max(0,P-O*A),A>=$&&(clearInterval(M),m.pause(),m.currentTime=0,E())},G);I.current=M}),_=(m,v,E)=>{const $=v/20,G=E/20;let O=0;const A=setInterval(()=>{O++,m.volume=Math.min(E,G*O),O>=20&&clearInterval(A)},$);I.current=A};return{setMasterVolume:g,setMusicVolume:R,setSoundVolume:y,setVoiceVolume:u,stopAll:()=>{d.current&&(d.current.pause(),d.current.currentTime=0),w.current&&(w.current.pause(),w.current.currentTime=0)}}}const Ce={click:"click.ogg",menuOpen:"menu_open.ogg",menuClose:"menu_close.ogg"};function oe(t={}){const{enabled:n=!0,basePath:r="/audio/ui",volume:a=.5,sounds:l={}}=t,[c,f]=o.useState(n),[h,x]=o.useState(a),g=o.useRef({...Ce,...l}),j=o.useCallback(u=>{if(!c||!u)return;const d=new Audio(`${r}/${u}`);d.volume=h,d.play().catch(()=>{})},[c,h,r]),R=o.useCallback(u=>{const d=g.current[u];d&&j(d)},[j]),C=o.useCallback(()=>j(g.current.click),[j]),y=o.useCallback(()=>j(g.current.menuOpen),[j]),T=o.useCallback(()=>j(g.current.menuClose),[j]);return{playClick:C,playMenuOpen:y,playMenuClose:T,playSound:R,setEnabled:f,setVolume:x,enabled:c,volume:h}}function ce({dialogue:t,className:n=""}){return e.jsxs("div",{className:`dialogue-box ${n}`,children:[t.portrait&&e.jsx("div",{className:"dialogue-portrait",children:e.jsx("img",{src:t.portrait,alt:t.speakerName})}),e.jsxs("div",{className:"dialogue-content",children:[e.jsx("div",{className:"dialogue-speaker",children:t.speakerName}),e.jsx("div",{className:"dialogue-text",children:t.text})]})]})}function ie({choices:t,onSelectChoice:n,className:r=""}){return t.length===0?null:e.jsx("div",{className:`choice-list ${r}`,children:t.map(a=>e.jsx("button",{className:"choice-button",onClick:()=>n(a.id),children:a.text},a.id))})}function ue({location:t,className:n=""}){return e.jsxs("div",{className:`location-view ${n}`,children:[t.banner&&e.jsx("div",{className:"location-banner",children:e.jsx("img",{src:t.banner,alt:t.name})}),e.jsxs("div",{className:"location-content",children:[e.jsx("h1",{className:"location-name",children:t.name}),e.jsx("p",{className:"location-description",children:t.description})]})]})}function de({characters:t,onTalkTo:n,className:r=""}){return t.length===0?null:e.jsxs("div",{className:`character-list ${r}`,children:[e.jsx("h2",{children:"Characters"}),e.jsx("div",{className:"character-grid",children:t.map(a=>e.jsxs("button",{className:"character-card",onClick:()=>n(a.id),children:[a.portrait&&e.jsx("img",{src:a.portrait,alt:a.name,className:"character-portrait"}),e.jsx("div",{className:"character-name",children:a.name})]},a.id))})]})}function me({items:t,className:n=""}){const[r,a]=o.useState(null);return e.jsxs("div",{className:`inventory ${n}`,children:[e.jsx("h2",{children:"Inventory"}),t.length===0?e.jsx("p",{className:"inventory-empty",children:"No items"}):e.jsx("div",{className:"inventory-grid",children:t.map(l=>e.jsxs("div",{className:"inventory-item",onClick:()=>a(l),children:[l.icon&&e.jsx("img",{src:l.icon,alt:l.name,className:"item-icon"}),e.jsx("div",{className:"item-name",children:l.name})]},l.id))}),r&&e.jsx("div",{className:"item-modal-overlay",onClick:()=>a(null),children:e.jsxs("div",{className:"item-modal",onClick:l=>l.stopPropagation(),children:[r.image&&e.jsx("img",{src:r.image,alt:r.name,className:"item-modal-image"}),e.jsx("h3",{className:"item-modal-name",children:r.name}),e.jsx("p",{className:"item-modal-description",children:r.description}),e.jsx("button",{className:"item-modal-close",onClick:()=>a(null),children:"Close"})]})})]})}function fe({quests:t,entries:n,className:r=""}){return e.jsxs("div",{className:`journal ${r}`,children:[e.jsx("h2",{children:"Journal"}),t.length>0&&e.jsxs("div",{className:"journal-quests",children:[e.jsx("h3",{children:"Active Quests"}),t.map(a=>e.jsxs("div",{className:"quest-entry",children:[e.jsx("div",{className:"quest-name",children:a.name}),e.jsx("div",{className:"quest-description",children:a.description}),e.jsx("div",{className:"quest-stage",children:a.currentStageDescription})]},a.id))]}),n.length>0&&e.jsxs("div",{className:"journal-entries",children:[e.jsx("h3",{children:"Entries"}),n.map(a=>e.jsxs("div",{className:`journal-entry journal-category-${a.category}`,children:[e.jsx("div",{className:"entry-title",children:a.title}),e.jsx("div",{className:"entry-text",children:a.text})]},a.id))]}),t.length===0&&n.length===0&&e.jsx("p",{className:"journal-empty",children:"No entries yet"})]})}function he({map:t,onTravelTo:n,className:r=""}){return t?e.jsxs("div",{className:`map-view ${r}`,children:[e.jsx("h2",{children:t.name}),e.jsxs("div",{className:"map-container",style:{position:"relative"},children:[t.image&&e.jsx("img",{src:t.image,alt:t.name,className:"map-image"}),t.locations.map(a=>e.jsx("button",{className:`map-marker ${a.isCurrent?"current":""}`,style:{position:"absolute",left:`${a.x}px`,top:`${a.y}px`},onClick:()=>!a.isCurrent&&n(a.id),disabled:a.isCurrent,title:a.name,children:a.name},a.id))]})]}):null}function ve({notifications:t,className:n=""}){return t.length===0?null:e.jsx("div",{className:`notification-area ${n}`,children:t.map((r,a)=>e.jsx("div",{className:"notification",children:r},a))})}function pe({onSave:t,onLoad:n,storageKey:r="doodle-engine-save",className:a=""}){const[l,c]=o.useState(""),f=()=>{const g=t();localStorage.setItem(r,JSON.stringify(g)),c("Saved!"),setTimeout(()=>c(""),2e3)},h=()=>{const g=localStorage.getItem(r);if(!g){c("No save found"),setTimeout(()=>c(""),2e3);return}const j=JSON.parse(g);n(j),c("Loaded!"),setTimeout(()=>c(""),2e3)},x=localStorage.getItem(r)!==null;return e.jsxs("div",{className:`save-load-panel ${a}`,children:[e.jsx("button",{className:"save-button",onClick:f,children:"Save"}),e.jsx("button",{className:"load-button",onClick:h,disabled:!x,children:"Load"}),l&&e.jsx("span",{className:"save-load-message",children:l})]})}function xe({className:t=""}){const{snapshot:n,actions:r}=K();ee(n);const a=Object.entries(n.variables).filter(([l])=>!l.startsWith("_"));return e.jsxs("div",{className:`game-renderer ${t}`,children:[e.jsx(ve,{notifications:n.notifications}),e.jsxs("div",{className:"game-main",children:[e.jsx(ue,{location:n.location}),n.dialogue&&e.jsxs("div",{className:"dialogue-container",children:[e.jsx(ce,{dialogue:n.dialogue}),e.jsx(ie,{choices:n.choices,onSelectChoice:r.selectChoice})]}),!n.dialogue&&e.jsx(de,{characters:n.charactersHere,onTalkTo:r.talkTo})]}),e.jsxs("div",{className:"game-sidebar",children:[e.jsx(pe,{onSave:r.saveGame,onLoad:r.loadGame}),a.length>0&&e.jsxs("div",{className:"resources",children:[e.jsx("h2",{children:"Resources"}),e.jsx("ul",{className:"resources-list",children:a.map(([l,c])=>e.jsxs("li",{className:"resource-entry",children:[e.jsx("span",{className:"resource-name",children:l}),e.jsx("span",{className:"resource-value",children:c})]},l))})]}),n.party.length>0&&e.jsxs("div",{className:"party",children:[e.jsx("h2",{children:"Party"}),e.jsx("ul",{className:"party-list",children:n.party.map(l=>e.jsx("li",{className:"party-member",children:e.jsx("span",{className:"party-member-name",children:l.name})},l.id))})]}),e.jsx(me,{items:n.inventory}),e.jsx(fe,{quests:n.quests,entries:n.journal}),n.map&&e.jsx(he,{map:n.map,onTravelTo:r.travelTo})]})]})}function je({logoSrc:t,title:n,onComplete:r,duration:a=2e3,className:l=""}){return o.useEffect(()=>{const c=setTimeout(r,a);return()=>clearTimeout(c)},[r,a]),e.jsxs("div",{className:`splash-screen ${l}`,onClick:r,children:[t&&e.jsx("img",{src:t,alt:n||"",className:"splash-logo"}),n&&e.jsx("h1",{className:"splash-title",children:n}),e.jsx("div",{className:"splash-loading",children:"Loading..."})]})}function be({title:t="Doodle Engine",subtitle:n,logoSrc:r,hasSaveData:a,onNewGame:l,onContinue:c,onSettings:f,className:h=""}){return e.jsxs("div",{className:`title-screen ${h}`,children:[r&&e.jsx("img",{src:r,alt:t,className:"title-logo"}),e.jsx("h1",{className:"title-heading",children:t}),n&&e.jsx("p",{className:"title-subtitle",children:n}),e.jsxs("div",{className:"title-menu",children:[e.jsx("button",{className:"title-button",onClick:l,children:"New Game"}),a&&e.jsx("button",{className:"title-button",onClick:c,children:"Continue"}),e.jsx("button",{className:"title-button",onClick:f,children:"Settings"})]})]})}function Ne({onResume:t,onSave:n,onLoad:r,onSettings:a,onQuitToTitle:l,className:c=""}){return e.jsx("div",{className:`pause-menu-overlay ${c}`,children:e.jsxs("div",{className:"pause-menu",children:[e.jsx("h2",{className:"pause-title",children:"Paused"}),e.jsxs("div",{className:"pause-buttons",children:[e.jsx("button",{className:"pause-button",onClick:t,children:"Resume"}),e.jsx("button",{className:"pause-button",onClick:n,children:"Save"}),e.jsx("button",{className:"pause-button",onClick:r,children:"Load"}),e.jsx("button",{className:"pause-button",onClick:a,children:"Settings"}),e.jsx("button",{className:"pause-button pause-button-quit",onClick:l,children:"Quit to Title"})]})]})})}function se({audioControls:t,uiSoundControls:n,availableLocales:r,currentLocale:a,onLocaleChange:l,onBack:c,className:f=""}){return e.jsxs("div",{className:`settings-panel ${f}`,children:[e.jsx("h2",{className:"settings-title",children:"Settings"}),e.jsxs("div",{className:"settings-section",children:[e.jsx("h3",{children:"Audio"}),e.jsx(W,{label:"Master",value:1,onChange:t.setMasterVolume}),e.jsx(W,{label:"Music",value:.7,onChange:t.setMusicVolume}),e.jsx(W,{label:"Sound Effects",value:.8,onChange:t.setSoundVolume}),e.jsx(W,{label:"Voice",value:1,onChange:t.setVoiceVolume}),n&&e.jsx(W,{label:"UI Sounds",value:n.volume,onChange:n.setVolume})]}),r&&r.length>1&&l&&e.jsxs("div",{className:"settings-section",children:[e.jsx("h3",{children:"Language"}),e.jsx("select",{className:"settings-locale-select",value:a,onChange:h=>l(h.target.value),children:r.map(h=>e.jsx("option",{value:h.code,children:h.label},h.code))})]}),e.jsx("button",{className:"settings-back-button",onClick:c,children:"Back"})]})}function W({label:t,value:n,onChange:r}){return e.jsxs("div",{className:"volume-slider",children:[e.jsx("label",{className:"volume-label",children:t}),e.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",defaultValue:n,onChange:a=>r(parseFloat(a.target.value)),className:"volume-input"})]})}function ge({src:t,basePath:n="/video",onComplete:r,className:a=""}){const l=o.useRef(null);return o.useEffect(()=>{const c=f=>{(f.key==="Escape"||f.key===" "||f.key==="Enter")&&(f.preventDefault(),r())};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[r]),e.jsxs("div",{className:`video-player-overlay ${a}`,children:[e.jsx("video",{ref:l,src:`${n}/${t}`,autoPlay:!0,onEnded:r,className:"video-player-video"}),e.jsx("button",{className:"video-player-skip-button",onClick:r,children:"Skip"})]})}function Te({registry:t,config:n,title:r="Doodle Engine",subtitle:a,logoSrc:l,splashDuration:c=2e3,uiSounds:f,audioOptions:h,storageKey:x="doodle-engine-save",availableLocales:g,videoBasePath:j="/video",className:R=""}){const[C,y]=o.useState(c>0?"splash":"title"),[T,u]=o.useState(!1),[d,w]=o.useState(!1),[L,I]=o.useState("title"),[J,F]=o.useState(null),[_,D]=o.useState(null),p=oe(f===!1?{enabled:!1}:f),m=localStorage.getItem(x)!==null,v=o.useCallback(()=>{const N={currentLocation:n.startLocation,currentTime:{...n.startTime},flags:{...n.startFlags},variables:{...n.startVariables},inventory:[...n.startInventory],questProgress:{},unlockedJournalEntries:[],playerNotes:[],dialogueState:null,characterState:{},itemLocations:{},mapEnabled:!0,notifications:[],pendingSounds:[],pendingVideo:null,currentLocale:"en"};return new re.Engine(t,N)},[t,n]),E=o.useCallback(()=>{p.playClick();const N=v(),V=N.newGame(n);D({engine:N,snapshot:V}),y("playing")},[v,n,p]),P=o.useCallback(()=>{p.playClick();const N=localStorage.getItem(x);if(!N)return;const V=JSON.parse(N),s=v(),i=s.loadGame(V);D({engine:s,snapshot:i}),y("playing")},[v,x,p]),$=o.useCallback(()=>{if(!_)return;p.playClick();const N=_.engine.saveGame();localStorage.setItem(x,JSON.stringify(N)),u(!1)},[_,x,p]),G=o.useCallback(()=>{const N=localStorage.getItem(x);if(!N||!_)return;p.playClick();const V=JSON.parse(N),s=_.engine.loadGame(V);D({engine:_.engine,snapshot:s}),u(!1)},[_,x,p]),O=o.useCallback(()=>{p.playClick(),u(!1),w(!1),D(null),y("title")},[p]),A=o.useCallback(N=>{p.playMenuOpen(),I(N),w(!0),N==="pause"&&u(!1)},[p]),M=o.useCallback(()=>{p.playMenuClose(),w(!1),L==="pause"&&u(!0)},[L,p]);o.useEffect(()=>{if(C!=="playing")return;const N=V=>{V.key==="Escape"&&(V.preventDefault(),d?M():(T?p.playMenuClose():p.playMenuOpen(),u(s=>!s)))};return window.addEventListener("keydown",N),()=>window.removeEventListener("keydown",N)},[C,T,d,M,p]);const B={setMasterVolume:()=>{},setMusicVolume:()=>{},setSoundVolume:()=>{},setVoiceVolume:()=>{},stopAll:()=>{}};return C==="splash"?e.jsx("div",{className:`game-shell ${R}`,children:e.jsx(je,{logoSrc:l,title:r,onComplete:()=>y("title"),duration:c})}):C==="title"?e.jsx("div",{className:`game-shell ${R}`,children:d?e.jsx(se,{audioControls:B,uiSoundControls:f!==!1?p:void 0,availableLocales:g,onBack:M}):e.jsx(be,{title:r,subtitle:a,logoSrc:l,hasSaveData:m,onNewGame:E,onContinue:P,onSettings:()=>A("title")})}):_?e.jsx("div",{className:`game-shell ${R}`,children:e.jsx(le,{engine:_.engine,initialSnapshot:_.snapshot,children:e.jsx(we,{audioOptions:h,uiSoundControls:f!==!1?p:void 0,showPauseMenu:T,showSettings:d,availableLocales:g,videoBasePath:j,pendingVideo:J,setPendingVideo:F,onPause:()=>{p.playMenuOpen(),u(!0)},onResume:()=>{p.playMenuClose(),u(!1)},onSave:$,onLoad:G,onSettings:()=>A("pause"),onQuitToTitle:O,onCloseSettings:M})})}):null}function we({audioOptions:t,uiSoundControls:n,showPauseMenu:r,showSettings:a,availableLocales:l,videoBasePath:c,pendingVideo:f,setPendingVideo:h,onPause:x,onResume:g,onSave:j,onLoad:R,onSettings:C,onQuitToTitle:y,onCloseSettings:T}){const{snapshot:u,actions:d}=K(),w=ee(u,t);return o.useEffect(()=>{u.pendingVideo&&h(u.pendingVideo)},[u.pendingVideo,h]),e.jsxs(e.Fragment,{children:[f&&e.jsx(ge,{src:f,basePath:c,onComplete:()=>h(null)}),e.jsx(xe,{}),!r&&!a&&!f&&e.jsx("button",{className:"game-shell-menu-button",onClick:x,"aria-label":"Menu",children:"Menu"}),r&&e.jsx(Ne,{onResume:g,onSave:j,onLoad:R,onSettings:C,onQuitToTitle:y}),a&&e.jsx(se,{audioControls:w,uiSoundControls:n,availableLocales:l,currentLocale:(u.time,void 0),onLocaleChange:d.setLocale,onBack:T})]})}Object.defineProperty(exports,"VERSION",{enumerable:!0,get:()=>re.VERSION});exports.CharacterList=de;exports.ChoiceList=ie;exports.DialogueBox=ce;exports.GameContext=Z;exports.GameProvider=le;exports.GameRenderer=xe;exports.GameShell=Te;exports.Inventory=me;exports.Journal=fe;exports.LocationView=ue;exports.MapView=he;exports.NotificationArea=ve;exports.PauseMenu=Ne;exports.SaveLoadPanel=pe;exports.SettingsPanel=se;exports.SplashScreen=je;exports.TitleScreen=be;exports.VideoPlayer=ge;exports.useAudioManager=ee;exports.useGame=K;exports.useUISounds=oe;
22
+ <%s key={someKey} {...props} />`,C,w,Y,w),E[w+C]=!0)}if(w=null,S!==void 0&&(r(S),w=""+S),m(u)&&(r(u.key),w=""+u.key),"key"in u){S={};for(var X in u)X!=="key"&&(S[X]=u[X])}else S=u;return w&&f(S,typeof n=="function"?n.displayName||n.name||"Unknown":n),N(n,w,S,o(),z,Q)}function R(n){T(n)?n._store&&(n._store.validated=1):typeof n=="object"&&n!==null&&n.$$typeof===i&&(n._payload.status==="fulfilled"?T(n._payload.value)&&n._payload.value._store&&(n._payload.value._store.validated=1):n._store&&(n._store.validated=1))}function T(n){return typeof n=="object"&&n!==null&&n.$$typeof===h}var k=l,h=Symbol.for("react.transitional.element"),p=Symbol.for("react.portal"),v=Symbol.for("react.fragment"),d=Symbol.for("react.strict_mode"),j=Symbol.for("react.profiler"),_=Symbol.for("react.consumer"),L=Symbol.for("react.context"),F=Symbol.for("react.forward_ref"),J=Symbol.for("react.suspense"),A=Symbol.for("react.suspense_list"),I=Symbol.for("react.memo"),i=Symbol.for("react.lazy"),g=Symbol.for("react.activity"),y=Symbol.for("react.client.reference"),P=k.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,$=Object.prototype.hasOwnProperty,D=Array.isArray,O=console.createTask?console.createTask:function(){return null};k={react_stack_bottom_frame:function(n){return n()}};var V,M={},G=k.react_stack_bottom_frame.bind(k,c)(),B=O(a(c)),E={};U.Fragment=v,U.jsx=function(n,u,S){var C=1e4>P.recentlyCreatedOwnerStacks++;return b(n,u,S,!1,C?Error("react-stack-top-frame"):G,C?O(a(n)):B)},U.jsxs=function(n,u,S){var C=1e4>P.recentlyCreatedOwnerStacks++;return b(n,u,S,!0,C?Error("react-stack-top-frame"):G,C?O(a(n)):B)}})()),U}var re;function Ce(){return re||(re=1,process.env.NODE_ENV==="production"?H.exports=ye():H.exports=Ee()),H.exports}var e=Ce();const K=l.createContext(null);function le({engine:t,initialSnapshot:s,children:r,devTools:a=!1}){const[o,c]=l.useState(s);l.useEffect(()=>{if(a)return Z.enableDevTools(t,()=>c(t.getSnapshot())),()=>{delete window.doodle}},[t,a]);const m=l.useCallback(d=>{const j=t.selectChoice(d);c(j)},[t]),f=l.useCallback(d=>{const j=t.talkTo(d);c(j)},[t]),x=l.useCallback(d=>{const j=t.takeItem(d);c(j)},[t]),N=l.useCallback(d=>{const j=t.travelTo(d);c(j)},[t]),b=l.useCallback((d,j)=>{const _=t.writeNote(d,j);c(_)},[t]),R=l.useCallback(d=>{const j=t.deleteNote(d);c(j)},[t]),T=l.useCallback(d=>{const j=t.setLocale(d);c(j)},[t]),k=l.useCallback(()=>t.saveGame(),[t]),h=l.useCallback(d=>{const j=t.loadGame(d);c(j)},[t]),p=l.useCallback(()=>{c(t.getSnapshot())},[t]),v={snapshot:o,actions:{selectChoice:m,talkTo:f,takeItem:x,travelTo:N,writeNote:b,deleteNote:R,setLocale:T,saveGame:k,loadGame:h,dismissInterlude:p}};return e.jsx(K.Provider,{value:v,children:r})}function ee(){const t=l.useContext(K);if(!t)throw new Error("useGame must be used within a GameProvider");return t}function te(t,s={}){var I;const{audioBasePath:r="/audio",masterVolume:a=1,musicVolume:o=.7,soundVolume:c=.8,voiceVolume:m=1,crossfadeDuration:f=1e3}=s,[x,N]=l.useState(a),[b,R]=l.useState(o),[T,k]=l.useState(c),[h,p]=l.useState(m),v=l.useRef(null),d=l.useRef(null),j=l.useRef(null),_=l.useRef(null);l.useEffect(()=>{const i=new Audio;i.loop=!0,v.current=i;const g=new Audio;return d.current=g,()=>{_.current&&clearInterval(_.current),i.pause(),g.pause(),i.src="",g.src=""}},[]),l.useEffect(()=>{const i=v.current;if(!i)return;const g=t.music;if(g!==j.current)if(j.current=g,!g)F(i,f);else{const y=`${r}/music/${g}`;L(i,y,f)}i.volume=x*b},[t.music,x,b,r,f]),l.useEffect(()=>{var y;const i=d.current;if(!i)return;const g=(y=t.dialogue)==null?void 0:y.voice;g&&(i.pause(),i.currentTime=0,i.src=`${r}/voice/${g}`,i.volume=x*h,i.play().catch(P=>{console.warn("Voice playback failed:",P)}))},[(I=t.dialogue)==null?void 0:I.voice,x,h,r]),l.useEffect(()=>{t.pendingSounds.length!==0&&t.pendingSounds.forEach(i=>{const g=new Audio(`${r}/sfx/${i}`);g.volume=x*T,g.play().catch(y=>{console.warn("Sound playback failed:",y)})})},[t.pendingSounds,x,T,r]);const L=(i,g,y)=>{F(i,y/2).then(()=>{i.src=g,i.load(),i.volume=0,i.play().then(()=>{J(i,y/2,x*b)}).catch(P=>{console.warn("Music playback failed:",P)})})},F=(i,g)=>new Promise(y=>{const P=i.volume,$=20,D=g/$,O=P/$;let V=0;const M=setInterval(()=>{V++,i.volume=Math.max(0,P-O*V),V>=$&&(clearInterval(M),i.pause(),i.currentTime=0,y())},D);_.current=M}),J=(i,g,y)=>{const $=g/20,D=y/20;let O=0;const V=setInterval(()=>{O++,i.volume=Math.min(y,D*O),O>=20&&clearInterval(V)},$);_.current=V};return{setMasterVolume:N,setMusicVolume:R,setSoundVolume:k,setVoiceVolume:p,stopAll:()=>{v.current&&(v.current.pause(),v.current.currentTime=0),d.current&&(d.current.pause(),d.current.currentTime=0)}}}const we={click:"click.ogg",menuOpen:"menu_open.ogg",menuClose:"menu_close.ogg"};function oe(t={}){const{enabled:s=!0,basePath:r="/audio/ui",volume:a=.5,sounds:o={}}=t,[c,m]=l.useState(s),[f,x]=l.useState(a),N=l.useRef({...we,...o}),b=l.useCallback(p=>{if(!c||!p)return;const v=new Audio(`${r}/${p}`);v.volume=f,v.play().catch(()=>{})},[c,f,r]),R=l.useCallback(p=>{const v=N.current[p];v&&b(v)},[b]),T=l.useCallback(()=>b(N.current.click),[b]),k=l.useCallback(()=>b(N.current.menuOpen),[b]),h=l.useCallback(()=>b(N.current.menuClose),[b]);return{playClick:T,playMenuOpen:k,playMenuClose:h,playSound:R,setEnabled:m,setVolume:x,enabled:c,volume:f}}function ce({dialogue:t,className:s=""}){return e.jsxs("div",{className:`dialogue-box ${s}`,children:[t.portrait&&e.jsx("div",{className:"dialogue-portrait",children:e.jsx("img",{src:t.portrait,alt:t.speakerName})}),e.jsxs("div",{className:"dialogue-content",children:[e.jsx("div",{className:"dialogue-speaker",children:t.speakerName}),e.jsx("div",{className:"dialogue-text",children:t.text})]})]})}function ie({choices:t,onSelectChoice:s,className:r=""}){return t.length===0?null:e.jsx("div",{className:`choice-list ${r}`,children:t.map(a=>e.jsx("button",{className:"choice-button",onClick:()=>s(a.id),children:a.text},a.id))})}function ue({location:t,className:s=""}){return e.jsxs("div",{className:`location-view ${s}`,children:[t.banner&&e.jsx("div",{className:"location-banner",children:e.jsx("img",{src:t.banner,alt:t.name})}),e.jsxs("div",{className:"location-content",children:[e.jsx("h1",{className:"location-name",children:t.name}),e.jsx("p",{className:"location-description",children:t.description})]})]})}function de({characters:t,onTalkTo:s,className:r=""}){return t.length===0?null:e.jsxs("div",{className:`character-list ${r}`,children:[e.jsx("h2",{children:"Characters"}),e.jsx("div",{className:"character-grid",children:t.map(a=>e.jsxs("button",{className:"character-card",onClick:()=>s(a.id),children:[a.portrait&&e.jsx("img",{src:a.portrait,alt:a.name,className:"character-portrait"}),e.jsx("div",{className:"character-name",children:a.name})]},a.id))})]})}function me({items:t,className:s=""}){const[r,a]=l.useState(null);return e.jsxs("div",{className:`inventory ${s}`,children:[e.jsx("h2",{children:"Inventory"}),t.length===0?e.jsx("p",{className:"inventory-empty",children:"No items"}):e.jsx("div",{className:"inventory-grid",children:t.map(o=>e.jsxs("div",{className:"inventory-item",onClick:()=>a(o),children:[o.icon&&e.jsx("img",{src:o.icon,alt:o.name,className:"item-icon"}),e.jsx("div",{className:"item-name",children:o.name})]},o.id))}),r&&e.jsx("div",{className:"item-modal-overlay",onClick:()=>a(null),children:e.jsxs("div",{className:"item-modal",onClick:o=>o.stopPropagation(),children:[r.image&&e.jsx("img",{src:r.image,alt:r.name,className:"item-modal-image"}),e.jsx("h3",{className:"item-modal-name",children:r.name}),e.jsx("p",{className:"item-modal-description",children:r.description}),e.jsx("button",{className:"item-modal-close",onClick:()=>a(null),children:"Close"})]})})]})}function fe({quests:t,entries:s,className:r=""}){return e.jsxs("div",{className:`journal ${r}`,children:[e.jsx("h2",{children:"Journal"}),t.length>0&&e.jsxs("div",{className:"journal-quests",children:[e.jsx("h3",{children:"Active Quests"}),t.map(a=>e.jsxs("div",{className:"quest-entry",children:[e.jsx("div",{className:"quest-name",children:a.name}),e.jsx("div",{className:"quest-description",children:a.description}),e.jsx("div",{className:"quest-stage",children:a.currentStageDescription})]},a.id))]}),s.length>0&&e.jsxs("div",{className:"journal-entries",children:[e.jsx("h3",{children:"Entries"}),s.map(a=>e.jsxs("div",{className:`journal-entry journal-category-${a.category}`,children:[e.jsx("div",{className:"entry-title",children:a.title}),e.jsx("div",{className:"entry-text",children:a.text})]},a.id))]}),t.length===0&&s.length===0&&e.jsx("p",{className:"journal-empty",children:"No entries yet"})]})}function he({map:t,onTravelTo:s,className:r=""}){return t?e.jsxs("div",{className:`map-view ${r}`,children:[e.jsx("h2",{children:t.name}),e.jsxs("div",{className:"map-container",style:{position:"relative"},children:[t.image&&e.jsx("img",{src:t.image,alt:t.name,className:"map-image"}),t.locations.map(a=>e.jsx("button",{className:`map-marker ${a.isCurrent?"current":""}`,style:{position:"absolute",left:`${a.x}px`,top:`${a.y}px`},onClick:()=>!a.isCurrent&&s(a.id),disabled:a.isCurrent,title:a.name,children:a.name},a.id))]})]}):null}function pe({notifications:t,className:s=""}){return t.length===0?null:e.jsx("div",{className:`notification-area ${s}`,children:t.map((r,a)=>e.jsx("div",{className:"notification",children:r},a))})}function ve({onSave:t,onLoad:s,storageKey:r="doodle-engine-save",className:a=""}){const[o,c]=l.useState(""),m=()=>{const N=t();localStorage.setItem(r,JSON.stringify(N)),c("Saved!"),setTimeout(()=>c(""),2e3)},f=()=>{const N=localStorage.getItem(r);if(!N){c("No save found"),setTimeout(()=>c(""),2e3);return}const b=JSON.parse(N);s(b),c("Loaded!"),setTimeout(()=>c(""),2e3)},x=localStorage.getItem(r)!==null;return e.jsxs("div",{className:`save-load-panel ${a}`,children:[e.jsx("button",{className:"save-button",onClick:m,children:"Save"}),e.jsx("button",{className:"load-button",onClick:f,disabled:!x,children:"Load"}),o&&e.jsx("span",{className:"save-load-message",children:o})]})}function xe({interlude:t,onDismiss:s}){const r=l.useRef(null),a=l.useRef(null),o=l.useRef(null),c=l.useRef(null),[m,f]=l.useState(!1),[x,N]=l.useState(0),b=t.scrollSpeed,R=t.scroll;l.useEffect(()=>{if(!R||m){o.current!==null&&(cancelAnimationFrame(o.current),o.current=null),c.current=null;return}const h=p=>{c.current===null&&(c.current=p);const v=(p-c.current)/1e3;c.current=p,N(d=>{const j=r.current,_=a.current;if(!j||!_)return d;const L=j.scrollHeight-_.clientHeight;return d>=L?d:d+b*v}),o.current=requestAnimationFrame(h)};return o.current=requestAnimationFrame(h),()=>{o.current!==null&&(cancelAnimationFrame(o.current),o.current=null)}},[R,m,b]),l.useEffect(()=>{a.current&&(a.current.scrollTop=x)},[x]);const T=l.useCallback(h=>{f(!0),N(p=>Math.max(0,p+h.deltaY))},[]),k=l.useCallback(h=>{(h.key==="ArrowDown"||h.key==="ArrowUp")&&(f(!0),N(p=>Math.max(0,p+(h.key==="ArrowDown"?40:-40)))),(h.key===" "||h.key==="Enter"||h.key==="Escape")&&(h.preventDefault(),s())},[s]);return l.useEffect(()=>(window.addEventListener("keydown",k),()=>window.removeEventListener("keydown",k)),[k]),e.jsxs("div",{className:"interlude-overlay",style:{backgroundImage:`url(${t.background})`},onClick:s,children:[t.banner&&e.jsx("img",{className:"interlude-banner",src:t.banner,alt:"","aria-hidden":"true"}),e.jsx("div",{ref:a,className:"interlude-scroll-container",onWheel:T,onClick:h=>h.stopPropagation(),children:e.jsx("div",{ref:r,className:"interlude-text",children:t.text.split(`
23
+ `).map((h,p)=>e.jsx("p",{children:h||" "},p))})}),e.jsx("button",{className:"interlude-skip-button",onClick:s,children:"Skip »"})]})}function je({className:t=""}){const{snapshot:s,actions:r}=ee();te(s);const a=Object.entries(s.variables).filter(([o])=>!o.startsWith("_"));return e.jsxs("div",{className:`game-renderer ${t}`,children:[s.pendingInterlude&&e.jsx(xe,{interlude:s.pendingInterlude,onDismiss:r.dismissInterlude}),e.jsx(pe,{notifications:s.notifications}),e.jsxs("div",{className:"game-main",children:[e.jsx(ue,{location:s.location}),s.dialogue&&e.jsxs("div",{className:"dialogue-container",children:[e.jsx(ce,{dialogue:s.dialogue}),e.jsx(ie,{choices:s.choices,onSelectChoice:r.selectChoice})]}),!s.dialogue&&e.jsx(de,{characters:s.charactersHere,onTalkTo:r.talkTo})]}),e.jsxs("div",{className:"game-sidebar",children:[e.jsx(ve,{onSave:r.saveGame,onLoad:r.loadGame}),a.length>0&&e.jsxs("div",{className:"resources",children:[e.jsx("h2",{children:"Resources"}),e.jsx("ul",{className:"resources-list",children:a.map(([o,c])=>e.jsxs("li",{className:"resource-entry",children:[e.jsx("span",{className:"resource-name",children:o}),e.jsx("span",{className:"resource-value",children:c})]},o))})]}),s.party.length>0&&e.jsxs("div",{className:"party",children:[e.jsx("h2",{children:"Party"}),e.jsx("ul",{className:"party-list",children:s.party.map(o=>e.jsx("li",{className:"party-member",children:e.jsx("span",{className:"party-member-name",children:o.name})},o.id))})]}),e.jsx(me,{items:s.inventory}),e.jsx(fe,{quests:s.quests,entries:s.journal}),s.map&&e.jsx(he,{map:s.map,onTravelTo:r.travelTo})]})]})}function be({logoSrc:t,title:s,onComplete:r,duration:a=2e3,className:o=""}){return l.useEffect(()=>{const c=setTimeout(r,a);return()=>clearTimeout(c)},[r,a]),e.jsxs("div",{className:`splash-screen ${o}`,onClick:r,children:[t&&e.jsx("img",{src:t,alt:s||"",className:"splash-logo"}),s&&e.jsx("h1",{className:"splash-title",children:s}),e.jsx("div",{className:"splash-loading",children:"Loading..."})]})}function Ne({title:t="Doodle Engine",subtitle:s,logoSrc:r,hasSaveData:a,onNewGame:o,onContinue:c,onSettings:m,className:f=""}){return e.jsxs("div",{className:`title-screen ${f}`,children:[r&&e.jsx("img",{src:r,alt:t,className:"title-logo"}),e.jsx("h1",{className:"title-heading",children:t}),s&&e.jsx("p",{className:"title-subtitle",children:s}),e.jsxs("div",{className:"title-menu",children:[e.jsx("button",{className:"title-button",onClick:o,children:"New Game"}),a&&e.jsx("button",{className:"title-button",onClick:c,children:"Continue"}),e.jsx("button",{className:"title-button",onClick:m,children:"Settings"})]})]})}function ge({onResume:t,onSave:s,onLoad:r,onSettings:a,onQuitToTitle:o,className:c=""}){return e.jsx("div",{className:`pause-menu-overlay ${c}`,children:e.jsxs("div",{className:"pause-menu",children:[e.jsx("h2",{className:"pause-title",children:"Paused"}),e.jsxs("div",{className:"pause-buttons",children:[e.jsx("button",{className:"pause-button",onClick:t,children:"Resume"}),e.jsx("button",{className:"pause-button",onClick:s,children:"Save"}),e.jsx("button",{className:"pause-button",onClick:r,children:"Load"}),e.jsx("button",{className:"pause-button",onClick:a,children:"Settings"}),e.jsx("button",{className:"pause-button pause-button-quit",onClick:o,children:"Quit to Title"})]})]})})}function ne({audioControls:t,uiSoundControls:s,availableLocales:r,currentLocale:a,onLocaleChange:o,onBack:c,className:m=""}){return e.jsxs("div",{className:`settings-panel ${m}`,children:[e.jsx("h2",{className:"settings-title",children:"Settings"}),e.jsxs("div",{className:"settings-section",children:[e.jsx("h3",{children:"Audio"}),e.jsx(W,{label:"Master",value:1,onChange:t.setMasterVolume}),e.jsx(W,{label:"Music",value:.7,onChange:t.setMusicVolume}),e.jsx(W,{label:"Sound Effects",value:.8,onChange:t.setSoundVolume}),e.jsx(W,{label:"Voice",value:1,onChange:t.setVoiceVolume}),s&&e.jsx(W,{label:"UI Sounds",value:s.volume,onChange:s.setVolume})]}),r&&r.length>1&&o&&e.jsxs("div",{className:"settings-section",children:[e.jsx("h3",{children:"Language"}),e.jsx("select",{className:"settings-locale-select",value:a,onChange:f=>o(f.target.value),children:r.map(f=>e.jsx("option",{value:f.code,children:f.label},f.code))})]}),e.jsx("button",{className:"settings-back-button",onClick:c,children:"Back"})]})}function W({label:t,value:s,onChange:r}){return e.jsxs("div",{className:"volume-slider",children:[e.jsx("label",{className:"volume-label",children:t}),e.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",defaultValue:s,onChange:a=>r(parseFloat(a.target.value)),className:"volume-input"})]})}function Se({src:t,basePath:s="/video",onComplete:r,className:a=""}){const o=l.useRef(null);return l.useEffect(()=>{const c=m=>{(m.key==="Escape"||m.key===" "||m.key==="Enter")&&(m.preventDefault(),r())};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[r]),e.jsxs("div",{className:`video-player-overlay ${a}`,children:[e.jsx("video",{ref:o,src:`${s}/${t}`,autoPlay:!0,onEnded:r,className:"video-player-video"}),e.jsx("button",{className:"video-player-skip-button",onClick:r,children:"Skip"})]})}function Re({registry:t,config:s,title:r="Doodle Engine",subtitle:a,logoSrc:o,splashDuration:c=2e3,uiSounds:m,audioOptions:f,storageKey:x="doodle-engine-save",availableLocales:N,videoBasePath:b="/video",className:R="",devTools:T=!1}){const[k,h]=l.useState(c>0?"splash":"title"),[p,v]=l.useState(!1),[d,j]=l.useState(!1),[_,L]=l.useState("title"),[F,J]=l.useState(null),[A,I]=l.useState(null),i=oe(m===!1?{enabled:!1}:m),g=localStorage.getItem(x)!==null,y=l.useCallback(()=>{const E={currentLocation:s.startLocation,currentTime:{...s.startTime},flags:{...s.startFlags},variables:{...s.startVariables},inventory:[...s.startInventory],questProgress:{},unlockedJournalEntries:[],playerNotes:[],dialogueState:null,characterState:{},itemLocations:{},mapEnabled:!0,notifications:[],pendingSounds:[],pendingVideo:null,pendingInterlude:null,currentLocale:"en"};return new Z.Engine(t,E)},[t,s]),P=l.useCallback(()=>{i.playClick();const E=y(),n=E.newGame(s);I({engine:E,snapshot:n}),h("playing")},[y,s,i]),$=l.useCallback(()=>{i.playClick();const E=localStorage.getItem(x);if(!E)return;const n=JSON.parse(E),u=y(),S=u.loadGame(n);I({engine:u,snapshot:S}),h("playing")},[y,x,i]),D=l.useCallback(()=>{if(!A)return;i.playClick();const E=A.engine.saveGame();localStorage.setItem(x,JSON.stringify(E)),v(!1)},[A,x,i]),O=l.useCallback(()=>{const E=localStorage.getItem(x);if(!E||!A)return;i.playClick();const n=JSON.parse(E),u=A.engine.loadGame(n);I({engine:A.engine,snapshot:u}),v(!1)},[A,x,i]),V=l.useCallback(()=>{i.playClick(),v(!1),j(!1),I(null),h("title")},[i]),M=l.useCallback(E=>{i.playMenuOpen(),L(E),j(!0),E==="pause"&&v(!1)},[i]),G=l.useCallback(()=>{i.playMenuClose(),j(!1),_==="pause"&&v(!0)},[_,i]);l.useEffect(()=>{if(k!=="playing")return;const E=n=>{n.key==="Escape"&&(n.preventDefault(),d?G():(p?i.playMenuClose():i.playMenuOpen(),v(u=>!u)))};return window.addEventListener("keydown",E),()=>window.removeEventListener("keydown",E)},[k,p,d,G,i]);const B={setMasterVolume:()=>{},setMusicVolume:()=>{},setSoundVolume:()=>{},setVoiceVolume:()=>{},stopAll:()=>{}};return k==="splash"?e.jsx("div",{className:`game-shell ${R}`,children:e.jsx(be,{logoSrc:o,title:r,onComplete:()=>h("title"),duration:c})}):k==="title"?e.jsx("div",{className:`game-shell ${R}`,children:d?e.jsx(ne,{audioControls:B,uiSoundControls:m!==!1?i:void 0,availableLocales:N,onBack:G}):e.jsx(Ne,{title:r,subtitle:a,logoSrc:o,hasSaveData:g,onNewGame:P,onContinue:$,onSettings:()=>M("title")})}):A?e.jsx("div",{className:`game-shell ${R}`,children:e.jsx(le,{engine:A.engine,initialSnapshot:A.snapshot,devTools:T,children:e.jsx(Te,{audioOptions:f,uiSoundControls:m!==!1?i:void 0,showPauseMenu:p,showSettings:d,availableLocales:N,videoBasePath:b,pendingVideo:F,setPendingVideo:J,onPause:()=>{i.playMenuOpen(),v(!0)},onResume:()=>{i.playMenuClose(),v(!1)},onSave:D,onLoad:O,onSettings:()=>M("pause"),onQuitToTitle:V,onCloseSettings:G})})}):null}function Te({audioOptions:t,uiSoundControls:s,showPauseMenu:r,showSettings:a,availableLocales:o,videoBasePath:c,pendingVideo:m,setPendingVideo:f,onPause:x,onResume:N,onSave:b,onLoad:R,onSettings:T,onQuitToTitle:k,onCloseSettings:h}){const{snapshot:p,actions:v}=ee(),d=te(p,t);return l.useEffect(()=>{p.pendingVideo&&f(p.pendingVideo)},[p.pendingVideo,f]),e.jsxs(e.Fragment,{children:[m&&e.jsx(Se,{src:m,basePath:c,onComplete:()=>f(null)}),e.jsx(je,{}),!r&&!a&&!m&&e.jsx("button",{className:"game-shell-menu-button",onClick:x,"aria-label":"Menu",children:"Menu"}),r&&e.jsx(ge,{onResume:N,onSave:b,onLoad:R,onSettings:T,onQuitToTitle:k}),a&&e.jsx(ne,{audioControls:d,uiSoundControls:s,availableLocales:o,currentLocale:(p.time,void 0),onLocaleChange:v.setLocale,onBack:h})]})}function _e({message:t="Loading...",className:s=""}){return e.jsx("div",{className:`loading-screen ${s}`,children:e.jsxs("div",{className:"loading-screen-content",children:[e.jsx("div",{className:"loading-screen-spinner"}),e.jsx("p",{className:"loading-screen-message",children:t})]})})}Object.defineProperty(exports,"VERSION",{enumerable:!0,get:()=>Z.VERSION});exports.CharacterList=de;exports.ChoiceList=ie;exports.DialogueBox=ce;exports.GameContext=K;exports.GameProvider=le;exports.GameRenderer=je;exports.GameShell=Re;exports.Interlude=xe;exports.Inventory=me;exports.Journal=fe;exports.LoadingScreen=_e;exports.LocationView=ue;exports.MapView=he;exports.NotificationArea=pe;exports.PauseMenu=ge;exports.SaveLoadPanel=ve;exports.SettingsPanel=ne;exports.SplashScreen=be;exports.TitleScreen=Ne;exports.VideoPlayer=Se;exports.useAudioManager=te;exports.useGame=ee;exports.useUISounds=oe;