@almadar/ui 5.76.1 → 5.76.4

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.
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Curated list of the PUBLIC 3D (Three.js) render-ui pattern components.
3
+ *
4
+ * The 3D family is a code-split optional surface (published via the
5
+ * `@almadar/ui/components/{organisms,molecules}/game/three` subpath, never in
6
+ * the main barrel — that would pull @react-three/fiber into every app). This
7
+ * file is the source of truth for WHICH 3D components are render-ui patterns:
8
+ * `pattern-sync` discovers `patterns.ts` files by walking the tree and admits
9
+ * exactly the names listed here, so the 3D scene internals re-exported alongside
10
+ * them (Scene3D, Camera3D, Lighting3D, ModelLoader, Canvas3D, …) do NOT leak in
11
+ * as factory patterns. Move this file anywhere under `components/` and the
12
+ * scanner still finds it.
13
+ *
14
+ * @packageDocumentation
15
+ */
16
+ export { GameCanvas3D } from './molecules/GameCanvas3D';
17
+ export { GameBoard3D } from './organisms/GameBoard3D';
18
+ export { GameCanvas3DBattleTemplate } from './templates/GameCanvas3DBattleTemplate';
19
+ export { GameCanvas3DCastleTemplate } from './templates/GameCanvas3DCastleTemplate';
20
+ export { GameCanvas3DWorldMapTemplate } from './templates/GameCanvas3DWorldMapTemplate';
@@ -30125,37 +30125,6 @@ var init_useCanvasEffects = __esm({
30125
30125
  init_combatPresets();
30126
30126
  }
30127
30127
  });
30128
- function GameAudioToggle({
30129
- size = "sm",
30130
- className
30131
- }) {
30132
- const ctx = providers.useGameAudioContextOptional();
30133
- const [localMuted, setLocalMuted] = React80.useState(false);
30134
- const muted = ctx ? ctx.muted : localMuted;
30135
- const setMuted = ctx ? ctx.setMuted : setLocalMuted;
30136
- const handleToggle = React80.useCallback(() => {
30137
- setMuted(!muted);
30138
- }, [muted, setMuted]);
30139
- return /* @__PURE__ */ jsxRuntime.jsx(
30140
- exports.Button,
30141
- {
30142
- variant: "ghost",
30143
- size,
30144
- onClick: handleToggle,
30145
- className: cn("text-lg leading-none px-2", className),
30146
- "aria-pressed": muted,
30147
- children: muted ? "\u{1F507}" : "\u{1F50A}"
30148
- }
30149
- );
30150
- }
30151
- var init_GameAudioToggle = __esm({
30152
- "components/game/2d/atoms/GameAudioToggle.tsx"() {
30153
- "use client";
30154
- init_atoms();
30155
- init_cn();
30156
- GameAudioToggle.displayName = "GameAudioToggle";
30157
- }
30158
- });
30159
30128
  function pickPath(entry) {
30160
30129
  if (Array.isArray(entry.path)) {
30161
30130
  return entry.path[Math.floor(Math.random() * entry.path.length)];
@@ -30423,6 +30392,101 @@ var init_useGameAudio = __esm({
30423
30392
  useGameAudio.displayName = "useGameAudio";
30424
30393
  }
30425
30394
  });
30395
+ function useGameAudioContext() {
30396
+ const ctx = React80.useContext(exports.GameAudioContext);
30397
+ if (!ctx) {
30398
+ throw new Error("useGameAudioContext must be used inside <GameAudioProvider>");
30399
+ }
30400
+ return ctx;
30401
+ }
30402
+ function useGameAudioContextOptional() {
30403
+ return React80.useContext(exports.GameAudioContext);
30404
+ }
30405
+ function GameAudioProvider({
30406
+ manifest,
30407
+ baseUrl = "",
30408
+ children,
30409
+ initialMuted = false
30410
+ }) {
30411
+ const eventBus = useEventBus();
30412
+ const { play, stop, stopAll, playMusic, stopMusic, muted, setMuted, masterVolume, setMasterVolume } = useGameAudio({ manifest, baseUrl, initialMuted });
30413
+ React80.useEffect(() => {
30414
+ const unsubPlay = eventBus.on("UI:PLAY_SOUND", (event) => {
30415
+ const key = event.payload?.key;
30416
+ if (key) play(key);
30417
+ });
30418
+ const unsubStop = eventBus.on("UI:STOP_SOUND", (event) => {
30419
+ const key = event.payload?.key;
30420
+ if (key) {
30421
+ stop(key);
30422
+ } else {
30423
+ stopAll();
30424
+ }
30425
+ });
30426
+ const unsubChangeMusic = eventBus.on("UI:CHANGE_MUSIC", (event) => {
30427
+ const key = event.payload?.key;
30428
+ if (key) {
30429
+ playMusic(key);
30430
+ } else {
30431
+ stopMusic();
30432
+ }
30433
+ });
30434
+ const unsubStopMusic = eventBus.on("UI:STOP_MUSIC", () => {
30435
+ stopMusic();
30436
+ });
30437
+ return () => {
30438
+ unsubPlay();
30439
+ unsubStop();
30440
+ unsubChangeMusic();
30441
+ unsubStopMusic();
30442
+ };
30443
+ }, [eventBus, play, stop, stopAll, playMusic, stopMusic]);
30444
+ const value = { muted, setMuted, masterVolume, setMasterVolume, play, playMusic, stopMusic };
30445
+ return /* @__PURE__ */ jsxRuntime.jsx(exports.GameAudioContext.Provider, { value, children });
30446
+ }
30447
+ exports.GameAudioContext = void 0;
30448
+ var init_GameAudioProvider = __esm({
30449
+ "components/game/shared/providers/GameAudioProvider.tsx"() {
30450
+ "use client";
30451
+ init_useEventBus();
30452
+ init_useGameAudio();
30453
+ exports.GameAudioContext = React80.createContext(null);
30454
+ exports.GameAudioContext.displayName = "GameAudioContext";
30455
+ GameAudioProvider.displayName = "GameAudioProvider";
30456
+ }
30457
+ });
30458
+ function GameAudioToggle({
30459
+ size = "sm",
30460
+ className
30461
+ }) {
30462
+ const ctx = useGameAudioContextOptional();
30463
+ const [localMuted, setLocalMuted] = React80.useState(false);
30464
+ const muted = ctx ? ctx.muted : localMuted;
30465
+ const setMuted = ctx ? ctx.setMuted : setLocalMuted;
30466
+ const handleToggle = React80.useCallback(() => {
30467
+ setMuted(!muted);
30468
+ }, [muted, setMuted]);
30469
+ return /* @__PURE__ */ jsxRuntime.jsx(
30470
+ exports.Button,
30471
+ {
30472
+ variant: "ghost",
30473
+ size,
30474
+ onClick: handleToggle,
30475
+ className: cn("text-lg leading-none px-2", className),
30476
+ "aria-pressed": muted,
30477
+ children: muted ? "\u{1F507}" : "\u{1F50A}"
30478
+ }
30479
+ );
30480
+ }
30481
+ var init_GameAudioToggle = __esm({
30482
+ "components/game/2d/atoms/GameAudioToggle.tsx"() {
30483
+ "use client";
30484
+ init_atoms();
30485
+ init_cn();
30486
+ init_GameAudioProvider();
30487
+ GameAudioToggle.displayName = "GameAudioToggle";
30488
+ }
30489
+ });
30426
30490
  function useBattleState(initialUnits, eventConfig = {}, callbacks = {}) {
30427
30491
  const eventBus = useEventBus();
30428
30492
  const {
@@ -36482,6 +36546,8 @@ var init_VisualNovelTemplate = __esm({
36482
36546
  VisualNovelTemplate.displayName = "VisualNovelTemplate";
36483
36547
  }
36484
36548
  });
36549
+
36550
+ // components/game/2d/molecules/index.ts
36485
36551
  var init_molecules = __esm({
36486
36552
  "components/game/2d/molecules/index.ts"() {
36487
36553
  init_shared();
@@ -36514,6 +36580,7 @@ var init_molecules = __esm({
36514
36580
  init_useUnitSpriteAtlas();
36515
36581
  init_CanvasEffect();
36516
36582
  init_useCanvasEffects();
36583
+ init_GameAudioProvider();
36517
36584
  init_GameAudioToggle();
36518
36585
  init_useGameAudio();
36519
36586
  init_useCamera();
@@ -36954,13 +37021,13 @@ var init_MapView = __esm({
36954
37021
  shadowSize: [41, 41]
36955
37022
  });
36956
37023
  L.Marker.prototype.options.icon = defaultIcon;
36957
- const { useEffect: useEffect78, useRef: useRef78, useCallback: useCallback127, useState: useState119 } = React80__namespace.default;
37024
+ const { useEffect: useEffect79, useRef: useRef78, useCallback: useCallback127, useState: useState119 } = React80__namespace.default;
36958
37025
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
36959
37026
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
36960
37027
  function MapUpdater({ centerLat, centerLng, zoom }) {
36961
37028
  const map = useMap();
36962
37029
  const prevRef = useRef78({ centerLat, centerLng, zoom });
36963
- useEffect78(() => {
37030
+ useEffect79(() => {
36964
37031
  const prev = prevRef.current;
36965
37032
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
36966
37033
  map.setView([centerLat, centerLng], zoom);
@@ -36971,7 +37038,7 @@ var init_MapView = __esm({
36971
37038
  }
36972
37039
  function MapClickHandler({ onMapClick }) {
36973
37040
  const map = useMap();
36974
- useEffect78(() => {
37041
+ useEffect79(() => {
36975
37042
  if (!onMapClick) return;
36976
37043
  const handler = (e) => {
36977
37044
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -52756,9 +52823,33 @@ var init_ToastSlot = __esm({
52756
52823
  exports.ToastSlot.displayName = "ToastSlot";
52757
52824
  }
52758
52825
  });
52759
-
52760
- // components/core/organisms/component-registry.generated.ts
52761
- var COMPONENT_REGISTRY;
52826
+ function lazyThree(name, loader) {
52827
+ const Lazy = React80__namespace.default.lazy(
52828
+ () => loader().then((m) => {
52829
+ const Resolved = m[name];
52830
+ if (!Resolved) {
52831
+ throw new Error(
52832
+ `[@almadar/ui] 3D component "${name}" was not found in the three subpath bundle.`
52833
+ );
52834
+ }
52835
+ return { default: Resolved };
52836
+ })
52837
+ );
52838
+ function ThreeWrapper(props) {
52839
+ return React80__namespace.default.createElement(
52840
+ ThreeBoundary,
52841
+ { name },
52842
+ React80__namespace.default.createElement(
52843
+ React80__namespace.default.Suspense,
52844
+ { fallback: null },
52845
+ React80__namespace.default.createElement(Lazy, props)
52846
+ )
52847
+ );
52848
+ }
52849
+ ThreeWrapper.displayName = `Lazy(${name})`;
52850
+ return ThreeWrapper;
52851
+ }
52852
+ var ThreeBoundary, GameBoard3D, GameCanvas3D, GameCanvas3DBattleTemplate, GameCanvas3DCastleTemplate, GameCanvas3DWorldMapTemplate, COMPONENT_REGISTRY;
52762
52853
  var init_component_registry_generated = __esm({
52763
52854
  "components/core/organisms/component-registry.generated.ts"() {
52764
52855
  init_AboutPageTemplate();
@@ -52869,9 +52960,11 @@ var init_component_registry_generated = __esm({
52869
52960
  init_Form();
52870
52961
  init_FormField();
52871
52962
  init_FormSectionHeader();
52963
+ init_GameAudioProvider();
52872
52964
  init_GameAudioToggle();
52873
52965
  init_GameCard();
52874
52966
  init_GameHud();
52967
+ init_GameIcon();
52875
52968
  init_GameMenu();
52876
52969
  init_GameShell();
52877
52970
  init_GameTemplate();
@@ -53056,6 +53149,33 @@ var init_component_registry_generated = __esm({
53056
53149
  init_WizardProgress();
53057
53150
  init_WorldMapBoard();
53058
53151
  init_WorldMapTemplate();
53152
+ ThreeBoundary = class extends React80__namespace.default.Component {
53153
+ constructor() {
53154
+ super(...arguments);
53155
+ __publicField(this, "state", { failed: false });
53156
+ }
53157
+ static getDerivedStateFromError() {
53158
+ return { failed: true };
53159
+ }
53160
+ render() {
53161
+ if (this.state.failed) {
53162
+ return React80__namespace.default.createElement(
53163
+ "div",
53164
+ {
53165
+ "data-testid": "three-unavailable",
53166
+ style: { padding: 16, fontSize: 13, lineHeight: 1.5, opacity: 0.7 }
53167
+ },
53168
+ `3D pattern "${this.props.name}" requires three.js. Install the optional peers three + @react-three/fiber + @react-three/drei (matching the host React major) to render it.`
53169
+ );
53170
+ }
53171
+ return this.props.children;
53172
+ }
53173
+ };
53174
+ GameBoard3D = lazyThree("GameBoard3D", () => import('@almadar/ui/components/molecules/game/three'));
53175
+ GameCanvas3D = lazyThree("GameCanvas3D", () => import('@almadar/ui/components/molecules/game/three'));
53176
+ GameCanvas3DBattleTemplate = lazyThree("GameCanvas3DBattleTemplate", () => import('@almadar/ui/components/molecules/game/three'));
53177
+ GameCanvas3DCastleTemplate = lazyThree("GameCanvas3DCastleTemplate", () => import('@almadar/ui/components/molecules/game/three'));
53178
+ GameCanvas3DWorldMapTemplate = lazyThree("GameCanvas3DWorldMapTemplate", () => import('@almadar/ui/components/molecules/game/three'));
53059
53179
  COMPONENT_REGISTRY = {
53060
53180
  "AboutPageTemplate": exports.AboutPageTemplate,
53061
53181
  "Accordion": exports.Accordion,
@@ -53171,9 +53291,16 @@ var init_component_registry_generated = __esm({
53171
53291
  "Form": exports.Form,
53172
53292
  "FormField": exports.FormField,
53173
53293
  "FormSectionHeader": exports.FormSectionHeader,
53294
+ "GameAudioProvider": GameAudioProvider,
53174
53295
  "GameAudioToggle": GameAudioToggle,
53296
+ "GameBoard3D": GameBoard3D,
53297
+ "GameCanvas3D": GameCanvas3D,
53298
+ "GameCanvas3DBattleTemplate": GameCanvas3DBattleTemplate,
53299
+ "GameCanvas3DCastleTemplate": GameCanvas3DCastleTemplate,
53300
+ "GameCanvas3DWorldMapTemplate": GameCanvas3DWorldMapTemplate,
53175
53301
  "GameCard": GameCard,
53176
53302
  "GameHud": GameHud,
53303
+ "GameIcon": GameIcon,
53177
53304
  "GameMenu": GameMenu,
53178
53305
  "GameShell": exports.GameShell,
53179
53306
  "GameTemplate": exports.GameTemplate,
@@ -56591,18 +56718,6 @@ function useGitHubBranches(owner, repo, enabled = true) {
56591
56718
  });
56592
56719
  }
56593
56720
 
56594
- Object.defineProperty(exports, "GameAudioContext", {
56595
- enumerable: true,
56596
- get: function () { return providers.GameAudioContext; }
56597
- });
56598
- Object.defineProperty(exports, "GameAudioProvider", {
56599
- enumerable: true,
56600
- get: function () { return providers.GameAudioProvider; }
56601
- });
56602
- Object.defineProperty(exports, "useGameAudioContext", {
56603
- enumerable: true,
56604
- get: function () { return providers.useGameAudioContext; }
56605
- });
56606
56721
  exports.ALMADAR_DND_MIME = ALMADAR_DND_MIME;
56607
56722
  exports.ActionButton = ActionButton;
56608
56723
  exports.ActionCard = Card2;
@@ -56647,6 +56762,7 @@ exports.EditorToolbar = EditorToolbar;
56647
56762
  exports.EventHandlerBoard = EventHandlerBoard;
56648
56763
  exports.EventLog = EventLog;
56649
56764
  exports.FishingBoard = FishingBoard;
56765
+ exports.GameAudioProvider = GameAudioProvider;
56650
56766
  exports.GameAudioToggle = GameAudioToggle;
56651
56767
  exports.GameCard = GameCard;
56652
56768
  exports.GameHud = GameHud;
@@ -56794,6 +56910,7 @@ exports.useExtensions = useExtensions;
56794
56910
  exports.useFileEditor = useFileEditor;
56795
56911
  exports.useFileSystem = useFileSystem;
56796
56912
  exports.useGameAudio = useGameAudio;
56913
+ exports.useGameAudioContext = useGameAudioContext;
56797
56914
  exports.useGitHubBranches = useGitHubBranches;
56798
56915
  exports.useGitHubRepo = useGitHubRepo;
56799
56916
  exports.useGitHubRepos = useGitHubRepos;
@@ -3,8 +3,7 @@ import * as React80 from 'react';
3
3
  import React80__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, useState, useId, Suspense, lazy, useLayoutEffect, useSyncExternalStore } from 'react';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
- import { EventBusContext, useTraitScope, useCurrentPagePath, useGameAudioContextOptional, useEntitySchemaOptional, TraitScopeProvider } from '@almadar/ui/providers';
7
- export { GameAudioContext, GameAudioProvider, useGameAudioContext } from '@almadar/ui/providers';
6
+ import { EventBusContext, useTraitScope, useCurrentPagePath, useEntitySchemaOptional, TraitScopeProvider } from '@almadar/ui/providers';
8
7
  import { createLogger, isLogLevelEnabled } from '@almadar/logger';
9
8
  import * as LucideIcons2 from 'lucide-react';
10
9
  import { X, List, Printer, ChevronRight, ChevronLeft, CheckCircle, XCircle, Wrench, RotateCcw, Send, Play, Terminal, ChevronDown, Bug, ArrowRight, Pause, SkipForward, Search, ChevronUp, MoreHorizontal, Package, Calendar, Pencil, Eye, Image as Image$1, Upload, ZoomIn, TrendingUp, TrendingDown, Minus, AlertCircle, Circle, Clock, CheckCircle2, Loader2, Code, FileText, WrapText, Check, Copy, HelpCircle, Type, Heading1, Heading2, Heading3, ListOrdered, Quote, GitBranch, Plus, Trash, ArrowLeft, Menu as Menu$1, AlertTriangle, Trash2, Eraser, ZoomOut, Download, Lightbulb, PauseCircle, Link2, Tag, User, DollarSign } from 'lucide-react';
@@ -30080,37 +30079,6 @@ var init_useCanvasEffects = __esm({
30080
30079
  init_combatPresets();
30081
30080
  }
30082
30081
  });
30083
- function GameAudioToggle({
30084
- size = "sm",
30085
- className
30086
- }) {
30087
- const ctx = useGameAudioContextOptional();
30088
- const [localMuted, setLocalMuted] = useState(false);
30089
- const muted = ctx ? ctx.muted : localMuted;
30090
- const setMuted = ctx ? ctx.setMuted : setLocalMuted;
30091
- const handleToggle = useCallback(() => {
30092
- setMuted(!muted);
30093
- }, [muted, setMuted]);
30094
- return /* @__PURE__ */ jsx(
30095
- Button,
30096
- {
30097
- variant: "ghost",
30098
- size,
30099
- onClick: handleToggle,
30100
- className: cn("text-lg leading-none px-2", className),
30101
- "aria-pressed": muted,
30102
- children: muted ? "\u{1F507}" : "\u{1F50A}"
30103
- }
30104
- );
30105
- }
30106
- var init_GameAudioToggle = __esm({
30107
- "components/game/2d/atoms/GameAudioToggle.tsx"() {
30108
- "use client";
30109
- init_atoms();
30110
- init_cn();
30111
- GameAudioToggle.displayName = "GameAudioToggle";
30112
- }
30113
- });
30114
30082
  function pickPath(entry) {
30115
30083
  if (Array.isArray(entry.path)) {
30116
30084
  return entry.path[Math.floor(Math.random() * entry.path.length)];
@@ -30378,6 +30346,101 @@ var init_useGameAudio = __esm({
30378
30346
  useGameAudio.displayName = "useGameAudio";
30379
30347
  }
30380
30348
  });
30349
+ function useGameAudioContext() {
30350
+ const ctx = useContext(GameAudioContext);
30351
+ if (!ctx) {
30352
+ throw new Error("useGameAudioContext must be used inside <GameAudioProvider>");
30353
+ }
30354
+ return ctx;
30355
+ }
30356
+ function useGameAudioContextOptional() {
30357
+ return useContext(GameAudioContext);
30358
+ }
30359
+ function GameAudioProvider({
30360
+ manifest,
30361
+ baseUrl = "",
30362
+ children,
30363
+ initialMuted = false
30364
+ }) {
30365
+ const eventBus = useEventBus();
30366
+ const { play, stop, stopAll, playMusic, stopMusic, muted, setMuted, masterVolume, setMasterVolume } = useGameAudio({ manifest, baseUrl, initialMuted });
30367
+ useEffect(() => {
30368
+ const unsubPlay = eventBus.on("UI:PLAY_SOUND", (event) => {
30369
+ const key = event.payload?.key;
30370
+ if (key) play(key);
30371
+ });
30372
+ const unsubStop = eventBus.on("UI:STOP_SOUND", (event) => {
30373
+ const key = event.payload?.key;
30374
+ if (key) {
30375
+ stop(key);
30376
+ } else {
30377
+ stopAll();
30378
+ }
30379
+ });
30380
+ const unsubChangeMusic = eventBus.on("UI:CHANGE_MUSIC", (event) => {
30381
+ const key = event.payload?.key;
30382
+ if (key) {
30383
+ playMusic(key);
30384
+ } else {
30385
+ stopMusic();
30386
+ }
30387
+ });
30388
+ const unsubStopMusic = eventBus.on("UI:STOP_MUSIC", () => {
30389
+ stopMusic();
30390
+ });
30391
+ return () => {
30392
+ unsubPlay();
30393
+ unsubStop();
30394
+ unsubChangeMusic();
30395
+ unsubStopMusic();
30396
+ };
30397
+ }, [eventBus, play, stop, stopAll, playMusic, stopMusic]);
30398
+ const value = { muted, setMuted, masterVolume, setMasterVolume, play, playMusic, stopMusic };
30399
+ return /* @__PURE__ */ jsx(GameAudioContext.Provider, { value, children });
30400
+ }
30401
+ var GameAudioContext;
30402
+ var init_GameAudioProvider = __esm({
30403
+ "components/game/shared/providers/GameAudioProvider.tsx"() {
30404
+ "use client";
30405
+ init_useEventBus();
30406
+ init_useGameAudio();
30407
+ GameAudioContext = createContext(null);
30408
+ GameAudioContext.displayName = "GameAudioContext";
30409
+ GameAudioProvider.displayName = "GameAudioProvider";
30410
+ }
30411
+ });
30412
+ function GameAudioToggle({
30413
+ size = "sm",
30414
+ className
30415
+ }) {
30416
+ const ctx = useGameAudioContextOptional();
30417
+ const [localMuted, setLocalMuted] = useState(false);
30418
+ const muted = ctx ? ctx.muted : localMuted;
30419
+ const setMuted = ctx ? ctx.setMuted : setLocalMuted;
30420
+ const handleToggle = useCallback(() => {
30421
+ setMuted(!muted);
30422
+ }, [muted, setMuted]);
30423
+ return /* @__PURE__ */ jsx(
30424
+ Button,
30425
+ {
30426
+ variant: "ghost",
30427
+ size,
30428
+ onClick: handleToggle,
30429
+ className: cn("text-lg leading-none px-2", className),
30430
+ "aria-pressed": muted,
30431
+ children: muted ? "\u{1F507}" : "\u{1F50A}"
30432
+ }
30433
+ );
30434
+ }
30435
+ var init_GameAudioToggle = __esm({
30436
+ "components/game/2d/atoms/GameAudioToggle.tsx"() {
30437
+ "use client";
30438
+ init_atoms();
30439
+ init_cn();
30440
+ init_GameAudioProvider();
30441
+ GameAudioToggle.displayName = "GameAudioToggle";
30442
+ }
30443
+ });
30381
30444
  function useBattleState(initialUnits, eventConfig = {}, callbacks = {}) {
30382
30445
  const eventBus = useEventBus();
30383
30446
  const {
@@ -36437,6 +36500,8 @@ var init_VisualNovelTemplate = __esm({
36437
36500
  VisualNovelTemplate.displayName = "VisualNovelTemplate";
36438
36501
  }
36439
36502
  });
36503
+
36504
+ // components/game/2d/molecules/index.ts
36440
36505
  var init_molecules = __esm({
36441
36506
  "components/game/2d/molecules/index.ts"() {
36442
36507
  init_shared();
@@ -36469,6 +36534,7 @@ var init_molecules = __esm({
36469
36534
  init_useUnitSpriteAtlas();
36470
36535
  init_CanvasEffect();
36471
36536
  init_useCanvasEffects();
36537
+ init_GameAudioProvider();
36472
36538
  init_GameAudioToggle();
36473
36539
  init_useGameAudio();
36474
36540
  init_useCamera();
@@ -36909,13 +36975,13 @@ var init_MapView = __esm({
36909
36975
  shadowSize: [41, 41]
36910
36976
  });
36911
36977
  L.Marker.prototype.options.icon = defaultIcon;
36912
- const { useEffect: useEffect78, useRef: useRef78, useCallback: useCallback127, useState: useState119 } = React80__default;
36978
+ const { useEffect: useEffect79, useRef: useRef78, useCallback: useCallback127, useState: useState119 } = React80__default;
36913
36979
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
36914
36980
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
36915
36981
  function MapUpdater({ centerLat, centerLng, zoom }) {
36916
36982
  const map = useMap();
36917
36983
  const prevRef = useRef78({ centerLat, centerLng, zoom });
36918
- useEffect78(() => {
36984
+ useEffect79(() => {
36919
36985
  const prev = prevRef.current;
36920
36986
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
36921
36987
  map.setView([centerLat, centerLng], zoom);
@@ -36926,7 +36992,7 @@ var init_MapView = __esm({
36926
36992
  }
36927
36993
  function MapClickHandler({ onMapClick }) {
36928
36994
  const map = useMap();
36929
- useEffect78(() => {
36995
+ useEffect79(() => {
36930
36996
  if (!onMapClick) return;
36931
36997
  const handler = (e) => {
36932
36998
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -52711,9 +52777,33 @@ var init_ToastSlot = __esm({
52711
52777
  ToastSlot.displayName = "ToastSlot";
52712
52778
  }
52713
52779
  });
52714
-
52715
- // components/core/organisms/component-registry.generated.ts
52716
- var COMPONENT_REGISTRY;
52780
+ function lazyThree(name, loader) {
52781
+ const Lazy = React80__default.lazy(
52782
+ () => loader().then((m) => {
52783
+ const Resolved = m[name];
52784
+ if (!Resolved) {
52785
+ throw new Error(
52786
+ `[@almadar/ui] 3D component "${name}" was not found in the three subpath bundle.`
52787
+ );
52788
+ }
52789
+ return { default: Resolved };
52790
+ })
52791
+ );
52792
+ function ThreeWrapper(props) {
52793
+ return React80__default.createElement(
52794
+ ThreeBoundary,
52795
+ { name },
52796
+ React80__default.createElement(
52797
+ React80__default.Suspense,
52798
+ { fallback: null },
52799
+ React80__default.createElement(Lazy, props)
52800
+ )
52801
+ );
52802
+ }
52803
+ ThreeWrapper.displayName = `Lazy(${name})`;
52804
+ return ThreeWrapper;
52805
+ }
52806
+ var ThreeBoundary, GameBoard3D, GameCanvas3D, GameCanvas3DBattleTemplate, GameCanvas3DCastleTemplate, GameCanvas3DWorldMapTemplate, COMPONENT_REGISTRY;
52717
52807
  var init_component_registry_generated = __esm({
52718
52808
  "components/core/organisms/component-registry.generated.ts"() {
52719
52809
  init_AboutPageTemplate();
@@ -52824,9 +52914,11 @@ var init_component_registry_generated = __esm({
52824
52914
  init_Form();
52825
52915
  init_FormField();
52826
52916
  init_FormSectionHeader();
52917
+ init_GameAudioProvider();
52827
52918
  init_GameAudioToggle();
52828
52919
  init_GameCard();
52829
52920
  init_GameHud();
52921
+ init_GameIcon();
52830
52922
  init_GameMenu();
52831
52923
  init_GameShell();
52832
52924
  init_GameTemplate();
@@ -53011,6 +53103,33 @@ var init_component_registry_generated = __esm({
53011
53103
  init_WizardProgress();
53012
53104
  init_WorldMapBoard();
53013
53105
  init_WorldMapTemplate();
53106
+ ThreeBoundary = class extends React80__default.Component {
53107
+ constructor() {
53108
+ super(...arguments);
53109
+ __publicField(this, "state", { failed: false });
53110
+ }
53111
+ static getDerivedStateFromError() {
53112
+ return { failed: true };
53113
+ }
53114
+ render() {
53115
+ if (this.state.failed) {
53116
+ return React80__default.createElement(
53117
+ "div",
53118
+ {
53119
+ "data-testid": "three-unavailable",
53120
+ style: { padding: 16, fontSize: 13, lineHeight: 1.5, opacity: 0.7 }
53121
+ },
53122
+ `3D pattern "${this.props.name}" requires three.js. Install the optional peers three + @react-three/fiber + @react-three/drei (matching the host React major) to render it.`
53123
+ );
53124
+ }
53125
+ return this.props.children;
53126
+ }
53127
+ };
53128
+ GameBoard3D = lazyThree("GameBoard3D", () => import('@almadar/ui/components/molecules/game/three'));
53129
+ GameCanvas3D = lazyThree("GameCanvas3D", () => import('@almadar/ui/components/molecules/game/three'));
53130
+ GameCanvas3DBattleTemplate = lazyThree("GameCanvas3DBattleTemplate", () => import('@almadar/ui/components/molecules/game/three'));
53131
+ GameCanvas3DCastleTemplate = lazyThree("GameCanvas3DCastleTemplate", () => import('@almadar/ui/components/molecules/game/three'));
53132
+ GameCanvas3DWorldMapTemplate = lazyThree("GameCanvas3DWorldMapTemplate", () => import('@almadar/ui/components/molecules/game/three'));
53014
53133
  COMPONENT_REGISTRY = {
53015
53134
  "AboutPageTemplate": AboutPageTemplate,
53016
53135
  "Accordion": Accordion,
@@ -53126,9 +53245,16 @@ var init_component_registry_generated = __esm({
53126
53245
  "Form": Form,
53127
53246
  "FormField": FormField,
53128
53247
  "FormSectionHeader": FormSectionHeader,
53248
+ "GameAudioProvider": GameAudioProvider,
53129
53249
  "GameAudioToggle": GameAudioToggle,
53250
+ "GameBoard3D": GameBoard3D,
53251
+ "GameCanvas3D": GameCanvas3D,
53252
+ "GameCanvas3DBattleTemplate": GameCanvas3DBattleTemplate,
53253
+ "GameCanvas3DCastleTemplate": GameCanvas3DCastleTemplate,
53254
+ "GameCanvas3DWorldMapTemplate": GameCanvas3DWorldMapTemplate,
53130
53255
  "GameCard": GameCard,
53131
53256
  "GameHud": GameHud,
53257
+ "GameIcon": GameIcon,
53132
53258
  "GameMenu": GameMenu,
53133
53259
  "GameShell": GameShell,
53134
53260
  "GameTemplate": GameTemplate,
@@ -56546,4 +56672,4 @@ function useGitHubBranches(owner, repo, enabled = true) {
56546
56672
  });
56547
56673
  }
56548
56674
 
56549
- export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AuthLayout, Avatar, Badge, BattleBoard, BattleTemplate, BehaviorView, BloomQuizBlock, BoardgameBoard, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas2D, CanvasEffect, Card, CardBattlerBoard, CardBattlerTemplate, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, CastleBoard, CastleTemplate, Center, Chart, ChartLegend, ChatBar, Checkbox, ChoiceButton, CityBuilderBoard, CityBuilderTemplate, ClassifierBoard, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EMPTY_EFFECT_STATE, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, FishingBoard, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioToggle, GameCard, GameHud, GameIcon, GameMenu, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, HexStrategyBoard, HolidayRunnerBoard, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, ItemSlot, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MatchPuzzleBoard, MatrixQuestion, MediaGallery, Menu, Meter, MiniMap, MinigolfBoard, Modal, ModalSlot, ModuleCard, Navigation, NegotiatorBoard, NodeSlotEditor, NotifyListener, NumberStepper, ObjectRulePanel, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PinballBoard, PirateBoard, PlatformerBoard, PlatformerTemplate, Popover, PositionedCanvas, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, RacingBoard, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, ResourceBar, ResourceCounter, RichBlockEditor, RoguelikeBoard, RoguelikeTemplate, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulationCanvas, SimulationControls, SimulationGraph, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SokobanBoard, SortableList, SpaceShmupBoard, SpaceStationBoard, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, SportsBoard, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateIndicator, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TanksBoard, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TopDownShooterBoard, TopDownShooterTemplate, TowerDefenseBoard, TowerDefenseTemplate, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UncontrolledBattleBoard, UploadDropZone, VStack, VariablePanel, VersionDiff, ViolationAlert, VisualNovelBoard, VisualNovelTemplate, VoteStack, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, WorldMapBoard, WorldMapTemplate, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createCombatPresets, createInitialGameState, createTranslate, createUnitAnimationState, drawEffectState, drawSprite, drawTintedImage, getAllEffectSpriteUrls, getCurrentFrame, getTileDimensions, hasActiveEffects, inferDirection, isoToScreen, makeAsset, makeAssetMap, mapBookData, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, screenToIso, spawnOverlay, spawnParticles, spawnSequence, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, updateEffectState, useAgentChat, useAnchorRect, useAuthContext, useBattleState, useCamera, useCanvasEffects, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useLongPress, useOrbitalHistory, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSwipeGesture, useTapReveal, useTraitListens, useTranslate135 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };
56675
+ export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AuthLayout, Avatar, Badge, BattleBoard, BattleTemplate, BehaviorView, BloomQuizBlock, BoardgameBoard, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas2D, CanvasEffect, Card, CardBattlerBoard, CardBattlerTemplate, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, CastleBoard, CastleTemplate, Center, Chart, ChartLegend, ChatBar, Checkbox, ChoiceButton, CityBuilderBoard, CityBuilderTemplate, ClassifierBoard, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EMPTY_EFFECT_STATE, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, FishingBoard, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioContext, GameAudioProvider, GameAudioToggle, GameCard, GameHud, GameIcon, GameMenu, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, HexStrategyBoard, HolidayRunnerBoard, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, ItemSlot, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MatchPuzzleBoard, MatrixQuestion, MediaGallery, Menu, Meter, MiniMap, MinigolfBoard, Modal, ModalSlot, ModuleCard, Navigation, NegotiatorBoard, NodeSlotEditor, NotifyListener, NumberStepper, ObjectRulePanel, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PinballBoard, PirateBoard, PlatformerBoard, PlatformerTemplate, Popover, PositionedCanvas, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, RacingBoard, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, ResourceBar, ResourceCounter, RichBlockEditor, RoguelikeBoard, RoguelikeTemplate, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulationCanvas, SimulationControls, SimulationGraph, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SokobanBoard, SortableList, SpaceShmupBoard, SpaceStationBoard, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, SportsBoard, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateIndicator, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TanksBoard, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TopDownShooterBoard, TopDownShooterTemplate, TowerDefenseBoard, TowerDefenseTemplate, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UncontrolledBattleBoard, UploadDropZone, VStack, VariablePanel, VersionDiff, ViolationAlert, VisualNovelBoard, VisualNovelTemplate, VoteStack, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, WorldMapBoard, WorldMapTemplate, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createCombatPresets, createInitialGameState, createTranslate, createUnitAnimationState, drawEffectState, drawSprite, drawTintedImage, getAllEffectSpriteUrls, getCurrentFrame, getTileDimensions, hasActiveEffects, inferDirection, isoToScreen, makeAsset, makeAssetMap, mapBookData, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, screenToIso, spawnOverlay, spawnParticles, spawnSequence, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, updateEffectState, useAgentChat, useAnchorRect, useAuthContext, useBattleState, useCamera, useCanvasEffects, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGameAudioContext, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useLongPress, useOrbitalHistory, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSwipeGesture, useTapReveal, useTraitListens, useTranslate135 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };