@energy8platform/shell 0.6.6 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/html.cjs.js +677 -109
  2. package/dist/html.cjs.js.map +1 -1
  3. package/dist/html.d.ts +207 -27
  4. package/dist/html.esm.js +670 -110
  5. package/dist/html.esm.js.map +1 -1
  6. package/dist/index.cjs.js +378 -22
  7. package/dist/index.cjs.js.map +1 -1
  8. package/dist/index.d.ts +199 -26
  9. package/dist/index.esm.js +371 -23
  10. package/dist/index.esm.js.map +1 -1
  11. package/dist/pixi.cjs.js +952 -282
  12. package/dist/pixi.cjs.js.map +1 -1
  13. package/dist/pixi.d.ts +202 -28
  14. package/dist/pixi.esm.js +945 -283
  15. package/dist/pixi.esm.js.map +1 -1
  16. package/package.json +1 -1
  17. package/src/core/ShellController.ts +68 -16
  18. package/src/core/format.ts +8 -4
  19. package/src/core/icon-names.ts +30 -0
  20. package/src/core/index.ts +4 -0
  21. package/src/core/menu.ts +301 -0
  22. package/src/core/popover.ts +81 -0
  23. package/src/core/renderer.ts +13 -10
  24. package/src/core/state.ts +2 -1
  25. package/src/core/types.ts +15 -6
  26. package/src/core/version.ts +1 -1
  27. package/src/ui/html/HtmlRenderer.ts +31 -8
  28. package/src/ui/html/components/GameInfo.ts +1 -1
  29. package/src/ui/html/components/Menu.ts +153 -0
  30. package/src/ui/html/icons.ts +16 -15
  31. package/src/ui/html/primitives.ts +142 -0
  32. package/src/ui/html/shell.css.ts +21 -1
  33. package/src/ui/pixi/PixiRenderer.ts +32 -14
  34. package/src/ui/pixi/components/BottomBar.ts +80 -9
  35. package/src/ui/pixi/components/GameInfo.ts +1 -1
  36. package/src/ui/pixi/components/Menu.ts +167 -0
  37. package/src/ui/pixi/context.ts +3 -2
  38. package/src/ui/pixi/icons.ts +16 -15
  39. package/src/ui/pixi/pixi-icon.ts +15 -3
  40. package/src/ui/pixi/primitives/controls.ts +46 -0
  41. package/src/ui/pixi/primitives/popover.ts +163 -0
  42. package/src/ui/pixi/primitives/scroll.ts +9 -5
  43. package/src/ui/html/components/Settings.ts +0 -68
  44. package/src/ui/pixi/components/Settings.ts +0 -132
package/dist/html.d.ts CHANGED
@@ -16,13 +16,117 @@ declare class EventEmitter<TEvents extends {}> {
16
16
  removeAllListeners(event?: keyof TEvents): this;
17
17
  }
18
18
 
19
+ declare const ICON_NAMES: readonly ["spin", "turbo1", "autoplay", "stop", "menu", "minus", "plus", "gift", "info", "soundOn", "soundOff", "close", "back", "chevronRight", "ticket", "turbo2", "turboOff", "chevronUp", "chevronDown"];
20
+ type IconName = (typeof ICON_NAMES)[number];
21
+
22
+ /** Built-in presets: the id alone is enough — the shell knows the label, icon and behaviour. */
23
+ type MenuPresetId = 'sound' | 'music' | 'sfx' | 'gameInfo';
24
+ declare function isPresetId(id: string): id is MenuPresetId;
25
+ interface MenuItemBase {
26
+ id: string;
27
+ /** Overrides the preset/default label. Run through the shell translator. */
28
+ label?: string;
29
+ icon?: IconName;
30
+ disabled?: boolean;
31
+ }
32
+ type MenuPresetItem = {
33
+ id: MenuPresetId;
34
+ } & Omit<MenuItemBase, 'id'>;
35
+ type MenuToggleItem = {
36
+ type: 'toggle';
37
+ value?: boolean;
38
+ onChange?(v: boolean): void;
39
+ } & MenuItemBase;
40
+ type MenuRangeItem = {
41
+ type: 'range';
42
+ min?: number;
43
+ max?: number;
44
+ step?: number;
45
+ value?: number;
46
+ /** Right-hand readout. Defaults to percent for a 0..1 range, else the raw number. */
47
+ format?(v: number): string;
48
+ onChange?(v: number): void;
49
+ } & MenuItemBase;
50
+ type MenuButtonItem = {
51
+ type: 'button';
52
+ chevron?: boolean;
53
+ onSelect?(): void;
54
+ } & MenuItemBase;
55
+ type MenuSeparatorItem = {
56
+ type: 'separator';
57
+ };
58
+ type MenuItem = MenuPresetItem | MenuToggleItem | MenuRangeItem | MenuButtonItem | MenuSeparatorItem;
59
+ /** The rows shown when `ShellConfig.menu` is omitted — today's Settings content, minus master. */
60
+ declare const DEFAULT_MENU: MenuItem[];
61
+ /** What `resolveMenu` reads. `ShellController` satisfies it; tests can supply a small literal. */
62
+ interface MenuHost {
63
+ readonly menu: MenuItem[];
64
+ t(text: string): string;
65
+ getMenuValue(id: string): boolean | number | undefined;
66
+ setMenuValue(id: string, value: boolean | number): void;
67
+ readonly actions: {
68
+ openInfo(): void;
69
+ };
70
+ }
71
+ /** A row, ready to draw: no preset knowledge left, no config shapes, just kind + accessors. */
72
+ type MenuRow = {
73
+ kind: 'separator';
74
+ } | {
75
+ kind: 'toggle';
76
+ id: string;
77
+ label: string;
78
+ disabled: boolean;
79
+ /** Glyph for the current value (the sound preset swaps speaker on/off). */
80
+ icon(value: boolean): IconName | undefined;
81
+ get(): boolean;
82
+ set(value: boolean): void;
83
+ } | {
84
+ kind: 'range';
85
+ id: string;
86
+ label: string;
87
+ icon?: IconName;
88
+ disabled: boolean;
89
+ min: number;
90
+ max: number;
91
+ step: number;
92
+ get(): number;
93
+ set(value: number): void;
94
+ format(value: number): string;
95
+ } | {
96
+ kind: 'button';
97
+ id: string;
98
+ label: string;
99
+ icon?: IconName;
100
+ disabled: boolean;
101
+ chevron: boolean;
102
+ select(): void;
103
+ };
104
+ /** Range bounds with defaults: 0..1 like a volume slider, step = a twentieth of the span. */
105
+ declare function rangeBounds(item: {
106
+ min?: number;
107
+ max?: number;
108
+ step?: number;
109
+ }): {
110
+ min: number;
111
+ max: number;
112
+ step: number;
113
+ };
114
+ /** Initial values for CUSTOM items (presets keep their own homes). Values already in `prev` win, so
115
+ * a later `setMenu()` with the same ids does not reset what the player has changed. */
116
+ declare function seedMenuValues(items: MenuItem[], prev?: Record<string, boolean | number>): Record<string, boolean | number>;
117
+ /** Expand the configured list into render-ready rows. A config mistake — an unknown preset id, an
118
+ * unrecognized custom `type`, or an invalid range span — is dropped with one warning rather than
119
+ * silently misbehaving: a typo must be visible, not silently invisible. A custom id that collides
120
+ * with a reserved preset id also warns, but keeps its row (see `custom()`). */
121
+ declare function resolveMenu(host: MenuHost): MenuRow[];
122
+
19
123
  /** `freeSpins` and `bonus` are the SAME bar layout (host-driven hero + Total Win); `freeSpins` is
20
124
  * kept as a back-compat alias for the common case (its readout is derived current/total), while
21
125
  * `bonus` pairs with `setBonus()` to show a game-supplied label + value (adventure, hold-and-spin,
22
126
  * respins — anything that isn't a plain free-spins counter). */
23
127
  type ShellMode = 'base' | 'bonus' | 'freeSpins' | 'replay';
24
- /** The three independent volume sliders shown in the Settings overlay. */
25
- type VolumeKey = 'master' | 'music' | 'sfx';
128
+ /** The two independent volume sliders shown in the bar menu. */
129
+ type VolumeKey = 'music' | 'sfx';
26
130
  type VolumeLevels = Record<VolumeKey, number>;
27
131
  interface CurrencyConfig {
28
132
  symbol: string;
@@ -34,6 +138,9 @@ interface CurrencyConfig {
34
138
  * trimmed down to this many places so small wins keep their significant digits (e.g. 0.0673)
35
139
  * while round amounts stay compact (e.g. 0.30). Everything else is shown at exactly this many. */
36
140
  minDecimals?: number;
141
+ /** Defaults to the platform convention: `{ thousands: ',', decimal: '.' }` → `€1,234.50`.
142
+ * Override only for a jurisdiction that requires another convention — a comma decimal reads
143
+ * as a thousands group to most players and inflates the perceived payout. */
37
144
  separator?: {
38
145
  thousands?: string;
39
146
  decimal?: string;
@@ -287,11 +394,13 @@ interface ShellConfig {
287
394
  onBonusBuy?: () => void;
288
395
  /** Initial Settings-overlay volume slider positions (each 0..1, defaults to 1 = 100%). The shell
289
396
  * keeps them stateful across opens; read/update at runtime via `shell.getVolume()` /
290
- * `shell.setVolume()`, and listen to `settingChange` ({ key: 'master'|'music'|'sfx' }) to apply. */
397
+ * `shell.setVolume()`, and listen to `settingChange` ({ key: 'music'|'sfx' }) to apply. */
291
398
  volumes?: Partial<VolumeLevels>;
399
+ /** Bar-menu items, in order. Omit for the default list (sound, music, sfx, ─, game info). */
400
+ menu?: MenuItem[];
292
401
  }
293
402
  /** ShellConfig after the controller applies defaults (version, isSocial, replay, theme). No mount. */
294
- type ResolvedShellConfig = Required<Pick<ShellConfig, 'language' | 'currency' | 'availableBets' | 'defaultBet' | 'balance' | 'win' | 'mode' | 'features' | 'gameInfo' | 'version' | 'isSocial' | 'replay'>> & Pick<ShellConfig, 'currentBet' | 'theme' | 'onBonusBuy' | 'volumes'>;
403
+ type ResolvedShellConfig = Required<Pick<ShellConfig, 'language' | 'currency' | 'availableBets' | 'defaultBet' | 'balance' | 'win' | 'mode' | 'features' | 'gameInfo' | 'version' | 'isSocial' | 'replay'>> & Pick<ShellConfig, 'currentBet' | 'theme' | 'onBonusBuy' | 'volumes' | 'menu'>;
295
404
  interface ShellState {
296
405
  mode: ShellMode;
297
406
  /** Sticky replay marker — true for a historical-round replay, regardless of the current
@@ -316,9 +425,11 @@ interface ShellState {
316
425
  /** The currently activated `feature` option (e.g. Ante), or null. Drives the
317
426
  * effective-bet readout tint and the BUY BONUS → DISABLE toggle on the bar. */
318
427
  activeFeature: BonusOption | null;
319
- /** Volume slider positions (0..1) surfaced in the Settings overlay. Stateful across opens so a
320
- * reopened overlay reflects the last-set positions instead of resetting to 100%. */
428
+ /** Volume slider positions (0..1) for the two sliders in the menu. */
321
429
  volumes: VolumeLevels;
430
+ /** Values of CUSTOM menu items, keyed by id. Seeded from the item list; preset values live in
431
+ * their own homes (`soundOn`, `volumes`) and are reached through `getMenuValue`. */
432
+ menu: Record<string, boolean | number>;
322
433
  }
323
434
  interface ShellEvents {
324
435
  spin: void;
@@ -399,8 +510,6 @@ interface ShellRenderer {
399
510
  openOverlay(req: OverlayRequest): OverlayHandle | void;
400
511
  /** Tear down any open overlay. */
401
512
  closeOverlay(): void;
402
- /** If the open overlay registered a sound-icon refresher, the controller calls this to refresh it. */
403
- refreshSoundIcon?(on: boolean): void;
404
513
  /** Fade out + remove all nodes; resolve when gone. */
405
514
  destroy(): Promise<void> | void;
406
515
  /** Insets a scene should avoid (only the bottom bar is reserved; the rest is full-bleed). */
@@ -439,17 +548,21 @@ interface ShellHost {
439
548
  emit: EventEmitter<ShellEvents>['emit'];
440
549
  /** Renderer reports its surface size; the controller recomputes layout + re-renders. */
441
550
  notifyResize(w: number, h: number): void;
442
- /** Flip shared sound state (emits settingChange + refreshes an open Settings icon). */
551
+ /** Flip shared sound state (emits settingChange + refreshes an open menu's sound icon). */
443
552
  setSound(on: boolean): void;
444
- /** An open Settings overlay registers an icon updater here (null clears it on close). */
445
- setSoundRefresh(fn: ((on: boolean) => void) | null): void;
446
- /** Current volume slider position (0..1) for master/music/sfx. */
553
+ /** Current volume slider position (0..1) for music/sfx. */
447
554
  getVolume(key: VolumeKey): number;
448
555
  /** Set a volume slider (0..1): clamps, stores, emits `settingChange`, and live-updates an open
449
- * Settings overlay. Called by the slider control on drag AND by game code as the public API. */
556
+ * menu. Called by the slider control on drag AND by game code as the public API. */
450
557
  setVolume(key: VolumeKey, value: number): void;
451
- /** An open Settings overlay registers a slider updater here (null clears it on close). */
452
- setVolumeRefresh(fn: ((key: VolumeKey, value: number) => void) | null): void;
558
+ /** The configured menu items (see core/menu.ts). */
559
+ readonly menu: MenuItem[];
560
+ /** Current value of a menu item — presets included (sound → soundOn, music/sfx → volumes). */
561
+ getMenuValue(id: string): boolean | number | undefined;
562
+ /** Set a menu value: clamps ranges, stores, emits `settingChange`, refreshes an open menu. */
563
+ setMenuValue(id: string, value: boolean | number): void;
564
+ /** An open menu registers a row updater here (null clears it on close). */
565
+ setMenuRefresh(fn: ((id: string, value: boolean | number) => void) | null): void;
453
566
  /** Logic-bearing actions invoked by renderer controls. */
454
567
  readonly actions: ShellActions;
455
568
  /** Re-show the replay summary modal through the controller (keeps its OverlayHandle in sync).
@@ -487,7 +600,7 @@ interface OverlayHandle {
487
600
  close(): void;
488
601
  }
489
602
  type OverlayRequest = {
490
- kind: 'settings';
603
+ kind: 'menu';
491
604
  } | {
492
605
  kind: 'gameInfo';
493
606
  } | {
@@ -518,14 +631,15 @@ declare class ShellController extends EventEmitter<ShellEvents> implements Shell
518
631
  tokens: ShellTokens;
519
632
  layout: ShellLayoutMode;
520
633
  soundOn: boolean;
521
- readonly engineVersion = "0.6.6";
634
+ readonly engineVersion = "0.7.1";
522
635
  readonly actions: ShellActions;
523
636
  private renderer;
524
637
  private i18n;
525
638
  private kbd?;
526
639
  private overlay;
527
- private soundRefresh;
528
- private volumeRefresh;
640
+ private menuItems;
641
+ private menuRefresh;
642
+ private overlayKind;
529
643
  private prevBalance;
530
644
  private prevWin;
531
645
  private destroyed;
@@ -538,7 +652,9 @@ declare class ShellController extends EventEmitter<ShellEvents> implements Shell
538
652
  private attachKeyboard;
539
653
  private pullFocus;
540
654
  private show;
655
+ /** Open the bar menu. Called again while it is open, it closes it — the burger toggles. */
541
656
  openMenu(): void;
657
+ /** @deprecated The Settings overlay is gone — this opens the bar menu. */
542
658
  openSettings(): void;
543
659
  openInfo(): void;
544
660
  openBuyBonus(): void;
@@ -549,13 +665,20 @@ declare class ShellController extends EventEmitter<ShellEvents> implements Shell
549
665
  /** Programmatically dismiss whatever overlay/modal is open. No-op when nothing is shown. */
550
666
  closeModal(): void;
551
667
  setSound(on: boolean): void;
552
- setSoundRefresh(fn: ((on: boolean) => void) | null): void;
553
668
  getVolume(key: VolumeKey): number;
554
669
  /** Set a volume slider (0..1). Shared by the slider control (drag) and game code (public API):
555
- * clamps, stores so a reopened Settings overlay reflects it, emits `settingChange`, and
556
- * live-updates the slider if the overlay is currently open. */
670
+ * clamps, stores so a reopened menu popover reflects it, emits `settingChange`, and
671
+ * live-updates the slider if the menu is currently open. */
557
672
  setVolume(key: VolumeKey, value: number): void;
558
- setVolumeRefresh(fn: ((key: VolumeKey, value: number) => void) | null): void;
673
+ get menu(): MenuItem[];
674
+ /** Replace the item list. Values of ids already in state are kept; new ids are seeded. */
675
+ setMenu(items: MenuItem[]): void;
676
+ getMenuValue(id: string): boolean | number | undefined;
677
+ /** Set a menu value. Presets route to their own homes so there is never a second copy. */
678
+ setMenuValue(id: string, value: boolean | number): void;
679
+ setMenuRefresh(fn: ((id: string, value: boolean | number) => void) | null): void;
680
+ /** Clamp to the declared bounds of a custom `range` item (a non-range id passes through). */
681
+ private clampRange;
559
682
  activateFeature(bonus: BonusOption): void;
560
683
  deactivateFeature(): void;
561
684
  private money;
@@ -587,6 +710,56 @@ declare class ShellController extends EventEmitter<ShellEvents> implements Shell
587
710
  destroy(): Promise<void>;
588
711
  }
589
712
 
713
+ /** Geometry for the bar-menu popover. Pure math over rectangles so the DOM and Pixi renderers
714
+ * place it identically — the renderers only supply measured sizes and apply the result. */
715
+ interface Rect {
716
+ x: number;
717
+ y: number;
718
+ w: number;
719
+ h: number;
720
+ }
721
+ interface Surface {
722
+ w: number;
723
+ h: number;
724
+ }
725
+ interface PopoverPlacement {
726
+ /** Top-left of the popover card, in surface coordinates. */
727
+ x: number;
728
+ y: number;
729
+ /** True space on the chosen side, in surface coordinates; may be less than minH on a very short surface. The row list scrolls inside it. */
730
+ maxH: number;
731
+ /** Arrow centre, relative to the card's left edge. `-1` when there is no anchor to point at. */
732
+ arrowX: number;
733
+ /** True when the card opens below the anchor (arrow flips to the top edge). */
734
+ below: boolean;
735
+ }
736
+ declare const POPOVER: {
737
+ /** Keep-out from the surface edges. */
738
+ readonly margin: 8;
739
+ /** Space between the anchor and the card. */
740
+ readonly gap: 8;
741
+ /** Minimum distance from the arrow tip to either rounded corner. */
742
+ readonly arrowInset: 14;
743
+ /** A card shorter than this does not fit — flip to the other side instead. */
744
+ readonly minH: 120;
745
+ readonly minW: 220;
746
+ readonly maxW: 320;
747
+ };
748
+ /** Card width: content width clamped to [minW, maxW] and never wider than the surface. */
749
+ declare function popoverWidth(surfaceW: number, contentW: number): number;
750
+ /** Place the card above the `anchor` (below if it does not fit), left-aligned to it and clamped
751
+ * inside the surface. `anchor === null` (no bar / hidden shell) centres it, arrow off.
752
+ *
753
+ * `anchor` drives PLACEMENT (x, y, maxH, below) — normally the bar's whole plaque ("plate"), so the
754
+ * card sits flush with the bar as a whole rather than with whichever control opened it. `pointer` is
755
+ * the (optional) rect the ARROW points at — normally the burger button, which can sit anywhere
756
+ * inside the plate. Defaults to `anchor` when omitted, so every caller that only ever had one rect
757
+ * (i.e. every caller before `pointer` existed) keeps behaving exactly as it did before. */
758
+ declare function placePopover(anchor: Rect | null, surface: Surface, size: {
759
+ w: number;
760
+ h: number;
761
+ }, pointer?: Rect | null): PopoverPlacement;
762
+
590
763
  /** Rewrite restricted gambling terms in `text` to social-safe phrasing, preserving case. */
591
764
  declare function socialize(text: string): string;
592
765
  type Lang = 'de' | 'en' | 'es' | 'fi' | 'fr' | 'hi' | 'id' | 'ja' | 'ko' | 'pl' | 'pt' | 'ru' | 'tr' | 'vi' | 'zh' | 'da';
@@ -603,7 +776,7 @@ interface I18n {
603
776
  declare function createI18n(opts: I18nOptions): I18n;
604
777
 
605
778
  /** The @energy8platform/shell package version, stamped into the game-info footer. */
606
- declare const PACKAGE_VERSION = "0.6.6";
779
+ declare const PACKAGE_VERSION = "0.7.1";
607
780
 
608
781
  /** A shell: the renderer-agnostic controller plus the surface facade (safeArea/barHeight/setVisible)
609
782
  * an embedding host reads. `createShell`, `createGameShell` and `createPixiShell` all return this. */
@@ -629,7 +802,11 @@ declare class HtmlRenderer implements ShellRenderer {
629
802
  private ro;
630
803
  private moneyAnims;
631
804
  private modalOnKey;
805
+ private popoverPosition;
632
806
  private destroyed;
807
+ /** The scale factor last applied to the bar by applyFitScale() — exposed so the menu popover can
808
+ * match it exactly (see getBarScale) rather than re-derive its own, possibly-disagreeing, value. */
809
+ private barScale;
633
810
  /** MutationObserver for buy-bonus confirm fit — fires fitModals() when nodes are added
634
811
  * inside the modalHost (e.g. the confirm dialog appended after the grid is open). */
635
812
  private mutObs;
@@ -644,10 +821,13 @@ declare class HtmlRenderer implements ShellRenderer {
644
821
  animateMoney(field: 'balance' | 'win', from: number, to: number, durationMs?: number): void;
645
822
  openOverlay(req: OverlayRequest): OverlayHandle | void;
646
823
  closeOverlay(): void;
647
- refreshSoundIcon?(_on: boolean): void;
648
824
  destroy(): Promise<void>;
649
825
  /** Trigger a bar fit-scale pass (used by tests that stub geometry after the initial render). */
650
826
  fitBar(): void;
827
+ /** The scale factor applyFitScale() last applied to the bar — the menu popover multiplies its own
828
+ * card by this SAME number so its typography/padding/row-heights carry the same visual weight
829
+ * relationship the bar has, instead of ignoring the viewport like a fixed-px card would. */
830
+ getBarScale(): number;
651
831
  private cancelMoneyAnims;
652
832
  private buildOverlay;
653
833
  private showModal;
@@ -676,5 +856,5 @@ declare function createGameShell(config: HtmlShellConfig): ShellController;
676
856
  /** Tear down the active shell (no argument — singleton). Resolves immediately when nothing is active. */
677
857
  declare function removeGameShell(): Promise<void>;
678
858
 
679
- export { DEFAULT_ACCENT, ShellController as GameShell, HtmlRenderer, PACKAGE_VERSION, SCHEMES, ShellController, createGameShell, createI18n, createShell, normalizeLang, removeGameShell, resolveConfig, resolveTheme, socialize };
680
- export type { AutoplayConfig, AutoplayOptions, BonusCardContext, BonusOption, BonusReadout, CellRef, CreateShellOptions, CurrencyConfig, FreeSpinsState, GameInfoContent, GameInfoSection, GameMode, HtmlShellConfig, I18n, I18nOptions, Lang, ModalAction, ModalOptions, OverlayHandle, OverlayRequest, PaylineDef, PaytableRow, ReplayModalOptions, ResolvedShellConfig, SafeArea, ShapeDef, Shell, ShellActions, HtmlShellConfig as ShellConfig, ShellEvents, ShellFeatures, ShellHost, ShellLayoutMode, ShellMode, ShellRenderer, ShellState, ShellSurface, ShellTokens, ThemeConfig, VolumeKey, VolumeLevels, WinSection };
859
+ export { DEFAULT_ACCENT, DEFAULT_MENU, ShellController as GameShell, HtmlRenderer, PACKAGE_VERSION, POPOVER, SCHEMES, ShellController, createGameShell, createI18n, createShell, isPresetId, normalizeLang, placePopover, popoverWidth, rangeBounds, removeGameShell, resolveConfig, resolveMenu, resolveTheme, seedMenuValues, socialize };
860
+ export type { AutoplayConfig, AutoplayOptions, BonusCardContext, BonusOption, BonusReadout, CellRef, CreateShellOptions, CurrencyConfig, FreeSpinsState, GameInfoContent, GameInfoSection, GameMode, HtmlShellConfig, I18n, I18nOptions, Lang, MenuHost, MenuItem, MenuPresetId, MenuRow, ModalAction, ModalOptions, OverlayHandle, OverlayRequest, PaylineDef, PaytableRow, PopoverPlacement, Rect as PopoverRect, ReplayModalOptions, ResolvedShellConfig, SafeArea, ShapeDef, Shell, ShellActions, HtmlShellConfig as ShellConfig, ShellEvents, ShellFeatures, ShellHost, ShellLayoutMode, ShellMode, ShellRenderer, ShellState, ShellSurface, ShellTokens, ThemeConfig, VolumeKey, VolumeLevels, WinSection };