@caperjs/core 0.1.0 → 0.1.2

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 (83) hide show
  1. package/lib/{CaptionsPlugin-Dc8fIrjy.js → CaptionsPlugin-DKhbmJvH.js} +15 -15
  2. package/lib/{CaptionsPlugin-Dc8fIrjy.js.map → CaptionsPlugin-DKhbmJvH.js.map} +1 -1
  3. package/lib/{DataAdapter-BY2114sp.js → DataAdapter-BZFTkFQ4.js} +4 -4
  4. package/lib/{DataAdapter-BY2114sp.js.map → DataAdapter-BZFTkFQ4.js.map} +1 -1
  5. package/lib/{DebugRenderer-BJMLILqI.js → DebugRenderer-C7X-nlXE.js} +2 -2
  6. package/lib/{DebugRenderer-BJMLILqI.js.map → DebugRenderer-C7X-nlXE.js.map} +1 -1
  7. package/lib/{DevToolsPlugin-wQ5rOkn0.js → DevToolsPlugin-P-atJ-5U.js} +2 -2
  8. package/lib/{DevToolsPlugin-wQ5rOkn0.js.map → DevToolsPlugin-P-atJ-5U.js.map} +1 -1
  9. package/lib/{GSAPPlugin-DHhSZKv8.js → GSAPPlugin-CeH9275z.js} +2 -2
  10. package/lib/{GSAPPlugin-DHhSZKv8.js.map → GSAPPlugin-CeH9275z.js.map} +1 -1
  11. package/lib/{LayoutPlugin-B-DF9SYM.js → LayoutPlugin-iZ3k6RsK.js} +4 -4
  12. package/lib/{LayoutPlugin-B-DF9SYM.js.map → LayoutPlugin-iZ3k6RsK.js.map} +1 -1
  13. package/lib/{SpinePlugin-Dz_3dljz.js → SpinePlugin-BWiavCpO.js} +2 -2
  14. package/lib/{SpinePlugin-Dz_3dljz.js.map → SpinePlugin-BWiavCpO.js.map} +1 -1
  15. package/lib/{StatsPlugin-Cg82JMBD.js → StatsPlugin-CBpzDJL0.js} +4 -4
  16. package/lib/{StatsPlugin-Cg82JMBD.js.map → StatsPlugin-CBpzDJL0.js.map} +1 -1
  17. package/lib/{VoiceOverPlugin-BR3ImT8C.js → VoiceOverPlugin-YaiKJtJ6.js} +26 -26
  18. package/lib/{VoiceOverPlugin-BR3ImT8C.js.map → VoiceOverPlugin-YaiKJtJ6.js.map} +1 -1
  19. package/lib/caper.mjs +95 -95
  20. package/lib/caper.mjs.map +1 -1
  21. package/lib/core/Application.d.ts +1 -1
  22. package/lib/core/Application.d.ts.map +1 -1
  23. package/lib/core/interfaces/IApplicationOptions.d.ts +2 -1
  24. package/lib/core/interfaces/IApplicationOptions.d.ts.map +1 -1
  25. package/lib/core/interfaces/ICoreSignals.d.ts +5 -1
  26. package/lib/core/interfaces/ICoreSignals.d.ts.map +1 -1
  27. package/lib/display/Container.d.ts +1 -1
  28. package/lib/display/Container.d.ts.map +1 -1
  29. package/lib/display/ParticleContainer.d.ts +1 -1
  30. package/lib/display/ParticleContainer.d.ts.map +1 -1
  31. package/lib/plugins/Plugin.d.ts +1 -1
  32. package/lib/plugins/Plugin.d.ts.map +1 -1
  33. package/lib/plugins/defaults.d.ts.map +1 -1
  34. package/lib/plugins/gesture/GesturePlugin.d.ts +58 -0
  35. package/lib/plugins/gesture/GesturePlugin.d.ts.map +1 -0
  36. package/lib/plugins/gesture/gestureMath.d.ts +32 -0
  37. package/lib/plugins/gesture/gestureMath.d.ts.map +1 -0
  38. package/lib/plugins/gesture/gestureMath.test.d.ts +2 -0
  39. package/lib/plugins/gesture/gestureMath.test.d.ts.map +1 -0
  40. package/lib/plugins/gesture/index.d.ts +3 -0
  41. package/lib/plugins/gesture/index.d.ts.map +1 -0
  42. package/lib/plugins/gesture/types.d.ts +45 -0
  43. package/lib/plugins/gesture/types.d.ts.map +1 -0
  44. package/lib/plugins/index.d.ts +1 -0
  45. package/lib/plugins/index.d.ts.map +1 -1
  46. package/lib/plugins/input/Controls.d.ts +5 -2
  47. package/lib/plugins/input/Controls.d.ts.map +1 -1
  48. package/lib/plugins/input/InputPlugin.d.ts +9 -2
  49. package/lib/plugins/input/InputPlugin.d.ts.map +1 -1
  50. package/lib/plugins/input/interfaces.d.ts +5 -3
  51. package/lib/plugins/input/interfaces.d.ts.map +1 -1
  52. package/lib/plugins/input/touch/{TouchControls.d.ts → VirtualControls.d.ts} +5 -4
  53. package/lib/plugins/input/touch/VirtualControls.d.ts.map +1 -0
  54. package/lib/plugins/input/touch/index.d.ts +1 -1
  55. package/lib/plugins/input/touch/index.d.ts.map +1 -1
  56. package/lib/{registries-CYCaYKZI.js → registries-qQmLeN0b.js} +505 -354
  57. package/lib/registries-qQmLeN0b.js.map +1 -0
  58. package/lib/utils/bind.test.d.ts +2 -0
  59. package/lib/utils/bind.test.d.ts.map +1 -0
  60. package/package.json +24 -23
  61. package/src/core/Application.ts +1 -1
  62. package/src/core/interfaces/IApplicationOptions.ts +2 -0
  63. package/src/core/interfaces/ICoreSignals.ts +9 -0
  64. package/src/display/Container.ts +1 -1
  65. package/src/display/ParticleContainer.ts +1 -1
  66. package/src/plugins/Plugin.ts +1 -1
  67. package/src/plugins/defaults.ts +6 -0
  68. package/src/plugins/gesture/GesturePlugin.ts +215 -0
  69. package/src/plugins/gesture/gestureMath.test.ts +75 -0
  70. package/src/plugins/gesture/gestureMath.ts +59 -0
  71. package/src/plugins/gesture/index.ts +2 -0
  72. package/src/plugins/gesture/types.ts +54 -0
  73. package/src/plugins/index.ts +1 -0
  74. package/src/plugins/input/Controls.ts +9 -3
  75. package/src/plugins/input/InputPlugin.ts +61 -14
  76. package/src/plugins/input/interfaces.ts +5 -3
  77. package/src/plugins/input/touch/{TouchControls.ts → VirtualControls.ts} +4 -1
  78. package/src/plugins/input/touch/index.ts +1 -1
  79. package/src/utils/bind.test.ts +99 -0
  80. package/src/version.ts +1 -1
  81. package/LICENSE +0 -22
  82. package/lib/plugins/input/touch/TouchControls.d.ts.map +0 -1
  83. package/lib/registries-CYCaYKZI.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registries-qQmLeN0b.js","names":["id","extensions","extensions","extensions","extensions$1"],"sources":["../src/utils/random.ts","../src/utils/bind.ts","../src/utils/env.ts","../src/utils/string.ts","../src/utils/console/Logger.ts","../src/utils/debug.ts","../src/utils/events.ts","../src/utils/promise/functions.ts","../src/utils/vite.ts","../src/utils/promise/Queue.ts","../src/utils/framework.ts","../src/utils/map.ts","../src/utils/math.ts","../src/utils/misc.ts","../src/utils/number.ts","../src/utils/object.ts","../src/utils/padding.ts","../src/utils/point.ts","../src/utils/web.ts","../src/core/config.ts","../src/core/interfaces/IStorageCapability.ts","../../../node_modules/.pnpm/typed-signals@2.5.0/node_modules/typed-signals/dist/Collector.js","../../../node_modules/.pnpm/typed-signals@2.5.0/node_modules/typed-signals/dist/CollectorArray.js","../../../node_modules/.pnpm/typed-signals@2.5.0/node_modules/typed-signals/dist/CollectorLast.js","../../../node_modules/.pnpm/typed-signals@2.5.0/node_modules/typed-signals/dist/CollectorUntil0.js","../../../node_modules/.pnpm/typed-signals@2.5.0/node_modules/typed-signals/dist/CollectorWhile0.js","../../../node_modules/.pnpm/typed-signals@2.5.0/node_modules/typed-signals/dist/SignalConnection.js","../../../node_modules/.pnpm/typed-signals@2.5.0/node_modules/typed-signals/dist/SignalLink.js","../../../node_modules/.pnpm/typed-signals@2.5.0/node_modules/typed-signals/dist/Signal.js","../../../node_modules/.pnpm/typed-signals@2.5.0/node_modules/typed-signals/dist/SignalConnections.js","../../../node_modules/.pnpm/typed-signals@2.5.0/node_modules/typed-signals/dist/index.js","../src/signals/Signal.ts","../src/store/Store.ts","../src/mixins/signals.ts","../src/mixins/animated.ts","../src/mixins/focus.ts","../src/mixins/interaction.ts","../src/mixins/factory/methods.ts","../src/display/Container.ts","../src/display/ParticleContainer.ts","../src/display/Svg.ts","../src/display/AnimatedSprite.ts","../src/display/SpineAnimation.ts","../src/ui/Button.ts","../src/ui/FlexContainer.ts","../src/plugins/Plugin.ts","../src/plugins/actions/ActionsPlugin.ts","../src/plugins/actions/constants.ts","../src/plugins/AssetsPlugin.ts","../src/plugins/breakpoints/evaluate.ts","../src/plugins/breakpoints/types.ts","../src/plugins/breakpoints/BreakpointPlugin.ts","../src/plugins/audio/AudioChannel.ts","../src/plugins/audio/AudioInstance.ts","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/instance.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/filters/Filter.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/webaudio/WebAudioUtils.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/filters/EqualizerFilter.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/htmlaudio/HTMLAudioContext.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/htmlaudio/HTMLAudioInstance.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/htmlaudio/HTMLAudioMedia.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/SoundSprite.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/utils/supported.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/webaudio/WebAudioInstance.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/Filterable.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/webaudio/WebAudioNodes.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/webaudio/WebAudioMedia.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/Sound.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/webaudio/WebAudioContext.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/SoundLibrary.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/soundAsset.mjs","../../../node_modules/.pnpm/@pixi+sound@6.0.1_pixi.js@8.19.0/node_modules/@pixi/sound/lib/index.mjs","../src/plugins/audio/AudioManagerPlugin.ts","../src/plugins/focus/FocusOutliner.ts","../src/plugins/focus/FocusManagerPlugin.ts","../src/plugins/FullScreenPlugin.ts","../src/plugins/gesture/gestureMath.ts","../src/plugins/gesture/types.ts","../src/plugins/gesture/GesturePlugin.ts","../src/plugins/i18nPlugin.ts","../src/plugins/input/constants.ts","../src/plugins/KeyboardPlugin.ts","../src/plugins/input/AbstractControls.ts","../src/plugins/input/keyboard/KeyboardContols.ts","../src/plugins/input/touch/VirtualControls.ts","../src/plugins/input/Controls.ts","../src/plugins/input/InputPlugin.ts","../src/plugins/LookupPlugin.ts","../src/plugins/PopupManagerPlugin.ts","../src/plugins/ResizerPlugin.ts","../src/plugins/SceneManagerPlugin.ts","../src/plugins/TimerPlugin.ts","../src/plugins/WebEventsPlugin.ts","../src/ui/Toast.ts","../src/ui/Toaster.ts","../src/ui/UICanvas.ts","../src/mixins/factory/registry.ts","../src/mixins/factory/ui-registry.ts","../src/mixins/factory/utils.ts","../src/mixins/factory/schema.ts","../src/mixins/factory/const.ts","../src/mixins/factory/Factory.ts","../src/plugins/defaults.ts","../src/core/Application.ts","../src/core/registries.ts"],"sourcesContent":["import { Point } from 'pixi.js';\n\n/**\n * Generates a UUID v4 string\n * @returns {string} A UUID v4 string\n */\nexport function randomUUID(): string {\n // Check if crypto.randomUUID is available\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n\n // Fallback implementation of UUID v4\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n/**\n * Find a float between two numbers, inclusive of {@param min} and optionally inclusive of {@param max}.\n * @param min The minimum value (inclusive)\n * @param max The maximum value (exclusive by default)\n * @param includeMax Whether the max value should be inclusive (default: false)\n * @returns number\n */\nexport function floatBetween(min: number, max: number, includeMax = false): number {\n return min + Math.random() * (max - min + (includeMax ? 1 : 0));\n}\n\n/**\n * Find a float between the x,y of a Point\n * @param pt The point containing min (x) and max (y) values\n * @param includeMax Whether the max value should be inclusive (default: false)\n * @returns number\n */\nexport function floatBetweenPoint(pt: Point, includeMax = false): number {\n return floatBetween(pt.x, pt.y, includeMax);\n}\n\n/**\n * Find an integer between two numbers, inclusive of {@param min} and optionally inclusive of {@param max}.\n * @param min The minimum value (inclusive)\n * @param max The maximum value (exclusive by default)\n * @param includeMax Whether the max value should be inclusive (default: false)\n * @returns number\n */\nexport function intBetween(min: number, max: number, includeMax = false): number {\n return Math.floor(floatBetween(min, max, includeMax));\n}\n\n/**\n * Find an int between the x,y of a Point\n * @param pt The point containing min (x) and max (y) values\n * @param includeMax Whether the max value should be inclusive (default: false)\n * @returns number\n */\nexport function intBetweenPoint(pt: Point, includeMax = false): number {\n return intBetween(pt.x, pt.y, includeMax);\n}\n\n/**\n * Get a random boolean value\n * @returns boolean\n */\nexport function bool(): boolean {\n return Math.random() < 0.5;\n}\n","type MethodNames = {\n [key: string]: any;\n};\n\n/**\n * Binds the provided methods to the provided instance.\n * @param instance - The instance to which the methods should be bound.\n * @param methodNames - The names of the methods to bind.\n */\nexport function bindMethods(instance: unknown, ...methodNames: string[]) {\n methodNames.forEach((methodName) => {\n const method = (instance as MethodNames)[methodName];\n if (typeof method === 'function') {\n (instance as MethodNames)[methodName] = method.bind(instance);\n }\n });\n}\n\n/**\n * Retrieves the names of all methods in an instance's prototype chain.\n * @param instance - The instance from which to retrieve method names.\n * @param excludePrefixes - An array of prefixes to exclude from the method names.\n * @param excludeMethodNames - An array of method names to exclude.\n * @returns An array of method names.\n */\nfunction getInstanceMethodNames(\n instance: any,\n excludePrefixes: string[] = [],\n excludeMethodNames: string[] = [],\n): string[] {\n let prototype = Object.getPrototypeOf(instance);\n const methodNames: string[] = [];\n\n while (prototype) {\n const filteredMethodNames = Object.getOwnPropertyNames(prototype).filter((propertyName) => {\n const ownDescriptor = Object.getOwnPropertyDescriptor(prototype, propertyName);\n return (\n typeof ownDescriptor?.value === 'function' &&\n propertyName !== 'constructor' &&\n !excludePrefixes.some((prefix) => propertyName.startsWith(prefix)) &&\n !excludeMethodNames.includes(propertyName)\n );\n });\n\n methodNames.push(...filteredMethodNames);\n\n if (prototype === Object.prototype || Object.prototype.hasOwnProperty.call(prototype.constructor, '__caper_method_binding_root')) {\n break;\n }\n\n prototype = Object.getPrototypeOf(prototype);\n }\n\n return methodNames;\n}\n\n/**\n * Binds all methods of an instance to the instance.\n * @param instance - The instance to which the methods should be bound.\n * @param excludePrefixes - An array of prefixes to exclude from the method names.\n * @param excludeMethodNames - An array of method names to exclude.\n */\nexport function bindAllMethods(instance: any, excludePrefixes: string[] = [], excludeMethodNames: string[] = []) {\n getInstanceMethodNames(instance, excludePrefixes, excludeMethodNames).forEach((methodName) => {\n instance[methodName] = instance[methodName].bind(instance);\n });\n}\n\n/**\n * Checks if a method exists on an object and, if it does, invokes it with the provided arguments.\n * @param obj - The object on which to check for the method.\n * @param methodName - The name of the method to check for and invoke.\n * @param methodArgs - The arguments to pass to the method.\n */\nexport function checkAndInvokeMethod(obj: any, methodName: string, ...methodArgs: any[]): void {\n if (typeof obj[methodName] === 'function') {\n obj[methodName](...methodArgs);\n }\n}\n","export const env = process.env.NODE_ENV;\nexport const isDev = env === 'development';\nexport const isProduction = env === 'production';\n","export function capitalize(str: string): string {\n if (!str) return '';\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nexport function capitalizeWords(str: string): string {\n if (!str) return '';\n return str.split(' ').map(capitalize).join(' ');\n}\n","import { isDev } from '../env';\nimport { capitalize } from '../string';\n\nconst colors = {\n log: 'background: #74b64c; color: black;',\n warn: 'background: yellow; color: black;',\n error: 'background: red; color: white;',\n};\nconst lifecycleColor = 'background: #1f2937; color: #74b64c;';\n\nexport type LoggerMode = 'development' | 'default' | 'disabled';\n\nexport class Logger {\n private static _instance: Logger | null = null;\n\n private constructor(mode?: LoggerMode) {\n Logger._instance = this;\n Logger.mode = mode !== undefined ? mode : isDev ? 'development' : 'default';\n // check if mode is one of the valid modes\n if (!['development', 'default', 'disabled'].includes(Logger.mode)) {\n Logger.mode = 'default';\n }\n }\n\n private static _mode: LoggerMode = 'disabled';\n\n static get mode(): LoggerMode {\n return Logger._mode;\n }\n\n static set mode(mode: LoggerMode) {\n Logger._mode = mode;\n }\n\n public static initialize(mode?: LoggerMode) {\n if (Logger._instance) {\n throw new Error('Logger has already been instantiated.');\n }\n Logger._instance = new Logger(mode);\n }\n\n public static log(...args: any) {\n Logger.trace('log', ...args);\n }\n\n public static warn(...args: any) {\n Logger.trace('warn', ...args);\n }\n\n public static error(...args: any) {\n Logger.trace('error', ...args);\n }\n\n public static lifecycle(subject: string, phase: 'init' | 'destroy' = 'init', ...args: any[]) {\n if (Logger.mode === 'disabled') {\n return;\n }\n\n const message = `${subject} ${phase}`;\n\n if (Logger.mode === 'default') {\n return console.log(`%c ${capitalize(phase)} `, lifecycleColor, message, ...args);\n }\n\n console.groupCollapsed(`%c ${capitalize(phase)} `, lifecycleColor, message, ...args);\n console.trace(`%c Stack `, lifecycleColor);\n console.groupEnd();\n }\n\n public static trace(type: 'log' | 'warn' | 'error' = 'log', ...args: any[]) {\n if (Logger.mode === 'disabled') {\n return;\n }\n if (type === 'error') {\n // Never collapse errors: console.error keeps them visible and renders\n // Error objects with proper source-mapped stacks.\n return console.error(`%c ${capitalize(type)} `, colors[type], ...args);\n }\n if (Logger.mode === 'default') {\n return console.log(`%c ${capitalize(type)} `, colors[type], ...args);\n }\n console.groupCollapsed(`%c ${capitalize(type)} `, colors[type], ...args);\n console.trace(`%c Stack `, colors[type]);\n console.groupEnd();\n }\n}\n","import { Graphics, Text } from 'pixi.js';\n\n// --- Color palette ---\nexport const DebugColors = {\n bounds: 0x00ffff, // cyan — container bounds\n innerBounds: 0x00ff00, // green — content/child bounds\n outerBounds: 0xff0000, // red — outer/padding bounds\n direction: 0xffff00, // yellow — flow direction indicators\n gap: 0xff00ff, // magenta — gap/spacing fills\n region: 0x0078ff, // blue — grid regions\n} as const;\n\nexport const DebugAlpha = {\n stroke: 0.6,\n fill: 0.1,\n fillActive: 0.2,\n crosshair: 0.5,\n} as const;\n\n/**\n * Creates a Graphics object pre-configured for debug overlays.\n * Non-interactive, excluded from layout, labeled for identification.\n */\nexport function createDebugGraphics(label?: string): Graphics {\n const g = new Graphics();\n g.eventMode = 'none';\n g.interactiveChildren = false;\n g.layout = false;\n g.label = label ?? 'DebugGraphics';\n return g;\n}\n\n/**\n * Creates a small monospace Text label for debug overlays.\n * Dark stroke ensures readability over any background.\n */\nexport function createDebugLabel(text: string, color: number = DebugColors.bounds): Text {\n const label = new Text({\n text,\n style: {\n fontFamily: 'monospace',\n fontSize: 10,\n fill: color,\n stroke: { color: 0x000000, width: 2 },\n },\n });\n label.eventMode = 'none';\n label.layout = false;\n label.label = 'DebugLabel';\n return label;\n}\n\n// --- Registry ---\n// Tracks active debug items. A future DebugPanel can iterate\n// getDebugRegistry() to render a color → label legend.\ntype DebugEntry = { label: string; color: number };\nconst _registry = new Map<string, DebugEntry>();\n\nexport function registerDebug(id: string, label: string, color: number): void {\n _registry.set(id, { label, color });\n}\n\nexport function unregisterDebug(id: string): void {\n _registry.delete(id);\n}\n\nexport function getDebugRegistry(): ReadonlyMap<string, DebugEntry> {\n return _registry;\n}\n","export enum CaperEvent {\n REQUIRED_ASSETS_START = 'caper-required-assets-start',\n REQUIRED_ASSETS_PROGRESS = 'caper-required-assets-progress',\n REQUIRED_ASSETS_COMPLETE = 'caper-required-assets-complete',\n ASSETS_START = 'caper-assets-start',\n ASSETS_PROGRESS = 'caper-assets-progress',\n ASSETS_COMPLETE = 'caper-assets-complete',\n}\n\nexport type CaperProgressEvent = CustomEvent<{ progress: number }>;\n","/**\n * Delays the execution of the subsequent code.\n * @param {number} seconds The delay time in seconds. Default is 0.\n * @returns {Promise<void>} A promise that resolves after the specified delay.\n */\nexport const delay = (seconds: number = 0): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, seconds * 1000));\n\nexport const wait = (seconds: number = 0): Promise<void> => delay(seconds);\n\n/**\n * Checks if the given value is a promise.\n * @param {any} value The value to check.\n * @returns {boolean} True if the value is a promise, false otherwise.\n */\nexport const isPromise = (value: any): value is Promise<any> => value && typeof value.then === 'function';\n","import { Logger } from './console';\n\ninterface ViteError {\n message: string;\n stack?: string;\n /**\n * The file path that caused the error, e.g., /src/main.ts\n */\n id?: string;\n /**\n * The line number of the error\n */\n line?: number;\n /**\n * The column number of the error\n */\n column?: number;\n}\n\n/**\n * Triggers the Vite error overlay with a custom error during development.\n * This is a no-op in production builds.\n *\n * @param error The error object or a simple message string to display.\n */\nexport function triggerViteError(error: ViteError | string): void {\n // Only run in development mode\n\n if (import.meta.env.DEV) {\n const errorData = typeof error === 'string' ? { message: error } : error;\n\n // Use Vite's HMR API to send a custom event to the server\n if (import.meta.hot) {\n import.meta.hot.send('caper:show-error', { error: errorData });\n } else {\n console.error('Vite HMR is not available. Could not show error overlay.', errorData);\n }\n }\n\n Logger.error(error);\n}\n","import { triggerViteError } from '../vite';\n\n/**\n * Creates a new Queue with the given promises.\n * @param {...(Promise<any> | (() => Promise<any | void>))[]} promises The promises to add to the queue.\n * @returns {Queue} The created Queue.\n */\nexport function createQueue(...promises: (Promise<any> | (() => Promise<any | void>))[]): Queue {\n return new Queue(promises);\n}\n\n/**\n * A class representing a queue of promises.\n * @template T The type of the values that the promises in the queue resolve to.\n */\nexport class Queue<T = any | void> {\n private _promises: (Promise<any> | (() => Promise<T>))[];\n private _currentIndex: number = 0;\n private _isPaused: boolean = false;\n private _isCanceled: boolean = false;\n\n /**\n * Creates a new Queue.\n * @param {(Promise<any> | (() => Promise<T>))[]} promises The promises to add to the queue.\n */\n constructor(promises: (Promise<any> | (() => Promise<T>))[] = []) {\n this._promises = promises;\n }\n\n private _results: T[];\n\n /**\n * Gets the results of the promises that have been resolved so far.\n * @returns {T[]} The results.\n */\n public get results(): T[] {\n return this._results;\n }\n\n /**\n * Gets the progress of the queue.\n * @returns {number} The progress (0-1)\n */\n public get progress(): number {\n return this._currentIndex / this._promises.length;\n }\n\n /**\n * Adds promises to the queue.\n * @param {...(Promise<any> | (() => Promise<T>))[]} args The promises to add.\n */\n public add(...args: (Promise<any> | (() => Promise<T>))[]) {\n this._promises.push(...args);\n }\n\n /**\n * Starts the execution of the promises in the queue.\n */\n public start(): void {\n if (this._currentIndex === 0) {\n // don't start if already started\n this._results = [];\n void this._next();\n }\n }\n\n /**\n * Pauses the execution of the promises in the queue.\n */\n public pause(): void {\n this._isPaused = true;\n }\n\n /**\n * Resumes the execution of the promises in the queue.\n */\n public resume(): void {\n if (this._isPaused) {\n this._isPaused = false;\n void this._next();\n }\n }\n\n /**\n * Cancels the execution of the promises in the queue.\n */\n public cancel(): void {\n this._isCanceled = true;\n this._promises = [];\n }\n\n /**\n * Executes the next promise in the queue.\n * @private\n * @returns {Promise<void>} A promise that resolves when the next promise in the queue has been executed.\n */\n private async _next(): Promise<void> {\n if (this._isPaused || this._isCanceled || this._currentIndex >= this._promises.length) {\n return;\n }\n\n const currentFunction = this._promises[this._currentIndex];\n\n try {\n const result = typeof currentFunction === 'function' ? await currentFunction() : await currentFunction;\n this._results.push(result);\n this._currentIndex++;\n void this._next();\n } catch (error: any) {\n const err = error instanceof Error ? error : new Error(String(error));\n // Log the original error object directly (outside Logger's collapsed\n // groups) so DevTools renders a source-mapped, clickable stack.\n console.error(\"Queue didn't complete due to an error:\", error);\n triggerViteError({\n message: `Queue didn't complete due to an error: ${err.message}`,\n stack: err.stack,\n id: error?.id,\n });\n // this._isCanceled = true;\n // remove the current promise from the queue\n this._promises.splice(this._currentIndex, 1);\n void this._next();\n }\n }\n}\n","import {isPromise} from './promise';\nimport {Constructor, ImportListItem, ImportListItemModule} from './types';\n\n/**\n * Checks if the given value is a class.\n * @param {any} value The value to check.\n * @returns {boolean} True if the value is a class, false otherwise.\n */\nfunction isClass(value: any): boolean {\n return typeof value === 'function' && /^class\\s/.test(Function.prototype.toString.call(value));\n}\n\n/**\n * Retrieves the constructor of the module from the given import list item.\n * If the module is a promise, it waits for it to resolve.\n * If the module is a class, it returns it directly.\n * If the module has a named export specified in the item, it returns that.\n * Otherwise, it returns the default export of the module.\n * @param {ImportListItem<T>} item The import list item to get the module from.\n * @returns {Promise<Constructor<T>>} A promise that resolves to the constructor of the module.\n */\nexport async function getDynamicModuleFromImportListItem<T = any>(\n item: ImportListItem<T>,\n): Promise<ImportListItemModule<T>> {\n let module;\n let ctor: ImportListItemModule<T>;\n\n if (isPromise(item.module)) {\n module = await item.module;\n ctor = item?.namedExport ? module[item.namedExport] : module.default;\n } else if (typeof item.module === 'function') {\n if (isClass(item.module)) {\n module = item.module;\n ctor = module as Constructor<T>;\n } else {\n module = await (item.module as () => Promise<any>)();\n ctor = item?.namedExport ? module[item.namedExport] : module.default;\n }\n } else {\n module = item.module;\n ctor = module;\n }\n\n return ctor;\n}\n","/**\n * Returns the map entry that comes before the entry with the provided key.\n * If the provided key is the first entry in the map or doesn't exist in the map, the function returns undefined.\n * @param {Map<K, V>} map The map to search in.\n * @param {any} currentKey The key of the map entry that comes after the desired entry.\n * @returns {[K, V] | undefined} The map entry that comes before the entry with the provided key, or undefined if such an entry doesn't exist.\n */\nexport function getPreviousMapEntry<K = any, V = any>(map: Map<K, V>, currentKey: any): [K, V] | undefined {\n let previous: [any, any] | undefined;\n\n for (const entry of map) {\n if (entry[0] === currentKey) {\n return previous;\n }\n previous = entry;\n }\n return undefined;\n}\n\n/**\n * Returns the map entry that comes after the entry with the provided key.\n * If the provided key is the first entry in the map or doesn't exist in the map, the function returns undefined.\n * @param {Map<K, V>} map The map to search in.\n * @param {any} currentKey The key of the map entry that comes after the desired entry.\n * @returns {[K, V] | undefined} The map entry that comes before the entry with the provided key, or undefined if such an entry doesn't exist.\n */\nexport function getNextMapEntry<K = any, V = any>(map: Map<K, V>, currentKey: any): [K, V] | undefined {\n let next: [any, any] | undefined;\n // go in reverse\n const entries = Array.from(map.entries());\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i];\n if (entry[0] === currentKey) {\n return next;\n }\n next = entry;\n }\n return undefined;\n}\n\n/**\n * Returns the last entry in the provided map.\n * If the map is empty, the function returns undefined.\n * @param {Map<K, V>} map The map to get the last entry from.\n * @returns {[K, V] | undefined} The last entry in the map, or undefined if the map is empty.\n */\nexport function getLastMapEntry<K = any, V = any>(map: Map<K, V>): [K, V] | undefined {\n return Array.from(map.entries()).pop() as [K, V];\n}\n\n/**\n * Returns the first entry in the provided map.\n * If the map is empty, the function returns undefined.\n * @param {Map<K, V>} map The map to get the last entry from.\n * @returns {[K, V] | undefined} The last entry in the map, or undefined if the map is empty.\n */\nexport function getFirstMapEntry<K = any, V = any>(map: Map<K, V>): [K, V] | undefined {\n return Array.from(map.entries()).shift() as [K, V];\n}\n","/**\n * Clamp a number\n * @param pValue\n * @param pMin\n * @param pMax\n */\nexport function clamp(pValue: number, pMin: number, pMax: number): number {\n return Math.max(pMin, Math.min(pMax, pValue));\n}\n\n/**\n * lerp\n * @param pMin\n * @param pMax\n * @param pPerc\n */\nexport function lerp(pMin: number, pMax: number, pPerc: number): number {\n return pMin + (pMax - pMin) * pPerc;\n}\n","import { Point } from 'pixi.js';\nimport type { Size, SizeLike } from './types';\n\nexport function resolveSizeLike(size?: SizeLike): Size {\n if (size === undefined) {\n return { width: 0, height: 0 };\n }\n if (Array.isArray(size)) {\n return { width: size[0], height: size[1] === undefined ? size[0] : size[1] };\n } else if (size instanceof Point) {\n return { width: size.x, height: size.y };\n } else if (typeof size === 'object') {\n // cast as an object\n const obj = size as { width: number; height: number };\n return { width: obj.width || 0, height: obj.height || 0 };\n } else {\n return { width: size ?? 0, height: size ?? 0 };\n }\n}\n\ntype DebouncedFunction<T extends (...args: any[]) => any> = (...args: Parameters<T>) => void;\n\n/**\n * Debounce a function\n * @param func - function to debounce\n * @param wait - time in milliseconds\n * @example const debounced = debounce(() => console.log('debounced'), 1000);\n * @example window.addEventListener('resize', debounced);\n */\nexport function debounce<T extends (...args: any[]) => any>(func: T, wait: number): DebouncedFunction<T> {\n let timeoutId: NodeJS.Timeout | null = null;\n\n return function (this: any, ...args: Parameters<T>) {\n // Clear existing timeout if any\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n // Set new timeout\n timeoutId = setTimeout(() => {\n func.apply(this, args);\n timeoutId = null;\n }, wait);\n };\n}\n","export function getZeroPaddedNumber(num: number, zeroPad: number = 0): string {\n return num.toString().padStart(zeroPad, '0');\n}\n","import { DeepPartial } from './types';\n\n/**\n * Plucks the specified keys from an object and returns a new object with only those keys.\n * @template T The type of the original object.\n * @template K The keys to pluck from the original object.\n * @param {T} obj The original object.\n * @param {K[]} keys The keys to pluck from the original object.\n * @returns {Pick<T, K>} A new object with only the plucked keys.\n */\nexport function pluck<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {\n return keys.reduce((acc, key) => (key in obj ? { ...acc, [key]: obj[key] } : acc), {} as Pick<T, K>);\n}\n\n/**\n * Omits the specified keys from an object and returns a new object without those keys.\n * @template T The type of the original object.\n * @template K The keys to omit from the original object.\n * @param {K[]} keysToOmit The keys to omit from the original object.\n * @param {Partial<T>} obj The original object.\n * @returns {Omit<T, K>} A new object without the omitted keys.\n */\nexport function omitKeys<T extends object, K extends keyof T>(keysToOmit: K[], obj: Partial<T>): Omit<T, K> {\n return Object.entries(obj)\n .filter(([key]) => !keysToOmit.includes(key as K))\n .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {} as Omit<T, K>);\n}\n\nexport function deepMerge<T extends Record<string, any>>(target: T, source: DeepPartial<T>): T {\n for (const key in source) {\n if (\n source[key] !== undefined &&\n Object.prototype.toString.call(source[key]) === '[object Object]' &&\n key in target &&\n typeof target[key] === 'object'\n ) {\n target[key] = deepMerge(target[key], source[key] as T[Extract<keyof T, string>]);\n } else if (source[key] !== undefined) {\n target[key] = source[key] as T[Extract<keyof T, string>];\n }\n }\n return target;\n}\n","import type { Padding, PointLike } from './types';\n\nexport function resolvePadding(paddingNum: number, size: number) {\n // check of the paddingNum is a decimal between 0 and 1\n // if it is, return a number that is the percentage of the size\n if (paddingNum >= 0 && paddingNum <= 1) {\n return paddingNum * size;\n }\n return paddingNum;\n}\n\nexport function ensurePadding(padding: Partial<Padding> | PointLike): Padding {\n if (Array.isArray(padding)) {\n return {\n top: padding[0],\n right: padding?.[1] ?? padding[0],\n bottom: padding?.[2] ?? padding[0],\n left: padding?.[3] ?? padding?.[1] ?? padding[0] ?? 0,\n };\n }\n if (typeof padding === 'number') {\n return { top: padding, right: padding, bottom: padding, left: padding };\n } else if (typeof padding === 'object') {\n const paddingAsPointLike = padding as { x?: number; y?: number };\n if (paddingAsPointLike.x !== undefined && paddingAsPointLike.y !== undefined) {\n return {\n top: paddingAsPointLike.y,\n right: paddingAsPointLike.x,\n bottom: paddingAsPointLike.y,\n left: paddingAsPointLike.x,\n };\n } else {\n return {\n top: (padding as Padding).top ?? 0,\n right: (padding as Padding).right ?? 0,\n bottom: (padding as Padding).bottom ?? 0,\n left: (padding as Padding).left ?? 0,\n };\n }\n } else {\n return { top: 0, right: 0, bottom: 0, left: 0 };\n }\n}\n","import { Point, PointLike } from 'pixi.js';\nimport { lerp } from './math';\nimport { PointLike as CaperPointLike } from './types';\n\n/**\n * Add the x and the y values of two Points together and return a new point.\n * @returns Point\n * @param a\n * @param b\n */\nexport function add(a: PointLike, b: PointLike): Point {\n return new Point(a.x + b.x, a.y + b.y);\n}\n\n/**\n * Increase the x,y of point A by the x,y of point B.\n * @param a\n * @param b\n */\nexport function addToPoint(a: PointLike, b: PointLike): void {\n a.x += b.x;\n a.y += b.y;\n}\n\n/**\n * Subtract the x and the y values of point B from Point A and return a new point.\n * @param a\n * @param b\n */\nexport function subtract(a: PointLike, b: PointLike): Point {\n return new Point(a.x - b.x, a.y - b.y);\n}\n\n/**\n * Decrease the x,y of point A by the x,y of point B.\n * @param a\n * @param b\n */\nexport function subtractFromPoint(a: PointLike, b: PointLike): void {\n a.x -= b.x;\n a.y -= b.y;\n}\n\n/**\n * Multply the x,y values of a point by the provided value.\n * @param a\n * @param pMult\n */\nexport function multiply(a: PointLike, pMult: number): Point {\n const point: Point = new Point(a.x, a.y);\n point.x *= pMult;\n point.y *= pMult;\n return point;\n}\n\n/**\n *\n * @param pt\n * @param percent\n */\nexport function lerpPoint(pt: PointLike, percent: number): number {\n return lerp(pt.x, pt.y, percent);\n}\n\n/**\n * Get the distance between two points.\n * @param a\n * @param b\n */\nexport function distance(a: PointLike, b: Point): number {\n return Math.sqrt(distanceSq(a, b));\n}\n\n/**\n * Get the squared distance between two points.\n * @param a\n * @param b\n */\nexport function distanceSq(a: PointLike, b: Point): number {\n return (b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y);\n}\n\n/**\n * Gets the magnitude of a point.\n * @param pt\n */\nexport function magnitude(pt: PointLike): number {\n return Math.sqrt(pt.x * pt.x + pt.y * pt.y);\n}\n\nexport type PointLikeResult = { x: number; y: number } | Point;\n\nexport function resolvePointLike(\n position?: CaperPointLike,\n asPoint?: false,\n x?: number,\n y?: number,\n): { x: number; y: number };\nexport function resolvePointLike(position?: CaperPointLike, asPoint?: true, x?: number, y?: number): Point;\nexport function resolvePointLike(\n position?: CaperPointLike,\n asPoint: boolean = false,\n x: number = 0,\n y: number = 0,\n): PointLikeResult {\n if (position instanceof Point) {\n x = position.x;\n y = position.y;\n } else if (Array.isArray(position)) {\n x = position[0];\n y = position[1] === undefined ? position[0] : position[1];\n } else if (typeof position === 'object') {\n // cast as an object\n const obj = position as { x: number; y: number };\n x = obj.x || 0;\n y = obj.y || 0;\n } else {\n x = position ?? x;\n y = position ?? y;\n }\n\n return asPoint ? new Point(x, y) : { x, y };\n}\n","export type Orientation = 'portrait' | 'landscape';\n\nexport function getOrientation(): Orientation {\n const width = window.innerWidth;\n const height = window.innerHeight;\n return width > height ? 'landscape' : 'portrait';\n}\n","import { IPlugin, PluginListItem } from '../plugins/Plugin';\nimport { type AppTypeOverrides, ImportList, Logger } from '../utils';\nimport { AppConfig } from './types';\n\ntype PluginId = AppTypeOverrides['Plugins'];\n\nexport type PluginConfig = PluginId | [PluginId, { autoLoad?: boolean; options?: any }];\n\n/**\n * Resolves the config's plugin list (which may be a mix of IDs and `[id, opts]`\n * tuples) against the discovered plugin registry injected by the Vite runtime\n * plugin. Plugin discovery now includes everything formerly registered as a\n * \"storage adapter\" — unified into a single list.\n */\nexport async function generatePluginList<T extends IPlugin = IPlugin>(plugins: PluginConfig[]): Promise<ImportList<T>> {\n const pluginsList: PluginListItem[] = Caper.get('pluginsList') || [];\n\n return plugins\n .map((plugin) => {\n const p = pluginsList.find((p) => p.id === plugin || p.id === plugin[0]);\n if (!p) {\n Logger.warn(`Plugin ${plugin} not found`);\n return null;\n }\n const pluginAsArray = plugin as [string, { autoLoad?: boolean; options?: any }];\n return {\n id: p.id,\n path: p.path,\n module: p.module,\n requires: p.requires ?? [],\n options: pluginAsArray[1]?.options,\n autoLoad: pluginAsArray[1]?.autoLoad === false ? false : true,\n };\n })\n .filter(Boolean) as ImportList<T>;\n}\n\nexport function defineConfig(config: Partial<AppConfig>) {\n return config;\n}\n\n/**\n * Topologically sort the active plugin list by each item's `requires` field\n * so dependencies initialize before dependents. Throws on missing required\n * plugin or on cycle. Used by `Application.registerPlugins()` at bootstrap.\n *\n * Behavior:\n * - If `B.requires = ['A']`, A is initialized before B regardless of the\n * order they appear in `caper.config.ts plugins[]`.\n * - If `B.requires = ['A']` but A is not in the active plugin list, this\n * throws with an error message that names B, names A, and tells the\n * user to add A to `caper.config.ts plugins[]`. We deliberately do NOT\n * auto-register the missing dep — the config file is the single source\n * of truth for what plugins run, and silently inserting transitive\n * deps would make it stop being trustworthy.\n * - If a cycle exists (A→B→A), throws with the cycle path printed.\n *\n * Stable order: items with no dependencies preserve their original\n * relative order from `caper.config.ts`. Only items participating in a\n * `requires` chain get reordered.\n */\nexport function sortPluginsByRequires<T extends ImportList<IPlugin>[number]>(items: T[]): T[] {\n if (items.length < 2) return items.slice();\n\n const byId = new Map<string, T>();\n for (const it of items) byId.set(it.id, it);\n\n // Verify every required id is present in the active set. Collect ALL\n // missing deps before throwing so the user can fix them in one pass\n // rather than play whack-a-mole.\n const missing: Array<{ from: string; required: string }> = [];\n for (const it of items) {\n for (const req of it.requires ?? []) {\n if (!byId.has(req)) missing.push({ from: it.id, required: req });\n }\n }\n if (missing.length > 0) {\n const lines = missing.map(\n (m) => ` - Plugin '${m.from}' requires '${m.required}' which is not registered.`,\n );\n const fix =\n `\\nAdd the missing plugin id(s) to plugins[] in caper.config.ts:\\n ` +\n [...new Set(missing.map((m) => `'${m.required}'`))].join(', ');\n throw new Error(`Caper bootstrap failed:\\n${lines.join('\\n')}${fix}`);\n }\n\n // Kahn's algorithm with deterministic tie-breaking by original index.\n const indexOf = new Map<string, number>();\n items.forEach((it, i) => indexOf.set(it.id, i));\n\n const inDegree = new Map<string, number>();\n const dependents = new Map<string, string[]>(); // id → [ids that require it]\n for (const it of items) {\n inDegree.set(it.id, (it.requires ?? []).length);\n for (const req of it.requires ?? []) {\n if (!dependents.has(req)) dependents.set(req, []);\n dependents.get(req)!.push(it.id);\n }\n }\n\n // Ready queue, ordered by original index for stability.\n const ready: string[] = [];\n for (const it of items) {\n if (inDegree.get(it.id) === 0) ready.push(it.id);\n }\n ready.sort((a, b) => indexOf.get(a)! - indexOf.get(b)!);\n\n const result: T[] = [];\n while (ready.length > 0) {\n const id = ready.shift()!;\n result.push(byId.get(id)!);\n for (const dep of dependents.get(id) ?? []) {\n inDegree.set(dep, inDegree.get(dep)! - 1);\n if (inDegree.get(dep) === 0) {\n // Insert in original-index order to keep stable.\n const idx = indexOf.get(dep)!;\n let i = 0;\n while (i < ready.length && indexOf.get(ready[i])! < idx) i++;\n ready.splice(i, 0, dep);\n }\n }\n }\n\n if (result.length !== items.length) {\n // Cycle: find one and report it.\n const remaining = items.filter((it) => !result.includes(it)).map((it) => it.id);\n const cyclePath = findCyclePath(remaining, byId);\n throw new Error(\n `Caper bootstrap failed: plugin dependency cycle detected: ${cyclePath.join(' → ')}\\n` +\n `Plugins involved: ${remaining.join(', ')}`,\n );\n }\n\n return result;\n}\n\nfunction findCyclePath<T extends { id: string; requires?: string[] }>(\n remainingIds: string[],\n byId: Map<string, T>,\n): string[] {\n // DFS from each remaining node until we revisit a node on the current path.\n const onStack = new Set<string>();\n const path: string[] = [];\n const remaining = new Set(remainingIds);\n\n function dfs(id: string): string[] | null {\n if (onStack.has(id)) {\n const startIdx = path.indexOf(id);\n return [...path.slice(startIdx), id];\n }\n if (!remaining.has(id)) return null;\n onStack.add(id);\n path.push(id);\n for (const req of byId.get(id)?.requires ?? []) {\n const found = dfs(req);\n if (found) return found;\n }\n path.pop();\n onStack.delete(id);\n return null;\n }\n\n for (const id of remainingIds) {\n const found = dfs(id);\n if (found) return found;\n }\n return remainingIds;\n}\n","/**\n * Marker interface for plugins that can act as a key/value store.\n *\n * Any plugin whose instance has `save` and `load` methods is considered\n * storage-capable and will be reachable via `app.store.getAdapter(id)` /\n * `app.store.save(id, ...)` / `app.store.load(id, ...)`.\n *\n * Implementations are free to interpret `key` and the variadic tail however\n * they like — e.g. Firebase treats `key` as a collection name.\n */\nexport interface IStorageCapability<TSaveResult = any, TLoadResult = any> {\n save(key: string, data: any, ...rest: any[]): Promise<TSaveResult> | TSaveResult;\n load(key: string, ...rest: any[]): Promise<TLoadResult | undefined> | TLoadResult | undefined;\n}\n\n/**\n * Duck-typed guard. No base class, no inheritance — any plugin that defines\n * `save` and `load` qualifies.\n */\nexport function isStorageCapable(plugin: unknown): plugin is IStorageCapability {\n return (\n !!plugin &&\n typeof (plugin as IStorageCapability).save === 'function' &&\n typeof (plugin as IStorageCapability).load === 'function'\n );\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Collector = void 0;\n/**\n * Base class for collectors.\n *\n * @typeparam THandler The function signature to be implemented by handlers.\n */\nclass Collector {\n /**\n * Create a new collector.\n *\n * @param signal The signal to emit.\n */\n constructor(signal) {\n // eslint-disable-next-line dot-notation\n this.emit = (...args) => {\n // eslint-disable-next-line dot-notation\n signal[\"emitCollecting\"](this, args);\n };\n }\n}\nexports.Collector = Collector;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.CollectorArray = void 0;\nconst Collector_1 = require(\"./Collector\");\n/**\n * Returns the result of the all signal handlers from a signal emission in an array.\n *\n * @typeparam THandler The function signature to be implemented by handlers.\n */\nclass CollectorArray extends Collector_1.Collector {\n constructor() {\n super(...arguments);\n this.result = [];\n }\n handleResult(result) {\n this.result.push(result);\n return true;\n }\n /**\n * Get the list of results from the signal handlers.\n */\n getResult() {\n return this.result;\n }\n /**\n * Reset the result\n */\n reset() {\n this.result.length = 0;\n }\n}\nexports.CollectorArray = CollectorArray;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.CollectorLast = void 0;\nconst Collector_1 = require(\"./Collector\");\n/**\n * Returns the result of the last signal handler from a signal emission.\n *\n * @typeparam THandler The function signature to be implemented by handlers.\n */\nclass CollectorLast extends Collector_1.Collector {\n handleResult(result) {\n this.result = result;\n return true;\n }\n /**\n * Get the result of the last signal handler.\n */\n getResult() {\n return this.result;\n }\n /**\n * Reset the result\n */\n reset() {\n delete this.result;\n }\n}\nexports.CollectorLast = CollectorLast;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.CollectorUntil0 = void 0;\nconst Collector_1 = require(\"./Collector\");\n/**\n * Keep signal emissions going while all handlers return true.\n *\n * @typeparam THandler The function signature to be implemented by handlers.\n */\nclass CollectorUntil0 extends Collector_1.Collector {\n constructor() {\n super(...arguments);\n this.result = false;\n }\n handleResult(result) {\n this.result = result;\n return this.result;\n }\n /**\n * Get the result of the last signal handler.\n */\n getResult() {\n return this.result;\n }\n /**\n * Reset the result\n */\n reset() {\n this.result = false;\n }\n}\nexports.CollectorUntil0 = CollectorUntil0;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.CollectorWhile0 = void 0;\nconst Collector_1 = require(\"./Collector\");\n/**\n * Keep signal emissions going while all handlers return false.\n *\n * @typeparam THandler The function signature to be implemented by handlers.\n */\nclass CollectorWhile0 extends Collector_1.Collector {\n constructor() {\n super(...arguments);\n this.result = false;\n }\n handleResult(result) {\n this.result = result;\n return !this.result;\n }\n /**\n * Get the result of the last signal handler.\n */\n getResult() {\n return this.result;\n }\n /**\n * Reset the result\n */\n reset() {\n this.result = false;\n }\n}\nexports.CollectorWhile0 = CollectorWhile0;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.SignalConnectionImpl = void 0;\n/**\n * Implementation of SignalConnection, for internal use only.\n * @private\n */\nclass SignalConnectionImpl {\n /**\n * @param link The actual link of the connection.\n * @param parentCleanup Callback to cleanup the parent signal when a connection is disconnected\n */\n constructor(link, parentCleanup) {\n this.link = link;\n this.parentCleanup = parentCleanup;\n }\n disconnect() {\n if (this.link !== null) {\n this.link.unlink();\n this.link = null;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.parentCleanup();\n this.parentCleanup = null;\n return true;\n }\n return false;\n }\n set enabled(enable) {\n if (this.link)\n this.link.setEnabled(enable);\n }\n get enabled() {\n // eslint-disable-next-line @typescript-eslint/prefer-optional-chain\n return this.link !== null && this.link.isEnabled();\n }\n}\nexports.SignalConnectionImpl = SignalConnectionImpl;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.SignalLink = void 0;\n/**\n * SignalLink implements a doubly-linked ring with nodes containing the signal handlers.\n * @private\n */\nclass SignalLink {\n constructor(prev = null, next = null, order = 0) {\n this.enabled = true;\n this.newLink = false;\n this.callback = null;\n this.prev = prev !== null && prev !== void 0 ? prev : this;\n this.next = next !== null && next !== void 0 ? next : this;\n this.order = order;\n }\n isEnabled() {\n return this.enabled && !this.newLink;\n }\n setEnabled(flag) {\n this.enabled = flag;\n }\n unlink() {\n this.callback = null;\n this.next.prev = this.prev;\n this.prev.next = this.next;\n }\n insert(callback, order) {\n let after = this.prev;\n while (after !== this) {\n if (after.order <= order)\n break;\n after = after.prev;\n }\n const link = new SignalLink(after, after.next, order);\n link.callback = callback;\n after.next = link;\n link.next.prev = link;\n return link;\n }\n}\nexports.SignalLink = SignalLink;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Signal = void 0;\nconst SignalConnection_1 = require(\"./SignalConnection\");\nconst SignalLink_1 = require(\"./SignalLink\");\n/**\n * A signal is a way to publish and subscribe to events.\n *\n * @typeparam THandler The function signature to be implemented by handlers.\n */\nclass Signal {\n constructor() {\n this.head = new SignalLink_1.SignalLink();\n this.hasNewLinks = false;\n this.emitDepth = 0;\n this.connectionsCount = 0;\n }\n /**\n * @returns The number of connections on this signal.\n */\n getConnectionsCount() {\n return this.connectionsCount;\n }\n /**\n * @returns true if this signal has connections.\n */\n hasConnections() {\n return this.connectionsCount > 0;\n }\n /**\n * Subscribe to this signal.\n *\n * @param callback This callback will be run when emit() is called.\n * @param order Handlers with a higher order value will be called later.\n */\n connect(callback, order = 0) {\n this.connectionsCount++;\n const link = this.head.insert(callback, order);\n if (this.emitDepth > 0) {\n this.hasNewLinks = true;\n link.newLink = true;\n }\n return new SignalConnection_1.SignalConnectionImpl(link, () => this.decrementConnectionCount());\n }\n decrementConnectionCount() {\n this.connectionsCount--;\n }\n /**\n * Unsubscribe from this signal with the original callback instance.\n * While you can use this method, the SignalConnection returned by connect() will not be updated!\n *\n * @param callback The callback you passed to connect().\n */\n disconnect(callback) {\n for (let link = this.head.next; link !== this.head; link = link.next) {\n if (link.callback === callback) {\n this.decrementConnectionCount();\n link.unlink();\n return true;\n }\n }\n return false;\n }\n /**\n * Disconnect all handlers from this signal event.\n */\n disconnectAll() {\n while (this.head.next !== this.head) {\n this.head.next.unlink();\n }\n this.connectionsCount = 0;\n }\n /**\n * Publish this signal event (call all handlers).\n */\n emit(...args) {\n this.emitDepth++;\n for (let link = this.head.next; link !== this.head; link = link.next) {\n if (link.isEnabled() && link.callback)\n link.callback.apply(null, args);\n }\n this.emitDepth--;\n this.unsetNewLink();\n }\n emitCollecting(collector, args) {\n this.emitDepth++;\n for (let link = this.head.next; link !== this.head; link = link.next) {\n if (link.isEnabled() && link.callback) {\n const result = link.callback.apply(null, args);\n if (!collector.handleResult(result))\n break;\n }\n }\n this.emitDepth--;\n this.unsetNewLink();\n }\n unsetNewLink() {\n if (this.hasNewLinks && this.emitDepth === 0) {\n for (let link = this.head.next; link !== this.head; link = link.next)\n link.newLink = false;\n this.hasNewLinks = false;\n }\n }\n}\nexports.Signal = Signal;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.SignalConnections = void 0;\n/**\n * Represents a list of connections to a signal for easy disconnect.\n */\nclass SignalConnections {\n constructor() {\n this.list = [];\n }\n /**\n * Add a connection to the list.\n * @param connection\n */\n add(connection) {\n this.list.push(connection);\n }\n /**\n * Disconnect all connections in the list and empty the list.\n */\n disconnectAll() {\n for (const connection of this.list) {\n connection.disconnect();\n }\n this.list = [];\n }\n /**\n * @returns The number of connections in this list.\n */\n getCount() {\n return this.list.length;\n }\n /**\n * @returns true if this list is empty.\n */\n isEmpty() {\n return this.list.length === 0;\n }\n}\nexports.SignalConnections = SignalConnections;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.SignalConnections = exports.Signal = exports.CollectorWhile0 = exports.CollectorUntil0 = exports.CollectorLast = exports.CollectorArray = exports.Collector = void 0;\nvar Collector_1 = require(\"./Collector\");\nObject.defineProperty(exports, \"Collector\", { enumerable: true, get: function () { return Collector_1.Collector; } });\nvar CollectorArray_1 = require(\"./CollectorArray\");\nObject.defineProperty(exports, \"CollectorArray\", { enumerable: true, get: function () { return CollectorArray_1.CollectorArray; } });\nvar CollectorLast_1 = require(\"./CollectorLast\");\nObject.defineProperty(exports, \"CollectorLast\", { enumerable: true, get: function () { return CollectorLast_1.CollectorLast; } });\nvar CollectorUntil0_1 = require(\"./CollectorUntil0\");\nObject.defineProperty(exports, \"CollectorUntil0\", { enumerable: true, get: function () { return CollectorUntil0_1.CollectorUntil0; } });\nvar CollectorWhile0_1 = require(\"./CollectorWhile0\");\nObject.defineProperty(exports, \"CollectorWhile0\", { enumerable: true, get: function () { return CollectorWhile0_1.CollectorWhile0; } });\nvar Signal_1 = require(\"./Signal\");\nObject.defineProperty(exports, \"Signal\", { enumerable: true, get: function () { return Signal_1.Signal; } });\nvar SignalConnections_1 = require(\"./SignalConnections\");\nObject.defineProperty(exports, \"SignalConnections\", { enumerable: true, get: function () { return SignalConnections_1.SignalConnections; } });\n","import {\n Collector,\n CollectorArray,\n CollectorLast,\n CollectorUntil0,\n CollectorWhile0,\n SignalConnection,\n SignalConnections,\n Signal as TsSignal,\n} from 'typed-signals';\n\nconst signalPriorities = {\n highest: Number.MIN_SAFE_INTEGER,\n higher: -1000,\n high: -100,\n normal: 0,\n low: 100,\n lower: 1000,\n lowest: Number.MAX_SAFE_INTEGER,\n} as const;\n\nexport type SignalOrder = 'highest' | 'high' | 'normal' | 'low' | 'lower' | 'lowest' | number;\n\nclass Signal<THandler extends (...args: any[]) => any> extends TsSignal<THandler> {\n // add a connectOnce method to the Signal class, that will connect a listener to the signal, and then remove it after the first time it is called\n public connectOnce(callback: THandler, order?: SignalOrder): SignalConnection {\n // Wrapper function to include logic for disconnecting\n const wrapper: THandler = ((...args: any[]) => {\n callback(...args);\n // Assuming you have a method to remove the connection, using it here to disconnect\n wrapperConnection.disconnect();\n }) as THandler;\n\n // Connect the wrapper with the same order, store the connection\n const wrapperConnection = this.connect(wrapper, order);\n return wrapperConnection;\n }\n\n public connectNTimes(callback: THandler, times: number, order?: SignalOrder): SignalConnection {\n let numTimes = 0;\n // Wrapper function to include logic for disconnecting\n const wrapper: THandler = ((...args: any[]) => {\n callback(...args);\n numTimes++;\n if (numTimes >= times) {\n wrapperConnection.disconnect();\n }\n }) as THandler;\n // Connect the wrapper with the same order, store the connection\n const wrapperConnection = this.connect(wrapper, order);\n return wrapperConnection;\n }\n\n /**\n * Subscribe to this signal.\n *\n * @param callback This callback will be run when emit() is called.\n * @param order Handlers with a higher order value will be called later.\n */\n public connect(callback: THandler, order: SignalOrder = 'normal'): SignalConnection {\n const priority = signalPriorities[order as keyof typeof signalPriorities] ?? order;\n return super.connect(callback, priority);\n }\n}\n\n// export anything useful from ts-signals, as well as the new Signal class\nexport { Collector, CollectorArray, CollectorLast, CollectorUntil0, CollectorWhile0, Signal, SignalConnections };\nexport type { SignalConnection };\n","import type { IApplication } from '../core';\nimport { isStorageCapable, type IStorageCapability } from '../core/interfaces/IStorageCapability';\nimport type { IPlugin } from '../plugins/Plugin';\nimport { Signal } from '../signals';\nimport { type AppTypeOverrides, Logger } from '../utils';\n\nexport type StoreErrorDetail = {\n adapterId: string;\n operation: 'save' | 'load';\n key: string;\n error: Error;\n};\n\ntype AppPlugins = AppTypeOverrides['Plugins'];\n\n/**\n * Configuration for a single save call.\n */\ntype AdapterSaveConfig = {\n adapterId: string;\n awaitSave: boolean;\n};\n\n/**\n * Thin façade over the Application's plugin registry.\n *\n * A \"storage adapter\" is nothing more than a `Plugin` whose instance implements\n * {@link IStorageCapability}. The `Store` doesn't own a second registry — it\n * just filters `app._plugins` for storage-capable entries and routes save/load\n * calls through them.\n */\nexport interface IStore {\n initialize(app: IApplication): IStore;\n\n destroy(): void;\n\n getAdapter<T extends IStorageCapability = IStorageCapability>(adapterId: AppPlugins): T;\n\n hasAdapter(adapterId: AppPlugins): boolean;\n\n save(\n adapterId: AppPlugins | AppPlugins[] | Partial<AdapterSaveConfig> | Partial<AdapterSaveConfig>[],\n key: string,\n data: any,\n awaitSave?: boolean,\n ): Promise<any>;\n\n load(adapterId: AppPlugins, key: string): Promise<any>;\n\n onError: Signal<(detail: StoreErrorDetail) => void>;\n}\n\nexport class Store implements IStore {\n public readonly onError = new Signal<(detail: StoreErrorDetail) => void>();\n private _app!: IApplication;\n\n public initialize(app: IApplication): IStore {\n this._app = app;\n return this;\n }\n\n public destroy(): void {\n // Plugin lifecycle is owned by Application. Nothing to clean up here.\n this.onError.disconnectAll();\n }\n\n private _emitError(detail: StoreErrorDetail): void {\n Logger.error(\n `[Store.${detail.operation}] adapter='${detail.adapterId}' key='${detail.key}': ${detail.error.message}`,\n );\n this.onError.emit(detail);\n }\n\n /**\n * Returns a storage-capable plugin by id. Throws if the plugin is missing or\n * does not implement {@link IStorageCapability}.\n */\n public getAdapter<T extends IStorageCapability = IStorageCapability>(adapterId: AppPlugins): T {\n const plugin = this._app.getPlugin(adapterId as string) as unknown as IPlugin & Partial<IStorageCapability>;\n if (!plugin) {\n throw new Error(`Adapter ${String(adapterId)} not found`);\n }\n if (!isStorageCapable(plugin)) {\n throw new Error(`Plugin '${String(adapterId)}' is not storage-capable (missing save/load)`);\n }\n return plugin as unknown as T;\n }\n\n public hasAdapter(adapterId: AppPlugins): boolean {\n const plugin = this._app.getPlugin(adapterId as string) as unknown as IPlugin | undefined;\n return !!plugin && isStorageCapable(plugin);\n }\n\n /**\n * Iterates every storage-capable plugin currently registered with the app.\n */\n private allAdapterIds(): string[] {\n // Application exposes its plugin map as `_plugins` (protected). We reach in\n // via a known cast rather than widening the public IApplication surface.\n const map = (this._app as unknown as { _plugins: Map<string, IPlugin> })._plugins;\n const ids: string[] = [];\n if (map) {\n for (const [id, plugin] of map) {\n if (isStorageCapable(plugin)) ids.push(id);\n }\n }\n return ids;\n }\n\n public async save(\n adapterId: AppPlugins | AppPlugins[] | Partial<AdapterSaveConfig> | Partial<AdapterSaveConfig>[],\n key: string,\n data: any,\n awaitSave = true,\n ): Promise<any> {\n let keys: string[] | Partial<AdapterSaveConfig>[] = [];\n const result: any[] = [];\n\n if (!Array.isArray(adapterId)) {\n if (typeof adapterId === 'object') {\n keys = [adapterId];\n } else {\n keys = [adapterId as string];\n }\n } else {\n keys = adapterId as string[] | Partial<AdapterSaveConfig>[];\n }\n\n if ((keys[0] as string) === '*' || (keys[0] as Partial<AdapterSaveConfig>)?.adapterId === '*') {\n keys = this.allAdapterIds();\n }\n\n for (let i = 0; i < keys.length; i++) {\n let aKey: string;\n let shouldAwait = false;\n if (typeof keys[i] === 'object') {\n const obj = keys[i] as Partial<AdapterSaveConfig>;\n aKey = obj.adapterId as string;\n shouldAwait = obj.awaitSave ?? false;\n } else {\n aKey = keys[i] as unknown as string;\n shouldAwait = awaitSave;\n }\n\n let adapter: IStorageCapability;\n try {\n adapter = this.getAdapter(aKey as AppPlugins);\n } catch (e) {\n this._emitError({ adapterId: aKey, operation: 'save', key, error: e as Error });\n throw e;\n }\n\n if (shouldAwait) {\n try {\n result.push(await adapter.save(key, data));\n } catch (e) {\n this._emitError({ adapterId: aKey, operation: 'save', key, error: e as Error });\n throw e;\n }\n } else {\n // Fire-and-forget: don't block caller, but never let failures vanish\n // as unhandled promise rejections. Route them through onError instead.\n const idForSignal = aKey;\n result.push(\n adapter.save(key, data).catch((e: unknown) => {\n this._emitError({\n adapterId: idForSignal,\n operation: 'save',\n key,\n error: e as Error,\n });\n }),\n );\n }\n }\n return result;\n }\n\n public async load(adapterId: AppPlugins, key: string): Promise<any> {\n try {\n return await this.getAdapter(adapterId).load(key);\n } catch (e) {\n this._emitError({\n adapterId: adapterId as string,\n operation: 'load',\n key,\n error: e as Error,\n });\n throw e;\n }\n }\n}\n","import { DestroyOptions } from 'pixi.js';\nimport { SignalConnection, SignalConnections } from '../signals';\nimport type { Constructor } from '../utils';\n\n/**\n * Interface for animated entities.\n */\nexport interface ISignalContainer {\n signalConnections: SignalConnections;\n\n destroy(options?: DestroyOptions): void;\n\n addSignalConnection(...args: SignalConnection[]): void;\n connectSignal(...args: SignalConnection[]): void;\n connectAction(...args: SignalConnection[]): void;\n}\n\nexport function WithSignals<TBase extends Constructor<any>>(Base: TBase): TBase & Constructor<ISignalContainer> {\n return class extends Base implements ISignalContainer {\n signalConnections: SignalConnections = new SignalConnections();\n\n /**\n * Add signal connections to the container.\n * @param args - The signal connections to add.\n */\n public addSignalConnection(...args: SignalConnection[]) {\n for (const connection of args) {\n this.signalConnections.add(connection);\n }\n }\n\n public connectSignal(...args: SignalConnection[]) {\n for (const connection of args) {\n this.signalConnections.add(connection);\n }\n }\n\n public connectAction(...args: SignalConnection[]) {\n for (const connection of args) {\n this.signalConnections.add(connection);\n }\n }\n\n destroy(options?: DestroyOptions): void {\n this.signalConnections.disconnectAll();\n super.destroy(options);\n }\n } as unknown as TBase & Constructor<ISignalContainer>;\n}\n","import { gsap } from 'gsap';\nimport { Signal } from '../signals';\nimport type { Constructor } from '../utils';\n\n/**\n * Extended GSAP animation configuration interface.\n */\nexport interface GSAPAnimationConfigExtended extends gsap.TweenVars {}\n\n/**\n * Type for GSAP entity.\n */\ntype GSAPEntity = gsap.core.Tween | gsap.core.Timeline;\n\ninterface ShakeConfig {\n duration: number;\n intensity: number;\n times: number;\n x: boolean;\n y: boolean;\n}\n\nconst defaultShakeConfig: ShakeConfig = {\n x: true,\n y: true,\n intensity: 3,\n duration: 0.05,\n times: 4,\n};\n\n/**\n * Interface for animated entities.\n */\nexport interface IAnimated {\n onAnimationStart: Signal<(entity: GSAPEntity) => void>;\n onAnimationUpdate: Signal<(entity: GSAPEntity) => void>;\n onAnimationComplete: Signal<(entity: GSAPEntity) => void>;\n\n animate(animationProps: GSAPAnimationConfigExtended, instance?: any): gsap.core.Tween;\n\n animateFrom(animationProps: GSAPAnimationConfigExtended, instance?: any): gsap.core.Tween;\n\n animateFromTo(\n fromProps: GSAPAnimationConfigExtended,\n toProps: GSAPAnimationConfigExtended,\n instance?: any,\n ): gsap.core.Tween;\n\n animateSequence(sequences: GSAPAnimationConfigExtended[], instance?: any): gsap.core.Timeline;\n\n pauseAnimations(): void;\n\n resumeAnimations(): void;\n\n destroyAnimations(): void;\n\n reverseAnimation(): void;\n\n isAnimationPlaying(): boolean;\n\n //utility\n shake(config?: Partial<ShakeConfig>, instance?: any): gsap.core.Tween;\n\n pulse(config?: { duration?: number; intensity?: number; times?: number }, instance?: any): gsap.core.Tween;\n\n bob(config?: { duration?: number; intensity?: number }, instance?: any): gsap.core.Tween;\n}\n\n/**\n * Animated mixin function.\n * @param Base - Base class to extend.\n * @returns Class that extends the base class and implements IAnimated.\n */\nexport function Animated<TBase extends Constructor>(Base: TBase): TBase & Constructor<IAnimated> {\n return class extends Base implements IAnimated {\n // signals for animation events\n onAnimationStart = new Signal<(entity: GSAPEntity) => void>();\n onAnimationUpdate = new Signal<(entity: GSAPEntity) => void>();\n onAnimationComplete = new Signal<(entity: GSAPEntity) => void>();\n\n // store active tweens / timelines\n _activeTweens: gsap.core.Tween[] = [];\n _activeTimeline?: gsap.core.Timeline;\n\n /**\n * Animate method.\n * @param animationProps - Animation properties.\n * @param instance - Instance to animate.\n * @returns GSAP Tween instance.\n */\n public animate(animationProps: GSAPAnimationConfigExtended, instance: any = this) {\n const tween = gsap.to(instance, {\n ...animationProps,\n onStart: () => {\n this._onAnimationStart(tween);\n },\n onUpdate: () => {\n this._onAnimationUpdate(tween);\n },\n onComplete: () => {\n this._onAnimationComplete(tween);\n this._activeTweens = this._activeTweens.filter((t) => t !== tween);\n },\n });\n this._activeTweens.push(tween);\n return tween;\n }\n\n /**\n * Animate from method.\n * @param animationProps - Animation properties.\n * @param instance - Instance to animate.\n * @returns GSAP Tween instance.\n */\n public animateFrom(animationProps: GSAPAnimationConfigExtended, instance: any = this) {\n const tween = gsap.from(instance, {\n ...animationProps,\n onStart: () => {\n this._onAnimationStart(tween);\n },\n onUpdate: () => {\n this._onAnimationUpdate(tween);\n },\n onComplete: () => {\n this._onAnimationComplete(tween);\n this._activeTweens = this._activeTweens.filter((t) => t !== tween);\n },\n });\n this._activeTweens.push(tween);\n return tween;\n }\n\n /**\n * Animate sequence method.\n * @param sequences - Array of animation sequences.\n * @param instance - Instance to animate.\n * @returns GSAP Timeline instance.\n */\n public animateSequence(sequences: GSAPAnimationConfigExtended[], instance: any = this): gsap.core.Timeline {\n if (!this._activeTimeline) {\n this._activeTimeline = gsap.timeline({\n onStart: () => this._onAnimationStart(this._activeTimeline),\n onUpdate: () => this._onAnimationUpdate(this._activeTimeline),\n onComplete: () => {\n this._onAnimationComplete(this._activeTimeline);\n this._activeTimeline = undefined;\n },\n });\n }\n\n sequences.forEach((sequence) => {\n this._activeTimeline?.to(instance, sequence);\n });\n\n return this._activeTimeline;\n }\n\n /**\n * Clear animations method.\n */\n public destroyAnimations() {\n this._activeTweens.forEach((tween) => tween.kill());\n this._activeTweens = [];\n this._activeTimeline?.clear();\n this._activeTimeline = undefined;\n }\n\n /**\n * Pause animations method.\n */\n public pauseAnimations() {\n this._activeTweens.forEach((tween) => tween.pause());\n this._activeTimeline?.pause();\n }\n\n /**\n * Resume animations method.\n */\n public resumeAnimations() {\n this._activeTweens.forEach((tween) => tween.play());\n this._activeTimeline?.play();\n }\n\n /**\n * Animate from-to method.\n * @param fromProps - Animation properties for the start state.\n * @param toProps - Animation properties for the end state.\n * @param instance - Instance to animate.\n * @returns GSAP Tween instance.\n */\n public animateFromTo(\n fromProps: GSAPAnimationConfigExtended,\n toProps: GSAPAnimationConfigExtended,\n instance: any = this,\n ) {\n const tween = gsap.fromTo(\n instance,\n {\n ...fromProps,\n },\n {\n ...toProps,\n },\n );\n tween.eventCallback('onStart', () => {\n this._onAnimationStart(tween);\n });\n tween.eventCallback('onUpdate', () => {\n this._onAnimationUpdate(tween);\n });\n tween.eventCallback('onComplete', () => {\n this._onAnimationComplete(tween);\n this._activeTweens = this._activeTweens.filter((t) => t !== tween);\n });\n\n this._activeTweens.push(tween);\n return tween;\n }\n\n /**\n * Reverses animations.\n */\n public reverseAnimation(): void {\n this._activeTweens.forEach((tween) => tween.reverse());\n this._activeTimeline?.reverse();\n }\n\n public isAnimationPlaying(): boolean {\n return (\n this._activeTweens?.some((tween) => !tween.paused()) ||\n (this._activeTimeline && !this._activeTimeline.paused()) ||\n false\n );\n }\n\n // utility animations\n /**\n * Shake animation.\n * @param config - Configuration object.\n * @param instance\n * @returns GSAP Tween instance.\n */\n public shake(config: Partial<ShakeConfig>, instance: any = this): gsap.core.Tween {\n const resolvedConfig = { ...defaultShakeConfig, ...config };\n const obj = { x: instance.x, y: instance.y };\n const origX = obj.x;\n const origY = obj.y;\n const repeat = resolvedConfig.times % 2 === 0 ? resolvedConfig.times + 1 : resolvedConfig.times;\n\n const tween = gsap.to(instance, {\n x: resolvedConfig.x\n ? origX + gsap.utils.random(-Math.max(resolvedConfig.intensity, 2), Math.max(resolvedConfig.intensity, 2))\n : origX,\n y: resolvedConfig.y\n ? origY + gsap.utils.random(-Math.max(resolvedConfig.intensity, 2), Math.max(resolvedConfig.intensity, 2))\n : origY,\n repeat,\n yoyo: true,\n duration: resolvedConfig.duration,\n });\n this._activeTweens.push(tween);\n return tween;\n }\n\n /**\n * Pulse animation.\n * @param config - Configuration object.\n * @param instance\n * @returns GSAP Tween instance.\n */\n public pulse(\n config: {\n duration?: number;\n intensity?: number;\n times?: number;\n } = {},\n instance: any = this,\n ): gsap.core.Tween {\n const { duration = 0.5, intensity = 1.2, times = 1 } = config;\n const repeat = times * 2 - 1;\n const tween = gsap.to(instance?.scale, {\n x: intensity,\n y: intensity,\n repeat,\n yoyo: true,\n duration: duration,\n });\n this._activeTweens.push(tween);\n return tween;\n }\n\n /**\n * Bob animation.\n * @param config - Configuration object.\n * @param instance\n * @returns GSAP Tween instance.\n */\n public bob(\n config: {\n duration?: number;\n intensity?: number;\n } = {},\n instance: any = this,\n ): gsap.core.Tween {\n const { duration = 0.5, intensity = 10 } = config;\n const tween = gsap.to(instance, {\n y: `-=${intensity}`,\n repeat: -1,\n yoyo: true,\n duration: duration,\n });\n this._activeTweens.push(tween);\n return tween;\n }\n\n /**\n * Private method for handling animation start event.\n * @param animationEntity - Animation entity.\n */\n private _onAnimationStart(animationEntity: GSAPEntity | undefined) {\n this.onAnimationStart.emit(animationEntity as GSAPEntity);\n }\n\n /**\n * Private method for handling animation update event.\n * @param animationEntity - Animation entity.\n */\n private _onAnimationUpdate(animationEntity: GSAPEntity | undefined) {\n this.onAnimationUpdate.emit(animationEntity as GSAPEntity);\n }\n\n /**\n * Private method for handling animation complete event.\n * @param animationEntity - Animation entity.\n */\n private _onAnimationComplete(animationEntity: GSAPEntity | undefined) {\n this.onAnimationComplete.emit(animationEntity as GSAPEntity);\n }\n } as unknown as TBase & Constructor<IAnimated>;\n}\n","import type { DestroyOptions, PointerEvents } from 'pixi.js';\nimport { Container, FederatedEvent } from 'pixi.js';\nimport type { Constructor, PointLike } from '../utils';\n\nimport { Application } from '../core/Application';\nimport type { IFocusable } from '../plugins';\nimport { Signal } from '../signals';\n\n/**\n * The Focusable function is a higher-order function that adds focus-related functionality to a given class.\n *\n * @param {TBase extends Constructor<Container>} Base - The base class to add focus functionality to.\n *\n * @returns {TBase & Constructor<IFocusable>} The modified class with focus functionality.\n */\nexport function Focusable<TBase extends Constructor<Container>>(Base: TBase): TBase & Constructor<IFocusable> {\n return class extends Base implements IFocusable {\n _accessibleDiv: HTMLElement;\n isFocused = false;\n isKeyDown = false;\n focusEnabled = true;\n tabIndex = 0;\n // pixi accessibility options\n accessible = false;\n accessibleType: keyof HTMLElementTagNameMap | undefined = 'button';\n accessibleTitle = 'Focusable';\n accessibleHint = 'Press enter to focus';\n accessiblePointerEvents: PointerEvents = 'auto';\n accessibleChildren = true;\n // signals\n onFocus = new Signal<(focusable: IFocusable) => void>();\n onFocusIn = new Signal<(focusable: IFocusable) => void>();\n onFocusOut = new Signal<(focusable: IFocusable) => void>();\n onBlur = new Signal<(focusable: IFocusable) => void>();\n\n private _eventsDisabled: boolean = false;\n\n constructor(...args: any[]) {\n super(...args);\n this.eventMode = 'static';\n this.on('mouseover', this._onMouseOver);\n this.on('mousedown', this._onMouseDown);\n this.on('click', this._handleClick);\n this.on('tap', this._handleClick);\n }\n\n get app() {\n return Application.getInstance();\n }\n\n public destroy(options?: DestroyOptions): void {\n this.off('mouseover', this._onMouseOver);\n this.off('mousedown', this._onMouseDown);\n this.off('click', this._handleClick);\n this.off('tap', this._handleClick);\n super.destroy(options);\n }\n\n public focusIn() {\n if (this.app.focus.active) {\n // @ts-expect-error Argument of type { type: string; } is not assignable to parameter of type FederatedPointerEvent\n this.emit('pointerover', { type: 'pointerover' });\n }\n }\n\n public blur() {\n if (!this.isKeyDown) {\n window.removeEventListener('keyup', this._handleKeyUp.bind(this));\n }\n }\n\n public focusOut() {\n if (!this.isKeyDown) {\n window.removeEventListener('keyup', this._handleKeyUp.bind(this));\n }\n if (this.app.focus.active) {\n // @ts-expect-error Argument of type { type: string; } is not assignable to parameter of type FederatedPointerEvent\n this.emit('pointerout', { type: 'pointerout' });\n }\n }\n\n public click() {}\n\n public getFocusPosition() {\n return null;\n }\n\n public getFocusArea() {\n return this.getBounds();\n }\n\n public getFocusSize(): PointLike | null {\n return [this.getFocusArea().width, this.getFocusArea().height];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected _onMouseOver(_e: MouseEvent) {\n this.app.focus.setFocus(this);\n }\n\n protected _onMouseDown(e: FederatedEvent) {\n this._maybeEmit('pointerdown', e);\n }\n\n protected _handleClick(e: FederatedEvent) {\n this._maybeEmit('click', e);\n this.click();\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected _handleKeyUp(_e: KeyboardEvent) {}\n\n private _maybeEmit(type: string, e: FederatedEvent) {\n if (this._eventsDisabled || e.type) {\n return;\n }\n this._eventsDisabled = true;\n this.emit(type, { type });\n this._eventsDisabled = false;\n }\n } as unknown as TBase & Constructor<IFocusable>;\n}\n\nFocusable.INITTED = false;\n","import type { AllFederatedEventMap, DestroyOptions } from 'pixi.js';\nimport { Container, FederatedEvent } from 'pixi.js';\nimport { Signal } from '../signals';\n\nimport { type Constructor } from '../utils';\n\n// gets all the event names from the PIXI event map\ntype InteractionEventName = keyof AllFederatedEventMap;\n\nexport type InteractionSignal = Signal<(event: FederatedEvent) => void>;\n\n/**\n * Represents an interactive element.\n */\nexport interface IInteractive {\n onInteraction: (eventName: InteractionEventName) => InteractionSignal;\n}\n\n/**\n * Adds interactive functionality to a container.\n *\n * @param {Constructor<Container>} Base - The base container class.\n * @returns {Constructor<IInteractive>} - The extended container class with interactive functionality.\n */\nexport function Interactive<TBase extends Constructor<Container>>(Base: TBase): TBase & Constructor<IInteractive> {\n return class extends Base implements IInteractive {\n private _signals: Map<InteractionEventName, InteractionSignal> = new Map();\n\n constructor(...args: any[]) {\n super(...args);\n this._emitSignal = this._emitSignal.bind(this);\n this.eventMode = 'static';\n }\n\n /**\n * Handles interaction events and returns the corresponding signal.\n *\n * @param {InteractionEventName} eventName - The name of the interaction event.\n * @return {InteractionSignal} The signal associated with the interaction event.\n */\n public onInteraction(eventName: InteractionEventName) {\n if (!this._signals.has(eventName)) {\n const signal = new Signal<(event: FederatedEvent) => void>();\n this._signals.set(eventName, signal);\n this.on(eventName, this._emitSignal);\n }\n return this._signals.get(eventName) as InteractionSignal;\n }\n\n public destroy(options: DestroyOptions): void {\n for (const eventName of this._signals.keys()) {\n this.off(eventName, this._emitSignal);\n }\n this._signals.clear();\n super.destroy(options);\n }\n\n /**\n * Emits a signal with the given event.\n *\n * @param {FederatedEvent} event - The event to emit.\n *\n * @return {void}\n */\n private _emitSignal(event: FederatedEvent) {\n const signalName = event.type as InteractionEventName;\n const signal = this._signals.get(signalName);\n\n if (signal) {\n signal.emit(event);\n }\n }\n } as unknown as TBase & Constructor<IInteractive>;\n}\n","import { defaultFactoryMethods } from './index';\n\nexport function createFactoryMethods<T extends typeof defaultFactoryMethods = typeof defaultFactoryMethods>(\n methods: Partial<T>,\n instance: any,\n addToStage: boolean,\n): T {\n const factoryMethods: any = {};\n for (const key in methods) {\n factoryMethods[key] = (...args: any[]) => {\n // @ts-expect-error - this is fine\n const obj = methods[key](...args);\n if (addToStage) {\n instance.addChild(obj);\n // instance.addChild(obj);\n }\n return obj;\n };\n }\n return factoryMethods as T;\n}\n","import { DestroyOptions, Container as PIXIContainer, Sprite, Texture, Ticker } from 'pixi.js';\nimport { Animated, Factory, WithSignals } from '../mixins';\n\nimport { Application } from '../core/Application';\nimport { Signal } from '../signals';\nimport { SignalOrder } from '../signals/Signal';\nimport type { AppTypeOverrides, PointLike, Size } from '../utils';\nimport { bindAllMethods } from '../utils';\n\n/**\n * Configuration for the Container class.\n */\nexport type ContainerConfig = {\n autoResize: boolean;\n autoUpdate: boolean;\n priority: SignalOrder;\n};\n\nexport const ContainerConfigKeys: (keyof ContainerConfig)[] = ['autoResize', 'autoUpdate', 'priority'];\n\nconst defaultConfig: ContainerConfig = { autoResize: true, autoUpdate: false, priority: 0 };\n\nexport type BackgroundConfig = {\n color: number;\n alpha: number;\n width: number;\n height: number;\n anchor: PointLike;\n autoResize: boolean;\n};\n\n/**\n * Interface for the Container class.\n */\nexport interface IContainer {\n app: AppTypeOverrides['App'];\n\n animationContext: string | undefined;\n\n onDestroy: Signal<() => void>;\n\n destroy(options?: DestroyOptions): void;\n\n added(): Promise<void> | void;\n\n removed(): Promise<void> | void;\n\n childAdded(child: PIXIContainer): Promise<void> | void;\n childRemoved(child: PIXIContainer): Promise<void> | void;\n\n resize(size?: Size): void;\n\n update(ticker?: Ticker | number): void;\n\n addColoredBackground(colorOrConfig?: number | Partial<BackgroundConfig>, alpha?: number): Sprite;\n}\n\n/**\n * The Container class extends the _Container class (which includes the Animated and Factory mixins) and implements the IContainer interface.\n * It represents a container for PIXI.js display objects.\n */\nexport class Container extends Animated(WithSignals(Factory())) implements IContainer {\n private static readonly __caper_method_binding_root = true;\n\n public onDestroy: Signal<() => void> = new Signal();\n\n protected __background: Sprite;\n\n protected _animationContext: string | undefined;\n public get animationContext(): string | undefined {\n return this._animationContext;\n }\n public set animationContext(value: string) {\n this._animationContext = value;\n }\n\n private __config: ContainerConfig;\n\n public static onGlobalChildAdded = new Signal<(child: PIXIContainer) => void>();\n public static onGlobalChildRemoved = new Signal<(child: PIXIContainer) => void>();\n\n public static childAdded(child: PIXIContainer) {\n Container.onGlobalChildAdded.emit(child);\n }\n\n public static childRemoved(child: PIXIContainer) {\n Container.onGlobalChildRemoved.emit(child);\n }\n\n /**\n * Get the application instance.\n */\n public get app(): AppTypeOverrides['App'] {\n return Application.getInstance();\n }\n\n /**\n * The constructor for the Container class.\n * @param config - The configuration for the container.\n */\n constructor(config: Partial<ContainerConfig> = {}) {\n super();\n this.__config = { ...defaultConfig, ...config };\n // Bind all methods of this class to the current instance.\n bindAllMethods(this);\n // Add an event listener for the 'added' event.\n this.on('added', this._added);\n this.on('removed', this._removed);\n this.on('childAdded', this._childAdded);\n this.on('childRemoved', this._childRemoved);\n }\n\n public addColoredBackground(colorOrConfig: number | Partial<BackgroundConfig> = 0x0, alpha: number = 1): Sprite {\n const defaultConfig = {\n color: 0x0,\n width: this.app.size.width,\n height: this.app.size.height,\n anchor: 0.5,\n alpha: 1,\n autoResize: true,\n };\n\n const opts: BackgroundConfig = Object.assign(\n defaultConfig,\n typeof colorOrConfig === 'number'\n ? {\n color: colorOrConfig,\n alpha: alpha,\n }\n : colorOrConfig,\n );\n\n this.__background = this.add.sprite({\n asset: Texture.WHITE,\n width: opts.width,\n height: opts.height,\n anchor: opts.anchor,\n tint: opts.color,\n alpha: opts.alpha,\n resolution: 2,\n });\n\n this.setChildIndex(this.__background, 0);\n\n if (opts.autoResize) {\n this.addSignalConnection(this.app.onResize.connect(this.__resizeBackground));\n this.__resizeBackground();\n }\n\n return this.__background;\n }\n\n /**\n * Update the container. This method is meant to be overridden by subclasses.\n * @param ticker\n */\n public update(ticker?: Ticker | number) {\n void ticker;\n }\n\n /**\n * Resize the container. This method is meant to be overridden by subclasses.\n * @param size\n */\n public resize(size?: Size) {\n void size;\n }\n\n /**\n * This method is called when the container is added to the stage. It is meant to be overridden by subclasses.\n */\n public added() {}\n\n public childAdded(child: PIXIContainer) {\n void child;\n }\n\n destroy(options?: DestroyOptions): void {\n this.app.animation.killAll(this.animationContext);\n if (this.__config.autoUpdate) {\n this.app.ticker.remove(this.update, this);\n }\n this.onDestroy.emit();\n super.destroy(options);\n }\n\n public removed() {}\n\n public childRemoved(child: PIXIContainer) {\n void child;\n }\n\n protected __resizeBackground() {\n this.__background.width = this.app.size.width;\n this.__background.height = this.app.size.height;\n }\n\n /**\n * This method is called when the container is added to the stage. It sets up auto-resizing and auto-updating if enabled.\n */\n private _added() {\n if (this.__config.autoResize) {\n this.addSignalConnection(this.app.onResize.connect(this.resize, this.__config.priority ?? 'highest'));\n }\n\n if (this.__config.autoUpdate) {\n this.app.ticker.add(this.update, this, -999999);\n }\n this.added();\n }\n\n private _removed() {\n if (this.__config.autoResize) {\n this.app.onResize.disconnect(this.resize);\n }\n\n if (this.__config.autoUpdate) {\n this.app.ticker.remove(this.update, this);\n }\n\n this.removed();\n }\n\n private _childAdded(child: PIXIContainer) {\n Container.childAdded(child);\n this.childAdded(child);\n }\n\n private _childRemoved(child: PIXIContainer) {\n Container.childRemoved(child);\n this.childRemoved(child);\n }\n\n protected addAnimation(\n anim: gsap.core.Tween | gsap.core.Timeline | (gsap.core.Tween | gsap.core.Timeline)[],\n contextId?: string,\n ): gsap.core.Tween | gsap.core.Timeline | (gsap.core.Tween | gsap.core.Timeline)[] {\n return this.app.addAnimation(anim, contextId ?? this.animationContext);\n }\n}\n","import { DestroyOptions, ParticleContainerOptions, ParticleContainer as PIXIParticleContainer, Ticker } from 'pixi.js';\n\nimport { Application } from '../core/Application';\nimport { Signal } from '../signals';\nimport type { AppTypeOverrides, Size } from '../utils';\nimport { bindAllMethods } from '../utils';\n\n/**\n * Configuration for the Container class.\n */\nexport interface ParticleContainerConfig extends ParticleContainerOptions {\n autoUpdate: boolean;\n priority: number;\n}\n\nexport const ParticleContainerConfigKeys: (keyof ParticleContainerConfig)[] = ['autoUpdate', 'priority'];\n\nconst defaultConfig: ParticleContainerConfig = { autoUpdate: true, priority: 0 };\n\nexport interface IParticleContainer {\n app: AppTypeOverrides['App'];\n\n onDestroy: Signal<() => void>;\n\n destroy(options?: DestroyOptions): void;\n\n added(): Promise<void> | void;\n\n update(ticker?: Ticker | number): void;\n}\n\n/**\n * The Container class extends the _Container class (which includes the Animated and Factory mixins) and implements the IContainer interface.\n * It represents a container for PIXI.js display objects.\n */\nexport class ParticleContainer extends PIXIParticleContainer implements IParticleContainer {\n onDestroy: Signal<() => void> = new Signal();\n static __caper_method_binding_root = true;\n private __config: ParticleContainerConfig;\n\n /**\n * The constructor for the Container class.\n * @param config - The configuration for the container.\n */\n constructor(config: Partial<ParticleContainerConfig> = {}) {\n super(config);\n this.__config = { ...defaultConfig, ...config };\n // Bind all methods of this class to the current instance.\n bindAllMethods(this);\n // Add an event listener for the 'added' event.\n this.on('added', this._added);\n this.on('removed', this._removed);\n }\n\n /**\n * Get the application instance.\n */\n public get app(): AppTypeOverrides['App'] {\n return Application.getInstance() as AppTypeOverrides['App'];\n }\n /**\n * Update the container. This method is meant to be overridden by subclasses.\n * @param ticker\n */\n public update(ticker?: Ticker | number) {\n void ticker;\n }\n\n /**\n * Resize the container. This method is meant to be overridden by subclasses.\n * @param size\n */\n public resize(size?: Size) {\n void size;\n }\n\n /**\n * This method is called when the container is added to the stage. It is meant to be overridden by subclasses.\n */\n public added() {}\n\n destroy(options?: DestroyOptions): void {\n if (this.__config.autoUpdate) {\n this.app.ticker.remove(this.update, this);\n }\n this.onDestroy.emit();\n super.destroy(options);\n }\n\n public removed() {}\n /**\n * This method is called when the container is added to the stage. It sets up auto-resizing and auto-updating if enabled.\n */\n private _added() {\n if (this.__config.autoUpdate) {\n this.app.ticker.add(this.update, this, this.__config.priority);\n }\n this.added();\n }\n\n private _removed() {\n if (this.__config.autoUpdate) {\n this.app.ticker.remove(this.update, this);\n }\n this.removed();\n }\n}\n","import { Assets, Graphics, GraphicsContext } from 'pixi.js';\n\nexport class Svg extends Graphics {\n constructor(ctx: string | GraphicsContext) {\n super(typeof ctx === 'string' ? Assets.get(ctx) : ctx);\n const bounds = this.getLocalBounds();\n this.pivot.set((bounds.x + bounds.width) / 2, (bounds.y + bounds.height) / 2);\n }\n}\n","import { AnimatedSprite as PIXIAnimatedSprite, Texture, Ticker } from 'pixi.js';\nimport { AnimatedSpriteProps, resolveTexture } from '../mixins';\nimport { Signal } from '../signals';\nimport {\n bindAllMethods,\n getFirstMapEntry,\n getLastMapEntry,\n getNextMapEntry,\n getPreviousMapEntry,\n getZeroPaddedNumber,\n type SpritesheetAsset,\n} from '../utils';\n\nexport class AnimatedSprite extends PIXIAnimatedSprite {\n onAnimationChange: Signal<(currentAnimation: string) => void> = new Signal();\n onAnimationStart: Signal<() => void> = new Signal();\n onAnimationStop: Signal<() => void> = new Signal();\n onAnimationLoop: Signal<() => void> = new Signal();\n onAnimationComplete: Signal<() => void> = new Signal();\n onAnimationFrameChange: Signal<() => void> = new Signal();\n public defaultTexturePrefix: string = '';\n public defaultSheet: string | undefined;\n public defaultAnimation: string;\n public defaultAnimationSpeed: number;\n public defaultZeroPad: number | undefined;\n public autoPlay: boolean;\n public currentAnimation: string;\n protected _animations: Map<string, Texture[]>;\n\n constructor(protected config?: Partial<AnimatedSpriteProps>) {\n // get default animation\n const animations = config?.animations ?? {};\n const defaultAnimationName = config?.animation ?? Object.keys(animations)[0];\n const defaultAnimation = animations[defaultAnimationName as string];\n const defaultSheet = config?.sheet;\n const defaultTexturePrefix = config?.texturePrefix || '';\n const defaultZeroPad = config?.zeroPad;\n const defaultStartIndex = config?.startIndex ?? 0;\n\n super(\n AnimatedSprite.generateTexturesFromProps(\n defaultAnimationName,\n defaultAnimation,\n defaultTexturePrefix,\n defaultSheet,\n defaultZeroPad,\n defaultStartIndex,\n ),\n config?.autoUpdate !== false,\n );\n bindAllMethods(this);\n this.defaultSheet = defaultSheet;\n this.defaultTexturePrefix = defaultTexturePrefix;\n this.defaultZeroPad = defaultZeroPad;\n this._generateAnimations();\n this.currentAnimation = this.defaultAnimation = defaultAnimationName;\n this.autoPlay = config?.autoPlay ?? true;\n this.loop = config?.loop ?? true;\n this.updateAnchor = config?.updateAnchor ?? false;\n this.animationSpeed = this.defaultAnimationSpeed = config?.animationSpeed ?? 1;\n this.on('added', this._added);\n }\n\n protected _paused: boolean = false;\n\n get paused(): boolean {\n return this._paused;\n }\n\n set paused(value: boolean) {\n this._paused = value;\n }\n\n get speed(): number {\n return this.animationSpeed;\n }\n\n set speed(value: number) {\n this.animationSpeed = this.defaultAnimationSpeed = value;\n }\n\n protected _isReversed: boolean = false;\n\n get isReversed(): boolean {\n return this._isReversed;\n }\n\n static generateTexturesFromProps(\n animationName: string,\n props?: Partial<AnimatedSpriteProps>,\n defaultTexturePrefix = '',\n defaultSheet: SpritesheetAsset | undefined = undefined,\n defaultZeroPad?: number,\n defaultStartIndex?: number,\n ): Texture[] {\n const textures: Texture[] = [];\n let asset = '';\n const sheet = props?.sheet ?? defaultSheet;\n if (props?.numFrames > 1) {\n const idx = props?.startIndex ?? defaultStartIndex ?? 0;\n for (let i = idx; i < idx + props?.numFrames; i++) {\n asset = `${defaultTexturePrefix}${props?.texturePrefix ?? animationName}${getZeroPaddedNumber(i, props?.zeroPad ?? defaultZeroPad)}`;\n textures.push(\n resolveTexture({\n asset,\n sheet,\n }),\n );\n }\n } else {\n asset = `${defaultTexturePrefix}${props?.texturePrefix ?? animationName}`;\n textures.push(\n resolveTexture({\n asset,\n sheet,\n }),\n );\n }\n return textures;\n }\n\n reverse() {\n this._isReversed = !this._isReversed;\n if (this._isReversed) {\n this.setAnimation(`${this.currentAnimation}_reverse`);\n } else {\n this.setAnimation(this.currentAnimation.split('_reverse')[0]);\n }\n }\n\n setAnimation(animationName: string, autoPlay: boolean = true) {\n if (!this._animations.has(animationName)) {\n throw new Error(`Animation ${animationName} does not exist`);\n }\n this.textures = this._animations.get(animationName) as Texture[];\n this.currentAnimation = animationName;\n const animSpeed = this.config?.animations?.[animationName.split('_reverse')[0]]?.animationSpeed;\n if (animSpeed) {\n this.animationSpeed = animSpeed;\n } else {\n this.animationSpeed = this.defaultAnimationSpeed;\n }\n this.onAnimationChange.emit(animationName);\n if (autoPlay) {\n this.play();\n }\n }\n\n play() {\n super.play();\n this.onAnimationStart?.emit();\n }\n\n stop() {\n super.stop();\n this.onAnimationStop?.emit();\n }\n\n nextAnimation() {\n const entry = getNextMapEntry(this._animations, this.currentAnimation) ?? getFirstMapEntry(this._animations);\n if (entry) {\n this.setAnimation(entry[0]);\n }\n }\n\n previousAnimation() {\n const entry = getPreviousMapEntry(this._animations, this.currentAnimation) ?? getLastMapEntry(this._animations);\n if (entry) {\n this.setAnimation(entry[0]);\n }\n }\n\n update(ticker: Ticker) {\n if (this._paused) {\n return;\n }\n super.update(ticker);\n }\n\n private _generateAnimations() {\n this._animations = new Map();\n const animations = this.config?.animations ?? {};\n if (animations) {\n for (const [key, value] of Object.entries(animations)) {\n this._animations.set(\n key,\n AnimatedSprite.generateTexturesFromProps(\n key,\n value,\n this.defaultTexturePrefix,\n this.defaultSheet,\n this.defaultZeroPad,\n ),\n );\n }\n if (this.config?.reversible) {\n for (const [key, value] of Object.entries(animations)) {\n const textures = AnimatedSprite.generateTexturesFromProps(\n key,\n value,\n this.defaultTexturePrefix,\n this.defaultSheet,\n this.defaultZeroPad,\n );\n textures.reverse();\n this._animations.set(`${key}_reverse`, textures);\n }\n }\n }\n }\n\n private _added() {\n this.onLoop = () => {\n this.onAnimationLoop.emit();\n };\n this.onComplete = () => {\n this.onAnimationComplete.emit();\n };\n this.onFrameChange = () => {\n this.onAnimationFrameChange.emit();\n };\n\n if (this.autoPlay) {\n this.play();\n }\n }\n}\n","import { type AnimationStateListener, type Event, type TrackEntry } from '@esotericsoftware/spine-core';\nimport { Application } from '../core/Application';\nimport type { SpineProps } from '../mixins';\nimport { Factory, WithSignals } from '../mixins';\nimport { Signal } from '../signals';\nimport { type AppTypeOverrides, bindAllMethods, Spine } from '../utils';\n\nconst _SpineAnimation = WithSignals(Factory());\n\nexport interface ISpineAnimation<ANames extends string = string> extends InstanceType<typeof _SpineAnimation> {\n readonly spine: Spine;\n readonly animationNames: ANames[];\n readonly app: AppTypeOverrides['App'];\n readonly onAnimationComplete: Signal<(entry: TrackEntry) => void>;\n readonly onAnimationStart: Signal<(entry: TrackEntry) => void>;\n readonly onAnimationInterrupt: Signal<(entry: TrackEntry) => void>;\n readonly onAnimationDispose: Signal<(entry: TrackEntry) => void>;\n readonly onAnimationEnd: Signal<(entry: TrackEntry) => void>;\n readonly onAnimationEvent: Signal<(entry: TrackEntry, event: Event) => void>;\n readonly onPaused: Signal<(entry: TrackEntry | null) => void>;\n readonly onResumed: Signal<(entry: TrackEntry | null) => void>;\n setAnimation(name: ANames, loop?: boolean, tracklndex?: number): void;\n getCurrentAnimation(tracklndex?: number): ANames;\n pause(): void;\n resume(): void;\n togglePause(): void;\n}\n\nexport class SpineAnimation<ANames extends string = string> extends _SpineAnimation {\n spine: Spine;\n paused: boolean;\n\n onAnimationComplete: Signal<(entry: TrackEntry) => void> = new Signal();\n onAnimationStart: Signal<(entry: TrackEntry) => void> = new Signal();\n onAnimationInterrupt: Signal<(entry: TrackEntry) => void> = new Signal();\n onAnimationDispose: Signal<(entry: TrackEntry) => void> = new Signal();\n onAnimationEnd: Signal<(entry: TrackEntry) => void> = new Signal();\n onAnimationEvent: Signal<(entry: TrackEntry, event: Event) => void> = new Signal();\n\n onPaused: Signal<(entry: TrackEntry | null) => void> = new Signal();\n onResumed: Signal<(entry: TrackEntry | null) => void> = new Signal();\n\n protected _stateListener: AnimationStateListener;\n\n get app(): AppTypeOverrides['App'] {\n return Application.getInstance();\n }\n\n get animationNames(): ANames[] {\n return this.spine.state.data.skeletonData.animations.map((a) => a.name) as ANames[];\n }\n\n get currentEntry() {\n return this.spine.state.getCurrent(0);\n }\n\n get elapsedAnimationTime() {\n if (this.currentEntry) {\n return this.currentEntry.trackTime;\n }\n return -1;\n }\n\n public constructor(props?: Partial<SpineProps>) {\n super();\n bindAllMethods(this);\n let data = props?.data;\n let spineData: { skeleton: string; atlas: string } | string = '';\n if (typeof data === 'string') {\n // get the spine data from cache\n // check if '.json' is the last part of the asset string, and add it if not\n let ext = data.slice(-5);\n if (ext !== '.json' && ext !== '.skel') {\n ext = '.json';\n } else {\n data = data.substring(0, data.length - 5);\n }\n spineData = { skeleton: data + ext, atlas: data + '.atlas' };\n }\n this.spine = (window as any).Spine.from(spineData);\n this.add.existing(this.spine);\n\n if (props) {\n if (props.autoUpdate !== undefined) this.spine.autoUpdate = props.autoUpdate;\n if (props.animationName) this.setAnimation(props.animationName as ANames, props.loop, props.trackIndex ?? 0);\n }\n\n this.addSignalConnection(this.app.actions('toggle_pause').connect(this.togglePause));\n\n if (props?.paused) {\n this.pause();\n }\n\n this._stateListener = {\n start: this._handleAnimationStart,\n interrupt: this._handleAnimationInterrupt,\n dispose: this._handleAnimationDispose,\n end: this._handleAnimationEnd,\n event: this._handleAnimationEvent,\n complete: this._handleAnimationComplete,\n };\n\n this.spine.state.addListener(this._stateListener);\n }\n\n destroy() {\n this.spine.state.removeListener(this._stateListener);\n super.destroy();\n }\n\n getCurrentAnimation(trackIndex: number = 0): ANames {\n return (this.spine.state.getCurrent(trackIndex)?.animation?.name as ANames) || ('' as ANames);\n }\n\n setAnimation(name: ANames, loop = false, tracklndex: number = 0) {\n this.spine.state.setAnimation(tracklndex, name, loop);\n }\n\n pause() {\n this.paused = true;\n this.spine.autoUpdate = false;\n\n if (this.currentEntry) {\n this.currentEntry.timeScale = 0;\n }\n this.onPaused.emit(this.currentEntry);\n }\n\n resume() {\n this.paused = false;\n this.spine.autoUpdate = true;\n if (this.currentEntry) {\n this.currentEntry.timeScale = 1;\n }\n this.onResumed.emit(this.currentEntry);\n }\n\n togglePause() {\n if (this.paused) {\n this.resume();\n } else {\n this.pause();\n }\n }\n\n // protected methods\n protected _handleAnimationComplete(entry: TrackEntry) {\n this.onAnimationComplete.emit(entry);\n }\n\n protected _handleAnimationStart(entry: TrackEntry) {\n this.onAnimationStart.emit(entry);\n }\n\n protected _handleAnimationInterrupt(entry: TrackEntry) {\n this.onAnimationInterrupt.emit(entry);\n }\n\n protected _handleAnimationDispose(entry: TrackEntry) {\n this.onAnimationDispose.emit(entry);\n }\n\n protected _handleAnimationEnd(entry: TrackEntry) {\n this.onAnimationEnd.emit(entry);\n }\n\n protected _handleAnimationEvent(entry: TrackEntry, event: Event) {\n this.onAnimationEvent.emit(entry, event);\n }\n}\n","import {\n BitmapText,\n Cursor,\n DestroyOptions,\n FederatedEvent,\n FederatedPointerEvent,\n HTMLText,\n Sprite,\n Text,\n} from 'pixi.js';\n\nimport { type LayoutOptions } from '@pixi/layout';\nimport type { IApplication } from '../core';\nimport { Application } from '../core/Application';\nimport { Factory, Focusable, HTMLTextProps, Interactive, type TextProps, WithSignals } from '../mixins';\nimport { Signal } from '../signals';\nimport { AudioAsset, bindAllMethods, type SpritesheetAsset, type TextureAsset } from '../utils';\n\nexport type ButtonCallback = (() => void) | (() => Promise<void>);\nexport type ButtonAction = { id: string | number; data?: any };\n\nexport type ButtonActionOrCallback = ButtonAction | ButtonCallback;\n\ntype ButtonTextureId = 'default' | 'hover' | 'active' | 'disabled';\n\nexport interface IButton {\n // signals\n onDown: Signal<() => void>;\n onUp: Signal<() => void>;\n onUpOutside: Signal<() => void>;\n onOut: Signal<() => void>;\n onOver: Signal<() => void>;\n onClick: Signal<() => void>;\n onEnabled: Signal<() => void>;\n onDisabled: Signal<() => void>;\n onDestroy: Signal<() => void>;\n onKeyboardEvent: Signal<(key: string) => void>;\n // visual\n view: Sprite;\n // whether the button is down\n isDown: boolean;\n isOver: boolean;\n //\n id: string;\n}\n\nexport type ButtonConfig = {\n id: string;\n textures: {\n default: TextureAsset;\n hover?: TextureAsset;\n active?: TextureAsset;\n disabled?: TextureAsset;\n };\n sounds?: {\n hover?: AudioAsset;\n out?: AudioAsset;\n down?: AudioAsset;\n click?: AudioAsset;\n };\n actions?: {\n hover?: ButtonActionOrCallback;\n out?: ButtonActionOrCallback;\n down?: ButtonActionOrCallback;\n click?: ButtonActionOrCallback;\n };\n textLabel?: Partial<TextProps | HTMLTextProps> & { type?: 'text' | 'html' | 'bitmap' };\n cursor: Cursor;\n disabledCursor: Cursor;\n sheet: SpritesheetAsset;\n enabled: boolean;\n layout?: Omit<LayoutOptions, 'target'> | null | boolean;\n};\n\nexport const ButtonConfigKeys: (keyof ButtonConfig)[] = [\n 'textures',\n 'sounds',\n 'actions',\n 'cursor',\n 'disabledCursor',\n 'sheet',\n 'enabled',\n 'layout',\n 'textLabel',\n];\n\n// Create a new class that extends Container and includes the Interactive and Focusable mixins.\nconst _Button = Focusable(Interactive(WithSignals(Factory())));\n\n/**\n * @class\n * @extends {Container}\n * A class representing a button.\n */\nexport class Button extends _Button implements IButton {\n // signals\n public onDown = new Signal<() => void>();\n public onUp = new Signal<() => void>();\n public onUpOutside = new Signal<() => void>();\n public onOut = new Signal<() => void>();\n public onOver = new Signal<() => void>();\n public onClick = new Signal<() => void>();\n public onEnabled = new Signal<() => void>();\n public onDisabled = new Signal<() => void>();\n public onKeyboardEvent = new Signal<(key: string) => void>();\n public onDestroy = new Signal<() => void>();\n public id: string;\n // visual\n public view: Sprite;\n // whether the button is down\n public isDown: boolean;\n public isOver: boolean;\n // config\n protected config: ButtonConfig;\n // a set of unique callbacks for when the button is down\n protected _isDownCallbacks: Map<string, () => void> = new Map();\n private _isDownListenerAdded: boolean = false;\n private _pointerId?: number;\n private _textLabel?: Text | HTMLText | BitmapText;\n\n /**\n * The text label of the button.\n * @returns {Text | HTMLText | BitmapText | undefined} The text label instance.\n */\n get textLabel() {\n return this._textLabel;\n }\n\n /**\n * @constructor\n * @param {Partial<ButtonConfig>} config - The configuration for the button.\n */\n constructor(config: Partial<ButtonConfig>) {\n super();\n\n bindAllMethods(this);\n\n this.config = Object.assign(\n {\n id: 'button',\n textures: { default: '' },\n sheet: undefined,\n enabled: true,\n cursor: 'default',\n disabledCursor: 'not-allowed',\n },\n config,\n ) as ButtonConfig;\n\n this.id = this.config.id;\n\n // Allow layout to be set via config, but default to false\n if (config.layout !== undefined) {\n this.layout = config.layout;\n } else {\n this.layout = false;\n }\n\n // Create a sprite with the default texture and add it to the container.\n this.view = this.add.sprite({\n asset: this.config.textures.default,\n sheet: this.config.sheet ?? undefined,\n });\n\n this.cursor = this.config.cursor;\n this.enabled = config.enabled !== false;\n\n if (this.layout?.style.transformOrigin !== 'top left') {\n this.layout = { transformOrigin: 'top left' };\n if (this.app.renderer.layout) {\n this.app.renderer.layout.update(this);\n }\n }\n\n if (this.config.textLabel) {\n this.addLabel(this.config.textLabel);\n }\n\n // Set up interaction handlers.\n // make them high priority so they run before any other interaction handlers\n this.addSignalConnection(\n this.onInteraction('pointerover').connect(this.handlePointerOver, -1),\n this.onInteraction('pointerout').connect(this.handlePointerOut, -1),\n this.onInteraction('pointerup').connect(this.handlePointerUp, -1),\n this.onInteraction('click').connect(this.handleClick, -1),\n this.onInteraction('tap').connect(this.handleClick, -1),\n this.onInteraction('pointerdown').connect(this.handlePointerDown, -1),\n );\n }\n\n // enabled state\n protected _enabled: boolean;\n\n /**\n * Sets the enabled state of the button.\n * @param {boolean} enabled - Whether the button is enabled.\n */\n public set enabled(enabled: boolean) {\n if (this._enabled === enabled) {\n return;\n }\n this._enabled = enabled;\n this.cursor = this._enabled ? this.config.cursor : this.config.disabledCursor;\n this.focusEnabled = enabled;\n if (this._enabled) {\n this.view.texture = this.make.texture({\n asset: this.config.textures.default,\n sheet: this.config.sheet ?? undefined,\n });\n this.onEnabled.emit();\n } else {\n this.view.texture = this.make.texture({\n asset: this.config.textures.disabled || this.config.textures.default,\n sheet: this.config.sheet ?? undefined,\n });\n this.onDisabled.emit();\n }\n }\n\n public addLabel<T extends Text | HTMLText | BitmapText>(\n config: (Partial<TextProps | HTMLTextProps> & { type?: 'text' | 'html' | 'bitmap' }) | T,\n ): T {\n if (config instanceof Text || config instanceof HTMLText || config instanceof BitmapText) {\n config.anchor.set(0.5, 0.5);\n this._textLabel = this.add.existing(config) as T;\n this._textLabel.layout = false;\n } else {\n config.anchor = 0.5;\n switch (config.type) {\n case 'bitmap':\n this._textLabel = this.add.bitmapText({ ...config, layout: false }) as BitmapText;\n break;\n case 'html':\n this._textLabel = this.add.htmlText({ ...config, layout: false }) as HTMLText;\n break;\n default:\n this._textLabel = this.add.text({ ...config, layout: false }) as Text;\n break;\n }\n }\n\n this.positionLabel();\n\n return this._textLabel as T;\n }\n\n public positionLabel() {\n if (this._textLabel) {\n this._textLabel.position.set(this.view.width * 0.5, this.view.height * 0.5);\n }\n }\n\n public get enabled() {\n return this._enabled;\n }\n\n get app(): IApplication {\n return Application.getInstance();\n }\n\n destroy(options?: DestroyOptions) {\n this.onDestroy.emit();\n super.destroy(options);\n }\n\n focusOut() {\n super.focusOut();\n this.isDown = false;\n this.isOver = false;\n }\n\n blur() {\n super.blur();\n this.isDown = false;\n this.isOver = false;\n }\n\n public getFocusArea() {\n return this.view.getBounds().clone();\n }\n\n addIsDownCallback(callbackId: string, callback: () => void) {\n this._isDownCallbacks.set(callbackId, callback);\n this._checkIsDownCallbacks();\n }\n\n removeIsDownCallback(callbackId: string) {\n this._isDownCallbacks.delete(callbackId);\n }\n\n setTexture(textureId: ButtonTextureId, texture: TextureAsset) {\n this.config.textures[textureId] = texture;\n if (textureId === 'default') {\n this.view.texture = this.make.texture({\n asset: this.config.textures.default,\n sheet: this.config.sheet,\n });\n }\n\n this.positionLabel();\n }\n\n /**\n * Sets the texture of the button to the hover texture and emits the onOver event.\n */\n protected handlePointerOver() {\n if (!this._enabled) {\n return;\n }\n if (!this.isOver) {\n this.isOver = true;\n }\n if (this.isDown) {\n return;\n }\n this.view.texture = this.make.texture({\n asset: this.config.textures.hover || this.config.textures.default,\n sheet: this.config.sheet,\n });\n this.onOver.emit();\n if (this.config.sounds?.hover) {\n void this.app.audio.play(this.config.sounds.hover, 'sfx');\n }\n if (this.config.actions?.hover) {\n this._doAction(this.config.actions.hover);\n }\n }\n\n /**\n * Sets the texture of the button to the default texture and emits the onOut event.\n */\n protected handlePointerOut() {\n this.isOver = false;\n if (!this._enabled) {\n return;\n }\n if (this.isDown) {\n return;\n }\n this.view.texture = this.make.texture({ asset: this.config.textures.default, sheet: this.config.sheet });\n\n if (this.config.sounds?.out) {\n void this.app.audio.play(this.config.sounds.out, 'sfx');\n }\n this.onOut.emit();\n }\n\n /**\n * Sets the isDown property to true and changes the texture of the button.\n */\n protected handlePointerDown(e: FederatedEvent) {\n if (!this._enabled && !this.isKeyDown) {\n return;\n }\n if (!this.isDown && this._pointerId === undefined) {\n this._pointerId = (e as FederatedPointerEvent).pointerId;\n\n window.removeEventListener('pointerup', this.handlePointerUpOutside);\n this.off('pointerupoutside', this.handlePointerUpOutside);\n\n window.addEventListener('pointerup', this.handlePointerUpOutside);\n this.on('pointerupoutside', this.handlePointerUpOutside);\n\n this.isDown = true;\n this.view.texture = this.make.texture({\n asset: this.config.textures.active || this.config.textures.hover || this.config.textures.default,\n sheet: this.config.sheet,\n });\n this.onDown.emit();\n if (this.config.sounds?.down) {\n void this.app.audio.play(this.config.sounds.down, 'sfx');\n }\n if (this.config.actions?.down) {\n this._doAction(this.config.actions.down);\n }\n }\n }\n\n /**\n * Removes the keyup event listener and emits the onPress and onUp events.\n */\n protected handlePointerUp(e: FederatedEvent) {\n if (!this._enabled || !this.isOver || (e as FederatedPointerEvent).pointerId !== this._pointerId) {\n return;\n }\n window.removeEventListener('pointerup', this.handlePointerUpOutside);\n\n this.view.texture = this.make.texture({ asset: this.config.textures.default, sheet: this.config.sheet });\n this.onUp.emit();\n\n this._pointerId = undefined;\n }\n\n protected handleClick() {\n if (!this._enabled) {\n return;\n }\n this.isDown = false;\n this.onClick.emit();\n if (this.config.sounds?.click) {\n void this.app.audio.play(this.config.sounds.click, 'sfx');\n }\n if (this.config.actions?.click) {\n this._doAction(this.config.actions.click);\n }\n }\n\n /**\n * Handles the pointer up event.\n */\n protected handlePointerUpOutside(e: PointerEvent | FederatedPointerEvent) {\n if (!this._enabled || e.pointerId !== this._pointerId) {\n return;\n }\n window.removeEventListener('pointerup', this.handlePointerUpOutside);\n this.off('pointerupoutside', this.handlePointerUpOutside);\n this.view.texture = this.make.texture({ asset: this.config.textures.default, sheet: this.config.sheet });\n this.isDown = false;\n this.isOver = false;\n this.onUpOutside.emit();\n\n this._pointerId = undefined;\n }\n\n private _doAction(action: ButtonActionOrCallback) {\n if (typeof action === 'function') {\n void action();\n } else {\n if (!action.data.button) {\n action.data.button = this;\n }\n this.app.action(action.id, action.data);\n }\n }\n\n private _checkIsDownCallbacks() {\n // check if there are any callbacks, if there are, add the ticker listener\n if (!this._isDownListenerAdded && this._isDownCallbacks.size > 0) {\n this._isDownListenerAdded = true;\n this.app.ticker.add(this._handleIsDownCallbacks);\n } else {\n this.app.ticker.remove(this._handleIsDownCallbacks);\n this._isDownListenerAdded = false;\n }\n }\n\n private _handleIsDownCallbacks() {\n if (this.isDown) {\n this._isDownCallbacks.forEach((callback) => {\n callback();\n });\n }\n }\n}\n","import type { LayoutOptions, NumberValue } from '@pixi/layout';\nimport { BitmapText, Graphics, Container as PIXIContainer, Text } from 'pixi.js';\nimport { Application } from '../core/Application';\nimport { Container } from '../display';\nimport { Factory, WithSignals } from '../mixins';\nimport { Signal } from '../signals';\nimport {\n AppTypeOverrides,\n bindAllMethods,\n type ContainerLike,\n createDebugGraphics,\n createDebugLabel,\n DebugAlpha,\n DebugColors,\n registerDebug,\n unregisterDebug,\n} from '../utils';\n\nconst _FlexContainer = WithSignals(Factory());\n\nexport function isText(child: PIXIContainer): child is Text | BitmapText {\n return child instanceof Text || child instanceof BitmapText;\n}\n\nexport interface FlexContainerConfig {\n bindTo?: ContainerLike;\n bindToAppSize?: boolean;\n autoLayoutChildren?: boolean;\n layout?: Omit<LayoutOptions, 'target'> | null | boolean;\n debug?: boolean;\n}\n\nexport const FlexContainerConfigKeys: (keyof FlexContainerConfig)[] = [\n 'bindTo',\n 'bindToAppSize',\n 'autoLayoutChildren',\n 'debug',\n];\n\nexport type FlexWrap = 'wrap' | 'nowrap' | 'wrap-reverse' | undefined;\nexport type FlexDirection = 'row' | 'column' | 'row-reverse' | 'column-reverse' | undefined;\nexport type AlignItems = 'center' | 'flex-start' | 'flex-end' | 'stretch' | 'baseline' | undefined;\nexport type JustifyContent =\n | 'center'\n | 'space-between'\n | 'space-around'\n | 'space-evenly'\n | 'flex-start'\n | 'flex-end'\n | undefined;\n\nexport type SizeNumber = NumberValue | 'auto' | 'intrinsic';\n\nexport class FlexContainer extends _FlexContainer {\n public onLayoutComplete = new Signal<() => void>();\n public config: Partial<FlexContainerConfig>;\n private _debugGraphics: Graphics | null = null;\n private _debugLabel: Text | null = null;\n\n constructor(config: Partial<FlexContainerConfig> = {}) {\n super();\n\n if (!this.app.config.useLayout) {\n throw new Error('You must set useLayout to true in your app config to use FlexContainer');\n }\n\n bindAllMethods(this);\n\n this.config = {\n autoLayoutChildren: true,\n ...config,\n };\n\n // Set up layout\n this.layout = this.createLayout(config);\n\n // Set up event listeners\n this.on('added', this.handleAdded);\n this.on('childAdded', this.handleChildAdded);\n this.on('childRemoved', this.handleChildRemoved);\n\n if (this.config.bindToAppSize) {\n this.app.onResize.connect(this.handleResize);\n }\n\n if (this.config.bindTo && 'on' in this.config.bindTo) {\n (this.config.bindTo as PIXIContainer).on('layout', this.handleBindToResize);\n }\n }\n\n private createLayout(config: Partial<FlexContainerConfig>): Omit<LayoutOptions, 'target'> | null | boolean {\n if (config?.layout === true) {\n config.layout = {};\n }\n const layout: Omit<LayoutOptions, 'target'> | null | boolean = { ...(config?.layout ?? {}) };\n\n if (this.config.bindToAppSize) {\n layout.width = this.app.size.width;\n layout.height = this.app.size.height;\n } else if (this.config.bindTo) {\n layout.width = this.config.bindTo.width;\n layout.height = this.config.bindTo.height;\n }\n\n return layout;\n }\n\n private handleAdded() {\n this.updateLayout();\n }\n\n private _updateLayout() {\n this.app.ticker.addOnce(this.updateLayout);\n }\n\n private handleChildAdded(child: PIXIContainer) {\n if (this.config.autoLayoutChildren) {\n if (!(child.layout as unknown as boolean)) {\n // No layout yet — set isLeaf (original behavior)\n child.layout = { isLeaf: true };\n } else if (isText(child) && !child.layout?.style?.isLeaf) {\n // Text/BitmapText with existing layout props (e.g. marginTop) but missing isLeaf.\n // Without isLeaf, Yoga won't measure the text's intrinsic bounds.\n // The layout setter merges, so existing props are preserved.\n child.layout = { isLeaf: true };\n }\n }\n\n Container.childAdded(child);\n child.on('layout', this._updateLayout);\n this._updateLayout();\n }\n\n private handleChildRemoved(child: PIXIContainer) {\n child.off('layout', this._updateLayout);\n Container.childRemoved(child);\n this._updateLayout();\n }\n\n private handleResize() {\n if (this.config.bindToAppSize) {\n this.layout = {\n width: this.app.size.width,\n height: this.app.size.height,\n };\n }\n this._updateLayout();\n }\n\n private handleBindToResize() {\n if (!this.config.bindTo) return;\n this.layout = {\n width: this.config.bindTo.width,\n height: this.config.bindTo.height,\n };\n this._updateLayout();\n }\n\n public updateLayout() {\n if (this.destroyed || !this.layout || !this.app?.renderer.layout) return;\n this.app.renderer.layout.update(this);\n this.onLayoutComplete.emit();\n if (this.config.debug) {\n this.drawDebug();\n }\n }\n\n public get app(): AppTypeOverrides['App'] {\n return Application.getInstance();\n }\n\n /**\n * Set multiple layout properties at once, triggering a single deferred layout update.\n */\n public configure(styles: Partial<Omit<LayoutOptions, 'target'>>): void {\n this.layout = styles;\n this._updateLayout();\n }\n\n // Convenience getters/setters for common layout properties\n get gap(): number {\n return (this.layout?.style?.gap as number) ?? 0;\n }\n\n set gap(value: number) {\n this.layout = { gap: value };\n this._updateLayout();\n }\n\n get flexWrap(): FlexWrap {\n return this.layout?.style?.flexWrap as FlexWrap;\n }\n\n set flexWrap(value: FlexWrap) {\n this.layout = { flexWrap: value };\n this._updateLayout();\n }\n\n get flexDirection(): FlexDirection {\n return this.layout?.style?.flexDirection as FlexDirection;\n }\n\n set flexDirection(value: FlexDirection) {\n this.layout = { flexDirection: value };\n this._updateLayout();\n }\n\n get alignItems(): AlignItems {\n return this.layout?.style?.alignItems as AlignItems;\n }\n\n set alignItems(value: AlignItems) {\n this.layout = { alignItems: value };\n this._updateLayout();\n }\n\n get justifyContent(): JustifyContent {\n return this.layout?.style?.justifyContent as JustifyContent;\n }\n\n set justifyContent(value: JustifyContent) {\n this.layout = { justifyContent: value };\n this._updateLayout();\n }\n\n get size(): { width: SizeNumber; height: SizeNumber } {\n return {\n width: this.layout?.style?.width as SizeNumber,\n height: this.layout?.style?.height as SizeNumber,\n };\n }\n\n set size(size: { width: SizeNumber; height: SizeNumber } | [SizeNumber, SizeNumber] | SizeNumber) {\n if (Array.isArray(size)) {\n size = { width: size[0], height: size[1] };\n }\n if (typeof size === 'number' || typeof size === 'string') {\n size = { width: size, height: size };\n }\n this.layout = { ...size };\n this._updateLayout();\n }\n\n get layoutWidth(): SizeNumber {\n return this.layout?.style?.width as SizeNumber;\n }\n\n set layoutWidth(width: SizeNumber) {\n this.layout = { width };\n this._updateLayout();\n }\n\n get layoutHeight(): SizeNumber {\n return this.layout?.style?.height as SizeNumber;\n }\n\n set layoutHeight(height: SizeNumber) {\n this.layout = { height };\n this._updateLayout();\n }\n\n // Padding convenience\n get padding(): NumberValue | undefined {\n return this.layout?.style?.padding as NumberValue | undefined;\n }\n\n set padding(value: NumberValue) {\n this.layout = { padding: value };\n this._updateLayout();\n }\n\n get paddingTop(): NumberValue | undefined {\n return this.layout?.style?.paddingTop as NumberValue | undefined;\n }\n\n set paddingTop(value: NumberValue) {\n this.layout = { paddingTop: value };\n this._updateLayout();\n }\n\n get paddingRight(): NumberValue | undefined {\n return this.layout?.style?.paddingRight as NumberValue | undefined;\n }\n\n set paddingRight(value: NumberValue) {\n this.layout = { paddingRight: value };\n this._updateLayout();\n }\n\n get paddingBottom(): NumberValue | undefined {\n return this.layout?.style?.paddingBottom as NumberValue | undefined;\n }\n\n set paddingBottom(value: NumberValue) {\n this.layout = { paddingBottom: value };\n this._updateLayout();\n }\n\n get paddingLeft(): NumberValue | undefined {\n return this.layout?.style?.paddingLeft as NumberValue | undefined;\n }\n\n set paddingLeft(value: NumberValue) {\n this.layout = { paddingLeft: value };\n this._updateLayout();\n }\n\n // Margin convenience\n get margin(): NumberValue | undefined {\n return this.layout?.style?.margin as NumberValue | undefined;\n }\n\n set margin(value: NumberValue) {\n this.layout = { margin: value };\n this._updateLayout();\n }\n\n get marginTop(): NumberValue | undefined {\n return this.layout?.style?.marginTop as NumberValue | undefined;\n }\n\n set marginTop(value: NumberValue) {\n this.layout = { marginTop: value };\n this._updateLayout();\n }\n\n get marginRight(): NumberValue | undefined {\n return this.layout?.style?.marginRight as NumberValue | undefined;\n }\n\n set marginRight(value: NumberValue) {\n this.layout = { marginRight: value };\n this._updateLayout();\n }\n\n get marginBottom(): NumberValue | undefined {\n return this.layout?.style?.marginBottom as NumberValue | undefined;\n }\n\n set marginBottom(value: NumberValue) {\n this.layout = { marginBottom: value };\n this._updateLayout();\n }\n\n get marginLeft(): NumberValue | undefined {\n return this.layout?.style?.marginLeft as NumberValue | undefined;\n }\n\n set marginLeft(value: NumberValue) {\n this.layout = { marginLeft: value };\n this._updateLayout();\n }\n\n // --- Debug visualization ---\n get debug(): boolean {\n return this.config.debug ?? false;\n }\n\n set debug(value: boolean) {\n this.config.debug = value;\n if (value) {\n const uid = `FlexContainer:${this.uid}`;\n registerDebug(uid, this.label || 'FlexContainer', DebugColors.bounds);\n this.drawDebug();\n } else {\n unregisterDebug(`FlexContainer:${this.uid}`);\n if (this._debugGraphics) {\n this._debugGraphics.clear();\n }\n if (this._debugLabel) {\n this._debugLabel.visible = false;\n }\n }\n }\n\n private drawDebug() {\n // Create or re-add debug graphics if orphaned by removeChildren()\n if (!this._debugGraphics || this._debugGraphics.parent !== this) {\n if (!this._debugGraphics) {\n this._debugGraphics = createDebugGraphics(`${this.label ?? 'FlexContainer'}:debug`);\n }\n this.addChild(this._debugGraphics);\n this._debugGraphics.layout = false; // override auto-isLeaf from handleChildAdded\n }\n if (!this._debugLabel || this._debugLabel.parent !== this) {\n if (!this._debugLabel) {\n this._debugLabel = createDebugLabel(this.label || 'FlexContainer', DebugColors.bounds);\n }\n this.addChild(this._debugLabel);\n this._debugLabel.layout = false;\n }\n\n // Update label text in case label changed\n this._debugLabel.text = this.label || 'FlexContainer';\n this._debugLabel.visible = true;\n\n // Ensure debug graphics render on top\n this.setChildIndex(this._debugGraphics, this.children.length - 1);\n this.setChildIndex(this._debugLabel, this.children.length - 1);\n\n this._debugGraphics.clear();\n\n const computedLayout = this.layout?.computedLayout;\n if (!computedLayout) return;\n\n const w = computedLayout.width;\n const h = computedLayout.height;\n const direction = (this.layout?.style?.flexDirection as string) ?? 'row';\n const gap = (this.layout?.style?.gap as number) ?? 0;\n\n // 1. Container bounds (cyan)\n this._debugGraphics\n .rect(0, 0, w, h)\n .stroke({ width: 1, color: DebugColors.bounds, alpha: DebugAlpha.stroke, pixelLine: true });\n\n // 2. Padding visualization (red subtle fill)\n const pt = (this.layout?.style?.paddingTop as number) ?? 0;\n const pr = (this.layout?.style?.paddingRight as number) ?? 0;\n const pb = (this.layout?.style?.paddingBottom as number) ?? 0;\n const pl = (this.layout?.style?.paddingLeft as number) ?? 0;\n if (pt > 0) {\n this._debugGraphics.rect(0, 0, w, pt).fill({ color: DebugColors.outerBounds, alpha: DebugAlpha.fill });\n }\n if (pb > 0) {\n this._debugGraphics.rect(0, h - pb, w, pb).fill({ color: DebugColors.outerBounds, alpha: DebugAlpha.fill });\n }\n if (pl > 0) {\n this._debugGraphics.rect(0, pt, pl, h - pt - pb).fill({ color: DebugColors.outerBounds, alpha: DebugAlpha.fill });\n }\n if (pr > 0) {\n this._debugGraphics\n .rect(w - pr, pt, pr, h - pt - pb)\n .fill({ color: DebugColors.outerBounds, alpha: DebugAlpha.fill });\n }\n\n // 3. Flex direction arrow (yellow)\n const arrowLen = Math.min(w, h, 40);\n const cx = w / 2;\n const cy = h / 2;\n const isRow = direction === 'row' || direction === 'row-reverse';\n if (isRow) {\n const dir = direction === 'row' ? 1 : -1;\n const startX = cx - (dir * arrowLen) / 2;\n const endX = cx + (dir * arrowLen) / 2;\n this._debugGraphics\n .moveTo(startX, cy)\n .lineTo(endX, cy)\n .moveTo(endX, cy)\n .lineTo(endX - dir * 6, cy - 4)\n .moveTo(endX, cy)\n .lineTo(endX - dir * 6, cy + 4)\n .stroke({ width: 1, color: DebugColors.direction, alpha: 0.8, pixelLine: true });\n } else {\n const dir = direction === 'column' ? 1 : -1;\n const startY = cy - (dir * arrowLen) / 2;\n const endY = cy + (dir * arrowLen) / 2;\n this._debugGraphics\n .moveTo(cx, startY)\n .lineTo(cx, endY)\n .moveTo(cx, endY)\n .lineTo(cx - 4, endY - dir * 6)\n .moveTo(cx, endY)\n .lineTo(cx + 4, endY - dir * 6)\n .stroke({ width: 1, color: DebugColors.direction, alpha: 0.8, pixelLine: true });\n }\n\n // 4. Gap indicators between children (magenta fills)\n if (gap > 0) {\n for (let i = 0; i < this.children.length - 1; i++) {\n const child = this.children[i];\n if (child === this._debugGraphics || child === this._debugLabel) continue;\n if (!child.layout?.computedLayout) continue;\n const cl = child.layout.computedLayout;\n if (isRow) {\n const gapX = cl.left + cl.width;\n this._debugGraphics.rect(gapX, 0, gap, h).fill({ color: DebugColors.gap, alpha: DebugAlpha.fill });\n } else {\n const gapY = cl.top + cl.height;\n this._debugGraphics.rect(0, gapY, w, gap).fill({ color: DebugColors.gap, alpha: DebugAlpha.fill });\n }\n }\n }\n\n // 5. Child bounding boxes (green outlines)\n for (const child of this.children) {\n if (child === this._debugGraphics || child === this._debugLabel) continue;\n if (!child.layout?.computedLayout) continue;\n const cl = child.layout.computedLayout;\n this._debugGraphics\n .rect(cl.left, cl.top, cl.width, cl.height)\n .stroke({ width: 1, color: DebugColors.innerBounds, alpha: 0.4, pixelLine: true });\n }\n\n // Position label at top-left with slight offset\n this._debugLabel.position.set(2, 2);\n }\n\n destroy() {\n // Clean up debug\n if (this.config.debug) {\n unregisterDebug(`FlexContainer:${this.uid}`);\n }\n if (this._debugGraphics) {\n this._debugGraphics.destroy();\n this._debugGraphics = null;\n }\n if (this._debugLabel) {\n this._debugLabel.destroy();\n this._debugLabel = null;\n }\n\n this.off('added', this.handleAdded);\n this.off('childAdded', this.handleChildAdded);\n this.off('childRemoved', this.handleChildRemoved);\n\n if (this.config.bindToAppSize) {\n this.app.onResize.disconnect(this.handleResize);\n }\n\n if (this.config.bindTo && 'off' in this.config.bindTo) {\n (this.config.bindTo as PIXIContainer).off('layout', this.handleBindToResize);\n }\n\n super.destroy();\n }\n}\n","import type { IApplication, ICoreFunctions, ICoreSignals } from '../core';\nimport { coreFunctionRegistry, coreSignalRegistry } from '../core';\nimport { Application } from '../core/Application';\nimport { SignalConnection, SignalConnections } from '../signals';\nimport { type AppTypeOverrides, bindAllMethods, ImportListItemModule } from '../utils';\n\n/**\n * Public contract for a Caper plugin. A plugin is a long-lived object\n * with `initialize` / `postInitialize` / `destroy` lifecycle hooks,\n * registered at app bootstrap and accessed via `app.getPlugin(id)`.\n *\n * **Lifecycle order** (per plugin):\n *\n * 1. `constructor` — instantiated by the framework. Don't reference\n * the app yet; it isn't attached.\n * 2. `initialize(options, app)` — set up internal state, parse options,\n * open connections, register signals. Awaited by the framework\n * before any other plugin's `initialize` runs (when ordered by\n * `requires`). Don't call out to other plugins here unless they\n * are listed in your `requires` — order isn't guaranteed otherwise.\n * 3. `postInitialize(app)` — runs after every plugin has finished\n * `initialize`. Safe to look up sibling plugins via `app.getPlugin`\n * regardless of `requires`. Use for cross-plugin wiring.\n * 4. (use phase) — the plugin is live; signal handlers fire, exposed\n * methods are called from scenes / other plugins / the app.\n * 5. `destroy()` — called when the app shuts down. Tear down\n * connections, disconnect signals, free resources. The base class\n * already disconnects everything added via `addSignalConnection`.\n *\n * Discovery: plugin classes under `src/plugins/` are auto-discovered\n * by the Vite plugin if they default-export a class. Annotate with\n * `definePlugin({ id, requires })` for the canonical id and any\n * dependency declarations:\n *\n * @example\n * ```ts\n * import { definePlugin, IApplication, Plugin } from '@caperjs/core';\n *\n * export const plugin = definePlugin({\n * id: 'leaderboard',\n * requires: ['firebase'], // firebase initializes first\n * });\n *\n * export default class LeaderboardPlugin extends Plugin {\n * public readonly id = 'leaderboard';\n *\n * async initialize(_options, app) {\n * this.firebase = app.getPlugin('firebase'); // guaranteed to exist\n * }\n * }\n * ```\n */\nexport interface IPlugin<O = any> {\n /** Unique plugin id. Must match the `definePlugin({ id })` value. */\n id: string;\n\n /** The owning application instance. Available after registration. */\n app: IApplication;\n\n /** Resolved options after `initialize` merges defaults with the user's. */\n readonly options: O;\n\n /**\n * Set up the plugin. Called once at bootstrap, awaited before any\n * dependent plugin's `initialize` runs. Use this to parse options,\n * open connections, and register signals.\n *\n * @param options Partial options from `caper.config.ts plugins[]`.\n * @param app The application instance, fully constructed but possibly\n * mid-bootstrap (other plugins may not yet be initialized — see\n * `requires` and `postInitialize`).\n */\n initialize(options: Partial<O>, app: IApplication): Promise<void> | void;\n\n /**\n * Cross-plugin wiring hook. Called after every plugin has finished\n * `initialize`. Safe to look up siblings via `app.getPlugin(id)` here\n * regardless of `requires` — they're all live.\n */\n postInitialize(_app: IApplication): Promise<void> | void;\n\n /** Tear down. Called on app shutdown. */\n destroy(): void;\n\n /**\n * Track a signal connection so it gets auto-disconnected on `destroy`.\n * Prefer this over storing connections manually.\n */\n addSignalConnection(...args: SignalConnection[]): void;\n\n /** Disconnect every connection added via `addSignalConnection`. */\n clearSignalConnections(): void;\n\n /** Register methods this plugin exposes via the core function registry. */\n registerCoreFunctions(): void;\n\n /** Register signals this plugin exposes via the core signal registry. */\n registerCoreSignals(): void;\n}\n\nexport interface PluginListItem {\n id: string;\n path: string;\n module?: ImportListItemModule<IPlugin>;\n assets?: string[];\n plugins?: string[];\n /**\n * IDs of other plugins that must initialize before this one. Populated\n * from `definePlugin({ requires: [...] })` for local plugins; carried\n * through discovery to bootstrap so the framework can topologically\n * sort the active plugin set.\n */\n requires?: string[];\n}\n\nexport class Plugin<O = any> implements IPlugin<O> {\n private static readonly __caper_method_binding_root = true;\n // A collection of signal connections.\n protected _signalConnections: SignalConnections = new SignalConnections();\n\n protected _options: O;\n\n get options(): O {\n return this._options;\n }\n\n constructor(public id: string = 'Plugin') {\n bindAllMethods(this);\n }\n\n public get app(): AppTypeOverrides['App'] {\n return Application.getInstance();\n }\n\n public destroy(): void {\n this._signalConnections.disconnectAll();\n }\n\n public initialize(options?: Partial<O>, _app?: IApplication): Promise<void> | void;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public async initialize(_options: Partial<O>, _app?: IApplication): Promise<void> {\n return Promise.resolve(undefined);\n }\n\n public postInitialize(_app: IApplication): Promise<void> | void;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public async postInitialize(_app: IApplication): Promise<void> {\n return Promise.resolve(undefined);\n }\n\n /**\n * Add signal connections to the container.\n * @param args - The signal connections to add.\n */\n public addSignalConnection(...args: SignalConnection[]) {\n for (const connection of args) {\n this._signalConnections.add(connection);\n }\n }\n\n public clearSignalConnections() {\n this._signalConnections.disconnectAll();\n }\n\n /**\n * @override\n * @protected\n */\n public registerCoreFunctions(): void {\n const functions = this.getCoreFunctions();\n functions.forEach((f) => {\n const fName = f as keyof ICoreFunctions;\n // @ts-expect-error implicit any\n coreFunctionRegistry[fName] = this[f];\n });\n }\n\n /**\n * @override\n * @protected\n */\n public registerCoreSignals(): void {\n const signals = this.getCoreSignals();\n signals.forEach((s) => {\n const sName = s as keyof ICoreSignals;\n // @ts-expect-error implicit any\n coreSignalRegistry[sName] = this[s];\n });\n }\n\n protected getCoreFunctions(): string[] {\n return [];\n }\n\n protected getCoreSignals(): string[] {\n return [];\n }\n}\n","import { Action, ActionContext, ActionDetail, ActionMap, ActionSignal } from '.';\nimport { IApplication } from '../../core';\nimport { Signal } from '../../signals';\nimport { Logger } from '../../utils';\nimport { IPlugin, Plugin } from '../Plugin';\n\nexport interface IActionsPlugin<C extends ActionContext = ActionContext> extends IPlugin {\n context: C;\n onActionContextChanged: Signal<(context: C) => void>;\n onActionDispatched: Signal<(detail: ActionDetail) => void>;\n initialize(options: Partial<IActionsPluginOptions>, app: IApplication): void;\n getAction<TActionData = any>(action: Action | string): ActionSignal<TActionData>;\n getActions(): ActionMap;\n sendAction<TActionData = any>(actionId: Action | string, data?: TActionData): void;\n setActionContext(context: C): string;\n debug: boolean;\n}\n\nexport interface IActionsPluginOptions {\n actions: Partial<ActionMap>;\n}\n\nexport class ActionsPlugin extends Plugin<IActionsPluginOptions> implements IActionsPlugin {\n public readonly id = 'actions';\n // signals\n public onActionContextChanged: Signal<(context: string | ActionContext) => void> = new Signal<\n (context: string | ActionContext) => void\n >();\n // emitted after an allowed action is dispatched (not for dropped out-of-context actions)\n public onActionDispatched: Signal<(detail: ActionDetail) => void> = new Signal<(detail: ActionDetail) => void>();\n\n // private properties\n private _context: ActionContext = 'default';\n private _signals: Map<string | number, ActionSignal> = new Map();\n private _actions: Partial<ActionMap> = {};\n private _debug: boolean = false;\n set debug(debug: boolean) {\n this._debug = debug;\n }\n get debug(): boolean {\n return this._debug;\n }\n\n // getter / setter\n get context(): string | ActionContext {\n return this._context;\n }\n\n set context(context: string | ActionContext) {\n if (this._context === context) {\n return;\n }\n this._context = context;\n this.onActionContextChanged.emit(context);\n }\n\n initialize(_options: Partial<IActionsPluginOptions>, app: IApplication): void {\n this._actions = app?.config?.actions ? app.config.actions || {} : {};\n }\n\n getAction<TActionData = any>(action: Action | string): ActionSignal<TActionData> {\n if (!this._signals.has(action)) {\n this._signals.set(action, new Signal<(actionDetail: ActionDetail<TActionData>) => void>());\n }\n return this._signals.get(action)!;\n }\n\n getActions(): ActionMap {\n return this._actions as ActionMap;\n }\n\n sendAction<TActionData = any>(actionId: Action | string, data?: TActionData): void {\n // check if action is defined\n if (!this._actions[actionId]) {\n if (this._debug) {\n Logger.warn(`Action ${actionId} is not defined`);\n }\n return;\n }\n\n // check if action is allowed for current context\n // send action if allowed\n if (\n this._actions[actionId]?.context === '*' ||\n this._actions[actionId]?.context === this.context ||\n this._actions[actionId]?.context?.includes(this.context)\n ) {\n const detail: ActionDetail<TActionData> = { id: actionId, context: this.context, data };\n this.getAction<TActionData>(actionId).emit(detail);\n // notify automation / observers of the dispatched (allowed) action\n this.onActionDispatched.emit(detail);\n return;\n }\n\n // the action wasn't allowed\n if (this._debug) {\n Logger.warn(`Action ${actionId} is not allowed for context ${this.context}`);\n }\n }\n\n setActionContext(context: string | ActionContext): string {\n this.context = context;\n return this.context;\n }\n\n protected getCoreFunctions(): string[] {\n return ['getAction', 'sendAction', 'setActionContext', 'getActions'];\n }\n\n protected getCoreSignals(): string[] {\n return ['onActionContextChanged', 'onActionDispatched'];\n }\n}\n","import { Action } from '../..';\n\nexport const DefaultActionContexts = {\n default: 'default',\n menu: 'menu',\n pause: 'pause',\n popup: 'popup',\n game: 'game',\n};\n\nexport const DefaultActionContextsArray = ['default', 'menu', 'pause', 'popup', 'game'];\n\nexport const DefaultActions: Action[] = [\n 'up',\n 'down',\n 'left',\n 'right',\n 'action',\n 'pause',\n 'unpause',\n 'start',\n 'select',\n 'menu',\n 'back',\n 'next',\n];\n\nexport const defaultActionsList = {\n action: { context: '*' },\n back: { context: ['menu', 'default', 'popup'] },\n next: { context: ['menu', 'default', 'popup'] },\n select: { context: ['menu', 'default', 'popup'] },\n menu: { context: ['default'] },\n down: { context: ['menu', 'default', 'popup'] },\n up: { context: ['menu', 'default', 'popup'] },\n left: { context: ['menu', 'default', 'popup'] },\n right: { context: '*' },\n pause: { context: '*' },\n unpause: { context: '*' },\n start: { context: '*' },\n};\n\nexport const DefaultButtonIds = {\n __default_do_not_use__: '__default_do_not_use__',\n};\n","import type { AssetsPreferences, ResolvedAsset, UnresolvedAsset } from 'pixi.js';\nimport { Assets } from 'pixi.js';\nimport type { IScene } from '../display';\nimport { Signal } from '../signals';\nimport {\n AssetLike,\n AssetLoadingOptions,\n AssetTypes,\n BundleTypes,\n CaperEvent,\n isDev,\n SceneImportListItem,\n} from '../utils';\nimport type { IPlugin } from './Plugin';\nimport { Plugin } from './Plugin';\n\nexport interface IAssetsPlugin extends IPlugin {\n onLoadStart: Signal<() => void>;\n onLoadProgress: Signal<(progress: number) => void>;\n onLoadComplete: Signal<() => void>;\n\n onLoadRequiredStart: Signal<() => void>;\n onLoadRequiredProgress: Signal<(progress: number) => void>;\n onLoadRequiredComplete: Signal<() => void>;\n\n onBackgroundLoadStart: Signal<() => void>;\n onBackgroundAssetLoaded: Signal<(asset: string) => void>;\n onBackgroundBundlesLoaded: Signal<(bundles: BundleTypes) => void>;\n\n webStartEvent: Event;\n webProgressEvent: CustomEvent<{ progress: number }>;\n webCompleteEvent: Event;\n\n webRequiredStartEvent: Event;\n webRequiredProgressEvent: CustomEvent<{ progress: number }>;\n webRequiredCompleteEvent: Event;\n\n loadAssets(\n assets: string | string[] | UnresolvedAsset | UnresolvedAsset[] | AssetLike | AssetLike[],\n reportProgress?: boolean,\n ): Promise<void>;\n\n loadBundles(bundle: BundleTypes, reportProgress?: boolean): Promise<void>;\n\n loadSceneAssets(scene: IScene | SceneImportListItem<any>, background?: boolean): Promise<void>;\n\n unloadSceneAssets(scene: IScene | SceneImportListItem<any>): Promise<void>;\n\n loadRequired(): Promise<void>;\n\n loadBackground(): void;\n}\n\nconst detaultAssetPreferences: Partial<AssetsPreferences> = {\n preferWorkers: !isDev,\n crossOrigin: 'anonymous',\n};\n\nfunction addParseAsGraphicsContext(asset: string | UnresolvedAsset): string | UnresolvedAsset {\n if (typeof asset === 'string') {\n if (!asset?.includes('.svg')) {\n return asset;\n }\n asset = { src: asset };\n } else {\n if (Array.isArray(asset.src) || !asset.src?.includes('.svg')) {\n return asset;\n }\n }\n if (!asset.data) {\n asset.data = {};\n }\n asset.data.parseAsGraphicsContext = true;\n return asset;\n}\n\nfunction getAssetList(assets: AssetTypes): UnresolvedAsset[] | string[] {\n if (!Array.isArray(assets)) {\n assets = [assets];\n }\n return assets.map((asset: string | UnresolvedAsset | AssetLike) => {\n if (typeof asset === 'string') {\n return addParseAsGraphicsContext(asset);\n } else if (typeof asset === 'object') {\n let alias: string | string[] = (asset?.src as string | string[]) || [];\n if (!Array.isArray(alias)) {\n alias = [alias];\n }\n if (asset.ext) {\n if (asset.src && !Array.isArray(asset.src)) {\n alias.push(asset.src as string);\n asset.src = [asset.src];\n }\n asset.src = (asset.src as string[]).map((src: string) => {\n return `${src}.${asset.ext}`;\n });\n asset.alias = [...alias, ...(asset.src as string[])].filter(Boolean);\n } else {\n addParseAsGraphicsContext(asset);\n }\n return asset;\n }\n });\n}\n\nexport class AssetsPlugin extends Plugin<AssetLoadingOptions> implements IAssetsPlugin {\n public readonly id: string = 'assets';\n public onLoadStart: Signal<() => void> = new Signal();\n public onLoadProgress: Signal<(progress: number) => void> = new Signal();\n public onLoadComplete: Signal<() => void> = new Signal();\n // required loading signals\n public onLoadRequiredStart: Signal<() => void> = new Signal();\n public onLoadRequiredProgress: Signal<(progress: number) => void> = new Signal();\n public onLoadRequiredComplete: Signal<() => void> = new Signal();\n\n public onBackgroundLoadStart: Signal<() => void> = new Signal();\n public onBackgroundAssetLoaded: Signal<(asset: string) => void> = new Signal();\n public onBackgroundBundlesLoaded: Signal<(bundles: BundleTypes) => void> = new Signal();\n\n private _loadedBundles: Set<string> = new Set();\n private _loadedAssets: Set<string | UnresolvedAsset> = new Set();\n\n private _required: { assets?: AssetTypes; bundles?: BundleTypes } = {};\n private _background: { assets?: AssetTypes; bundles?: BundleTypes } = {};\n\n private _isLoadingRequired: boolean = false;\n\n public webRequiredStartEvent: Event = new Event(CaperEvent.REQUIRED_ASSETS_START, {\n bubbles: true,\n cancelable: false,\n });\n public webRequiredProgressEvent: CustomEvent<{ progress: number }> = new CustomEvent<{ progress: number }>(\n CaperEvent.REQUIRED_ASSETS_PROGRESS,\n {\n bubbles: true,\n cancelable: false,\n detail: {\n progress: 0,\n },\n },\n );\n public webRequiredCompleteEvent: Event = new Event(CaperEvent.REQUIRED_ASSETS_COMPLETE, {\n bubbles: true,\n cancelable: false,\n });\n\n public webStartEvent: Event = new Event(CaperEvent.ASSETS_START, {\n bubbles: true,\n cancelable: false,\n });\n public webProgressEvent: CustomEvent<{ progress: number }> = new CustomEvent<{ progress: number }>(\n CaperEvent.ASSETS_PROGRESS,\n {\n bubbles: true,\n cancelable: false,\n detail: {\n progress: 0,\n },\n },\n );\n public webCompleteEvent: Event = new Event(CaperEvent.ASSETS_COMPLETE, {\n bubbles: true,\n cancelable: false,\n });\n\n public initialize(options?: AssetLoadingOptions): Promise<void> | void {\n if (options?.preload) {\n this._required = options.preload;\n }\n if (options?.background) {\n this._background = options.background;\n }\n Assets.setPreferences({ ...detaultAssetPreferences, ...options?.assetPreferences });\n }\n\n public async loadRequired() {\n this._isLoadingRequired = true;\n this._handleLoadStart();\n this._handleLoadProgress(0);\n if (this._required) {\n if (this._required.assets) {\n await Assets.load(getAssetList(this._required.assets), this._handleLoadProgress);\n }\n if (this._required.bundles) {\n let bundles = this._required.bundles;\n if (!Array.isArray(bundles)) {\n bundles = [bundles];\n }\n bundles = bundles.filter((bundle) => !this._isBundleLoaded(bundle));\n await Assets.loadBundle(this._required.bundles, this._handleLoadProgress);\n }\n }\n this._handleLoadComplete();\n this._isLoadingRequired = false;\n return Promise.resolve();\n }\n\n public loadBackground() {\n this.onBackgroundLoadStart.emit();\n if (this._background) {\n if (this._background.assets) {\n const list = getAssetList(this._background.assets);\n list.forEach((asset) => {\n if ((asset as UnresolvedAsset)?.src) {\n const src = (asset as UnresolvedAsset).src as string[];\n if (src) {\n return Assets.backgroundLoad(src);\n }\n }\n return Assets.backgroundLoad(asset as string).then(() => {\n this.onBackgroundAssetLoaded.emit(asset as string);\n });\n });\n }\n if (this._background.bundles) {\n void Assets.backgroundLoadBundle(this._background.bundles).then(() => {\n this.onBackgroundBundlesLoaded.emit(this._background.bundles as BundleTypes);\n });\n }\n }\n }\n\n public async loadAssets(assets: AssetTypes, reportProgress: boolean = true) {\n assets = getAssetList(assets);\n await Assets.load(assets, reportProgress ? this._handleLoadProgress : undefined);\n this._markAssetsLoaded(assets as UnresolvedAsset[] | string[]);\n return Promise.resolve();\n }\n\n public async loadBundles(bundles: BundleTypes, reportProgress: boolean = true) {\n await Assets.loadBundle(bundles, reportProgress ? this._handleLoadProgress : undefined);\n this._markBundlesLoaded(bundles);\n return Promise.resolve();\n }\n\n public async unloadSceneAssets(scene: IScene | SceneImportListItem<any>) {\n if (scene.assets?.preload?.assets) {\n const assets = getAssetList(scene.assets.preload.assets);\n Assets.unload(assets as ResolvedAsset[] | string[]).then(() => {\n // Logger.log('assets unloaded');\n this._markAssetsUnloaded(assets);\n });\n }\n if (scene.assets?.preload?.bundles) {\n const bundles = scene.assets.preload.bundles;\n void Assets.unloadBundle(bundles).then(() => {\n this._markBundlesUnloaded(bundles);\n });\n }\n return Promise.resolve();\n }\n\n public async loadSceneAssets(scene: IScene | SceneImportListItem<any>, background = false) {\n if (background) {\n if (scene.assets?.background) {\n if (scene.assets.background.assets) {\n const assets = getAssetList(scene.assets.background.assets);\n const filteredAssets = assets.filter((asset: string | UnresolvedAsset) => !this._isAssetLoaded(asset));\n if (filteredAssets.length) {\n filteredAssets.forEach((asset) => {\n if ((asset as UnresolvedAsset)?.src) {\n const src = (asset as UnresolvedAsset).src as string[];\n if (src) {\n return Assets.backgroundLoad(src);\n }\n }\n return Assets.backgroundLoad(asset as string);\n });\n }\n }\n if (scene.assets.background.bundles) {\n let bundles = Array.isArray(scene.assets.background.bundles)\n ? scene.assets.background.bundles\n : [scene.assets.background.bundles];\n bundles = bundles.filter((bundle) => !this._isBundleLoaded(bundle));\n if (bundles.length) {\n void Assets.backgroundLoadBundle(bundles);\n }\n }\n }\n } else {\n this._handleLoadStart();\n this._handleLoadProgress(0);\n if (scene.assets?.preload?.assets) {\n const assets = getAssetList(scene.assets.preload.assets);\n const filteredAssets = assets.filter((asset) => !this._isAssetLoaded(asset));\n if (filteredAssets.length) {\n await Assets.load(filteredAssets, this._handleLoadProgress);\n this._markAssetsLoaded(assets);\n }\n }\n if (scene.assets?.preload?.bundles) {\n let bundles: string[] = Array.isArray(scene.assets.preload.bundles)\n ? scene.assets.preload.bundles\n : [scene.assets.preload.bundles];\n bundles = bundles.filter((bundle) => !this._isBundleLoaded(bundle));\n if (bundles.length) {\n await Assets.loadBundle(bundles, this._handleLoadProgress);\n this._markBundlesLoaded(bundles);\n }\n }\n this._handleLoadComplete();\n }\n }\n\n protected getCoreFunctions(): string[] {\n return ['loadSceneAssets', 'unloadSceneAssets', 'loadAssets', 'loadBundles', 'loadRequired'];\n }\n\n protected getCoreSignals(): string[] {\n return [\n 'onLoadStart',\n 'onLoadProgress',\n 'onLoadComplete',\n 'onBackgroundLoadStart',\n 'onBackgroundAssetLoaded',\n 'onBackgroundBundlesLoaded',\n 'onLoadRequiredStart',\n 'onLoadRequiredProgress',\n 'onLoadRequiredComplete',\n ];\n }\n\n private _isAssetLoaded(alias: string | UnresolvedAsset) {\n return this._loadedAssets.has(alias);\n }\n\n private _isBundleLoaded(alias: string) {\n return this._loadedBundles.has(alias);\n }\n\n private _markAssetsLoaded(urls: UnresolvedAsset[] | string[]) {\n urls.forEach((url) => {\n this._loadedAssets.add(url);\n });\n }\n\n private _markBundlesLoaded(aliases: string[] | string) {\n if (!Array.isArray(aliases)) {\n aliases = [aliases];\n }\n aliases.forEach((alias) => {\n this._loadedBundles.add(alias);\n });\n }\n\n private _markAssetsUnloaded(urls: string[] | string | UnresolvedAsset | UnresolvedAsset[]) {\n if (!Array.isArray(urls)) {\n urls = [urls];\n }\n urls.forEach((url: string | UnresolvedAsset) => {\n this._loadedAssets.delete(url);\n });\n }\n\n private _markBundlesUnloaded(aliases: string[] | string) {\n if (!Array.isArray(aliases)) {\n aliases = [aliases];\n }\n aliases.forEach((alias) => {\n this._loadedBundles.delete(alias);\n });\n }\n\n private _handleLoadStart() {\n this.onLoadStart.emit();\n this.dispatchWebEvent(this.webStartEvent);\n if (this._isLoadingRequired) {\n this.onLoadRequiredStart.emit();\n this.dispatchWebEvent(this.webRequiredStartEvent);\n }\n }\n\n private _handleLoadProgress(progress: number) {\n this.onLoadProgress.emit(progress);\n this.dispatchWebEvent(this.webProgressEvent, { progress });\n if (this._isLoadingRequired) {\n this.onLoadRequiredProgress.emit(progress);\n this.dispatchWebEvent(this.webRequiredProgressEvent, { progress });\n }\n }\n\n private _handleLoadComplete() {\n this._handleLoadProgress(1);\n this.onLoadComplete.emit();\n this.dispatchWebEvent(this.webCompleteEvent);\n\n if (this._isLoadingRequired) {\n this.onLoadRequiredComplete.emit();\n this.dispatchWebEvent(this.webRequiredCompleteEvent);\n }\n }\n\n private dispatchWebEvent(event: Event | CustomEvent, detail?: any) {\n if (detail) {\n for (const key in detail) {\n const e = event as CustomEvent<any>;\n e.detail[key] = detail[key];\n }\n }\n try {\n this.app.canvas.dispatchEvent(event);\n } catch (error: any) {\n throw new Error('Error dispatching web event', { cause: error });\n }\n }\n}\n","import { Logger } from '../../utils';\nimport type { Size } from '../../utils';\n\nimport type { BreakpointContext, BreakpointMode, BreakpointNameLike, Pointer } from './types';\n\n/**\n * A tier ladder, validated and sorted ascending by stop. `names[i]` and\n * `stops[i]` are parallel arrays so tier lookup is a single forward scan.\n */\nexport interface NormalizedLadder {\n readonly names: string[];\n readonly stops: number[];\n readonly byName: Readonly<Record<string, number>>;\n}\n\n/**\n * Validate and sort a tier map. Throws rather than warns: a silently wrong\n * ladder is far more expensive to debug than a boot failure (spec §11).\n */\nexport function normalizeTiers(tiers: Record<string, number>): NormalizedLadder {\n const entries = Object.entries(tiers);\n if (entries.length === 0) {\n throw new Error('[breakpoints] `tiers` is empty — declare at least one tier in caper.config.ts.');\n }\n\n for (const [name, stop] of entries) {\n if (!Number.isFinite(stop) || stop < 0) {\n throw new Error(\n `[breakpoints] tier '${name}' has an invalid stop (${stop}) — stops must be finite numbers >= 0.`,\n );\n }\n }\n\n const sorted = entries.slice().sort((a, b) => a[1] - b[1]);\n\n if (sorted[0][1] !== 0) {\n throw new Error(\n `[breakpoints] the lowest tier must start at 0, but '${sorted[0][0]}' starts at ${sorted[0][1]}.`,\n );\n }\n\n for (let i = 1; i < sorted.length; i++) {\n if (sorted[i][1] === sorted[i - 1][1]) {\n throw new Error(\n `[breakpoints] tiers '${sorted[i - 1][0]}' and '${sorted[i][0]}' share the same stop (${sorted[i][1]}) — stops must be unique.`,\n );\n }\n }\n\n return {\n names: sorted.map(([name]) => name),\n stops: sorted.map(([, stop]) => stop),\n byName: Object.fromEntries(sorted),\n };\n}\n\n/** The highest tier whose stop is <= width. Clamps to the lowest tier. */\nexport function resolveTier(ladder: NormalizedLadder, width: number): BreakpointNameLike {\n let name = ladder.names[0];\n for (let i = 0; i < ladder.stops.length; i++) {\n if (width < ladder.stops[i]) break;\n name = ladder.names[i];\n }\n return name;\n}\n\n/** Names already warned about, so a resize drag cannot flood the console. */\nconst warned = new Set<string>();\n\nfunction warnOnce(key: string, message: string): void {\n if (warned.has(key)) return;\n warned.add(key);\n Logger.warn(message);\n}\n\n/**\n * Turn a tier name or raw pixel value into a width stop. The single place\n * names become numbers, so mode bodies and the plugin's own `atLeast`/`below`\n * cannot disagree.\n */\nexport function resolveStop(\n ladder: NormalizedLadder,\n value: BreakpointNameLike | number,\n): number | undefined {\n if (typeof value === 'number') return value;\n const stop = ladder.byName[value];\n if (stop === undefined) {\n warnOnce(`stop:${value}`, `[breakpoints] unknown tier '${value}' — known tiers: ${ladder.names.join(', ')}.`);\n }\n return stop;\n}\n\n/**\n * Evaluate one mode against a context. Object keys are ANDed; an unknown tier\n * name fails the whole mode; a throwing predicate is treated as false.\n */\nexport function matchesMode(\n ctx: BreakpointContext,\n mode: BreakpointMode,\n ladder: NormalizedLadder,\n label = 'mode',\n): boolean {\n if (typeof mode === 'function') {\n try {\n return mode(ctx) === true;\n } catch (e) {\n warnOnce(`predicate:${label}`, `[breakpoints] mode '${label}' threw; treating as false. ${String(e)}`);\n return false;\n }\n }\n\n if (mode.tier !== undefined) {\n const wanted = Array.isArray(mode.tier) ? mode.tier : [mode.tier];\n if (!wanted.includes(ctx.tier as never)) return false;\n }\n\n if (mode.atLeast !== undefined) {\n const stop = resolveStop(ladder, mode.atLeast);\n if (stop === undefined || ctx.width < stop) return false;\n }\n\n if (mode.below !== undefined) {\n const stop = resolveStop(ladder, mode.below);\n if (stop === undefined || ctx.width >= stop) return false;\n }\n\n if (mode.orientation !== undefined && ctx.orientation !== mode.orientation) return false;\n if (mode.pointer !== undefined && ctx.pointer !== mode.pointer) return false;\n if (mode.minHeight !== undefined && ctx.height < mode.minHeight) return false;\n if (mode.maxHeight !== undefined && ctx.height > mode.maxHeight) return false;\n\n return true;\n}\n\n/** Build the evaluated state from a raw size plus the pointer axis. */\nexport function buildContext(size: Size, ladder: NormalizedLadder, pointer: Pointer): BreakpointContext {\n const { width, height } = size;\n return {\n width,\n height,\n aspect: height === 0 ? 0 : width / height,\n tier: resolveTier(ladder, width),\n orientation: width > height ? 'landscape' : 'portrait',\n pointer,\n };\n}\n\n/**\n * Every name currently true: the active tier, both axis values, and each\n * matching mode. One set backs `is()`, the enter/leave signals and the diff,\n * so they can never disagree.\n */\nexport function activeNames(\n ctx: BreakpointContext,\n modes: ReadonlyMap<string, BreakpointMode>,\n ladder: NormalizedLadder,\n): Set<string> {\n const active = new Set<string>([ctx.tier as string, ctx.orientation, ctx.pointer]);\n for (const [name, mode] of modes) {\n if (matchesMode(ctx, mode, ladder, name)) active.add(name);\n }\n return active;\n}\n\n/** Names that turned on and off between two active sets. */\nexport function diffNames(\n prev: ReadonlySet<string>,\n next: ReadonlySet<string>,\n): { entered: string[]; left: string[] } {\n const entered: string[] = [];\n const left: string[] = [];\n for (const name of next) if (!prev.has(name)) entered.push(name);\n for (const name of prev) if (!next.has(name)) left.push(name);\n return { entered, left };\n}\n\n/**\n * Mobile-first cascade: the entry for the current tier, else the nearest\n * defined tier below it, else the lowest defined entry. A non-empty map\n * therefore never yields undefined. An explicit `undefined` value counts as\n * absent, which is what makes partial maps ergonomic.\n *\n * An unknown tier behaves like the bottom of the ladder (index -1), so the\n * first loop is skipped and the lowest defined entry wins.\n */\nexport function resolveValue<T>(\n ladder: NormalizedLadder,\n tier: BreakpointNameLike,\n map: Partial<Record<string, T>>,\n): T | undefined {\n const idx = ladder.names.indexOf(tier as string);\n for (let i = idx; i >= 0; i--) {\n const value = map[ladder.names[i]];\n if (value !== undefined) return value;\n }\n for (let i = 0; i < ladder.names.length; i++) {\n const value = map[ladder.names[i]];\n if (value !== undefined) return value;\n }\n return undefined;\n}\n","import type { AppTypeOverrides, Orientation, Size } from '../../utils';\n\n/** Default ladder. Values are min-widths; the lowest must be 0. */\nexport const defaultBreakpoints = {\n mobile: 0,\n tablet: 768,\n desktop: 1024,\n wide: 1440,\n} as const;\n\nexport type DefaultTierName = keyof typeof defaultBreakpoints;\n\nexport type Pointer = 'coarse' | 'fine';\n\n/**\n * Ladder tier names. When the app declares its own set in `caper.config.ts`,\n * the generated `Breakpoints` override REPLACES the defaults rather than\n * adding to them — a config with `ultrawide` but no `mobile` must not\n * autocomplete `mobile`.\n */\nexport type BreakpointTierName = AppTypeOverrides extends { Breakpoints: infer B }\n ? B & string\n : DefaultTierName;\n\n/** Config-declared mode names. `never` when none are declared. */\nexport type BreakpointModeName = AppTypeOverrides extends { BreakpointModes: infer M }\n ? M & string\n : never;\n\n/** Everything nameable: tiers, modes and axis values share one namespace. */\nexport type BreakpointName = BreakpointTierName | BreakpointModeName | Orientation | Pointer;\n\n/**\n * Accepted at call sites: known names autocomplete, runtime-defined names\n * still compile.\n */\nexport type BreakpointNameLike = BreakpointName | (string & {});\n\n/** The evaluated state every decision is made against. */\nexport interface BreakpointContext {\n width: number;\n height: number;\n /** width / height; 0 when height is 0 */\n aspect: number;\n tier: BreakpointNameLike;\n orientation: Orientation;\n pointer: Pointer;\n}\n\n/** The body of a mode: a condition object, or a predicate for anything else. */\nexport type BreakpointMode<N extends string = BreakpointNameLike> =\n | ((ctx: BreakpointContext) => boolean)\n | {\n /** the active tier is this one (or one of these) */\n tier?: N | N[];\n /** width >= this stop (tier name or raw px) */\n atLeast?: N | number;\n /** width < this stop (tier name or raw px) */\n below?: N | number;\n orientation?: Orientation;\n pointer?: Pointer;\n minHeight?: number;\n maxHeight?: number;\n };\n\n/** The shape of the top-level `breakpoints` key in caper.config.ts. */\nexport type BreakpointsConfig<\n T extends Record<string, number> = Record<string, number>,\n M extends Record<string, BreakpointMode> = Record<string, BreakpointMode>,\n> = {\n tiers: T;\n modes: M;\n};\n\n/** What the plugin receives from `config.breakpoints`; both halves optional. */\nexport type BreakpointPluginOptions = Partial<BreakpointsConfig>;\n\nexport interface BreakpointChangeDetail {\n current: BreakpointNameLike;\n previous: BreakpointNameLike;\n /** names that became true this evaluation — tiers, modes, orientation, pointer */\n entered: string[];\n /** names that became false this evaluation */\n left: string[];\n size: Size;\n}\n","import type { IApplication } from '../../core';\nimport { Signal, type SignalConnection, type SignalOrder } from '../../signals';\nimport { Logger, type Orientation, type Size } from '../../utils';\nimport type { IPlugin } from '../Plugin';\nimport { Plugin } from '../Plugin';\nimport type { NormalizedLadder } from './evaluate';\nimport {\n activeNames,\n buildContext,\n diffNames,\n matchesMode,\n normalizeTiers,\n resolveStop,\n resolveValue,\n} from './evaluate';\nimport type {\n BreakpointChangeDetail,\n BreakpointContext,\n BreakpointMode,\n BreakpointNameLike,\n BreakpointPluginOptions,\n BreakpointTierName,\n Pointer,\n} from './types';\nimport { defaultBreakpoints } from './types';\n\nconst AXIS_NAMES = new Set<string>(['portrait', 'landscape', 'coarse', 'fine']);\nconst ZERO: Size = { width: 0, height: 0 };\n\nexport interface IBreakpointPlugin extends IPlugin<BreakpointPluginOptions> {\n readonly onBreakpointChanged: Signal<(detail: BreakpointChangeDetail) => void>;\n readonly onChange: Signal<(detail: BreakpointChangeDetail) => void>;\n readonly current: BreakpointNameLike;\n readonly size: Size;\n readonly width: number;\n readonly height: number;\n readonly orientation: Orientation;\n readonly pointer: Pointer;\n is(name: BreakpointNameLike): boolean;\n atLeast(value: BreakpointNameLike | number): boolean;\n below(value: BreakpointNameLike | number): boolean;\n between(lower: BreakpointNameLike | number, upper: BreakpointNameLike | number): boolean;\n matches(mode: BreakpointMode): boolean;\n value<T>(map: Partial<Record<BreakpointTierName, T>>): T | undefined;\n define(name: string, mode: BreakpointMode): void;\n undefine(name: string): void;\n onEnter(name: BreakpointNameLike, callback: () => void, order?: SignalOrder): SignalConnection;\n onLeave(name: BreakpointNameLike, callback: () => void, order?: SignalOrder): SignalConnection;\n when(name: BreakpointNameLike, callback: () => void, order?: SignalOrder): SignalConnection;\n}\n\n/**\n * Named responsive state derived from the renderer size.\n *\n * Declare tiers and modes in `caper.config.ts`; the plugin re-evaluates on\n * every resize but only emits when a name actually flips.\n *\n * @example\n * ```ts\n * const bp = app.breakpoints;\n *\n * const columns = bp.value({ mobile: 1, tablet: 2, desktop: 3 });\n * if (bp.is('stacked')) { ... }\n *\n * // run now, and again on every entry into the mode\n * this.addSignalConnection(bp.when('stacked', () => this.relayout()));\n * ```\n *\n * Listen to `app.onResize` or `bp.onChange` — never `app.webEvents.onResize`,\n * which fires ahead of this plugin and so reports a stale tier.\n */\nexport class BreakpointPlugin extends Plugin<BreakpointPluginOptions> implements IBreakpointPlugin {\n public readonly id = 'breakpoints';\n\n /**\n * Named to match its `ICoreSignals` key — `registerCoreSignals` copies\n * `this[name]` into the registry under the same string.\n */\n public readonly onBreakpointChanged = new Signal<(detail: BreakpointChangeDetail) => void>();\n\n private _ladder: NormalizedLadder;\n private _modes = new Map<string, BreakpointMode>();\n private _ctx: BreakpointContext;\n private _active: Set<string> = new Set();\n private _enter = new Map<string, Signal<() => void>>();\n private _leave = new Map<string, Signal<() => void>>();\n private _pointer: Pointer = 'fine';\n private _pointerQuery: MediaQueryList | null = null;\n private _warnedListenerNames = new Set<string>();\n\n /** Fluent alias for {@link onBreakpointChanged}. */\n get onChange(): Signal<(detail: BreakpointChangeDetail) => void> {\n return this.onBreakpointChanged;\n }\n\n get current(): BreakpointNameLike {\n return this._ctx.tier;\n }\n\n get size(): Size {\n return { width: this._ctx.width, height: this._ctx.height };\n }\n\n get width(): number {\n return this._ctx.width;\n }\n\n get height(): number {\n return this._ctx.height;\n }\n\n get orientation(): Orientation {\n return this._ctx.orientation;\n }\n\n get pointer(): Pointer {\n return this._ctx.pointer;\n }\n\n async initialize(options: Partial<BreakpointPluginOptions> = {}) {\n // Seed a safe default ladder and context before validating the user's\n // tiers below. `normalizeTiers` throws on an invalid ladder, and\n // `Application.registerPlugin` swallows a rejected `initialize` and\n // continues — leaving `_ladder`/`_ctx` unset would turn every later\n // accessor into an unrelated TypeError instead of surfacing the real\n // cause (spec §11).\n this._ladder = normalizeTiers({ ...defaultBreakpoints });\n this._ctx = buildContext(ZERO, this._ladder, this._pointer);\n\n this._options = {\n tiers: options.tiers ?? { ...defaultBreakpoints },\n modes: options.modes ?? {},\n };\n this._ladder = normalizeTiers(this._options.tiers!);\n for (const [name, mode] of Object.entries(this._options.modes!)) {\n this._modes.set(name, mode);\n }\n this._initPointer();\n this._ctx = buildContext(ZERO, this._ladder, this._pointer);\n this._active = activeNames(this._ctx, this._modes, this._ladder);\n }\n\n /**\n * `'highest'` priority so `current` is already updated when normal-priority\n * scene resize handlers run.\n */\n async postInitialize(_app: IApplication) {\n this._evaluate(this.app.size ?? ZERO);\n this.addSignalConnection(this.app.onResize.connect(this._evaluate, 'highest'));\n }\n\n public destroy(): void {\n this._pointerQuery?.removeEventListener('change', this._onPointerChange);\n this._pointerQuery = null;\n for (const signal of this._enter.values()) signal.disconnectAll();\n for (const signal of this._leave.values()) signal.disconnectAll();\n this._enter.clear();\n this._leave.clear();\n this.onBreakpointChanged.disconnectAll();\n super.destroy();\n }\n\n public is(name: BreakpointNameLike): boolean {\n if (!this._isKnown(name as string)) {\n Logger.warn(`[breakpoints] unknown name '${name}'. Known: ${this._knownNames().join(', ')}.`);\n return false;\n }\n return this._active.has(name as string);\n }\n\n public atLeast(value: BreakpointNameLike | number): boolean {\n const stop = resolveStop(this._ladder, value);\n return stop !== undefined && this._ctx.width >= stop;\n }\n\n public below(value: BreakpointNameLike | number): boolean {\n const stop = resolveStop(this._ladder, value);\n return stop !== undefined && this._ctx.width < stop;\n }\n\n public between(lower: BreakpointNameLike | number, upper: BreakpointNameLike | number): boolean {\n return this.atLeast(lower) && this.below(upper);\n }\n\n public matches(mode: BreakpointMode): boolean {\n return matchesMode(this._ctx, mode, this._ladder);\n }\n\n public value<T>(map: Partial<Record<BreakpointTierName, T>>): T | undefined {\n return resolveValue(this._ladder, this._ctx.tier, map as Partial<Record<string, T>>);\n }\n\n public define(name: string, mode: BreakpointMode): void {\n this._modes.set(name, mode);\n this._evaluate(this.size);\n }\n\n public undefine(name: string): void {\n if (!this._modes.delete(name)) return;\n this._evaluate(this.size);\n }\n\n public onEnter(name: BreakpointNameLike, callback: () => void, order?: SignalOrder): SignalConnection {\n this._warnIfUnknown(name as string);\n return this._signal(this._enter, name as string).connect(callback, order);\n }\n\n public onLeave(name: BreakpointNameLike, callback: () => void, order?: SignalOrder): SignalConnection {\n this._warnIfUnknown(name as string);\n return this._signal(this._leave, name as string).connect(callback, order);\n }\n\n /** Run now if already matching, then on every subsequent entry. */\n public when(name: BreakpointNameLike, callback: () => void, order?: SignalOrder): SignalConnection {\n if (this._active.has(name as string)) callback();\n return this.onEnter(name, callback, order);\n }\n\n protected getCoreSignals(): string[] {\n return ['onBreakpointChanged'];\n }\n\n /**\n * Re-derive state from a size. Emits leave before enter — a scene tears the\n * old layout down before the new one goes up — and `onChange` last.\n */\n private _evaluate = (size: Size): void => {\n const next = buildContext(size ?? ZERO, this._ladder, this._pointer);\n const nextActive = activeNames(next, this._modes, this._ladder);\n const { entered, left } = diffNames(this._active, nextActive);\n const previous = this._ctx.tier;\n\n this._ctx = next;\n this._active = nextActive;\n\n if (entered.length === 0 && left.length === 0) return;\n\n for (const name of left) this._leave.get(name)?.emit();\n for (const name of entered) this._enter.get(name)?.emit();\n\n this.onBreakpointChanged.emit({\n current: next.tier,\n previous,\n entered,\n left,\n size: { width: next.width, height: next.height },\n });\n };\n\n private _onPointerChange = (e: MediaQueryListEvent): void => {\n this._pointer = e.matches ? 'coarse' : 'fine';\n this._evaluate(this.size);\n };\n\n private _initPointer(): void {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n this._pointer = 'fine';\n return;\n }\n this._pointerQuery = window.matchMedia('(pointer: coarse)');\n this._pointer = this._pointerQuery.matches ? 'coarse' : 'fine';\n this._pointerQuery.addEventListener('change', this._onPointerChange);\n }\n\n private _signal(store: Map<string, Signal<() => void>>, name: string): Signal<() => void> {\n let signal = store.get(name);\n if (!signal) {\n signal = new Signal<() => void>();\n store.set(name, signal);\n }\n return signal;\n }\n\n private _isKnown(name: string): boolean {\n return name in this._ladder.byName || this._modes.has(name) || AXIS_NAMES.has(name);\n }\n\n /**\n * `onEnter`/`onLeave` (and `when`, which delegates to `onEnter`) still\n * connect a live signal for an unknown name — it may be `define`d later\n * (§8) — but warn once per name so a typo doesn't silently create a\n * listener nothing will ever emit.\n */\n private _warnIfUnknown(name: string): void {\n if (this._isKnown(name) || this._warnedListenerNames.has(name)) return;\n this._warnedListenerNames.add(name);\n Logger.warn(`[breakpoints] unknown name '${name}'. Known: ${this._knownNames().join(', ')}.`);\n }\n\n private _knownNames(): string[] {\n return [...this._ladder.names, ...this._modes.keys(), ...AXIS_NAMES];\n }\n}\n","import { Logger } from '../../utils';\nimport { IAudioInstance } from './AudioInstance';\nimport { ChannelName, IAudioManagerPlugin } from './AudioManagerPlugin';\n\nexport interface IAudioChannel {\n name: string;\n muted: boolean;\n volume: number;\n instances: IAudioInstance[];\n\n add(id: string, instance: IAudioInstance): IAudioInstance;\n\n get(id: string): IAudioInstance | undefined;\n\n remove(id: string): IAudioInstance | undefined;\n\n removeInstance(instance: IAudioInstance): void;\n\n updateVolume(): void;\n\n restore(): void;\n\n destroy(): void;\n\n pause(): void;\n\n resume(): void;\n}\n\nexport class AudioChannel<C extends ChannelName = ChannelName> {\n private _sounds: Map<string, IAudioInstance[]> = new Map<string, IAudioInstance[]>();\n\n constructor(\n public name: C,\n public manager: IAudioManagerPlugin<C>,\n ) {\n this.muted = this.manager.muted;\n }\n\n get instances(): IAudioInstance[] {\n return Array.from(this._sounds.values()).flat();\n }\n\n private _muted: boolean = false;\n\n get muted(): boolean {\n return this._muted;\n }\n\n set muted(value: boolean) {\n this._muted = value;\n this.manager.onChannelMuted.emit({ channel: this, muted: value });\n this._setMuted();\n }\n\n private _volume: number = 1.0;\n\n get volume(): number {\n return this._volume;\n }\n\n set volume(value: number) {\n this._volume = value;\n this.updateVolume();\n }\n\n add(id: string, instance: IAudioInstance): IAudioInstance {\n const bucket = this._sounds.get(id);\n if (bucket) {\n bucket.push(instance);\n } else {\n this._sounds.set(id, [instance]);\n }\n return instance;\n }\n\n get(id: string): IAudioInstance | undefined {\n const bucket = this._sounds.get(id);\n return bucket ? bucket[bucket.length - 1] : undefined;\n }\n\n remove(id: string): IAudioInstance | undefined {\n const bucket = this._sounds.get(id);\n if (!bucket) {\n return undefined;\n }\n const lastInstance = bucket[bucket.length - 1];\n // destroy() -> stop() -> emits onEnd, whose handler may call\n // removeInstance() and mutate `bucket` mid-iteration. Iterate a copy.\n [...bucket].forEach((instance) => instance.destroy());\n this._sounds.delete(id);\n return lastInstance;\n }\n\n /**\n * Removes a single instance from its alias bucket without stopping or\n * destroying it, for use when an instance has naturally reached the end\n * of its life. No-op if the instance is not currently tracked.\n */\n removeInstance(instance: IAudioInstance): void {\n const bucket = this._sounds.get(instance.id);\n if (!bucket) {\n return;\n }\n const index = bucket.indexOf(instance);\n if (index === -1) {\n return;\n }\n bucket.splice(index, 1);\n if (bucket.length === 0) {\n this._sounds.delete(instance.id);\n }\n }\n\n pause(): void {\n this._sounds.forEach((bucket) => {\n bucket.forEach((sound) => {\n try {\n sound.pause();\n } catch (error) {\n Logger.error('Error pausing sound', sound.id, error);\n }\n });\n });\n }\n\n resume(): void {\n this._sounds.forEach((bucket) => {\n bucket.forEach((sound) => {\n try {\n sound.resume();\n } catch (error) {\n Logger.error('Error resuming sound', sound.id, error);\n }\n });\n });\n }\n\n _setMuted(): void {\n this._sounds.forEach((bucket) => {\n bucket.forEach((sound) => {\n sound.muted = this._muted;\n });\n });\n }\n\n updateVolume() {\n this.manager.app.ticker.addOnce(() => {\n this._sounds.forEach((bucket) => {\n bucket.forEach((sound) => {\n sound.updateVolume();\n });\n });\n this.manager.onChannelVolumeChanged.emit({ channel: this, volume: this._volume });\n });\n }\n\n restore() {\n this.muted = this._muted;\n this.volume = this._volume;\n }\n\n destroy() {}\n}\n","import { IMediaInstance } from '@pixi/sound';\nimport { gsap } from 'gsap';\nimport { Signal } from '../../signals';\nimport { bindAllMethods } from '../../utils';\nimport { IAudioChannel } from './AudioChannel';\nimport { ChannelName, IAudioManagerPlugin } from './AudioManagerPlugin';\n\nexport interface IAudioInstance<C extends ChannelName = ChannelName> {\n volume: number;\n storedVolume: number;\n media: IMediaInstance;\n channel: IAudioChannel;\n muted: boolean;\n id: string;\n manager: IAudioManagerPlugin<C>;\n onStart: Signal<(instance: IAudioInstance) => void>;\n onStop: Signal<(instance: IAudioInstance) => void>;\n onEnd: Signal<(instance: IAudioInstance) => void>;\n onPaused: Signal<(instance: IAudioInstance) => void>;\n onResumed: Signal<(instance: IAudioInstance) => void>;\n isPlaying: boolean;\n\n fadeTo(volume: number, duration: number): gsap.core.Tween;\n\n stop(): void;\n\n destroy(): void;\n\n remove(): void;\n\n updateVolume(): void;\n\n addListeners(): void;\n\n removeListeners(): void;\n\n pause(): void;\n\n play(): void;\n\n resume(): void;\n}\n\nexport class AudioInstance<C extends ChannelName = ChannelName> implements IAudioInstance {\n public storedVolume: number;\n public onStart: Signal<(instance: IAudioInstance) => void> = new Signal<(instance: IAudioInstance) => void>();\n public onStop: Signal<(instance: IAudioInstance) => void> = new Signal<(instance: IAudioInstance) => void>();\n public onEnd: Signal<(instance: IAudioInstance) => void> = new Signal<(instance: IAudioInstance) => void>();\n public onPaused: Signal<(instance: IAudioInstance) => void> = new Signal<(instance: IAudioInstance) => void>();\n public onResumed: Signal<(instance: IAudioInstance) => void> = new Signal<(instance: IAudioInstance) => void>();\n public onProgress: Signal<(instance: IAudioInstance) => void> = new Signal<(instance: IAudioInstance) => void>();\n\n constructor(\n public id: string,\n public channel: IAudioChannel,\n public manager: IAudioManagerPlugin,\n ) {\n bindAllMethods(this);\n this.muted = this.channel.muted;\n }\n\n private _media: IMediaInstance;\n\n get media(): IMediaInstance {\n return this._media;\n }\n\n set media(value: IMediaInstance) {\n this._media = value;\n if (value) {\n this._media.volume = this._effectiveVolume;\n if (this.muted) {\n this._media.muted = this.muted;\n }\n this.addListeners();\n }\n }\n\n private _volume: number = 1;\n\n public get volume(): number {\n return this._volume;\n }\n\n public set volume(value: number) {\n this._volume = value;\n if (this._media) {\n this._media.volume = this._effectiveVolume;\n }\n }\n\n private _muted: boolean = false;\n\n get muted(): boolean {\n return this._muted;\n }\n\n set muted(value: boolean) {\n this._muted = value;\n if (this._media) {\n this._media.muted = this._muted;\n this._media.volume = this._effectiveVolume;\n }\n }\n\n /**\n * The volume that should actually reach the media instance: the logical\n * (unmuted) volume folded through the channel and master volume, forced\n * to 0 whenever this instance or its channel is muted. Centralizing this\n * keeps `media.muted` from being the sole thing standing between a muted\n * channel and audible sound.\n */\n private get _effectiveVolume(): number {\n const muteFactor = this._muted || this.channel.muted ? 0 : 1;\n return this._volume * this.channel.volume * this.manager.masterVolume * muteFactor;\n }\n\n private _isPlaying: boolean = false;\n\n get isPlaying() {\n return this._isPlaying;\n }\n\n set isPlaying(value: boolean) {\n this._isPlaying = value;\n }\n\n pause(): void {\n this._isPlaying = false;\n if (this._media) {\n this._media.paused = true;\n }\n }\n\n resume(): void {\n this._isPlaying = true;\n if (this._media) {\n this._media.paused = false;\n }\n }\n\n remove(): void {\n this._isPlaying = false;\n this.channel.remove(this.id);\n }\n\n stop() {\n if (this._media) {\n this._media.stop();\n }\n this._isPlaying = false;\n this.onEnd.emit(this);\n }\n\n updateVolume(): void {\n this.volume = this._volume;\n }\n\n addListeners() {\n this.removeListeners();\n this._media.on('end', this._handleMediaEnded);\n this._media.on('start', this._handleMediaStarted);\n this._media.on('stop', this._handleMediaStopped);\n this._media.on('pause', this._handleMediaPaused);\n this._media.on('progress', this._handleMediaProgress);\n this._media.on('resumed', this._handleMediaResumed);\n }\n\n removeListeners() {\n if (!this.media) {\n return;\n }\n\n this._media.off('end', this._handleMediaEnded);\n this._media.off('start', this._handleMediaStarted);\n this._media.off('stop', this._handleMediaStopped);\n this._media.off('pause', this._handleMediaPaused);\n this._media.off('progress', this._handleMediaProgress);\n this._media.off('resumed', this._handleMediaResumed);\n }\n\n public destroy() {\n this.stop();\n this.removeListeners();\n }\n\n public fadeTo(volume: number, duration: number): gsap.core.Tween {\n return gsap.to(this.media, { volume, duration });\n }\n\n public play(time?: number): void {\n this._isPlaying = true;\n if (time) {\n this.media.play({ start: time });\n } else {\n this.media.play({});\n }\n }\n\n private _handleMediaEnded() {\n this._isPlaying = false;\n this.onEnd.emit(this);\n }\n\n private _handleMediaStarted() {\n this._isPlaying = true;\n this.onStart.emit(this);\n }\n\n private _handleMediaStopped() {\n this._isPlaying = false;\n this.onStop.emit(this);\n }\n\n private _handleMediaPaused() {\n this._isPlaying = false;\n this.onPaused.emit(this);\n }\n\n private _handleMediaProgress() {\n this.onProgress.emit(this);\n }\n\n private _handleMediaResumed() {\n this._isPlaying = true;\n this.onResumed.emit(this);\n }\n}\n","let instance;\nfunction setInstance(sound) {\n instance = sound;\n return sound;\n}\nfunction getInstance() {\n return instance;\n}\n\nexport { getInstance, instance, setInstance };\n//# sourceMappingURL=instance.mjs.map\n","class Filter {\n /**\n * @param {AudioNode} destination - The audio node to use as the destination for the input AudioNode\n * @param {AudioNode} [source] - Optional output node, defaults to destination node. This is useful\n * when creating filters which contains multiple AudioNode elements chained together.\n */\n constructor(destination, source) {\n this.init(destination, source);\n }\n /** Reinitialize */\n init(destination, source) {\n this.destination = destination;\n this.source = source || destination;\n }\n /**\n * Connect to the destination.\n * @param {AudioNode} destination - The destination node to connect the output to\n */\n connect(destination) {\n this.source?.connect(destination);\n }\n /** Completely disconnect filter from destination and source nodes. */\n disconnect() {\n this.source?.disconnect();\n }\n /** Destroy the filter and don't use after this. */\n destroy() {\n this.disconnect();\n this.destination = null;\n this.source = null;\n }\n}\n\nexport { Filter };\n//# sourceMappingURL=Filter.mjs.map\n","import { getInstance } from '../instance.mjs';\n\nclass WebAudioUtils {\n /**\n * Dezippering is removed in the future Web Audio API, instead\n * we use the `setValueAtTime` method, however, this is not available\n * in all environments (e.g., Android webview), so we fallback to the `value` setter.\n * @param param - AudioNode parameter object\n * @param value - Value to set\n * @return The value set\n */\n static setParamValue(param, value) {\n if (param.setValueAtTime) {\n const context = getInstance().context;\n param.setValueAtTime(value, context.audioContext.currentTime);\n } else {\n param.value = value;\n }\n return value;\n }\n}\n\nexport { WebAudioUtils };\n//# sourceMappingURL=WebAudioUtils.mjs.map\n","import { getInstance } from '../instance.mjs';\nimport { WebAudioUtils } from '../webaudio/WebAudioUtils.mjs';\nimport { Filter } from './Filter.mjs';\n\nconst _EqualizerFilter = class extends Filter {\n /**\n * @param f32 - Default gain for 32 Hz\n * @param f64 - Default gain for 64 Hz\n * @param f125 - Default gain for 125 Hz\n * @param f250 - Default gain for 250 Hz\n * @param f500 - Default gain for 500 Hz\n * @param f1k - Default gain for 1000 Hz\n * @param f2k - Default gain for 2000 Hz\n * @param f4k - Default gain for 4000 Hz\n * @param f8k - Default gain for 8000 Hz\n * @param f16k - Default gain for 16000 Hz\n */\n constructor(f32 = 0, f64 = 0, f125 = 0, f250 = 0, f500 = 0, f1k = 0, f2k = 0, f4k = 0, f8k = 0, f16k = 0) {\n let bands = [];\n const equalizerBands = [\n {\n f: _EqualizerFilter.F32,\n type: \"lowshelf\",\n gain: f32\n },\n {\n f: _EqualizerFilter.F64,\n type: \"peaking\",\n gain: f64\n },\n {\n f: _EqualizerFilter.F125,\n type: \"peaking\",\n gain: f125\n },\n {\n f: _EqualizerFilter.F250,\n type: \"peaking\",\n gain: f250\n },\n {\n f: _EqualizerFilter.F500,\n type: \"peaking\",\n gain: f500\n },\n {\n f: _EqualizerFilter.F1K,\n type: \"peaking\",\n gain: f1k\n },\n {\n f: _EqualizerFilter.F2K,\n type: \"peaking\",\n gain: f2k\n },\n {\n f: _EqualizerFilter.F4K,\n type: \"peaking\",\n gain: f4k\n },\n {\n f: _EqualizerFilter.F8K,\n type: \"peaking\",\n gain: f8k\n },\n {\n f: _EqualizerFilter.F16K,\n type: \"highshelf\",\n gain: f16k\n }\n ];\n if (!getInstance().useLegacy) {\n bands = equalizerBands.map((band) => {\n const node = getInstance().context.audioContext.createBiquadFilter();\n node.type = band.type;\n WebAudioUtils.setParamValue(node.Q, 1);\n node.frequency.value = band.f;\n WebAudioUtils.setParamValue(node.gain, band.gain);\n return node;\n });\n }\n super(bands[0], bands[bands.length - 1]);\n this.bands = bands;\n this.bandsMap = {};\n for (let i = 0; i < this.bands.length; i++) {\n const node = this.bands[i];\n if (i > 0) {\n this.bands[i - 1].connect(node);\n }\n this.bandsMap[node.frequency.value] = node;\n }\n }\n /**\n * Set gain on a specific frequency.\n * @param frequency - The frequency, see EqualizerFilter.F* for bands\n * @param gain - Recommended -40 to 40.\n */\n setGain(frequency, gain = 0) {\n if (!this.bandsMap[frequency]) {\n throw new Error(`No band found for frequency ${frequency}`);\n }\n WebAudioUtils.setParamValue(this.bandsMap[frequency].gain, gain);\n }\n /**\n * Get gain amount on a specific frequency.\n * @return The amount of gain set.\n */\n getGain(frequency) {\n if (!this.bandsMap[frequency]) {\n throw new Error(`No band found for frequency ${frequency}`);\n }\n return this.bandsMap[frequency].gain.value;\n }\n /**\n * Gain at 32 Hz frequencey.\n * @default 0\n */\n set f32(value) {\n this.setGain(_EqualizerFilter.F32, value);\n }\n get f32() {\n return this.getGain(_EqualizerFilter.F32);\n }\n /**\n * Gain at 64 Hz frequencey.\n * @default 0\n */\n set f64(value) {\n this.setGain(_EqualizerFilter.F64, value);\n }\n get f64() {\n return this.getGain(_EqualizerFilter.F64);\n }\n /**\n * Gain at 125 Hz frequencey.\n * @default 0\n */\n set f125(value) {\n this.setGain(_EqualizerFilter.F125, value);\n }\n get f125() {\n return this.getGain(_EqualizerFilter.F125);\n }\n /**\n * Gain at 250 Hz frequencey.\n * @default 0\n */\n set f250(value) {\n this.setGain(_EqualizerFilter.F250, value);\n }\n get f250() {\n return this.getGain(_EqualizerFilter.F250);\n }\n /**\n * Gain at 500 Hz frequencey.\n * @default 0\n */\n set f500(value) {\n this.setGain(_EqualizerFilter.F500, value);\n }\n get f500() {\n return this.getGain(_EqualizerFilter.F500);\n }\n /**\n * Gain at 1 KHz frequencey.\n * @default 0\n */\n set f1k(value) {\n this.setGain(_EqualizerFilter.F1K, value);\n }\n get f1k() {\n return this.getGain(_EqualizerFilter.F1K);\n }\n /**\n * Gain at 2 KHz frequencey.\n * @default 0\n */\n set f2k(value) {\n this.setGain(_EqualizerFilter.F2K, value);\n }\n get f2k() {\n return this.getGain(_EqualizerFilter.F2K);\n }\n /**\n * Gain at 4 KHz frequencey.\n * @default 0\n */\n set f4k(value) {\n this.setGain(_EqualizerFilter.F4K, value);\n }\n get f4k() {\n return this.getGain(_EqualizerFilter.F4K);\n }\n /**\n * Gain at 8 KHz frequencey.\n * @default 0\n */\n set f8k(value) {\n this.setGain(_EqualizerFilter.F8K, value);\n }\n get f8k() {\n return this.getGain(_EqualizerFilter.F8K);\n }\n /**\n * Gain at 16 KHz frequencey.\n * @default 0\n */\n set f16k(value) {\n this.setGain(_EqualizerFilter.F16K, value);\n }\n get f16k() {\n return this.getGain(_EqualizerFilter.F16K);\n }\n /** Reset all frequency bands to have gain of 0 */\n reset() {\n this.bands.forEach((band) => {\n WebAudioUtils.setParamValue(band.gain, 0);\n });\n }\n destroy() {\n this.bands.forEach((band) => {\n band.disconnect();\n });\n this.bands = null;\n this.bandsMap = null;\n }\n};\nlet EqualizerFilter = _EqualizerFilter;\n/**\n * Band at 32 Hz\n * @readonly\n */\nEqualizerFilter.F32 = 32;\n/**\n * Band at 64 Hz\n * @readonly\n */\nEqualizerFilter.F64 = 64;\n/**\n * Band at 125 Hz\n * @readonly\n */\nEqualizerFilter.F125 = 125;\n/**\n * Band at 250 Hz\n * @readonly\n */\nEqualizerFilter.F250 = 250;\n/**\n * Band at 500 Hz\n * @readonly\n */\nEqualizerFilter.F500 = 500;\n/**\n * Band at 1000 Hz\n * @readonly\n */\nEqualizerFilter.F1K = 1e3;\n/**\n * Band at 2000 Hz\n * @readonly\n */\nEqualizerFilter.F2K = 2e3;\n/**\n * Band at 4000 Hz\n * @readonly\n */\nEqualizerFilter.F4K = 4e3;\n/**\n * Band at 8000 Hz\n * @readonly\n */\nEqualizerFilter.F8K = 8e3;\n/**\n * Band at 16000 Hz\n * @readonly\n */\nEqualizerFilter.F16K = 16e3;\n\nexport { EqualizerFilter };\n//# sourceMappingURL=EqualizerFilter.mjs.map\n","import { EventEmitter } from 'pixi.js';\n\nclass HTMLAudioContext extends EventEmitter {\n constructor() {\n super(...arguments);\n /** Current global speed from 0 to 1 */\n this.speed = 1;\n /** Current muted status of the context */\n this.muted = false;\n /** Current volume from 0 to 1 */\n this.volume = 1;\n /** Current paused status */\n this.paused = false;\n }\n /** Internal trigger when volume, mute or speed changes */\n refresh() {\n this.emit(\"refresh\");\n }\n /** Internal trigger paused changes */\n refreshPaused() {\n this.emit(\"refreshPaused\");\n }\n /**\n * HTML Audio does not support filters, this is non-functional API.\n */\n get filters() {\n console.warn(\"HTML Audio does not support filters\");\n return null;\n }\n set filters(_filters) {\n console.warn(\"HTML Audio does not support filters\");\n }\n /**\n * HTML Audio does not support `audioContext`\n * @readonly\n * @type {AudioContext}\n */\n get audioContext() {\n console.warn(\"HTML Audio does not support audioContext\");\n return null;\n }\n /**\n * Toggles the muted state.\n * @return The current muted state.\n */\n toggleMute() {\n this.muted = !this.muted;\n this.refresh();\n return this.muted;\n }\n /**\n * Toggles the paused state.\n * @return The current paused state.\n */\n togglePause() {\n this.paused = !this.paused;\n this.refreshPaused();\n return this.paused;\n }\n /** Destroy and don't use after this */\n destroy() {\n this.removeAllListeners();\n }\n}\n\nexport { HTMLAudioContext };\n//# sourceMappingURL=HTMLAudioContext.mjs.map\n","import { EventEmitter, Ticker } from 'pixi.js';\n\nlet id = 0;\nconst _HTMLAudioInstance = class extends EventEmitter {\n /** @param parent - Parent element */\n constructor(parent) {\n super();\n this.id = id++;\n this.init(parent);\n }\n /**\n * Set a property by name, this makes it easy to chain values\n * @param name - Name of the property to set\n * @param value - Value to set property to\n */\n set(name, value) {\n if (this[name] === void 0) {\n throw new Error(`Property with name ${name} does not exist.`);\n } else {\n switch (name) {\n case \"speed\":\n this.speed = value;\n break;\n case \"volume\":\n this.volume = value;\n break;\n case \"paused\":\n this.paused = value;\n break;\n case \"loop\":\n this.loop = value;\n break;\n case \"muted\":\n this.muted = value;\n break;\n }\n }\n return this;\n }\n /** The current playback progress from 0 to 1. */\n get progress() {\n const { currentTime } = this._source;\n return currentTime / this._duration;\n }\n /** Pauses the sound. */\n get paused() {\n return this._paused;\n }\n set paused(paused) {\n this._paused = paused;\n this.refreshPaused();\n }\n /**\n * Reference: http://stackoverflow.com/a/40370077\n * @private\n */\n _onPlay() {\n this._playing = true;\n }\n /**\n * Reference: http://stackoverflow.com/a/40370077\n * @private\n */\n _onPause() {\n this._playing = false;\n }\n /**\n * Initialize the instance.\n * @param {htmlaudio.HTMLAudioMedia} media - Same as constructor\n */\n init(media) {\n this._playing = false;\n this._duration = media.source.duration;\n const source = this._source = media.source.cloneNode(false);\n source.src = media.parent.url;\n source.onplay = this._onPlay.bind(this);\n source.onpause = this._onPause.bind(this);\n media.context.on(\"refresh\", this.refresh, this);\n media.context.on(\"refreshPaused\", this.refreshPaused, this);\n this._media = media;\n }\n /**\n * Stop the sound playing\n * @private\n */\n _internalStop() {\n if (this._source && this._playing) {\n this._source.onended = null;\n this._source.pause();\n }\n }\n /** Stop the sound playing */\n stop() {\n this._internalStop();\n if (this._source) {\n this.emit(\"stop\");\n }\n }\n /** Set the instance speed from 0 to 1 */\n get speed() {\n return this._speed;\n }\n set speed(speed) {\n this._speed = speed;\n this.refresh();\n }\n /** Get the set the volume for this instance from 0 to 1 */\n get volume() {\n return this._volume;\n }\n set volume(volume) {\n this._volume = volume;\n this.refresh();\n }\n /** If the sound instance should loop playback */\n get loop() {\n return this._loop;\n }\n set loop(loop) {\n this._loop = loop;\n this.refresh();\n }\n /** `true` if the sound is muted */\n get muted() {\n return this._muted;\n }\n set muted(muted) {\n this._muted = muted;\n this.refresh();\n }\n /**\n * HTML Audio does not support filters, this is non-functional API.\n */\n get filters() {\n console.warn(\"HTML Audio does not support filters\");\n return null;\n }\n set filters(_filters) {\n console.warn(\"HTML Audio does not support filters\");\n }\n /** Call whenever the loop, speed or volume changes */\n refresh() {\n const global = this._media.context;\n const sound = this._media.parent;\n this._source.loop = this._loop || sound.loop;\n const globalVolume = global.volume * (global.muted ? 0 : 1);\n const soundVolume = sound.volume * (sound.muted ? 0 : 1);\n const instanceVolume = this._volume * (this._muted ? 0 : 1);\n this._source.volume = instanceVolume * globalVolume * soundVolume;\n this._source.playbackRate = this._speed * global.speed * sound.speed;\n }\n /** Handle changes in paused state, either globally or sound or instance */\n refreshPaused() {\n const global = this._media.context;\n const sound = this._media.parent;\n const pausedReal = this._paused || sound.paused || global.paused;\n if (pausedReal !== this._pausedReal) {\n this._pausedReal = pausedReal;\n if (pausedReal) {\n this._internalStop();\n this.emit(\"paused\");\n } else {\n this.emit(\"resumed\");\n this.play({\n start: this._source.currentTime,\n end: this._end,\n volume: this._volume,\n speed: this._speed,\n loop: this._loop\n });\n }\n this.emit(\"pause\", pausedReal);\n }\n }\n /** Start playing the sound/ */\n play(options) {\n const { start, end, speed, loop, volume, muted } = options;\n if (end) {\n console.assert(end > start, \"End time is before start time\");\n }\n this._speed = speed;\n this._volume = volume;\n this._loop = !!loop;\n this._muted = muted;\n this.refresh();\n if (this.loop && end !== null) {\n console.warn('Looping not support when specifying an \"end\" time');\n this.loop = false;\n }\n this._start = start;\n this._end = end || this._duration;\n this._start = Math.max(0, this._start - _HTMLAudioInstance.PADDING);\n this._end = Math.min(this._end + _HTMLAudioInstance.PADDING, this._duration);\n this._source.onloadedmetadata = () => {\n if (this._source) {\n this._source.currentTime = start;\n this._source.onloadedmetadata = null;\n this.emit(\"progress\", start / this._duration, this._duration);\n Ticker.shared.add(this._onUpdate, this);\n }\n };\n this._source.onended = this._onComplete.bind(this);\n this._source.play();\n this.emit(\"start\");\n }\n /**\n * Handle time update on sound.\n * @private\n */\n _onUpdate() {\n this.emit(\"progress\", this.progress, this._duration);\n if (this._source.currentTime >= this._end && !this._source.loop) {\n this._onComplete();\n }\n }\n /**\n * Callback when completed.\n * @private\n */\n _onComplete() {\n Ticker.shared.remove(this._onUpdate, this);\n this._internalStop();\n this.emit(\"progress\", 1, this._duration);\n this.emit(\"end\", this);\n }\n /** Don't use after this. */\n destroy() {\n Ticker.shared.remove(this._onUpdate, this);\n this.removeAllListeners();\n const source = this._source;\n if (source) {\n source.onended = null;\n source.onplay = null;\n source.onpause = null;\n this._internalStop();\n }\n this._source = null;\n this._speed = 1;\n this._volume = 1;\n this._loop = false;\n this._end = null;\n this._start = 0;\n this._duration = 0;\n this._playing = false;\n this._pausedReal = false;\n this._paused = false;\n this._muted = false;\n if (this._media) {\n this._media.context.off(\"refresh\", this.refresh, this);\n this._media.context.off(\"refreshPaused\", this.refreshPaused, this);\n this._media = null;\n }\n }\n /**\n * To string method for instance.\n * @return The string representation of instance.\n */\n toString() {\n return `[HTMLAudioInstance id=${this.id}]`;\n }\n};\nlet HTMLAudioInstance = _HTMLAudioInstance;\n/** Extra padding, in seconds, to deal with low-latecy of HTMLAudio. */\nHTMLAudioInstance.PADDING = 0.1;\n\nexport { HTMLAudioInstance };\n//# sourceMappingURL=HTMLAudioInstance.mjs.map\n","import { EventEmitter } from 'pixi.js';\nimport { HTMLAudioInstance } from './HTMLAudioInstance.mjs';\n\nclass HTMLAudioMedia extends EventEmitter {\n init(parent) {\n this.parent = parent;\n this._source = parent.options.source || new Audio();\n if (parent.url) {\n this._source.src = parent.url;\n }\n }\n // Implement create\n create() {\n return new HTMLAudioInstance(this);\n }\n /**\n * If the audio media is playable (ready).\n * @readonly\n */\n get isPlayable() {\n return !!this._source && this._source.readyState === 4;\n }\n /**\n * THe duration of the media in seconds.\n * @readonly\n */\n get duration() {\n return this._source.duration;\n }\n /**\n * Reference to the context.\n * @readonly\n */\n get context() {\n return this.parent.context;\n }\n /** The collection of filters, does not apply to HTML Audio. */\n get filters() {\n return null;\n }\n set filters(_filters) {\n console.warn(\"HTML Audio does not support filters\");\n }\n // Override the destroy\n destroy() {\n this.removeAllListeners();\n this.parent = null;\n if (this._source) {\n this._source.src = \"\";\n this._source.load();\n this._source = null;\n }\n }\n /**\n * Get the audio source element.\n * @type {HTMLAudioElement}\n * @readonly\n */\n get source() {\n return this._source;\n }\n // Implement the method to being preloading\n load(callback) {\n const source = this._source;\n const sound = this.parent;\n if (source.readyState === 4) {\n sound.isLoaded = true;\n const instance = sound.autoPlayStart();\n if (callback) {\n setTimeout(() => {\n callback(null, sound, instance);\n }, 0);\n }\n return;\n }\n if (!sound.url) {\n callback(new Error(\"sound.url or sound.source must be set\"));\n return;\n }\n source.src = sound.url;\n const onLoad = () => {\n removeListeners();\n sound.isLoaded = true;\n const instance = sound.autoPlayStart();\n if (callback) {\n callback(null, sound, instance);\n }\n };\n const onAbort = () => {\n removeListeners();\n if (callback) {\n callback(new Error(\"Sound loading has been aborted\"));\n }\n };\n const onError = () => {\n removeListeners();\n const message = `Failed to load audio element (code: ${source.error.code})`;\n if (callback) {\n callback(new Error(message));\n } else {\n console.error(message);\n }\n };\n const removeListeners = () => {\n source.removeEventListener(\"canplaythrough\", onLoad);\n source.removeEventListener(\"load\", onLoad);\n source.removeEventListener(\"abort\", onAbort);\n source.removeEventListener(\"error\", onError);\n };\n source.addEventListener(\"canplaythrough\", onLoad, false);\n source.addEventListener(\"load\", onLoad, false);\n source.addEventListener(\"abort\", onAbort, false);\n source.addEventListener(\"error\", onError, false);\n source.load();\n }\n}\n\nexport { HTMLAudioMedia };\n//# sourceMappingURL=HTMLAudioMedia.mjs.map\n","class SoundSprite {\n /**\n * @param parent - The parent sound\n * @param options - Data associated with object.\n */\n constructor(parent, options) {\n this.parent = parent;\n Object.assign(this, options);\n this.duration = this.end - this.start;\n console.assert(this.duration > 0, \"End time must be after start time\");\n }\n /**\n * Play the sound sprite.\n * @param {Function} [complete] - Function call when complete\n * @return Sound instance being played.\n */\n play(complete) {\n return this.parent.play({\n complete,\n speed: this.speed || this.parent.speed,\n end: this.end,\n start: this.start,\n loop: this.loop\n });\n }\n /** Destroy and don't use after this */\n destroy() {\n this.parent = null;\n }\n}\n\nexport { SoundSprite };\n//# sourceMappingURL=SoundSprite.mjs.map\n","const extensions = [\n \"ogg\",\n \"oga\",\n \"opus\",\n \"m4a\",\n \"mp3\",\n \"mpeg\",\n \"wav\",\n \"aiff\",\n \"wma\",\n \"mid\",\n \"caf\"\n];\nconst mimes = [\n \"audio/mpeg\",\n \"audio/ogg\"\n];\nconst supported = {};\nfunction validateFormats(typeOverrides) {\n const overrides = {\n m4a: \"audio/mp4\",\n oga: \"audio/ogg\",\n opus: 'audio/ogg; codecs=\"opus\"',\n caf: 'audio/x-caf; codecs=\"opus\"',\n ...typeOverrides || {}\n };\n const audio = document.createElement(\"audio\");\n const formats = {};\n const no = /^no$/;\n extensions.forEach((ext) => {\n const canByExt = audio.canPlayType(`audio/${ext}`).replace(no, \"\");\n const canByType = overrides[ext] ? audio.canPlayType(overrides[ext]).replace(no, \"\") : \"\";\n formats[ext] = !!canByExt || !!canByType;\n });\n Object.assign(supported, formats);\n}\nvalidateFormats();\n\nexport { extensions, mimes, supported, validateFormats };\n//# sourceMappingURL=supported.mjs.map\n","import { EventEmitter, Ticker } from 'pixi.js';\nimport { WebAudioUtils } from './WebAudioUtils.mjs';\n\nlet id = 0;\nclass WebAudioInstance extends EventEmitter {\n constructor(media) {\n super();\n this.id = id++;\n this._media = null;\n this._paused = false;\n this._muted = false;\n this._elapsed = 0;\n this.init(media);\n }\n /**\n * Set a property by name, this makes it easy to chain values\n * @param name - Name of the property to set.\n * @param value - Value to set property to.\n */\n set(name, value) {\n if (this[name] === void 0) {\n throw new Error(`Property with name ${name} does not exist.`);\n } else {\n switch (name) {\n case \"speed\":\n this.speed = value;\n break;\n case \"volume\":\n this.volume = value;\n break;\n case \"muted\":\n this.muted = value;\n break;\n case \"loop\":\n this.loop = value;\n break;\n case \"paused\":\n this.paused = value;\n break;\n }\n }\n return this;\n }\n /** Stops the instance, don't use after this. */\n stop() {\n if (this._source) {\n this._internalStop();\n this.emit(\"stop\");\n }\n }\n /** Set the instance speed from 0 to 1 */\n get speed() {\n return this._speed;\n }\n set speed(speed) {\n this._speed = speed;\n this.refresh();\n this._update(true);\n }\n /** Get the set the volume for this instance from 0 to 1 */\n get volume() {\n return this._volume;\n }\n set volume(volume) {\n this._volume = volume;\n this.refresh();\n }\n /** `true` if the sound is muted */\n get muted() {\n return this._muted;\n }\n set muted(muted) {\n this._muted = muted;\n this.refresh();\n }\n /** If the sound instance should loop playback */\n get loop() {\n return this._loop;\n }\n set loop(loop) {\n this._loop = loop;\n this.refresh();\n }\n /** The collection of filters. */\n get filters() {\n return this._filters;\n }\n set filters(filters) {\n if (this._filters) {\n this._filters?.filter((filter) => filter).forEach((filter) => filter.disconnect());\n this._filters = null;\n this._source.connect(this._gain);\n }\n this._filters = filters?.length ? filters.slice(0) : null;\n this.refresh();\n }\n /** Refresh loop, volume and speed based on changes to parent */\n refresh() {\n if (!this._source) {\n return;\n }\n const global = this._media.context;\n const sound = this._media.parent;\n this._source.loop = this._loop || sound.loop;\n const globalVolume = global.volume * (global.muted ? 0 : 1);\n const soundVolume = sound.volume * (sound.muted ? 0 : 1);\n const instanceVolume = this._volume * (this._muted ? 0 : 1);\n WebAudioUtils.setParamValue(this._gain.gain, instanceVolume * soundVolume * globalVolume);\n WebAudioUtils.setParamValue(this._source.playbackRate, this._speed * sound.speed * global.speed);\n this.applyFilters();\n }\n /** Connect filters nodes to audio context */\n applyFilters() {\n if (this._filters?.length) {\n this._source.disconnect();\n let source = this._source;\n this._filters.forEach((filter) => {\n source.connect(filter.destination);\n source = filter;\n });\n source.connect(this._gain);\n }\n }\n /** Handle changes in paused state, either globally or sound or instance */\n refreshPaused() {\n const global = this._media.context;\n const sound = this._media.parent;\n const pausedReal = this._paused || sound.paused || global.paused;\n if (pausedReal !== this._pausedReal) {\n this._pausedReal = pausedReal;\n if (pausedReal) {\n this._internalStop();\n this.emit(\"paused\");\n } else {\n this.emit(\"resumed\");\n this.play({\n start: this._elapsed % this._duration,\n end: this._end,\n speed: this._speed,\n loop: this._loop,\n volume: this._volume\n });\n }\n this.emit(\"pause\", pausedReal);\n }\n }\n /**\n * Plays the sound.\n * @param options - Play options.\n */\n play(options) {\n const { start, end, speed, loop, volume, muted, filters } = options;\n if (end) {\n console.assert(end > start, \"End time is before start time\");\n }\n this._paused = false;\n const { source, gain } = this._media.nodes.cloneBufferSource();\n this._source = source;\n this._gain = gain;\n this._speed = speed;\n this._volume = volume;\n this._loop = !!loop;\n this._muted = muted;\n this._filters = filters;\n this.refresh();\n const duration = this._source.buffer.duration;\n this._duration = duration;\n this._end = end;\n this._lastUpdate = this._now();\n this._elapsed = start;\n this._source.onended = this._onComplete.bind(this);\n if (this._loop) {\n this._source.loopEnd = end;\n this._source.loopStart = start;\n this._source.start(0, start);\n } else if (end) {\n this._source.start(0, start, end - start);\n } else {\n this._source.start(0, start);\n }\n this.emit(\"start\");\n this._update(true);\n this.enableTicker(true);\n }\n /** Start the update progress. */\n enableTicker(enabled) {\n Ticker.shared.remove(this._updateListener, this);\n if (enabled) {\n Ticker.shared.add(this._updateListener, this);\n }\n }\n /** The current playback progress from 0 to 1. */\n get progress() {\n return this._progress;\n }\n /** Pauses the sound. */\n get paused() {\n return this._paused;\n }\n set paused(paused) {\n this._paused = paused;\n this.refreshPaused();\n }\n /** Don't use after this. */\n destroy() {\n this.removeAllListeners();\n this._internalStop();\n if (this._gain) {\n this._gain.disconnect();\n this._gain = null;\n }\n if (this._media) {\n this._media.context.events.off(\"refresh\", this.refresh, this);\n this._media.context.events.off(\"refreshPaused\", this.refreshPaused, this);\n this._media = null;\n }\n this._filters?.forEach((filter) => filter.disconnect());\n this._filters = null;\n this._end = null;\n this._speed = 1;\n this._volume = 1;\n this._loop = false;\n this._elapsed = 0;\n this._duration = 0;\n this._paused = false;\n this._muted = false;\n this._pausedReal = false;\n }\n /**\n * To string method for instance.\n * @return The string representation of instance.\n */\n toString() {\n return `[WebAudioInstance id=${this.id}]`;\n }\n /**\n * Get the current time in seconds.\n * @return Seconds since start of context\n */\n _now() {\n return this._media.context.audioContext.currentTime;\n }\n /** Callback for update listener */\n _updateListener() {\n this._update();\n }\n /** Internal update the progress. */\n _update(force = false) {\n if (this._source) {\n const now = this._now();\n const delta = now - this._lastUpdate;\n if (delta > 0 || force) {\n const speed = this._source.playbackRate.value;\n this._elapsed += delta * speed;\n this._lastUpdate = now;\n const duration = this._duration;\n let progress;\n if (this._source.loopStart) {\n const soundLength = this._source.loopEnd - this._source.loopStart;\n progress = (this._source.loopStart + this._elapsed % soundLength) / duration;\n } else {\n progress = this._elapsed % duration / duration;\n }\n this._progress = progress;\n this.emit(\"progress\", this._progress, duration);\n }\n }\n }\n /** Initializes the instance. */\n init(media) {\n this._media = media;\n media.context.events.on(\"refresh\", this.refresh, this);\n media.context.events.on(\"refreshPaused\", this.refreshPaused, this);\n }\n /** Stops the instance. */\n _internalStop() {\n if (this._source) {\n this.enableTicker(false);\n this._source.onended = null;\n this._source.stop(0);\n this._source.disconnect();\n try {\n this._source.buffer = null;\n } catch (err) {\n console.warn(\"Failed to set AudioBufferSourceNode.buffer to null:\", err);\n }\n this._source = null;\n }\n }\n /** Callback when completed. */\n _onComplete() {\n if (this._source) {\n this.enableTicker(false);\n this._source.onended = null;\n this._source.disconnect();\n try {\n this._source.buffer = null;\n } catch (err) {\n console.warn(\"Failed to set AudioBufferSourceNode.buffer to null:\", err);\n }\n }\n this._source = null;\n this._progress = 1;\n this.emit(\"progress\", 1, this._duration);\n this.emit(\"end\", this);\n }\n}\n\nexport { WebAudioInstance };\n//# sourceMappingURL=WebAudioInstance.mjs.map\n","class Filterable {\n /**\n * @param input - The source audio node\n * @param output - The output audio node\n */\n constructor(input, output) {\n this._output = output;\n this._input = input;\n }\n /** The destination output audio node */\n get destination() {\n return this._input;\n }\n /** The collection of filters. */\n get filters() {\n return this._filters;\n }\n set filters(filters) {\n if (this._filters) {\n this._filters.forEach((filter) => {\n if (filter) {\n filter.disconnect();\n }\n });\n this._filters = null;\n this._input.connect(this._output);\n }\n if (filters && filters.length) {\n this._filters = filters.slice(0);\n this._input.disconnect();\n let prevFilter = null;\n filters.forEach((filter) => {\n if (prevFilter === null) {\n this._input.connect(filter.destination);\n } else {\n prevFilter.connect(filter.destination);\n }\n prevFilter = filter;\n });\n prevFilter.connect(this._output);\n }\n }\n /** Cleans up. */\n destroy() {\n this.filters = null;\n this._input = null;\n this._output = null;\n }\n}\n\nexport { Filterable };\n//# sourceMappingURL=Filterable.mjs.map\n","import { Filterable } from '../Filterable.mjs';\nimport { WebAudioUtils } from './WebAudioUtils.mjs';\n\nconst _WebAudioNodes = class extends Filterable {\n /**\n * @param context - The audio context.\n */\n constructor(context) {\n const audioContext = context.audioContext;\n const bufferSource = audioContext.createBufferSource();\n const gain = audioContext.createGain();\n const analyser = audioContext.createAnalyser();\n bufferSource.connect(analyser);\n analyser.connect(gain);\n gain.connect(context.destination);\n super(analyser, gain);\n this.context = context;\n this.bufferSource = bufferSource;\n this.gain = gain;\n this.analyser = analyser;\n }\n /**\n * Get the script processor node.\n * @readonly\n */\n get script() {\n if (!this._script) {\n this._script = this.context.audioContext.createScriptProcessor(_WebAudioNodes.BUFFER_SIZE);\n this._script.connect(this.context.destination);\n }\n return this._script;\n }\n /** Cleans up. */\n destroy() {\n super.destroy();\n this.bufferSource.disconnect();\n if (this._script) {\n this._script.disconnect();\n }\n this.gain.disconnect();\n this.analyser.disconnect();\n this.bufferSource = null;\n this._script = null;\n this.gain = null;\n this.analyser = null;\n this.context = null;\n }\n /**\n * Clones the bufferSource. Used just before playing a sound.\n * @returns {SourceClone} The clone AudioBufferSourceNode.\n */\n cloneBufferSource() {\n const orig = this.bufferSource;\n const source = this.context.audioContext.createBufferSource();\n source.buffer = orig.buffer;\n WebAudioUtils.setParamValue(source.playbackRate, orig.playbackRate.value);\n source.loop = orig.loop;\n const gain = this.context.audioContext.createGain();\n source.connect(gain);\n gain.connect(this.destination);\n return { source, gain };\n }\n /**\n * Get buffer size of `ScriptProcessorNode`.\n * @readonly\n */\n get bufferSize() {\n return this.script.bufferSize;\n }\n};\nlet WebAudioNodes = _WebAudioNodes;\n/**\n * The buffer size for script processor, default is `0` which auto-detects. If you plan to use\n * script node on iOS, you'll need to provide a non-zero amount.\n * @default 0\n */\nWebAudioNodes.BUFFER_SIZE = 0;\n\nexport { WebAudioNodes };\n//# sourceMappingURL=WebAudioNodes.mjs.map\n","import { DOMAdapter } from 'pixi.js';\nimport { WebAudioInstance } from './WebAudioInstance.mjs';\nimport { WebAudioNodes } from './WebAudioNodes.mjs';\n\nclass WebAudioMedia {\n /**\n * Re-initialize without constructing.\n * @param parent - - Instance of parent Sound container\n */\n init(parent) {\n this.parent = parent;\n this._nodes = new WebAudioNodes(this.context);\n this._source = this._nodes.bufferSource;\n this.source = parent.options.source;\n }\n /** Destructor, safer to use `SoundLibrary.remove(alias)` to remove this sound. */\n destroy() {\n this.parent = null;\n this._nodes.destroy();\n this._nodes = null;\n try {\n this._source.buffer = null;\n } catch (err) {\n console.warn(\"Failed to set AudioBufferSourceNode.buffer to null:\", err);\n }\n this._source = null;\n this.source = null;\n }\n // Implement create\n create() {\n return new WebAudioInstance(this);\n }\n // Implement context\n get context() {\n return this.parent.context;\n }\n // Implement isPlayable\n get isPlayable() {\n return !!this._source && !!this._source.buffer;\n }\n // Implement filters\n get filters() {\n return this._nodes.filters;\n }\n set filters(filters) {\n this._nodes.filters = filters;\n }\n // Implements duration\n get duration() {\n console.assert(this.isPlayable, \"Sound not yet playable, no duration\");\n return this._source.buffer.duration;\n }\n /** Gets and sets the buffer. */\n get buffer() {\n return this._source.buffer;\n }\n set buffer(buffer) {\n this._source.buffer = buffer;\n }\n /** Get the current chained nodes object */\n get nodes() {\n return this._nodes;\n }\n // Implements load\n load(callback) {\n if (this.source) {\n this._decode(this.source, callback);\n } else if (this.parent.url) {\n this._loadUrl(callback);\n } else if (callback) {\n callback(new Error(\"sound.url or sound.source must be set\"));\n } else {\n console.error(\"sound.url or sound.source must be set\");\n }\n }\n /** Loads a sound using XHMLHttpRequest object. */\n async _loadUrl(callback) {\n const url = this.parent.url;\n const response = await DOMAdapter.get().fetch(url);\n this._decode(await response.arrayBuffer(), callback);\n }\n /**\n * Decodes the array buffer.\n * @param arrayBuffer - From load.\n * @param {Function} callback - Callback optional\n */\n _decode(arrayBuffer, callback) {\n const audioBufferReadyFn = (err, buffer) => {\n if (err) {\n if (callback) {\n callback(err);\n }\n } else {\n this.parent.isLoaded = true;\n this.buffer = buffer;\n const instance = this.parent.autoPlayStart();\n if (callback) {\n callback(null, this.parent, instance);\n }\n }\n };\n if (arrayBuffer instanceof AudioBuffer) {\n audioBufferReadyFn(null, arrayBuffer);\n } else {\n const context = this.parent.context;\n context.decode(arrayBuffer, audioBufferReadyFn);\n }\n }\n}\n\nexport { WebAudioMedia };\n//# sourceMappingURL=WebAudioMedia.mjs.map\n","import { path } from 'pixi.js';\nimport { HTMLAudioMedia } from './htmlaudio/HTMLAudioMedia.mjs';\nimport { getInstance } from './instance.mjs';\nimport { SoundSprite } from './SoundSprite.mjs';\nimport { supported, extensions } from './utils/supported.mjs';\nimport { WebAudioMedia } from './webaudio/WebAudioMedia.mjs';\n\nconst _Sound = class {\n /**\n * Create a new sound instance from source.\n * @param source - Either the path or url to the source file.\n * or the object of options to use.\n * @return Created sound instance.\n */\n static from(source) {\n let options = {};\n if (typeof source === \"string\") {\n options.url = source;\n } else if (source instanceof ArrayBuffer || source instanceof AudioBuffer || source instanceof HTMLAudioElement) {\n options.source = source;\n } else if (Array.isArray(source)) {\n options.url = source;\n } else {\n options = source;\n }\n options = {\n autoPlay: false,\n singleInstance: false,\n url: null,\n source: null,\n preload: false,\n volume: 1,\n speed: 1,\n complete: null,\n loaded: null,\n loop: false,\n ...options\n };\n Object.freeze(options);\n const media = getInstance().useLegacy ? new HTMLAudioMedia() : new WebAudioMedia();\n return new _Sound(media, options);\n }\n /**\n * Use `Sound.from`\n * @ignore\n */\n constructor(media, options) {\n this.media = media;\n this.options = options;\n this._instances = [];\n this._sprites = {};\n this.media.init(this);\n const complete = options.complete;\n this._autoPlayOptions = complete ? { complete } : null;\n this.isLoaded = false;\n this._preloadQueue = null;\n this.isPlaying = false;\n this.autoPlay = options.autoPlay;\n this.singleInstance = options.singleInstance;\n this.preload = options.preload || this.autoPlay;\n this.url = Array.isArray(options.url) ? this.preferUrl(options.url) : options.url;\n this.speed = options.speed;\n this.volume = options.volume;\n this.loop = options.loop;\n if (options.sprites) {\n this.addSprites(options.sprites);\n }\n if (this.preload) {\n this._preload(options.loaded);\n }\n }\n /**\n * Internal help for resolving which file to use if there are multiple provide\n * this is especially helpful for working with bundlers (non Assets loading).\n */\n preferUrl(urls) {\n const [file] = urls.map((url) => ({ url, ext: path.extname(url).slice(1) })).filter(({ ext }) => supported[ext]).sort((a, b) => extensions.indexOf(a.ext) - extensions.indexOf(b.ext));\n if (!file) {\n throw new Error(\"No supported file type found\");\n }\n return file.url;\n }\n /** Instance of the media context. */\n get context() {\n return getInstance().context;\n }\n /** Stops all the instances of this sound from playing. */\n pause() {\n this.isPlaying = false;\n this.paused = true;\n return this;\n }\n /** Resuming all the instances of this sound from playing */\n resume() {\n this.isPlaying = this._instances.length > 0;\n this.paused = false;\n return this;\n }\n /** Stops all the instances of this sound from playing. */\n get paused() {\n return this._paused;\n }\n set paused(paused) {\n this._paused = paused;\n this.refreshPaused();\n }\n /** The playback rate. */\n get speed() {\n return this._speed;\n }\n set speed(speed) {\n this._speed = speed;\n this.refresh();\n }\n /** Set the filters. Only supported with WebAudio. */\n get filters() {\n return this.media.filters;\n }\n set filters(filters) {\n this.media.filters = filters;\n }\n /**\n * @ignore\n */\n addSprites(source, data) {\n if (typeof source === \"object\") {\n const results = {};\n for (const alias in source) {\n results[alias] = this.addSprites(alias, source[alias]);\n }\n return results;\n }\n console.assert(!this._sprites[source], `Alias ${source} is already taken`);\n const sprite = new SoundSprite(this, data);\n this._sprites[source] = sprite;\n return sprite;\n }\n /** Destructor, safer to use `SoundLibrary.remove(alias)` to remove this sound. */\n destroy() {\n this._removeInstances();\n this.removeSprites();\n this.media.destroy();\n this.media = null;\n this._sprites = null;\n this._instances = null;\n }\n /**\n * Remove a sound sprite.\n * @param alias - The unique name of the sound sprite, if alias is omitted, removes all sprites.\n */\n removeSprites(alias) {\n if (!alias) {\n for (const name in this._sprites) {\n this.removeSprites(name);\n }\n } else {\n const sprite = this._sprites[alias];\n if (sprite !== void 0) {\n sprite.destroy();\n delete this._sprites[alias];\n }\n }\n return this;\n }\n /** If the current sound is playable (loaded). */\n get isPlayable() {\n return this.isLoaded && this.media && this.media.isPlayable;\n }\n /** Stops all the instances of this sound from playing. */\n stop() {\n if (!this.isPlayable) {\n this.autoPlay = false;\n this._autoPlayOptions = null;\n return this;\n }\n this.isPlaying = false;\n for (let i = this._instances.length - 1; i >= 0; i--) {\n this._instances[i].stop();\n }\n return this;\n }\n // Overloaded function\n play(source, complete) {\n let options;\n if (typeof source === \"string\") {\n const sprite = source;\n options = { sprite, loop: this.loop, complete };\n } else if (typeof source === \"function\") {\n options = {};\n options.complete = source;\n } else {\n options = source;\n }\n options = {\n complete: null,\n loaded: null,\n sprite: null,\n end: null,\n start: 0,\n volume: 1,\n speed: 1,\n muted: false,\n loop: false,\n ...options || {}\n };\n if (options.sprite) {\n const alias = options.sprite;\n console.assert(!!this._sprites[alias], `Alias ${alias} is not available`);\n const sprite = this._sprites[alias];\n options.start = sprite.start + (options.start || 0);\n options.end = sprite.end;\n options.speed = sprite.speed || 1;\n options.loop = sprite.loop || options.loop;\n delete options.sprite;\n }\n if (options.offset) {\n options.start = options.offset;\n }\n if (!this.isLoaded) {\n if (this._preloadQueue) {\n return new Promise((resolve) => {\n this._preloadQueue.push(() => {\n resolve(this.play(options));\n });\n });\n }\n this._preloadQueue = [];\n this.autoPlay = true;\n this._autoPlayOptions = options;\n return new Promise((resolve, reject) => {\n this._preload((err, sound, media) => {\n this._preloadQueue.forEach((resolve2) => resolve2());\n this._preloadQueue = null;\n if (err) {\n reject(err);\n } else {\n if (options.loaded) {\n options.loaded(err, sound, media);\n }\n resolve(media);\n }\n });\n });\n }\n if (this.singleInstance || options.singleInstance) {\n this._removeInstances();\n }\n const instance = this._createInstance();\n this._instances.push(instance);\n this.isPlaying = true;\n instance.once(\"end\", () => {\n if (options.complete) {\n options.complete(this);\n }\n this._onComplete(instance);\n });\n instance.once(\"stop\", () => {\n this._onComplete(instance);\n });\n instance.play(options);\n return instance;\n }\n /** Internal only, speed, loop, volume change occured. */\n refresh() {\n const len = this._instances.length;\n for (let i = 0; i < len; i++) {\n this._instances[i].refresh();\n }\n }\n /** Handle changes in paused state. Internal only. */\n refreshPaused() {\n const len = this._instances.length;\n for (let i = 0; i < len; i++) {\n this._instances[i].refreshPaused();\n }\n }\n /** Gets and sets the volume. */\n get volume() {\n return this._volume;\n }\n set volume(volume) {\n this._volume = volume;\n this.refresh();\n }\n /** Gets and sets the muted flag. */\n get muted() {\n return this._muted;\n }\n set muted(muted) {\n this._muted = muted;\n this.refresh();\n }\n /** Gets and sets the looping. */\n get loop() {\n return this._loop;\n }\n set loop(loop) {\n this._loop = loop;\n this.refresh();\n }\n /** Starts the preloading of sound. */\n _preload(callback) {\n this.media.load(callback);\n }\n /** Gets the list of instances that are currently being played of this sound. */\n get instances() {\n return this._instances;\n }\n /** Get the map of sprites. */\n get sprites() {\n return this._sprites;\n }\n /** Get the duration of the audio in seconds. */\n get duration() {\n return this.media.duration;\n }\n /** Auto play the first instance. */\n autoPlayStart() {\n let instance;\n if (this.autoPlay) {\n instance = this.play(this._autoPlayOptions);\n }\n return instance;\n }\n /** Removes all instances. */\n _removeInstances() {\n for (let i = this._instances.length - 1; i >= 0; i--) {\n this._poolInstance(this._instances[i]);\n }\n this._instances.length = 0;\n }\n /**\n * Sound instance completed.\n * @param instance\n */\n _onComplete(instance) {\n if (this._instances) {\n const index = this._instances.indexOf(instance);\n if (index > -1) {\n this._instances.splice(index, 1);\n }\n this.isPlaying = this._instances.length > 0;\n }\n this._poolInstance(instance);\n }\n /** Create a new instance. */\n _createInstance() {\n if (_Sound._pool.length > 0) {\n const instance = _Sound._pool.pop();\n instance.init(this.media);\n return instance;\n }\n return this.media.create();\n }\n /**\n * Destroy/recycling the instance object.\n * @param instance - Instance to recycle\n */\n _poolInstance(instance) {\n instance.destroy();\n if (_Sound._pool.indexOf(instance) < 0) {\n _Sound._pool.push(instance);\n }\n }\n};\nlet Sound = _Sound;\n/** Pool of instances */\nSound._pool = [];\n\nexport { Sound };\n//# sourceMappingURL=Sound.mjs.map\n","import { EventEmitter } from 'pixi.js';\nimport { Filterable } from '../Filterable.mjs';\n\nclass WebAudioContext extends Filterable {\n constructor() {\n const win = window;\n const ctx = new WebAudioContext.AudioContext();\n const compressor = ctx.createDynamicsCompressor();\n const analyser = ctx.createAnalyser();\n analyser.connect(compressor);\n compressor.connect(ctx.destination);\n super(analyser, compressor);\n /** Set to false ignore suspending when window is blurred */\n this.autoPause = true;\n this._ctx = ctx;\n this._offlineCtx = new WebAudioContext.OfflineAudioContext(\n 1,\n 2,\n win.OfflineAudioContext ? Math.max(8e3, Math.min(96e3, ctx.sampleRate)) : 44100\n );\n this.compressor = compressor;\n this.analyser = analyser;\n this.events = new EventEmitter();\n this.volume = 1;\n this.speed = 1;\n this.muted = false;\n this.paused = false;\n this._locked = ctx.state === \"suspended\" && (\"ontouchstart\" in globalThis || \"onclick\" in globalThis);\n if (this._locked) {\n this._unlock();\n this._unlock = this._unlock.bind(this);\n document.addEventListener(\"mousedown\", this._unlock, true);\n document.addEventListener(\"touchstart\", this._unlock, true);\n document.addEventListener(\"touchend\", this._unlock, true);\n }\n this.onFocus = this.onFocus.bind(this);\n this.onBlur = this.onBlur.bind(this);\n globalThis.addEventListener(\"focus\", this.onFocus);\n globalThis.addEventListener(\"blur\", this.onBlur);\n }\n /** Handle mobile WebAudio context resume */\n onFocus() {\n if (!this.autoPause) {\n return;\n }\n const state = this._ctx.state;\n if (state === \"suspended\" || state === \"interrupted\" || !this._locked) {\n this.paused = this._pausedOnBlur;\n this.refreshPaused();\n }\n }\n /** Handle mobile WebAudio context suspend */\n onBlur() {\n if (!this.autoPause) {\n return;\n }\n if (!this._locked) {\n this._pausedOnBlur = this._paused;\n this.paused = true;\n this.refreshPaused();\n }\n }\n /**\n * Try to unlock audio on iOS. This is triggered from either WebAudio plugin setup (which will work if inside of\n * a `mousedown` or `touchend` event stack), or the first document touchend/mousedown event. If it fails (touchend\n * will fail if the user presses for too long, indicating a scroll event instead of a click event.\n *\n * Note that earlier versions of iOS supported `touchstart` for this, but iOS9 removed this functionality. Adding\n * a `touchstart` event to support older platforms may preclude a `mousedown` even from getting fired on iOS9, so we\n * stick with `mousedown` and `touchend`.\n */\n _unlock() {\n if (!this._locked) {\n return;\n }\n this.playEmptySound();\n if (this._ctx.state === \"running\") {\n document.removeEventListener(\"mousedown\", this._unlock, true);\n document.removeEventListener(\"touchend\", this._unlock, true);\n document.removeEventListener(\"touchstart\", this._unlock, true);\n this._locked = false;\n }\n }\n /**\n * Plays an empty sound in the web audio context. This is used to enable web audio on iOS devices, as they\n * require the first sound to be played inside of a user initiated event (touch/click).\n */\n playEmptySound() {\n const source = this._ctx.createBufferSource();\n source.buffer = this._ctx.createBuffer(1, 1, 22050);\n source.connect(this._ctx.destination);\n source.start(0, 0, 0);\n if (source.context.state === \"suspended\") {\n source.context.resume();\n }\n }\n /**\n * Get AudioContext class, if not supported returns `null`\n * @type {AudioContext}\n * @readonly\n */\n static get AudioContext() {\n const win = window;\n return win.AudioContext || win.webkitAudioContext || null;\n }\n /**\n * Get OfflineAudioContext class, if not supported returns `null`\n * @type {OfflineAudioContext}\n * @readonly\n */\n static get OfflineAudioContext() {\n const win = window;\n return win.OfflineAudioContext || win.webkitOfflineAudioContext || null;\n }\n /** Destroy this context. */\n destroy() {\n super.destroy();\n const ctx = this._ctx;\n if (typeof ctx.close !== \"undefined\") {\n ctx.close();\n }\n globalThis.removeEventListener(\"focus\", this.onFocus);\n globalThis.removeEventListener(\"blur\", this.onBlur);\n this.events.removeAllListeners();\n this.analyser.disconnect();\n this.compressor.disconnect();\n this.analyser = null;\n this.compressor = null;\n this.events = null;\n this._offlineCtx = null;\n this._ctx = null;\n }\n /**\n * The WebAudio API AudioContext object.\n * @readonly\n * @type {AudioContext}\n */\n get audioContext() {\n return this._ctx;\n }\n /**\n * The WebAudio API OfflineAudioContext object.\n * @readonly\n * @type {OfflineAudioContext}\n */\n get offlineContext() {\n return this._offlineCtx;\n }\n /**\n * Pauses all sounds, even though we handle this at the instance\n * level, we'll also pause the audioContext so that the\n * time used to compute progress isn't messed up.\n * @default false\n */\n set paused(paused) {\n if (paused && this._ctx.state === \"running\") {\n this._ctx.suspend();\n } else if (!paused && this._ctx.state === \"suspended\") {\n this._ctx.resume();\n }\n this._paused = paused;\n }\n get paused() {\n return this._paused;\n }\n /** Emit event when muted, volume or speed changes */\n refresh() {\n this.events.emit(\"refresh\");\n }\n /** Emit event when muted, volume or speed changes */\n refreshPaused() {\n this.events.emit(\"refreshPaused\");\n }\n /**\n * Toggles the muted state.\n * @return The current muted state.\n */\n toggleMute() {\n this.muted = !this.muted;\n this.refresh();\n return this.muted;\n }\n /**\n * Toggles the paused state.\n * @return The current muted state.\n */\n togglePause() {\n this.paused = !this.paused;\n this.refreshPaused();\n return this._paused;\n }\n /**\n * Decode the audio data\n * @param arrayBuffer - Buffer from loader\n * @param callback - When completed, error and audioBuffer are parameters.\n */\n decode(arrayBuffer, callback) {\n const handleError = (err) => {\n callback(new Error(err?.message || \"Unable to decode file\"));\n };\n const result = this._offlineCtx.decodeAudioData(\n arrayBuffer,\n (buffer) => {\n callback(null, buffer);\n },\n handleError\n );\n if (result) {\n result.catch(handleError);\n }\n }\n}\n\nexport { WebAudioContext };\n//# sourceMappingURL=WebAudioContext.mjs.map\n","import { HTMLAudioContext } from './htmlaudio/HTMLAudioContext.mjs';\nimport { Sound } from './Sound.mjs';\nimport { WebAudioContext } from './webaudio/WebAudioContext.mjs';\n\nclass SoundLibrary {\n constructor() {\n this.init();\n }\n /**\n * Re-initialize the sound library, this will\n * recreate the AudioContext. If there's a hardware-failure\n * call `close` and then `init`.\n * @return Sound instance\n */\n init() {\n if (this.supported) {\n this._webAudioContext = new WebAudioContext();\n }\n this._htmlAudioContext = new HTMLAudioContext();\n this._sounds = {};\n this.useLegacy = !this.supported;\n return this;\n }\n /**\n * The global context to use.\n * @readonly\n */\n get context() {\n return this._context;\n }\n /**\n * Apply filters to all sounds. Can be useful\n * for setting global planning or global effects.\n * **Only supported with WebAudio.**\n * @example\n * import { sound, filters } from '@pixi/sound';\n * // Adds a filter to pan all output left\n * sound.filtersAll = [\n * new filters.StereoFilter(-1)\n * ];\n */\n get filtersAll() {\n if (!this.useLegacy) {\n return this._context.filters;\n }\n return [];\n }\n set filtersAll(filtersAll) {\n if (!this.useLegacy) {\n this._context.filters = filtersAll;\n }\n }\n /**\n * `true` if WebAudio is supported on the current browser.\n */\n get supported() {\n return WebAudioContext.AudioContext !== null;\n }\n /**\n * @ignore\n */\n add(source, sourceOptions) {\n if (typeof source === \"object\") {\n const results = {};\n for (const alias in source) {\n const options2 = this._getOptions(\n source[alias],\n sourceOptions\n );\n results[alias] = this.add(alias, options2);\n }\n return results;\n }\n console.assert(!this._sounds[source], `Sound with alias ${source} already exists.`);\n if (sourceOptions instanceof Sound) {\n this._sounds[source] = sourceOptions;\n return sourceOptions;\n }\n const options = this._getOptions(sourceOptions);\n const sound = Sound.from(options);\n this._sounds[source] = sound;\n return sound;\n }\n /**\n * Internal methods for getting the options object\n * @private\n * @param source - The source options\n * @param overrides - Override default options\n * @return The construction options\n */\n _getOptions(source, overrides) {\n let options;\n if (typeof source === \"string\") {\n options = { url: source };\n } else if (Array.isArray(source)) {\n options = { url: source };\n } else if (source instanceof ArrayBuffer || source instanceof AudioBuffer || source instanceof HTMLAudioElement) {\n options = { source };\n } else {\n options = source;\n }\n options = { ...options, ...overrides || {} };\n return options;\n }\n /**\n * Do not use WebAudio, force the use of legacy. This **must** be called before loading any files.\n */\n get useLegacy() {\n return this._useLegacy;\n }\n set useLegacy(legacy) {\n this._useLegacy = legacy;\n this._context = !legacy && this.supported ? this._webAudioContext : this._htmlAudioContext;\n }\n /**\n * This disables auto-pause all playback when the window blurs (WebAudio only).\n * This is helpful to keep from playing sounds when the user switches tabs.\n * However, if you're running content within an iframe, this may be undesirable\n * and you should disable (set to `true`) this behavior.\n * @default false\n */\n get disableAutoPause() {\n return !this._webAudioContext.autoPause;\n }\n set disableAutoPause(autoPause) {\n this._webAudioContext.autoPause = !autoPause;\n }\n /**\n * Removes a sound by alias.\n * @param alias - The sound alias reference.\n * @return Instance for chaining.\n */\n remove(alias) {\n this.exists(alias, true);\n this._sounds[alias].destroy();\n delete this._sounds[alias];\n return this;\n }\n /**\n * Set the global volume for all sounds. To set per-sound volume see {@link SoundLibrary#volume}.\n */\n get volumeAll() {\n return this._context.volume;\n }\n set volumeAll(volume) {\n this._context.volume = volume;\n this._context.refresh();\n }\n /**\n * Set the global speed for all sounds. To set per-sound speed see {@link SoundLibrary#speed}.\n */\n get speedAll() {\n return this._context.speed;\n }\n set speedAll(speed) {\n this._context.speed = speed;\n this._context.refresh();\n }\n /**\n * Toggle paused property for all sounds.\n * @return `true` if all sounds are paused.\n */\n togglePauseAll() {\n return this._context.togglePause();\n }\n /**\n * Pauses any playing sounds.\n * @return Instance for chaining.\n */\n pauseAll() {\n this._context.paused = true;\n this._context.refreshPaused();\n return this;\n }\n /**\n * Resumes any sounds.\n * @return Instance for chaining.\n */\n resumeAll() {\n this._context.paused = false;\n this._context.refreshPaused();\n return this;\n }\n /**\n * Toggle muted property for all sounds.\n * @return `true` if all sounds are muted.\n */\n toggleMuteAll() {\n return this._context.toggleMute();\n }\n /**\n * Mutes all playing sounds.\n * @return Instance for chaining.\n */\n muteAll() {\n this._context.muted = true;\n this._context.refresh();\n return this;\n }\n /**\n * Unmutes all playing sounds.\n * @return Instance for chaining.\n */\n unmuteAll() {\n this._context.muted = false;\n this._context.refresh();\n return this;\n }\n /**\n * Stops and removes all sounds. They cannot be used after this.\n * @return Instance for chaining.\n */\n removeAll() {\n for (const alias in this._sounds) {\n this._sounds[alias].destroy();\n delete this._sounds[alias];\n }\n return this;\n }\n /**\n * Stops all sounds.\n * @return Instance for chaining.\n */\n stopAll() {\n for (const alias in this._sounds) {\n this._sounds[alias].stop();\n }\n return this;\n }\n /**\n * Checks if a sound by alias exists.\n * @param alias - Check for alias.\n * @param assert - Whether enable console.assert.\n * @return true if the sound exists.\n */\n exists(alias, assert = false) {\n const exists = !!this._sounds[alias];\n if (assert) {\n console.assert(exists, `No sound matching alias '${alias}'.`);\n }\n return exists;\n }\n /**\n * Convenience function to check to see if any sound is playing.\n * @returns `true` if any sound is currently playing.\n */\n isPlaying() {\n for (const alias in this._sounds) {\n if (this._sounds[alias].isPlaying) {\n return true;\n }\n }\n return false;\n }\n /**\n * Find a sound by alias.\n * @param alias - The sound alias reference.\n * @return Sound object.\n */\n find(alias) {\n this.exists(alias, true);\n return this._sounds[alias];\n }\n /**\n * Plays a sound.\n * @method play\n * @instance\n * @param {string} alias - The sound alias reference.\n * @param {string} sprite - The alias of the sprite to play.\n * @return {IMediaInstance|null} The sound instance, this cannot be reused\n * after it is done playing. Returns `null` if the sound has not yet loaded.\n */\n /**\n * Plays a sound.\n * @param alias - The sound alias reference.\n * @param {PlayOptions|Function} options - The options or callback when done.\n * @return The sound instance,\n * this cannot be reused after it is done playing. Returns a Promise if the sound\n * has not yet loaded.\n */\n play(alias, options) {\n return this.find(alias).play(options);\n }\n /**\n * Stops a sound.\n * @param alias - The sound alias reference.\n * @return Sound object.\n */\n stop(alias) {\n return this.find(alias).stop();\n }\n /**\n * Pauses a sound.\n * @param alias - The sound alias reference.\n * @return Sound object.\n */\n pause(alias) {\n return this.find(alias).pause();\n }\n /**\n * Resumes a sound.\n * @param alias - The sound alias reference.\n * @return Instance for chaining.\n */\n resume(alias) {\n return this.find(alias).resume();\n }\n /**\n * Get or set the volume for a sound.\n * @param alias - The sound alias reference.\n * @param volume - Optional current volume to set.\n * @return The current volume.\n */\n volume(alias, volume) {\n const sound = this.find(alias);\n if (volume !== void 0) {\n sound.volume = volume;\n }\n return sound.volume;\n }\n /**\n * Get or set the speed for a sound.\n * @param alias - The sound alias reference.\n * @param speed - Optional current speed to set.\n * @return The current speed.\n */\n speed(alias, speed) {\n const sound = this.find(alias);\n if (speed !== void 0) {\n sound.speed = speed;\n }\n return sound.speed;\n }\n /**\n * Get the length of a sound in seconds.\n * @param alias - The sound alias reference.\n * @return The current duration in seconds.\n */\n duration(alias) {\n return this.find(alias).duration;\n }\n /**\n * Closes the sound library. This will release/destroy\n * the AudioContext(s). Can be used safely if you want to\n * initialize the sound library later. Use `init` method.\n */\n close() {\n this.removeAll();\n this._sounds = null;\n if (this._webAudioContext) {\n this._webAudioContext.destroy();\n this._webAudioContext = null;\n }\n if (this._htmlAudioContext) {\n this._htmlAudioContext.destroy();\n this._htmlAudioContext = null;\n }\n this._context = null;\n return this;\n }\n}\n\nexport { SoundLibrary };\n//# sourceMappingURL=SoundLibrary.mjs.map\n","import { ExtensionType, LoaderParserPriority, path, extensions as extensions$1 } from 'pixi.js';\nimport { getInstance } from './instance.mjs';\nimport { Sound } from './Sound.mjs';\nimport { extensions, supported, mimes } from './utils/supported.mjs';\n\nconst getAlias = (asset) => {\n const src = asset.src;\n let alias = asset?.alias?.[0];\n if (!alias || asset.src === alias) {\n alias = path.basename(src, path.extname(src));\n }\n return alias;\n};\nconst soundAsset = {\n extension: ExtensionType.Asset,\n detection: {\n test: async () => true,\n add: async (formats) => [...formats, ...extensions.filter((ext) => supported[ext])],\n remove: async (formats) => formats.filter((ext) => formats.includes(ext))\n },\n loader: {\n name: \"sound\",\n extension: {\n type: [ExtensionType.LoadParser],\n priority: LoaderParserPriority.High\n },\n /** Should we attempt to load this file? */\n test(url) {\n const ext = path.extname(url).slice(1);\n return !!supported[ext] || mimes.some((mime) => url.startsWith(`data:${mime}`));\n },\n /** Load the sound file, this is mostly handled by Sound.from() */\n async load(url, asset) {\n const sound = await new Promise((resolve, reject) => Sound.from({\n ...asset.data,\n url,\n preload: true,\n loaded(err, sound2) {\n if (err) {\n reject(err);\n } else {\n resolve(sound2);\n }\n asset.data?.loaded?.(err, sound2);\n }\n }));\n getInstance().add(getAlias(asset), sound);\n return sound;\n },\n /** Remove the sound from the library */\n async unload(_sound, asset) {\n getInstance().remove(getAlias(asset));\n }\n }\n};\nextensions$1.add(soundAsset);\n\nexport { soundAsset };\n//# sourceMappingURL=soundAsset.mjs.map\n","import * as index from './filters/index.mjs';\nexport { index as filters };\nimport * as index$1 from './htmlaudio/index.mjs';\nexport { index$1 as htmlaudio };\nimport { setInstance } from './instance.mjs';\nimport { SoundLibrary } from './SoundLibrary.mjs';\nimport * as index$2 from './utils/index.mjs';\nexport { index$2 as utils };\nimport * as index$3 from './webaudio/index.mjs';\nexport { index$3 as webaudio };\nexport { Filterable } from './Filterable.mjs';\nexport { Filter } from './filters/Filter.mjs';\nexport { Sound } from './Sound.mjs';\nexport { soundAsset } from './soundAsset.mjs';\nexport { SoundSprite } from './SoundSprite.mjs';\n\nconst sound = setInstance(new SoundLibrary());\n\nexport { SoundLibrary, sound };\n//# sourceMappingURL=index.mjs.map\n","import { Options, PlayOptions, Sound, sound, SoundMap, SoundSourceMap } from '@pixi/sound';\nimport { gsap } from 'gsap';\nimport { Assets, AssetsManifest, UnresolvedAsset } from 'pixi.js';\nimport { Signal } from '../../signals';\nimport { AudioAsset, Logger } from '../../utils';\nimport type { IPlugin } from '../Plugin';\nimport { Plugin } from '../Plugin';\n\nimport { IApplication } from '../../core';\nimport { AudioChannel, IAudioChannel } from './AudioChannel';\nimport { AudioInstance, IAudioInstance } from './AudioInstance';\nimport TweenVars = gsap.TweenVars;\n\nexport type SoundDetail = { id: string; instance: IAudioInstance; channelName: string };\nexport type ChannelVolumeDetail = { channel: IAudioChannel; volume: number };\nexport type ChannelMutedDetail = { channel: IAudioChannel; muted: boolean };\nexport type ChannelName = 'music' | 'sfx' | 'voiceover' | (string & {});\n\n// patch sound.add to fix console.assert error\nsound.add = function (\n source: string | SoundSourceMap,\n sourceOptions?: Options | string | ArrayBuffer | AudioBuffer | HTMLAudioElement | Sound,\n): any {\n if (typeof source === 'object') {\n const results: SoundMap = {};\n\n for (const alias in source) {\n // @ts-expect-error _getOptions is private\n const options: Options = this._getOptions(source[alias], sourceOptions as Options);\n\n results[alias] = this.add(alias, options);\n }\n\n return results;\n }\n\n \n\n if (sourceOptions instanceof Sound) {\n // @ts-expect-error _sounds is private\n this._sounds[source] = sourceOptions;\n\n return sourceOptions;\n }\n // @ts-expect-error _getOptions is private\n const options: Options = this._getOptions(sourceOptions);\n const sound: Sound = Sound.from(options);\n // @ts-expect-error _sounds is private\n this._sounds[source] = sound;\n\n return sound;\n};\n\nexport interface IAudioManagerPlugin<C extends ChannelName = ChannelName> extends IPlugin {\n onSoundStarted: Signal<(detail: SoundDetail) => void>;\n onSoundEnded: Signal<(detail: SoundDetail) => void>;\n onMasterVolumeChanged: Signal<(volume: number) => void>;\n onChannelVolumeChanged: Signal<(detail: ChannelVolumeDetail) => void>;\n onMuted: Signal<(muted: boolean) => void>;\n onChannelMuted: Signal<(detail: ChannelMutedDetail) => void>;\n\n masterVolume: number;\n muted: boolean;\n channels: Map<string, IAudioChannel>;\n music: IAudioChannel;\n sfx: IAudioChannel;\n voiceover: IAudioChannel;\n vo: IAudioChannel;\n\n readonly paused: boolean;\n\n /**\n * The WebAudio context sounds are actually played on. Anything building\n * `PlayOptions.filters` MUST create its nodes on this context: WebAudio\n * refuses to connect nodes across contexts, and caper may not share a\n * `@pixi/sound` instance (and therefore a context) with the consuming app.\n * `undefined` under the htmlaudio fallback, where filters do not apply.\n */\n readonly audioContext: AudioContext | undefined;\n\n createChannel(name: string): void;\n\n play(soundId: AudioAsset, channelName: C, options?: PlayOptions): Promise<IAudioInstance>;\n\n isPlaying(soundId: AudioAsset, channelName: C): boolean;\n\n load(soundId: AudioAsset | AudioAsset[], channelName: C, options?: PlayOptions): void;\n\n stop(soundId: AudioAsset, channelName: C): IAudioInstance | undefined;\n\n setChannelVolume(channelName: C | C[], volume: number): void;\n\n getChannel(name: C): IAudioChannel | undefined;\n\n addAllFromManifest(manifest: AssetsManifest): void;\n\n addAllFromBundle(bundleName: string, manifest?: AssetsManifest | string | undefined): void;\n\n add(soundAsset: UnresolvedAsset): void;\n\n fade(soundId: AudioAsset, channelName: C, props?: gsap.TweenVars): Promise<gsap.core.Tween | null>;\n\n fadeIn(soundId: AudioAsset, channelName: C, props?: gsap.TweenVars): Promise<gsap.core.Tween | null>;\n\n fadeOut(soundId: AudioAsset, channelName: C, props?: gsap.TweenVars): Promise<gsap.core.Tween | null>;\n\n crossFade(\n outSoundId: AudioAsset,\n inSoundId: AudioAsset,\n channelName: C,\n duration?: number,\n ): Promise<gsap.core.Tween | null>;\n\n mute(): void;\n\n unmute(): void;\n\n pause(): void;\n\n resume(): void;\n\n suspend(): void;\n\n restore(): Promise<void>;\n\n getAudioInstance(soundId: AudioAsset, channelName: C): IAudioInstance | undefined;\n\n stopAll(fade?: boolean, duration?: number, props?: TweenVars): void;\n}\n\n/**\n * AudioManager is a class that manages audio playback in the application.\n * It provides methods to play, stop, fade in/out, and crossfade sounds.\n * It also allows you to create and manage audio channels.\n *\n * @example\n * const audioManager = new AudioManager();\n * audioManager.play('soundId', 'music');\n */\nexport class AudioManagerPlugin<C extends ChannelName = ChannelName> extends Plugin implements IAudioManagerPlugin<C> {\n // signals\n /**\n * Signal that is emitted when a sound starts playing.\n * The callback function receives a SoundDetail object.\n */\n public onSoundStarted: Signal<(detail: SoundDetail) => void> = new Signal<(detail: SoundDetail) => void>();\n /**\n * Signal that is emitted when a sound ends.\n * The callback function receives a SoundDetail object.\n */\n public onSoundEnded: Signal<(detail: SoundDetail) => void> = new Signal<(detail: SoundDetail) => void>();\n /**\n * Signal that is emitted when the system is muted or unmuted.\n */\n public onMuted: Signal<(muted: boolean) => void> = new Signal<(muted: boolean) => void>();\n /**\n * Signal that is emitted when the master volume changes.\n * The callback function receives the new volume as a number.\n */\n public onMasterVolumeChanged: Signal<(volume: number) => void> = new Signal<(volume: number) => void>();\n /**\n * Signal that is emitted when a channel's volume changes.\n * The callback function receives a ChannelVolumeDetail object.\n */\n public onChannelVolumeChanged: Signal<(detail: ChannelVolumeDetail) => void> = new Signal<\n (detail: ChannelVolumeDetail) => void\n >();\n /**\n * Signal that is emitted when a channel is muted or unmuted.\n * The callback function receives a ChannelMutedDetail object.\n */\n public onChannelMuted: Signal<(detail: ChannelMutedDetail) => void> = new Signal<\n (detail: ChannelMutedDetail) => void\n >();\n\n private _storedVolume: number | undefined = undefined;\n private _paused: boolean = false;\n private _idMap: Map<string, string> = new Map();\n\n /**\n * Creates a new AudioManager instance.\n * @param {string} id - The ID of the AudioManager. Default is 'AudioManager'.\n */\n public constructor(id: string = 'audio') {\n super(id);\n\n this.createChannel('music');\n this.createChannel('sfx');\n this.createChannel('voiceover');\n }\n\n private _masterVolume: number = 1;\n\n /**\n * The WebAudio context sounds actually play on — see\n * {@link IAudioManagerPlugin.audioContext}. Exposed so consumers can build\n * `PlayOptions.filters` on the right context instead of guessing.\n */\n get audioContext(): AudioContext | undefined {\n return sound.context?.audioContext;\n }\n\n /**\n * Gets the master volume.\n * @returns {number} The master volume.\n */\n get masterVolume(): number {\n return this._masterVolume;\n }\n\n /**\n * Sets the master volume.\n * @param {number} value - The new master volume.\n */\n set masterVolume(value: number) {\n this._masterVolume = value;\n this._channels.forEach((channel) => channel.updateVolume());\n }\n\n private _muted: boolean = false;\n\n /**\n * Gets whether the audio is muted.\n * @returns {boolean} True if the audio is muted, false otherwise.\n */\n get muted(): boolean {\n return this._muted;\n }\n\n /**\n * Sets whether the audio is muted.\n * @param {boolean} value - True to mute the audio, false to unmute.\n */\n set muted(value: boolean) {\n this._muted = value;\n this._setMuted();\n }\n\n private _channels: Map<C, IAudioChannel> = new Map();\n\n /**\n * Gets the map of audio channels.\n * @returns {Map<string, IAudioChannel>} The map of audio channels.\n */\n get channels(): Map<string, IAudioChannel> {\n return this._channels;\n }\n\n get music(): IAudioChannel {\n return this._channels.get('music' as C)!;\n }\n\n get sfx(): IAudioChannel {\n return this._channels.get('sfx' as C)!;\n }\n\n get voiceover(): IAudioChannel {\n return this._channels.get('voiceover' as C)!;\n }\n\n get vo(): IAudioChannel {\n return this._channels.get('voiceover' as C)!;\n }\n\n public destroy(): void {\n this._channels.forEach((channel) => {\n channel.destroy();\n });\n this._channels.clear();\n this.onSoundStarted.disconnectAll();\n this.onSoundEnded.disconnectAll();\n this.onMuted.disconnectAll();\n this.onMasterVolumeChanged.disconnectAll();\n this.onChannelVolumeChanged.disconnectAll();\n\n super.destroy();\n }\n\n /**\n * Initializes the AudioManager.\n * @param {IApplication} app\n * @returns {Promise<void>}\n */\n public initialize(_options: any, app: IApplication): Promise<void> {\n sound.disableAutoPause = true;\n if (typeof app?.manifest === 'object') {\n this.addAllFromManifest(app.manifest);\n }\n return Promise.resolve();\n }\n\n /**\n * Creates a new audio channel.\n * @param {string} name\n */\n public createChannel(name: string): void {\n if (this._channels.has(name as C)) {\n throw new Error(`Channel with name ${name} already exists.`);\n }\n const channel = new AudioChannel<C>(name as C, this);\n this._channels.set(name as C, channel);\n }\n\n /**\n * Sets the volume of the specified channel.\n * @param {ChannelName|ChannelName[]} channelName\n * @param {number} volume\n */\n public setChannelVolume(channelName: C | C[], volume: number): void {\n if (!Array.isArray(channelName)) {\n channelName = [channelName];\n }\n channelName.forEach((name) => this._setChannelVolume(name as C, volume));\n }\n\n /**\n * Gets the audio channel with the specified name.\n * @param {C} name\n * @returns {IAudioChannel | undefined}\n */\n public getChannel(name: C): IAudioChannel | undefined {\n return this._channels.get(name);\n }\n\n /**\n * Mutes the audio.\n */\n public mute() {\n this._muted = true;\n this._setMuted();\n }\n\n /**\n * Unmutes the audio.\n */\n public unmute() {\n this._muted = false;\n this._setMuted();\n }\n\n /**\n * Pauses the audio.\n */\n public pause(): void {\n this._paused = true;\n this._setPaused();\n }\n\n /**\n * Resumes the audio.\n */\n public resume(): void {\n this._paused = false;\n this._setPaused();\n }\n\n get paused(): boolean {\n return this._paused;\n }\n\n /**\n * Adds all sound assets from the specified manifest.\n * @param {AssetsManifest} manifest\n */\n public addAllFromManifest(manifest: AssetsManifest) {\n manifest.bundles.forEach((bundle) => {\n this.addAllFromBundle(bundle.name, manifest);\n });\n }\n\n private _addPrefix(asset: UnresolvedAsset): void {\n const prefix = Assets.resolver.basePath.replace('./', '');\n if (Array.isArray(asset.src)) {\n const mappedSrc = asset.src.map((s) => {\n return (s as string).startsWith(prefix) ? s : `${prefix}/${s}`;\n });\n asset.src = mappedSrc;\n } else {\n asset.src = asset.src?.startsWith(prefix) ? asset.src : `${prefix}/${asset.src}`;\n }\n }\n\n /**\n * Adds all sound assets from the specified bundle.\n * @param {string} bundleName\n * @param {AssetsManifest | string | undefined} manifest\n */\n public addAllFromBundle(bundleName: string, manifest?: AssetsManifest | string | undefined) {\n if (!manifest) {\n manifest = this.app.manifest;\n }\n if (manifest === undefined || typeof manifest === 'string') {\n throw new Error('Manifest is not available');\n }\n const bundle = manifest.bundles.find((b) => b.name === bundleName);\n if (bundle === undefined) {\n throw new Error(`Bundle with name ${bundleName} does not exist.`);\n }\n if (!Array.isArray(bundle?.assets)) {\n bundle.assets = [bundle.assets];\n }\n bundle.assets.forEach((asset) => {\n this._addPrefix(asset);\n // detect sound assets by asset.src extension\n let src = asset.src;\n if (Array.isArray(src)) {\n src = src[0];\n }\n const ext = (src as string).split('.').pop();\n if (ext === 'mp3' || ext === 'ogg' || ext === 'wav' || ext === 'webm') {\n this.add(asset);\n }\n });\n }\n\n /**\n * Adds a sound asset to the AudioManager.\n * @param {UnresolvedAsset} soundAsset\n */\n public add(soundAsset: UnresolvedAsset): void {\n let alias = soundAsset.alias;\n if (!Array.isArray(soundAsset.alias)) {\n alias = [soundAsset.alias as string];\n }\n if (!alias) return;\n\n const obj: SoundSourceMap = {};\n let hasNew = false;\n (alias as string[]).forEach((a: string) => {\n if (a === undefined || sound.exists(a)) {\n return;\n }\n // @ts-expect-error soundAsset is not a string error\n obj[a] = soundAsset.src;\n hasNew = true;\n });\n // Skip the sound.add() call if every alias is already registered.\n // Calling sound.add({}) trips a console.assert inside @pixi/sound,\n // which fires on every scene load that re-processes an already-added bundle.\n if (hasNew) sound.add(obj);\n }\n\n isPlaying(soundId: string, channelName: C): boolean {\n const channel = this._channels.get(channelName);\n if (channel) {\n return channel.get(soundId)?.isPlaying === true;\n }\n return false;\n }\n\n /**\n * Plays a sound with the specified ID in the specified channel.\n * @param {string} soundId\n * @param {C} channelName\n * @param {PlayOptions} options\n * @returns {Promise<IAudioInstance>}\n */\n /**\n * Drops any filter whose nodes belong to a different `AudioContext` than the\n * one playback runs on.\n *\n * WebAudio refuses cross-context `connect()`, and @pixi/sound wires filters\n * deep inside `WebAudioInstance.play()` — so one foreign filter throws\n * `InvalidAccessError` from a place the caller cannot catch, and the sound\n * never plays AT ALL. Silent-and-unattributable is the worst failure mode we\n * can hand an app, so prefer dry audio plus a pointed error: the sound is\n * still heard, and the log says exactly how to fix it. This is easy to hit\n * because an app bundling its own `@pixi/sound` gets a different context than\n * caper's — build filters on {@link audioContext}.\n */\n private _usableFilters(filters?: PlayOptions['filters']): PlayOptions['filters'] {\n if (!filters?.length) {\n return filters;\n }\n const context = this.audioContext;\n if (!context) {\n return filters;\n }\n const usable = filters.filter((filter) => {\n // A Filter exposes its input as `destination` and its output as `source`.\n const node = (filter as unknown as { destination?: AudioNode; source?: AudioNode })?.destination;\n return !node?.context || node.context === context;\n });\n if (usable.length !== filters.length) {\n Logger.error(\n 'AudioManager: ignoring filter(s) built on a different AudioContext — playing dry. ' +\n 'Build filter nodes on `app.audio.audioContext` (an app bundling its own copy of ' +\n '@pixi/sound gets a separate context).',\n );\n }\n return usable.length ? usable : undefined;\n }\n\n public async play(soundId: AudioAsset, channelName: C = 'sfx' as C, options?: PlayOptions): Promise<IAudioInstance> {\n if (this._idMap.has(soundId)) {\n soundId = this._idMap.get(soundId) as string;\n }\n const channel = this._channels.get(channelName);\n if (channel) {\n soundId = this._verifySoundId(soundId);\n const audioInstance = channel.add(\n soundId,\n new AudioInstance<C>(soundId, channel, this as IAudioManagerPlugin<C>),\n );\n // @pixi/sound starts playback at options.volume the instant sound.play()\n // is called, synchronously and before the await below resolves. The\n // channel × masterVolume correction previously only landed via\n // audioInstance.media/volume AFTER the await, a microtask too late —\n // producing an audible click/pop transient even when the correct\n // steady-state volume is 0 (master muted or channel muted). Compute the\n // real effective volume/mute state up front and hand it to sound.play\n // so the very first sample already plays at the right level.\n const startVolume = (options?.volume ?? 1) * channel.volume * this.masterVolume;\n const mediaInstance = await sound.play(soundId, {\n ...options,\n filters: this._usableFilters(options?.filters),\n volume: channel.muted ? 0 : startVolume,\n muted: channel.muted,\n });\n audioInstance.media = mediaInstance;\n if (options?.volume !== undefined) {\n // Route the per-play volume through AudioInstance's setter so the\n // channel × masterVolume math applies. Writing mediaInstance.volume\n // directly bypassed it — any explicit PlayOptions.volume ignored the\n // master volume entirely (master 0 never silenced SFX).\n audioInstance.volume = options.volume;\n }\n audioInstance.onStart.connect(() => {\n this._soundStarted(soundId, audioInstance, channelName);\n });\n audioInstance.onEnd.connect(() => {\n channel.removeInstance(audioInstance);\n this._soundEnded(soundId, audioInstance, channelName);\n });\n audioInstance.onStop.connect(() => {\n channel.removeInstance(audioInstance);\n });\n audioInstance.isPlaying = true;\n return audioInstance;\n } else {\n throw new Error(`Channel ${channelName} does not exist.`);\n }\n }\n\n /**\n * Stops a sound with the specified ID in the specified channel.\n * @param {AudioAsset} soundId\n * @param {C} channelName\n * @returns {IAudioInstance | undefined}\n */\n public stop(soundId: AudioAsset, channelName: C = 'sfx' as C): IAudioInstance | undefined {\n const channel = this._channels.get(channelName);\n if (channel) {\n return channel.remove(soundId);\n } else {\n throw new Error(`Channel ${channelName} does not exist.`);\n }\n }\n\n /**\n * Fades in a sound with the specified ID in the specified channel.\n * @param {AudioAsset} soundId\n * @param {C} channelName\n * @param {gsap.TweenVars} props\n * @returns {Promise<gsap.core.Tween | null>}\n */\n public async fadeIn(\n soundId: AudioAsset,\n channelName: C = 'music' as C,\n props: gsap.TweenVars,\n ): Promise<gsap.core.Tween | null> {\n const channel = this._channels.get(channelName);\n if (channel) {\n soundId = this._verifySoundId(soundId);\n }\n if (!channel?.get(soundId)) {\n await this.play(soundId, channelName, { volume: 0 });\n }\n if (props?.volume === 0) {\n Logger.warn('fadeIn volume is 0', soundId, channelName, props);\n }\n const fadeProps = Object.assign({ volume: props?.volume ?? 1, duration: 1, ease: 'linear.easeNone' }, props);\n return this.fade(soundId, channelName, fadeProps);\n }\n\n /**\n * Fades out a sound with the specified ID in the specified channel.\n * @param {AudioAsset} soundId\n * @param {C} channelName\n * @param {Partial<gsap.TweenVars>} props\n * @returns {Promise<gsap.core.Tween | null>}\n */\n public async fadeOut(\n soundId: AudioAsset,\n channelName: C = 'music' as C,\n props: Partial<gsap.TweenVars> = { volume: 0 },\n ): Promise<gsap.core.Tween | null> {\n if (!props) {\n props = {};\n }\n if (props?.volume === undefined) {\n props.volume = 0;\n }\n if (props?.volume > 0) {\n Logger.warn('fadeOut volume should probably be 0', soundId, channelName, props);\n }\n const fadeProps = Object.assign({ volume: 0, duration: 1, ease: 'linear.easeNone' }, props);\n return this.fade(soundId, channelName, fadeProps, true);\n }\n\n /**\n * Crossfades between two sounds in the specified channel.\n * @param {AudioAsset} outSoundId\n * @param {AudioAsset} inSoundId\n * @param {ChannelName} channelName\n * @param {number} duration\n * @returns {Promise<gsap.core.Tween | null>}\n */\n public async crossFade(\n outSoundId: AudioAsset,\n inSoundId: AudioAsset,\n channelName: ChannelName = 'music',\n duration: number = 2,\n ): Promise<gsap.core.Tween | null> {\n const crossFadeProps = { duration, ease: 'linear.easeNone' };\n void this.fadeOut(outSoundId, channelName as C, crossFadeProps);\n return this.fadeIn(inSoundId, channelName as C, crossFadeProps);\n }\n\n /**\n * Fades a sound with the specified ID in the specified channel.\n * @param {AudioAsset} soundId\n * @param {ChannelName} channelName\n * @param {gsap.TweenVars} props\n * @param {boolean} stopOnComplete\n * @returns {Promise<gsap.core.Tween | null>}\n */\n public async fade(\n soundId: AudioAsset,\n channelName: ChannelName = 'music',\n props: gsap.TweenVars,\n stopOnComplete: boolean = false,\n ): Promise<gsap.core.Tween | null> {\n const channel = this._channels.get(channelName as C);\n if (channel) {\n soundId = this._verifySoundId(soundId);\n }\n const soundInstance = channel?.get(soundId);\n if (soundInstance) {\n const tween = gsap.to(soundInstance, props);\n tween.eventCallback('onComplete', () => {\n if (stopOnComplete) {\n this.stop(soundId, channelName as C);\n }\n });\n return tween;\n }\n return null;\n }\n\n /**\n * Restores the audio state after it has been suspended.\n */\n public async restore() {\n const ctx = sound?.context?.audioContext;\n if (ctx) {\n await ctx.resume();\n }\n this.resume();\n if (this._storedVolume !== undefined) {\n this.masterVolume = this._storedVolume;\n }\n this._channels.forEach((channel) => {\n channel.restore();\n });\n this.muted = this._muted;\n }\n\n /**\n * Suspends the audio by setting the master volume to 0 and pausing all sounds.\n */\n public suspend() {\n this._storedVolume = this._masterVolume;\n this.masterVolume = 0;\n this.pause();\n }\n\n public getAudioInstance(soundId: AudioAsset, channelName: C = 'sfx' as C): IAudioInstance | undefined {\n const channel = this._channels.get(channelName);\n soundId = this._verifySoundId(soundId);\n if (channel) {\n return channel.get(soundId);\n } else {\n throw new Error(`Channel ${channelName} does not exist.`);\n }\n }\n\n public load(soundId: AudioAsset | AudioAsset[], channelName: C = 'sfx' as C, options?: PlayOptions): void {\n if (!Array.isArray(soundId)) {\n soundId = [soundId];\n }\n for (let id of soundId) {\n if (this._idMap.has(id)) {\n soundId = this._idMap.get(id) as string;\n }\n const channel = this._channels.get(channelName);\n if (channel) {\n id = this._verifySoundId(id);\n // const audioInstance = new AudioInstance(id, channel, this);\n const soundInstance = sound.find(id);\n soundInstance.options = { ...options, autoPlay: false };\n const audioInstance = channel.add(id, new AudioInstance<C>(id, channel, this as IAudioManagerPlugin<C>));\n audioInstance.media = soundInstance.instances[0];\n audioInstance.pause();\n } else {\n throw new Error(`Channel ${channelName} does not exist.`);\n }\n }\n }\n\n public stopAll(fade: boolean = false, duration: number = 1, props: TweenVars = {}) {\n if (fade) {\n // get all playing sounds\n const playingSounds: IAudioInstance[] = [];\n this._channels.forEach((channel) => {\n channel.instances.forEach((instance) => {\n if (instance.isPlaying) {\n instance.storedVolume = instance.volume;\n playingSounds.push(instance);\n }\n });\n });\n if (playingSounds.length > 0) {\n gsap.to(playingSounds, {\n volume: 0,\n duration,\n ...props,\n onComplete: () => {\n playingSounds.forEach((instance) => {\n instance.stop();\n instance.volume = instance.storedVolume;\n });\n },\n });\n }\n } else {\n sound.stopAll();\n }\n }\n\n protected getCoreSignals(): string[] {\n return [\n 'onSoundStarted',\n 'onSoundEnded',\n 'onMuted',\n 'onMasterVolumeChanged',\n 'onChannelVolumeChanged',\n 'onChannelMuted',\n ];\n }\n\n private _verifySoundId(soundId: AudioAsset): string {\n const originalSoundId = soundId;\n if (this._idMap.has(soundId)) {\n return this._idMap.get(soundId) as string;\n }\n // try appending .mp3 or .ogg\n if (!sound.exists(soundId)) {\n // Logger.log(`Sound with ID ${soundId} does not exist. Trying different extensions.`);\n if (sound.exists(soundId + '.mp3')) {\n soundId += '.mp3';\n } else if (sound.exists(soundId + '.ogg')) {\n soundId += '.ogg';\n } else if (sound.exists(soundId + '.wav')) {\n soundId += '.wav';\n } else {\n soundId = originalSoundId;\n let sound = Assets.get(soundId);\n if (!sound) {\n soundId = originalSoundId + '.mp3';\n sound = Assets.get(soundId);\n }\n if (!sound) {\n soundId = originalSoundId + '.ogg';\n sound = Assets.get(soundId);\n }\n if (!sound) {\n soundId = originalSoundId + '.wav';\n sound = Assets.get(soundId);\n }\n if (sound) {\n this._findAndAddFromManifest(soundId, sound);\n } else {\n throw new Error(`Sound with ID ${soundId} does not exist.`);\n }\n }\n }\n this._idMap.set(soundId, soundId);\n return soundId;\n }\n\n private _findAndAddFromManifest(soundId: AudioAsset, sound: Sound) {\n const manifest = this.app.manifest;\n if (manifest === undefined || typeof manifest === 'string') {\n throw new Error('Manifest is not available');\n }\n for (let i = 0; i < manifest.bundles.length; i++) {\n const bundle = manifest.bundles[i];\n if (!Array.isArray(bundle?.assets)) {\n bundle.assets = [bundle.assets];\n }\n for (let j = 0; j < bundle.assets.length; j++) {\n const asset = bundle.assets[j];\n this._addPrefix(asset);\n // detect sound assets by asset.src extension\n const src = asset.src;\n const filename = sound.url.split('/').pop() ?? '';\n if (Array.isArray(src)) {\n for (let s = 0; s < src.length; s++) {\n const urlOrResolvedSrc = src[s];\n let url: string;\n if (typeof urlOrResolvedSrc !== 'string') {\n url = urlOrResolvedSrc.src!;\n } else {\n url = urlOrResolvedSrc as string;\n }\n if (url.includes(filename)) {\n this.add(asset);\n return;\n }\n }\n } else {\n if (src?.includes(filename)) {\n this.add(asset);\n return;\n }\n }\n }\n }\n }\n\n /**\n * @private\n */\n private _setMuted(): void {\n if (this._muted) {\n sound.muteAll();\n } else {\n sound.unmuteAll();\n }\n this.onMuted.emit(this._muted);\n }\n\n /**\n * @private\n */\n private _setPaused(): void {\n if (this._paused) {\n sound.pauseAll();\n } else {\n sound.resumeAll();\n }\n }\n\n /**\n * Sets the volume of the specified channel.\n * @param {C} channelName\n * @param {number} volume\n * @private\n */\n private _setChannelVolume(channelName: C, volume: number): void {\n const channel = this._channels.get(channelName);\n if (channel) {\n channel.volume = volume;\n } else {\n throw new Error(`Channel ${channelName} does not exist.`);\n }\n }\n\n /**\n * Sound started event handler. Emit the onSoundStarted signal.\n * @param {string} id\n * @param {IAudioInstance} instance\n * @param {C} channelName\n * @private\n */\n private _soundStarted(id: string, instance: IAudioInstance, channelName: C): void {\n // Logger.log(`${id} started in ${channelName} channel`);\n this.onSoundStarted.emit({ id, instance, channelName });\n }\n\n /**\n * Sound ended event handler. Emit the onSoundEnded signal.\n * @param {string} id\n * @param {IAudioInstance} instance\n * @param {C} channelName\n * @private\n */\n private _soundEnded(id: string, instance: IAudioInstance, channelName: C): void {\n // Logger.log(`${id} ended in ${channelName} channel`);\n this.onSoundEnded.emit({ id, instance, channelName });\n }\n}\n","import { Bounds, Container, DestroyOptions, Graphics, Point, PointLike } from 'pixi.js';\nimport { Application } from '../../core/Application';\nimport { bindAllMethods, resolvePointLike } from '../../utils';\nimport type { IFocusable } from './FocusManagerPlugin';\n\nexport type FocusOutlinerConfig = {\n color: number;\n shape: 'rectangle' | 'rounded rectangle';\n lineWidth?: number;\n radius?: number;\n};\n\nexport interface IFocusOutliner {\n position: PointLike;\n focusBounds: Bounds;\n\n draw(focusTarget: IFocusable): void;\n\n clear(): void;\n\n destroy(args?: DestroyOptions): void;\n\n setFocusTarget(focusTarget: IFocusable): void;\n\n clearFocusTarget(): void;\n\n updatePosition(): void;\n}\n\nexport class FocusOutliner extends Container implements IFocusOutliner {\n focusBounds: Bounds;\n focusTarget: IFocusable | null;\n protected _config: FocusOutlinerConfig;\n protected _graphics: Graphics;\n\n constructor(config?: Partial<FocusOutlinerConfig>) {\n super();\n bindAllMethods(this);\n this._config = {\n color: 0x00ffff,\n shape: 'rounded rectangle',\n radius: 8,\n lineWidth: 2,\n ...config,\n };\n this._graphics = new Graphics();\n this.addChild(this._graphics);\n }\n\n public draw(focusTarget: IFocusable): void {\n this.clear();\n this.setFocusTarget(focusTarget);\n if (!this.focusTarget) {\n return;\n }\n\n this._graphics.strokeStyle = { width: this._config.lineWidth, color: this._config.color, alpha: 1 };\n if (this._config.shape === 'rectangle') {\n this._graphics.rect(0, 0, this.focusBounds.width, this.focusBounds.height);\n } else {\n this._graphics.roundRect(0, 0, this.focusBounds.width, this.focusBounds.height, this._config.radius);\n }\n this._graphics.stroke();\n }\n\n public clear(): void {\n if (this._graphics) {\n this._graphics.clear();\n }\n this.clearFocusTarget();\n }\n\n public destroy(options?: DestroyOptions) {\n this.clear();\n this._graphics.destroy();\n super.destroy(options);\n }\n\n public setFocusTarget(focusTarget: IFocusable) {\n if (focusTarget) {\n this.focusTarget = focusTarget;\n this.focusBounds = this.focusTarget.getFocusArea().clone();\n Application.getInstance().ticker.add(this.updatePosition);\n }\n }\n\n public clearFocusTarget() {\n this.focusTarget = null;\n Application.getInstance().ticker.remove(this.updatePosition);\n }\n\n public updatePosition() {\n if (!this.focusTarget || !this.parent) {\n return;\n }\n let pos;\n if (this.focusTarget.layout && this.focusTarget.parent) {\n const pt = new Point(this.focusTarget.layout.realX, this.focusTarget.layout.realY);\n pos = this.parent.toLocal(this.focusTarget.parent.toGlobal(pt));\n } else {\n pos = this.parent.toLocal(this.focusTarget.getGlobalPosition());\n }\n const focusPos = this.focusTarget.getFocusPosition();\n if (focusPos) {\n const fp = resolvePointLike(focusPos);\n pos.x += fp.x;\n pos.y += fp.y;\n }\n this.position.set(pos.x, pos.y);\n }\n}\n","import { Bounds, Container, Point, PointerEvents } from 'pixi.js';\nimport { IApplication } from '../../core';\nimport { Signal } from '../../signals';\nimport type { PointLike as CaperPointLike, Constructor } from '../../utils';\nimport { bindMethods, getLastMapEntry, getPreviousMapEntry, Logger } from '../../utils';\nimport type { IPlugin } from '../Plugin';\nimport { Plugin } from '../Plugin';\nimport type { IFocusOutliner } from './FocusOutliner';\nimport { FocusOutliner, FocusOutlinerConfig } from './FocusOutliner';\n\nexport type FocusManagerPluginOptions = {\n outliner: IFocusOutliner | Partial<FocusOutlinerConfig> | typeof FocusOutliner;\n usePixiAccessibility: boolean;\n};\n\nexport interface IFocusable extends Container {\n isFocused: boolean;\n isKeyDown: boolean;\n focusEnabled: boolean;\n tabIndex: number;\n _accessibleDiv?: HTMLElement;\n\n // pixi accessibility features\n accessible: boolean;\n accessibleType: keyof HTMLElementTagNameMap | undefined;\n accessibleTitle: string;\n accessibleHint: string;\n accessiblePointerEvents?: PointerEvents;\n accessibleChildren: boolean;\n\n // signals\n onFocusIn: Signal<(focusable: IFocusable) => void>;\n onFocusOut: Signal<(focusable: IFocusable) => void>;\n onFocus: Signal<(focusable: IFocusable) => void>;\n onBlur: Signal<(focusable: IFocusable) => void>;\n\n focusIn(): void;\n\n focusOut(): void;\n\n click(): void;\n\n blur(): void;\n\n getGlobalPosition(): Point;\n\n getFocusArea(): Bounds;\n\n getFocusPosition(): CaperPointLike | null;\n\n getFocusSize(): CaperPointLike | null;\n}\n\nexport interface IFocusLayer {\n currentFocusable: IFocusable | null;\n defaultFocusable: IFocusable | null;\n lastFocusable: IFocusable | null;\n current: boolean;\n availableFocusables: IFocusable[];\n\n setCurrentFocusable(focusable: IFocusable | null): IFocusable | null;\n\n hasFocusable(focusable: IFocusable | null): boolean;\n\n setCurrent(): void;\n\n addFocusable(focusable: IFocusable, isDefault?: boolean): void;\n\n removeFocusable(focusable: IFocusable): void;\n\n sortFocusables(): void;\n\n sortFocusablesByPosition(): void;\n\n next(): IFocusable | null;\n\n prev(): IFocusable | null;\n}\n\nclass FocusLayer implements IFocusLayer {\n public currentFocusable: IFocusable | null = null;\n public lastFocusable: IFocusable | null = null;\n public defaultFocusable: IFocusable | null = null;\n\n private _focusables: IFocusable[] = [];\n private _currentIndex: number = 0;\n\n constructor(public id: string | number) {}\n\n private _current: boolean = false;\n\n set current(value: boolean) {\n this._current = value;\n this.setCurrent();\n }\n\n public get availableFocusables(): IFocusable[] {\n return this._focusables.filter((f) => f.focusEnabled);\n }\n\n public setCurrent() {\n if (this._current) {\n if (!this.defaultFocusable) {\n this.defaultFocusable = this._focusables[0];\n }\n this.sortFocusables();\n } else {\n for (let i = 0; i < this._focusables.length; i++) {\n this._focusables[i].accessible = false;\n }\n }\n }\n\n public hasFocusable(focusable: IFocusable | null) {\n if (!focusable) {\n return false;\n }\n return this._focusables.indexOf(focusable) > -1;\n }\n\n public addFocusable(focusable: IFocusable, isDefault: boolean = false): void {\n this._focusables.push(focusable);\n if (isDefault) {\n this.defaultFocusable = focusable;\n }\n if (this._current) {\n this.sortFocusables();\n }\n }\n\n public removeFocusable(focusable: IFocusable) {\n const index = this._focusables.indexOf(focusable);\n if (index !== -1) {\n this._focusables.splice(index, 1);\n\n if (this.currentFocusable === focusable) {\n this.currentFocusable = null;\n }\n\n if (this.lastFocusable === focusable) {\n this.lastFocusable = null;\n }\n\n if (this.defaultFocusable === focusable) {\n this.defaultFocusable = null;\n }\n }\n if (this._current) {\n this.sortFocusables();\n }\n }\n\n public sortFocusables() {\n for (let i = 0; i < this._focusables.length; i++) {\n this._focusables[i].accessible = this._current;\n this._focusables[i].tabIndex = this._current ? Math.max(i, 1) + 1 : -1;\n if (this._focusables[i] === this.defaultFocusable) {\n this._focusables[i].tabIndex = this._current ? 1 : -1;\n }\n }\n if (this._current) {\n this._focusables.sort((a, b) => a.tabIndex - b.tabIndex);\n }\n }\n\n public sortFocusablesByPosition() {\n if (this._current) {\n this._focusables.sort((a: IFocusable, b: IFocusable) => {\n if (a.position.y !== b.position.y) {\n return a.position.y - b.position.y;\n }\n return a.position.x - b.position.x;\n });\n }\n }\n\n setCurrentFocusable(focusable: IFocusable | null): IFocusable | null {\n if (focusable) {\n this._currentIndex = this._focusables.indexOf(focusable);\n this.currentFocusable = focusable;\n if (this.availableFocusables.length === 0) {\n return null;\n }\n if (!this.currentFocusable.focusEnabled) {\n return this.next();\n }\n } else {\n this._currentIndex = -1;\n this.currentFocusable = null;\n }\n return this.currentFocusable;\n }\n\n public next(): IFocusable | null {\n this._currentIndex = this._currentIndex + 1;\n if (this._currentIndex >= this._focusables.length) {\n this._currentIndex = 0;\n }\n this.currentFocusable = this._focusables[this._currentIndex];\n if (this.availableFocusables.length === 0) {\n return null;\n }\n if (!this.currentFocusable.focusEnabled) {\n return this.next();\n }\n return this.currentFocusable;\n }\n\n public prev(): IFocusable | null {\n this._currentIndex = this._currentIndex - 1;\n if (this._currentIndex < 0) {\n this._currentIndex = this._focusables.length - 1;\n }\n this.currentFocusable = this._focusables[this._currentIndex];\n if (this.availableFocusables.length === 0) {\n return null;\n }\n if (!this.currentFocusable.focusEnabled) {\n return this.prev();\n }\n return this.currentFocusable;\n }\n}\n\nexport type FocusChangeDetail = { layer: string | number | null; focusable: IFocusable | null };\n\nexport interface IFocusManagerPlugin extends IPlugin {\n readonly view: Container;\n readonly layerCount: number;\n readonly currentLayer: IFocusLayer | undefined;\n readonly currentLayerId: string | number | null;\n readonly active: boolean;\n readonly layers: Map<string | number, IFocusLayer>;\n\n onFocusManagerActivated: Signal<() => void>;\n onFocusManagerDeactivated: Signal<() => void>;\n onFocusLayerChange: Signal<(currentLayerId: string | number) => void>;\n onFocusChange: Signal<(detail: FocusChangeDetail) => void>;\n enabled: boolean;\n\n restart(): void;\n\n focus(focusable: IFocusable): void;\n\n forceFocus(focusable: IFocusable): void;\n\n setFocus(focusable: IFocusable): void;\n\n addFocusLayer(layerId?: string | number, setAsCurrent?: boolean, focusables?: IFocusable | IFocusable[]): IFocusLayer;\n\n removeFocusLayer(layerId?: string | number): void;\n\n setFocusLayer(layerId: string | number): void;\n\n setLayerOrder(layerIds: (string | number)[]): void;\n\n add(focusable: IFocusable | IFocusable[], layerId?: string | number, isDefault?: boolean): void;\n\n addFocusable(focusable: IFocusable | IFocusable[], layerId?: string | number, isDefault?: boolean): void;\n\n remove(focusable: IFocusable | IFocusable[]): void;\n\n removeFocusable(focusable: IFocusable | IFocusable[]): void;\n\n deactivate(): void;\n\n clearFocus(): void;\n\n removeAllFocusLayers(): void;\n\n sortFocusablesByPosition(): void;\n}\n\nexport class FocusManagerPlugin extends Plugin<FocusManagerPluginOptions> implements IFocusManagerPlugin {\n public override readonly id: string = 'focus';\n public readonly view = new Container({ label: 'FocusManager' });\n // signals\n public onFocusManagerActivated: Signal<() => void> = new Signal<() => void>();\n public onFocusManagerDeactivated: Signal<() => void> = new Signal<() => void>();\n public onFocusLayerChange: Signal<(currentLayerId: string | number) => void> = new Signal<\n (currentLayerId: string | number) => void\n >();\n public onFocusChange: Signal<(detail: FocusChangeDetail) => void> = new Signal<(detail: FocusChangeDetail) => void>();\n //\n private _focusOutliner: IFocusOutliner;\n private _focusTarget: IFocusable | null = null;\n private _keyboardActive: boolean = false;\n private _layers: Map<string | number, IFocusLayer> = new Map();\n\n public get layers(): Map<string | number, IFocusLayer> {\n return this._layers;\n }\n\n private _currentLayerId: string | number | null = null;\n\n get currentLayerId(): string | number | null {\n return this._currentLayerId;\n }\n\n get currentLayer(): IFocusLayer | undefined {\n if (!this._currentLayerId) {\n return undefined;\n }\n return this._layers.get(this._currentLayerId);\n }\n\n private _active: boolean = false;\n\n get active(): boolean {\n return this._active;\n }\n\n private _enabled: boolean = true;\n\n get enabled() {\n return this._enabled;\n }\n\n set enabled(value: boolean) {\n this._enabled = value;\n }\n\n public get layerCount(): number {\n return this._layers.size;\n }\n\n public sortFocusablesByPosition() {\n this._getCurrentLayer()?.sortFocusablesByPosition();\n }\n\n public initialize(_options: Partial<FocusManagerPluginOptions>, app: IApplication): void {\n bindMethods(this, 'removeAllFocusLayers', '_handleGlobalMouseMove', '_handleGlobalPointerDown');\n const options: Partial<FocusManagerPluginOptions> = app.config?.focus || {};\n options.usePixiAccessibility = options.usePixiAccessibility ?? false;\n this._focusOutliner =\n typeof options?.outliner === 'function'\n ? new (options.outliner as Constructor<IFocusOutliner>)()\n : new FocusOutliner(options.outliner as Partial<FocusOutlinerConfig>);\n\n this._options = options as FocusManagerPluginOptions;\n\n this.view.addChild(this._focusOutliner as unknown as Container);\n\n this._updatePixiAccessibility();\n\n this._setupKeyboardListeners();\n this._setupAppListeners();\n }\n\n public destroy(): void {\n this._removeGlobalListeners();\n this.deactivate();\n this._focusOutliner.destroy();\n this._layers.clear();\n super.destroy();\n }\n\n public deactivate(): void {\n this._setTarget(null);\n this._updateOutliner();\n this._active = false;\n }\n\n public add(focusable: IFocusable | IFocusable[], layerId?: string | number, isDefault: boolean = false): void {\n this.addFocusable(focusable, layerId, isDefault);\n }\n\n public addFocusable(\n focusable: IFocusable | IFocusable[],\n layerId?: string | number | null | undefined,\n isDefault: boolean = false,\n ): void {\n if (layerId === undefined || layerId == null) {\n layerId = this._currentLayerId ?? null;\n }\n const layer = this._layers.get(layerId!);\n if (!layer) {\n Logger.error(`Layer with ID ${layerId} does not exist.`);\n return;\n }\n if (!Array.isArray(focusable)) {\n focusable = [focusable];\n }\n (focusable as IFocusable[]).forEach((f, idx) => {\n layer.addFocusable(f, idx === 0 && isDefault);\n });\n\n if (this._active && isDefault) {\n this._setTarget(layer.currentFocusable || layer.defaultFocusable || null, !this._active);\n }\n }\n\n public remove(focusable: IFocusable | IFocusable[]) {\n this.removeFocusable(focusable);\n }\n\n public removeFocusable(focusable: IFocusable | IFocusable[]) {\n if (!Array.isArray(focusable)) {\n focusable = [focusable];\n }\n this._layers.forEach((layer) => {\n (focusable as IFocusable[]).forEach((f) => {\n layer.removeFocusable(f);\n });\n });\n if (this._focusTarget && focusable.includes(this._focusTarget)) {\n this._setTarget(null);\n }\n }\n\n public setLayerOrder(layerIds: (string | number)[]): void {\n const newLayers: Map<string | number, IFocusLayer> = new Map();\n layerIds.forEach((layerId) => {\n if (!this._layers.has(layerId)) {\n throw new Error(`Layer with ID ${layerId} does not exist.`);\n }\n newLayers.set(layerId, this._layers.get(layerId)!);\n });\n this._layers = newLayers;\n }\n\n public addFocusLayer(\n layerId?: string | number,\n setAsCurrent: boolean = true,\n focusables?: IFocusable | IFocusable[],\n ): IFocusLayer {\n if (layerId === undefined) {\n layerId = this._layers.size;\n }\n let newLayer;\n if (this._layers.has(layerId)) {\n Logger.error(`Layer with ID ${layerId} already exists.`);\n newLayer = this._layers.get(layerId)!;\n } else {\n newLayer = new FocusLayer(layerId);\n this._layers.set(layerId, newLayer);\n }\n\n if (setAsCurrent || this._currentLayerId === null) {\n this.setFocusLayer(layerId);\n }\n if (focusables) {\n this.addFocusable(focusables, layerId);\n }\n return newLayer;\n }\n\n public removeFocusLayer(layerId?: string | number, removeTopLayerIfUndefined = true): void {\n if (layerId === undefined && removeTopLayerIfUndefined) {\n return this._removeTopLayer();\n }\n if (!this._layers.has(layerId!)) {\n Logger.warn(`Layer with ID ${layerId} does not exist.`);\n }\n const nextLayerId = getPreviousMapEntry(this._layers, layerId)?.[0];\n this._layers.delete(layerId!);\n this._postDelete(nextLayerId);\n }\n\n public restart(reverse: boolean = false) {\n const layer = this._getCurrentLayer();\n this._setTarget(\n reverse\n ? layer?.availableFocusables?.[layer?.availableFocusables?.length - 1] || null\n : layer?.availableFocusables?.[0] || null,\n );\n }\n\n public forceFocus(focusable: IFocusable) {\n this.focus(focusable);\n }\n\n public setFocus(focusable: IFocusable) {\n this.focus(focusable);\n }\n\n public focus(focusable: IFocusable) {\n this._setTarget(focusable);\n }\n\n public setFocusLayer(layerId: string | number): void {\n if (!this._layers.has(layerId)) {\n throw new Error(`Layer with ID ${layerId} does not exist.`);\n }\n this._currentLayerId = layerId;\n const currentLayer = this._getCurrentLayer();\n if (currentLayer) {\n currentLayer.current = true;\n this._layers.forEach((layer, key) => {\n layer.current = key === layerId;\n });\n currentLayer.sortFocusables();\n this._setTarget(currentLayer.currentFocusable || currentLayer.defaultFocusable || null, !this._active);\n }\n this.onFocusLayerChange.emit(this._currentLayerId);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public postInitialize(_app: IApplication): Promise<void> | void {}\n\n public clearFocus() {\n this._setTarget(null);\n }\n\n public removeAllFocusLayers(): void {\n this._layers.clear();\n this._setTarget(null);\n }\n\n _onKeyDown(e: KeyboardEvent) {\n if (!this._enabled || (e.key !== 'Tab' && e.key !== 'Enter' && e.key !== ' ' && e.key !== 'Space')) {\n return;\n }\n if (!this._options.usePixiAccessibility) {\n // e.preventDefault();\n if (e.key === 'Tab') {\n e.preventDefault();\n const layer = this._getCurrentLayer();\n const focusables = layer?.availableFocusables;\n if (!focusables) {\n return;\n }\n if (!this._keyboardActive) {\n this._activate();\n this._setTarget(this._focusTarget || layer.currentFocusable || layer.defaultFocusable || null);\n } else {\n // check if we're on the last focusable\n if (e.shiftKey) {\n this._prev();\n } else {\n this._next();\n }\n }\n } else if (e.key === 'Enter' || e.key === ' ' || e.key === 'Space') {\n if (this._focusTarget && this._focusTarget.isFocused) {\n // @ts-expect-error event assignment\n this._focusTarget.emit('pointerdown', { type: 'pointerdown' });\n }\n }\n }\n }\n\n _onKeyUp(e: any) {\n if (!this._enabled || (e.key !== 'Enter' && e.key !== ' ' && e.key !== 'Space')) {\n return;\n }\n if (!this._options.usePixiAccessibility) {\n // e.preventDefault();\n if (this._focusTarget && this._focusTarget.isFocused) {\n // @ts-expect-error event assignment\n this._focusTarget?.emit('click', { type: 'click', originalEvent: e });\n // @ts-expect-error event assignment\n this._focusTarget?.emit('pointerup', { type: 'pointerup', originalEvent: e });\n }\n }\n }\n\n _onMouseMove(e: MouseEvent) {\n if (e.movementX === 0 && e.movementY === 0) {\n return;\n }\n this._deactivate();\n }\n\n protected getCoreFunctions(): string[] {\n return [\n 'addFocusable',\n 'removeFocusable',\n 'setLayerOrder',\n 'addFocusLayer',\n 'removeFocusLayer',\n 'setFocusLayer',\n 'setFocus',\n 'focus',\n 'clearFocus',\n 'removeAllFocusLayers',\n ];\n }\n\n protected getCoreSignals(): string[] {\n return ['onFocusManagerActivated', 'onFocusManagerDeactivated', 'onFocusLayerChange', 'onFocusChange'];\n }\n\n private _next() {\n const nextTarget = this._getCurrentLayer()?.next();\n if (!nextTarget) {\n Logger.error('FocusManager:: _next():: No focusable found in the current layer.');\n return;\n }\n this._setTarget(nextTarget);\n }\n\n private _prev() {\n const nextTarget = this._getCurrentLayer()?.prev();\n if (!nextTarget) {\n Logger.error('FocusManager:: _prev():: No focusable found in the current layer.');\n return;\n }\n this._setTarget(nextTarget);\n }\n\n private _deactivate() {\n if (!this._keyboardActive) {\n return;\n }\n this._keyboardActive = false;\n }\n\n private _activate() {\n if (this._keyboardActive) {\n return;\n }\n this._keyboardActive = true;\n globalThis.document.addEventListener('mousemove', this._onMouseMove, true);\n }\n\n private _updatePixiAccessibility() {\n // @ts-expect-error _div is protected\n if (this.app.renderer.accessibility?._div) {\n // @ts-expect-error _div is protected\n this.app.renderer.accessibility._div.setAttribute('id', 'pixi-accessibility');\n }\n if (!this._options.usePixiAccessibility) {\n // @ts-expect-error _div is protected\n if (this.app.renderer.accessibility?._div) {\n // @ts-expect-error _div is protected\n this.app.renderer.accessibility._div.setAttribute('disabled', 'disabled');\n }\n this.app.renderer.accessibility?.destroy();\n globalThis.addEventListener('keydown', this._onKeyDown, false);\n globalThis.addEventListener('keyup', this._onKeyUp, false);\n }\n }\n\n private _getCurrentLayer(): IFocusLayer | null {\n return this._currentLayerId != null ? this._layers.get(this._currentLayerId) || null : null;\n }\n\n private _removeTopLayer() {\n const layerId = getLastMapEntry(this._layers)?.[0];\n const nextLayerId = getPreviousMapEntry(this._layers, layerId)?.[0];\n if (layerId === undefined) {\n return;\n }\n this._layers.delete(layerId);\n this._postDelete(nextLayerId);\n }\n\n private _postDelete(nextLayerId: string | number | undefined) {\n if (this._layers.size === 0) {\n this._currentLayerId = null;\n } else if (nextLayerId !== undefined) {\n this.setFocusLayer(nextLayerId);\n }\n }\n\n private _setTarget(focusTarget: IFocusable | null, setInactiveOnNull: boolean = true) {\n const layer = this._getCurrentLayer();\n const oldFocusTarget = this._focusTarget;\n this._focusTarget = focusTarget;\n // call the focus out methods on the current focusable, which is changing\n if (oldFocusTarget && this._active) {\n this._clearFocusTarget(oldFocusTarget);\n }\n if (this.app.renderer.accessibility.isActive || this._keyboardActive) {\n if (this._focusTarget) {\n if (!this._active) {\n this._active = true;\n }\n if (this._options.usePixiAccessibility && !this._focusTarget._accessibleDiv) {\n this.app.renderer.accessibility.postrender();\n }\n\n if (this._options.usePixiAccessibility) {\n this.app.ticker.addOnce(() => {\n this._focusTarget?._accessibleDiv?.focus();\n });\n }\n\n if (layer?.hasFocusable(focusTarget)) {\n // call focusIn on the focusable\n if (this._focusTarget) {\n this._focusTarget.focusIn();\n this._focusTarget.isFocused = true;\n this._focusTarget.onFocusIn.emit(this._focusTarget);\n layer.setCurrentFocusable(this._focusTarget);\n this._updateOutliner();\n }\n } else {\n Logger.warn(\n `The focusable`,\n focusTarget,\n `does not exist on the current focus layer: ${this._currentLayerId}`,\n );\n }\n } else {\n this._focusOutliner.clear();\n }\n } else {\n this._focusOutliner.clear();\n if (this._active && setInactiveOnNull) {\n this._active = false;\n this.onFocusManagerDeactivated.emit();\n return;\n }\n }\n\n if (oldFocusTarget !== focusTarget && this._active) {\n this.onFocusChange.emit({ focusable: this._focusTarget, layer: this._currentLayerId });\n }\n }\n\n private _clearFocusTarget(focusTarget: IFocusable | null) {\n if (!focusTarget) {\n return;\n }\n focusTarget.focusOut();\n focusTarget.isFocused = false;\n focusTarget.onFocusOut.emit(focusTarget);\n focusTarget.blur();\n focusTarget.onBlur.emit(focusTarget);\n }\n\n private _setupKeyboardListeners(): void {\n window.addEventListener('keydown', this._onKeyDown, false);\n this._addGlobalListeners();\n }\n\n private _addGlobalListeners() {\n globalThis.document.addEventListener('mousemove', this._handleGlobalMouseMove);\n globalThis.document.addEventListener('pointerdown', this._handleGlobalPointerDown);\n }\n\n private _removeGlobalListeners() {\n globalThis.document.removeEventListener('mousemove', this._handleGlobalMouseMove);\n globalThis.document.removeEventListener('pointerdown', this._handleGlobalPointerDown);\n }\n\n private _handleGlobalMouseMove() {\n if (!this._enabled) {\n return;\n }\n if (this._active) {\n this.deactivate();\n }\n }\n\n private _handleGlobalPointerDown() {\n if (!this._enabled) {\n return;\n }\n if (this._active) {\n this.deactivate();\n }\n if (this.app.renderer.accessibility.isActive || this._keyboardActive) {\n // @ts-expect-error _deactivate is protected\n this.app.renderer.accessibility._deactivate();\n this._deactivate();\n }\n }\n\n private _setupAppListeners(): void {\n this.app.scenes.onSceneChangeStart.connect(this.removeAllFocusLayers);\n }\n\n private _updateOutliner() {\n if (this._focusTarget) {\n this._focusOutliner.draw(this._focusTarget);\n } else {\n this._focusOutliner.clear();\n }\n }\n}\n","import { Application } from '../core/Application';\nimport { Signal } from '../signals';\nimport { bindAllMethods, Logger } from '../utils';\nimport type { IPlugin } from './Plugin';\nimport { Plugin } from './Plugin';\n\n/**\n * Interface for the FullScreen plugin providing cross-browser fullscreen functionality.\n * Handles fullscreen mode management with comprehensive browser compatibility.\n */\nexport interface IFullScreenPlugin extends IPlugin {\n /** Current fullscreen state */\n isFullScreen: boolean;\n /** The HTML element or Window object used for fullscreen operations */\n fullScreenElement: HTMLElement | Window | null;\n /** Signal emitted when fullscreen state changes */\n onFullScreenChange: Signal<(isFullscreen: boolean) => void>;\n /** Toggles between fullscreen and windowed mode */\n toggleFullScreen: () => void;\n /** Sets the fullscreen state explicitly */\n setFullScreen: (value: boolean) => void;\n /** Sets the element to be used for fullscreen operations */\n setFullScreenElement: (element: HTMLElement | Window | null) => void;\n /** Whether the current environment supports fullscreen functionality */\n readonly canFullscreen: boolean;\n}\n\n/**\n * Cross-browser fullscreen functionality plugin for web applications.\n *\n * Provides comprehensive fullscreen mode management with automatic browser\n * compatibility handling, event management, and flexible element targeting.\n * Supports all major browsers including Chrome, Firefox, Safari, and Edge.\n *\n * Key Features:\n * - Cross-browser fullscreen API compatibility\n * - Automatic event handling and state synchronization\n * - Flexible element targeting (container, window, or custom elements)\n * - Signal-based event system for reactive programming\n * - Graceful fallback handling for unsupported browsers\n * - Automatic cleanup and error handling\n *\n * @example\n * ```typescript\n * // Get the fullscreen plugin\n * const fullscreen = app.plugins.get<IFullScreenPlugin>('fullscreen');\n *\n * // Listen for fullscreen changes\n * fullscreen.onFullScreenChange.connect((isFullscreen) => {\n * console.log('Fullscreen state:', isFullscreen);\n * updateUIForFullscreen(isFullscreen);\n * });\n *\n * // Toggle fullscreen mode\n * document.getElementById('fullscreenBtn').addEventListener('click', () => {\n * if (fullscreen.canFullscreen) {\n * fullscreen.toggleFullScreen();\n * } else {\n * console.warn('Fullscreen not supported');\n * }\n * });\n *\n * // Set custom element for fullscreen\n * const gameContainer = document.getElementById('gameContainer');\n * fullscreen.setFullScreenElement(gameContainer);\n * fullscreen.setFullScreen(true);\n * ```\n */\nexport class FullScreenPlugin extends Plugin implements IFullScreenPlugin {\n /** Plugin identifier for framework registration */\n public readonly id = 'fullscreen';\n\n /**\n * Signal emitted when fullscreen state changes.\n * Provides the new fullscreen state as a boolean parameter.\n */\n public onFullScreenChange: Signal<(isFullscreen: boolean) => void> = new Signal<(isFullscreen: boolean) => void>();\n\n /** Internal fullscreen state tracking */\n private _isFullScreen: boolean = false;\n /** Internal reference to the fullscreen target element */\n private _fullScreenElement: HTMLElement | Window | null = null;\n\n /**\n * Sets the fullscreen state and triggers the appropriate fullscreen operation.\n * @param value - True to enter fullscreen, false to exit\n */\n set isFullScreen(value: boolean) {\n this._isFullScreen = value;\n this.setFullScreen(value);\n }\n\n /**\n * Gets the current fullscreen state.\n * @returns True if currently in fullscreen mode\n */\n get isFullScreen(): boolean {\n return this._isFullScreen;\n }\n\n /**\n * Sets the element to be used for fullscreen operations.\n * @param value - The HTML element or Window object to use for fullscreen\n */\n set fullScreenElement(value: HTMLElement | Window | null) {\n this.setFullScreenElement(value);\n }\n\n /**\n * Gets the current fullscreen target element.\n * @returns The element currently set for fullscreen operations\n */\n get fullScreenElement(): HTMLElement | Window | null {\n return this._fullScreenElement;\n }\n\n /**\n * Creates the fullscreen plugin instance.\n * Binds all methods to maintain proper context when used as event handlers.\n */\n constructor() {\n super();\n bindAllMethods(this);\n }\n\n /**\n * Gets the application instance.\n * @returns The singleton Application instance\n */\n get app(): Application {\n return Application.getInstance();\n }\n\n /**\n * Initializes the fullscreen plugin by setting up browser event listeners.\n * Registers listeners for all major browser fullscreen change events.\n *\n * @example\n * ```typescript\n * // Called automatically by the plugin system\n * // Registers listeners for: fullscreenchange, webkitfullscreenchange,\n * // mozfullscreenchange, msfullscreenchange\n * ```\n */\n public initialize(): void {\n document.addEventListener('fullscreenchange', this._onFullScreenChange);\n document.addEventListener('webkitfullscreenchange', this._onFullScreenChange);\n document.addEventListener('mozfullscreenchange', this._onFullScreenChange);\n document.addEventListener('msfullscreenchange', this._onFullScreenChange);\n document.addEventListener('fullscreenchange', this._onFullScreenChange);\n }\n\n /**\n * Cleans up the plugin by removing all event listeners.\n * Called automatically when the plugin is destroyed.\n */\n public destroy() {\n document.removeEventListener('fullscreenchange', this._onFullScreenChange);\n document.removeEventListener('webkitfullscreenchange', this._onFullScreenChange);\n document.removeEventListener('mozfullscreenchange', this._onFullScreenChange);\n document.removeEventListener('msfullscreenchange', this._onFullScreenChange);\n document.removeEventListener('fullscreenchange', this._onFullScreenChange);\n }\n\n /**\n * Toggles between fullscreen and windowed mode.\n *\n * @example\n * ```typescript\n * // Toggle fullscreen on button click\n * button.addEventListener('click', () => {\n * fullscreenPlugin.toggleFullScreen();\n * });\n *\n * // Keyboard shortcut for fullscreen\n * document.addEventListener('keydown', (e) => {\n * if (e.key === 'F11') {\n * e.preventDefault();\n * fullscreenPlugin.toggleFullScreen();\n * }\n * });\n * ```\n */\n public toggleFullScreen() {\n this.setFullScreen(!this._isFullScreen);\n }\n\n /**\n * Sets the fullscreen state explicitly.\n *\n * @param value - True to enter fullscreen, false to exit fullscreen\n *\n * @example\n * ```typescript\n * // Enter fullscreen mode\n * fullscreenPlugin.setFullScreen(true);\n *\n * // Exit fullscreen mode\n * fullscreenPlugin.setFullScreen(false);\n *\n * // Conditional fullscreen based on game state\n * if (gameState === 'playing') {\n * fullscreenPlugin.setFullScreen(true);\n * }\n * ```\n */\n public setFullScreen(value: boolean) {\n this._isFullScreen = value;\n if (value) {\n this._requestFullscreen();\n } else {\n this._exitFullscreen();\n }\n }\n\n /**\n * Sets the element to be used for fullscreen operations.\n * If no element is provided, uses the default application container.\n *\n * @param value - The HTML element or Window to use for fullscreen operations\n *\n * @example\n * ```typescript\n * // Use a specific game container\n * const gameDiv = document.getElementById('game-container');\n * fullscreenPlugin.setFullScreenElement(gameDiv);\n *\n * // Use the entire window\n * fullscreenPlugin.setFullScreenElement(window);\n *\n * // Reset to default (application container)\n * fullscreenPlugin.setFullScreenElement(null);\n * ```\n */\n public setFullScreenElement(value: HTMLElement | Window | null) {\n if (!value) {\n Logger.warn('No element passed to setFullScreenElement for fullscreen mode');\n }\n this._fullScreenElement = value;\n }\n\n /**\n * Checks if the current environment and element support fullscreen functionality.\n *\n * @returns True if fullscreen is supported and available\n *\n * @example\n * ```typescript\n * if (fullscreenPlugin.canFullscreen) {\n * // Show fullscreen button\n * fullscreenButton.style.display = 'block';\n * } else {\n * // Hide fullscreen button or show alternative\n * fullscreenButton.style.display = 'none';\n * console.log('Fullscreen not supported on this device');\n * }\n * ```\n */\n public get canFullscreen(): boolean {\n const element = this._fullScreenElement || Application.containerElement;\n if (!element) return false;\n\n const fullscreenElement = element as HTMLElement;\n return !!(\n fullscreenElement.requestFullscreen ||\n (fullscreenElement as any).webkitRequestFullscreen ||\n (fullscreenElement as any).msRequestFullscreen ||\n (fullscreenElement as any).mozRequestFullScreen\n );\n }\n\n /**\n * Checks if the document is currently in fullscreen mode.\n * Uses browser-specific properties for cross-browser compatibility.\n *\n * @returns True if any element is currently in fullscreen mode\n */\n public get isFullscreen(): boolean {\n return !!(\n document.fullscreenElement ||\n (document as any).webkitFullscreenElement ||\n (document as any).msFullscreenElement ||\n (document as any).mozFullScreenElement\n );\n }\n\n /**\n * Gets the core signals exposed by this plugin.\n * @returns Array of signal names available on the plugin\n * @protected\n */\n protected getCoreSignals(): string[] {\n return ['onFullScreenChange'];\n }\n\n /**\n * Gets the core functions exposed by this plugin.\n * @returns Array of function names available on the plugin\n * @protected\n */\n protected getCoreFunctions(): string[] {\n return ['toggleFullScreen', 'setFullScreen', 'setFullScreenElement'];\n }\n\n /**\n * Requests fullscreen mode using the appropriate browser API.\n * Handles cross-browser compatibility and error cases.\n * @private\n */\n private _requestFullscreen() {\n const element = this._fullScreenElement || Application.containerElement;\n if (!element) {\n throw new Error('No element available for fullscreen mode');\n }\n\n const fullscreenElement = element as HTMLElement;\n try {\n if (fullscreenElement.requestFullscreen) {\n fullscreenElement.requestFullscreen();\n } else if ((fullscreenElement as any).webkitRequestFullscreen) {\n (fullscreenElement as any).webkitRequestFullscreen();\n } else if ((fullscreenElement as any).msRequestFullscreen) {\n (fullscreenElement as any).msRequestFullscreen();\n } else if ((fullscreenElement as any).mozRequestFullScreen) {\n (fullscreenElement as any).mozRequestFullScreen();\n }\n } catch (error) {\n Logger.error('Failed to request fullscreen:', error);\n // Reset the fullscreen state since it failed\n this._isFullScreen = false;\n }\n }\n\n /**\n * Exits fullscreen mode using the appropriate browser API.\n * Handles cross-browser compatibility for fullscreen exit.\n * @private\n */\n private _exitFullscreen() {\n if (document.exitFullscreen) {\n document.exitFullscreen();\n } else if ((document as any).webkitExitFullscreen) {\n (document as any).webkitExitFullscreen();\n } else if ((document as any).msExitFullscreen) {\n (document as any).msExitFullscreen();\n } else if ((document as any).mozCancelFullScreen) {\n (document as any).mozCancelFullScreen();\n }\n }\n\n /**\n * Handles browser fullscreen change events.\n * Updates internal state and emits the onFullScreenChange signal.\n * @private\n */\n private _onFullScreenChange(): void {\n this.onFullScreenChange.emit(document.fullscreenElement !== null);\n }\n}\n","/**\n * Pure multi-touch gesture math — centroid, spread and frame-to-frame deltas.\n * No Pixi/caper imports so it stays trivially unit-testable.\n */\n\nexport interface PointerSample {\n id: number;\n x: number;\n y: number;\n}\n\nexport interface GestureFrame {\n centerX: number;\n centerY: number;\n /** Mean distance from the centroid across all tracked pointers. */\n spread: number;\n}\n\n/** Below this, `frameDelta` treats the previous spread as unusable and returns `scale: 1`. */\nconst SPREAD_EPSILON = 0.01;\n\n/**\n * Centroid and mean radial spread of a set of pointers. For two pointers,\n * `spread` is half the pair distance; since only the *ratio* between two\n * frames is ever used, this generalises to 3+ fingers for free.\n */\nexport function computeFrame(pointers: PointerSample[]): GestureFrame {\n const count = pointers.length;\n if (count === 0) return { centerX: 0, centerY: 0, spread: 0 };\n\n let sumX = 0;\n let sumY = 0;\n for (const p of pointers) {\n sumX += p.x;\n sumY += p.y;\n }\n const centerX = sumX / count;\n const centerY = sumY / count;\n\n let sumDist = 0;\n for (const p of pointers) {\n sumDist += Math.hypot(p.x - centerX, p.y - centerY);\n }\n const spread = sumDist / count;\n\n return { centerX, centerY, spread };\n}\n\n/**\n * Centroid translation and spread ratio between two frames. `scale` is\n * guarded to `1` when `prev.spread` is too small to divide by, so a\n * near-zero starting spread can't produce a huge or infinite jump.\n */\nexport function frameDelta(prev: GestureFrame, next: GestureFrame): { dx: number; dy: number; scale: number } {\n const dx = next.centerX - prev.centerX;\n const dy = next.centerY - prev.centerY;\n const scale = prev.spread < SPREAD_EPSILON ? 1 : next.spread / prev.spread;\n return { dx, dy, scale };\n}\n","/** The shape of the `gesture:` key in `caper.config.ts`, and the plugin's resolved options. */\nexport interface GesturePluginOptions {\n /** @default true */\n enabled?: boolean;\n /** @default ['touch'] */\n pointerTypes?: string[];\n /** Pixels of spread change to cross before a pending gesture goes active. @default 8 */\n pinchThreshold?: number;\n /** Pixels of centroid movement to cross before a pending gesture goes active. @default 8 */\n panThreshold?: number;\n /** Also sets `canvas.style.touchAction = 'none'` while enabled. @default true */\n preventDefault?: boolean;\n}\n\nexport const defaultGestureOptions: Required<GesturePluginOptions> = {\n enabled: true,\n pointerTypes: ['touch'],\n pinchThreshold: 8,\n panThreshold: 8,\n preventDefault: true,\n};\n\nexport interface GestureStartDetail {\n /** Client CSS pixels. */\n centerX: number;\n /** Client CSS pixels. */\n centerY: number;\n pointerCount: number;\n}\n\nexport interface GestureChangeDetail {\n /** Client CSS pixels. */\n centerX: number;\n /** Client CSS pixels. */\n centerY: number;\n /** Client-pixel delta since the previous frame. */\n dx: number;\n /** Client-pixel delta since the previous frame. */\n dy: number;\n /** Spread ratio since the previous frame. */\n scale: number;\n /** Spread ratio since the gesture started. */\n totalScale: number;\n pointerCount: number;\n}\n\nexport interface GestureEndDetail {\n /** Client CSS pixels. */\n centerX: number;\n /** Client CSS pixels. */\n centerY: number;\n /** Spread ratio since the gesture started. */\n totalScale: number;\n}\n","import type { IApplication } from '../../core';\nimport { Signal } from '../../signals';\nimport type { IPlugin } from '../Plugin';\nimport { Plugin } from '../Plugin';\nimport type { GestureFrame, PointerSample } from './gestureMath';\nimport { computeFrame, frameDelta } from './gestureMath';\nimport type { GestureChangeDetail, GestureEndDetail, GesturePluginOptions, GestureStartDetail } from './types';\nimport { defaultGestureOptions } from './types';\n\ntype GestureState = 'idle' | 'pending' | 'active';\n\n/** Below this, `totalScale` is reported as `1` rather than dividing by a near-zero spread. */\nconst SPREAD_EPSILON = 0.01;\n\nexport interface IGesturePlugin extends IPlugin<GesturePluginOptions> {\n readonly onGestureStart: Signal<(detail: GestureStartDetail) => void>;\n readonly onGestureChange: Signal<(detail: GestureChangeDetail) => void>;\n readonly onGestureEnd: Signal<(detail: GestureEndDetail) => void>;\n readonly isActive: boolean;\n readonly pointerCount: number;\n}\n\n/**\n * Multi-touch gesture recognizer: pinch zoom and two-finger pan combined\n * into one gesture, the way map apps work. There is no mode and no toggle —\n * a pinch that also drifts pans, a two-finger drag that also spreads zooms.\n *\n * One finger is never a camera gesture; games are expected to use it for\n * aim/build/UI as normal. Rotation is deliberately not recognised.\n *\n * Listens on raw DOM pointer events — `pointerdown` on `app.canvas`,\n * `pointermove`/`pointerup`/`pointercancel` on `window` — rather than PixiJS\n * federated events, so it sees every pointer regardless of scene-graph hit\n * testing, and lift-outside is always seen.\n *\n * @example\n * ```ts\n * app.signal.onGestureChange.connect(({ dx, dy, scale, centerX, centerY }) => {\n * camera.pinchZoomAt(scale, centerX, centerY);\n * camera.panBy(dx, dy);\n * });\n * ```\n */\nexport class GesturePlugin extends Plugin<GesturePluginOptions> implements IGesturePlugin {\n public readonly id = 'gesture';\n\n public readonly onGestureStart = new Signal<(detail: GestureStartDetail) => void>();\n public readonly onGestureChange = new Signal<(detail: GestureChangeDetail) => void>();\n public readonly onGestureEnd = new Signal<(detail: GestureEndDetail) => void>();\n\n private _pointers = new Map<number, PointerSample>();\n private _state: GestureState = 'idle';\n private _startFrame: GestureFrame | null = null;\n private _lastFrame: GestureFrame | null = null;\n private _canvas: HTMLCanvasElement | null = null;\n private _previousTouchAction = '';\n\n get isActive(): boolean {\n return this._state === 'active';\n }\n\n get pointerCount(): number {\n return this._pointers.size;\n }\n\n async initialize(options: Partial<GesturePluginOptions> = {}, app: IApplication): Promise<void> {\n this._options = { ...defaultGestureOptions, ...options };\n if (!this._options.enabled) return;\n\n const canvas = app.canvas as HTMLCanvasElement;\n this._canvas = canvas;\n if (this._options.preventDefault) {\n this._previousTouchAction = canvas.style.touchAction;\n canvas.style.touchAction = 'none';\n }\n\n canvas.addEventListener('pointerdown', this._onPointerDown);\n window.addEventListener('pointermove', this._onPointerMove);\n window.addEventListener('pointerup', this._onPointerUp);\n window.addEventListener('pointercancel', this._onPointerCancel);\n }\n\n public destroy(): void {\n if (this._canvas) {\n this._canvas.removeEventListener('pointerdown', this._onPointerDown);\n if (this._options.preventDefault) {\n this._canvas.style.touchAction = this._previousTouchAction;\n }\n this._canvas = null;\n }\n window.removeEventListener('pointermove', this._onPointerMove);\n window.removeEventListener('pointerup', this._onPointerUp);\n window.removeEventListener('pointercancel', this._onPointerCancel);\n\n this._pointers.clear();\n this._state = 'idle';\n this._startFrame = null;\n this._lastFrame = null;\n\n this.onGestureStart.disconnectAll();\n this.onGestureChange.disconnectAll();\n this.onGestureEnd.disconnectAll();\n super.destroy();\n }\n\n protected getCoreSignals(): string[] {\n return ['onGestureStart', 'onGestureChange', 'onGestureEnd'];\n }\n\n private _onPointerDown = (e: PointerEvent): void => {\n if (!this._options.pointerTypes!.includes(e.pointerType)) return;\n\n const before = this._state;\n const hadTwoOrMore = this._pointers.size >= 2;\n this._pointers.set(e.pointerId, { id: e.pointerId, x: e.clientX, y: e.clientY });\n\n if (this._state === 'idle' && this._pointers.size === 2) {\n const frame = computeFrame([...this._pointers.values()]);\n this._startFrame = frame;\n this._lastFrame = frame;\n this._state = 'pending';\n } else if (this._state !== 'idle' && hadTwoOrMore) {\n // a 3rd+ finger joined mid-gesture — rebase without emitting so it doesn't jump the frame\n this._lastFrame = computeFrame([...this._pointers.values()]);\n }\n\n this._maybePreventDefault(e, before, this._state);\n };\n\n private _onPointerMove = (e: PointerEvent): void => {\n if (!this._pointers.has(e.pointerId)) return;\n this._pointers.set(e.pointerId, { id: e.pointerId, x: e.clientX, y: e.clientY });\n\n const before = this._state;\n\n if (this._pointers.size >= 2) {\n const next = computeFrame([...this._pointers.values()]);\n\n if (this._state === 'pending') {\n const delta = frameDelta(this._lastFrame!, next);\n const spreadDelta = Math.abs(next.spread - this._lastFrame!.spread);\n const centroidDelta = Math.hypot(delta.dx, delta.dy);\n if (spreadDelta >= this._options.pinchThreshold! || centroidDelta >= this._options.panThreshold!) {\n this._lastFrame = next; // rebase — discard the threshold slack, no jump\n this._state = 'active';\n this.onGestureStart.emit({\n centerX: next.centerX,\n centerY: next.centerY,\n pointerCount: this._pointers.size,\n });\n }\n } else if (this._state === 'active') {\n const delta = frameDelta(this._lastFrame!, next);\n const totalScale = this._computeTotalScale(next);\n this._lastFrame = next;\n this.onGestureChange.emit({\n centerX: next.centerX,\n centerY: next.centerY,\n dx: delta.dx,\n dy: delta.dy,\n scale: delta.scale,\n totalScale,\n pointerCount: this._pointers.size,\n });\n }\n }\n\n this._maybePreventDefault(e, before, this._state);\n };\n\n private _onPointerUp = (e: PointerEvent): void => {\n this._endPointer(e);\n };\n\n private _onPointerCancel = (e: PointerEvent): void => {\n this._endPointer(e);\n };\n\n private _endPointer(e: PointerEvent): void {\n if (!this._pointers.has(e.pointerId)) return;\n\n const before = this._state;\n this._pointers.delete(e.pointerId);\n\n if (this._pointers.size < 2) {\n if (this._state === 'active' && this._lastFrame) {\n this.onGestureEnd.emit({\n centerX: this._lastFrame.centerX,\n centerY: this._lastFrame.centerY,\n totalScale: this._computeTotalScale(this._lastFrame),\n });\n }\n this._state = 'idle';\n this._startFrame = null;\n this._lastFrame = null;\n } else if (this._state !== 'idle') {\n // a finger lifted but 2+ remain — rebase without emitting so it doesn't jump the frame\n this._lastFrame = computeFrame([...this._pointers.values()]);\n }\n\n this._maybePreventDefault(e, before, this._state);\n }\n\n private _computeTotalScale(frame: GestureFrame): number {\n if (!this._startFrame || this._startFrame.spread < SPREAD_EPSILON) return 1;\n return frame.spread / this._startFrame.spread;\n }\n\n /** Preventable only for tracked pointer events while a gesture is pending or active. */\n private _maybePreventDefault(e: PointerEvent, before: GestureState, after: GestureState): void {\n if (this._options.preventDefault && (before !== 'idle' || after !== 'idle')) {\n e.preventDefault();\n }\n }\n}\n","import { Assets } from 'pixi.js';\nimport { Signal } from '../signals';\nimport type { AppTypeOverrides, ImportListItem, ImportListItemModule } from '../utils';\nimport { getDynamicModuleFromImportListItem, Logger } from '../utils';\nimport type { IPlugin } from './Plugin';\nimport { Plugin } from './Plugin';\n\n/**\n * Flattened dot-path keys for the project's reference locale (e.g. 'foo',\n * 'obj.nested'). Generated from `src/locales/<reference>.ts` by the Vite\n * plugin. Falls back to `string` when no locales are discovered.\n *\n * `(string & {})` preserves autocomplete for known keys while still\n * accepting dynamic strings like `t(\\`errors.\\${code}\\`)`.\n */\nexport type LocaleKey = AppTypeOverrides extends { LocaleKeys: infer K extends string }\n ? K | (string & {})\n : string;\n\n/**\n * Type definition for i18n dictionary.\n */\nexport type i18nDict = Record<string, any>;\n\n/**\n * Type definition for i18n translation parameters.\n */\nexport type i18nTParams = { variant?: number | 'random' } & Record<string, any>;\n\n/**\n * Type definition for i18n import list item.\n */\ntype i18nImportListItem<T> = {\n id: string;\n namedExport?: string;\n options?: any;\n module?: ImportListItemModule<T>;\n} & {\n json?: string;\n};\n\n/**\n * Type definition for i18n options.\n */\nexport type i18nOptions = {\n defaultLocale: string;\n locales: string[];\n loadAll: boolean;\n files: i18nImportListItem<i18nDict>[];\n};\n\n/**\n * Default options for i18n module.\n */\nconst defaultOptions: i18nOptions = {\n defaultLocale: 'en',\n locales: ['en'],\n loadAll: false,\n files: [],\n};\n\n/**\n * Interface for i18n module.\n */\nexport interface Ii18nPlugin extends IPlugin {\n readonly locale: string;\n readonly locales: string[];\n onLocaleChanged: Signal<(locale: string) => void>;\n\n setLocale(localeId: string): Promise<string>;\n\n loadLocale(localeId: string): Promise<void>;\n\n t(key: LocaleKey, params?: i18nTParams, locale?: string): string;\n\n parse(input: string, locale?: string): string;\n}\n\n/**\n * Resolves a dot-path (e.g. `'obj.nested.value'`) against a dictionary\n * object. Returns `undefined` if any segment is missing or if a non-object\n * is traversed mid-path.\n */\nfunction resolveLocalePath(dict: i18nDict, key: string): unknown {\n if (key in dict) return dict[key];\n if (!key.includes('.')) return undefined;\n let cur: unknown = dict;\n for (const segment of key.split('.')) {\n if (cur && typeof cur === 'object' && segment in (cur as Record<string, unknown>)) {\n cur = (cur as Record<string, unknown>)[segment];\n } else {\n return undefined;\n }\n }\n return cur;\n}\n\n/**\n * i18n module class.\n */\nexport class i18nPlugin extends Plugin<i18nOptions> implements Ii18nPlugin {\n public readonly id = 'i18n';\n public onLocaleChanged: Signal<(locale: string) => void> = new Signal<(locale: string) => void>();\n\n private _dicts: Record<string, i18nDict> = {};\n\n private _locale: string;\n\n /**\n * Getter for locale.\n */\n get locale(): string {\n return this._locale;\n }\n\n get locales(): string[] {\n return this._options.locales;\n }\n\n /**\n * Initializes the i18n module.\n * sets the default locale and loads the locale files.\n * @param app The application instance.\n * @param options The i18n options.\n * @returns Promise<void>\n */\n public async initialize(options: Partial<i18nOptions>): Promise<void> {\n this._options = { ...defaultOptions, ...options };\n this._locale = this._options.defaultLocale;\n if (this._options.loadAll && this._options.files.length > 0) {\n const files = this._options.files.filter((file) => this._options.locales.includes(file.id));\n for (const file of files) {\n await this.loadLocale(file.id);\n }\n } else if (this._options.files.length > 0) {\n await this.loadLocale(this._locale);\n }\n }\n\n /**\n * Sets the locale.\n * If the locale is not loaded, it will load it first.\n * @param localeId The locale id to set.\n * @returns Promise<string>\n */\n\n async setLocale(localeId: string) {\n this._locale = localeId;\n await this._loadAndSetLocale(localeId);\n return this._locale;\n }\n\n /**\n * Translates a key into a string.\n * If the key is not found, it will return an empty string.\n * If the key is found, it will replace any placeholders in the string with the values from the params object.\n * If the key contains a variant, it will select a random variant if the variant param is set to 'random'.\n * If the key contains a number variant, it will select the variant based on the variant param.\n * @param key The key to translate.\n * @param params The parameters to replace in the string.\n * @param locale The locale to use for translation.\n * @returns The translated string.\n */\n\n t(key: LocaleKey, params?: i18nTParams, locale: string = this._locale): string {\n const dict = this._dicts[locale];\n if (!dict) {\n Logger.error(`i18n:: No dictionary loaded for current locale: ${locale}`);\n return '';\n }\n // Dot-path resolution: `t('obj.nested')` walks the dict tree. Flat keys\n // still work (including keys that literally contain dots, via the\n // short-circuit in resolveLocalePath).\n const resolved = resolveLocalePath(dict, key as string);\n let str = typeof resolved === 'string' ? resolved : undefined;\n\n if (!str) {\n Logger.error(`i18n:: No result found for the key ${key} in the locale: ${this._locale}`);\n return '';\n }\n\n if (params) {\n if (typeof params.variant === 'number' || params.variant === 'random') {\n const match = /\\[(.*?)\\]/.exec(str);\n if (match) {\n // Split the string by the \"|\" character to get an array of variations.\n const items = match[1].split('|');\n\n // Get the selected variant based on the \"variation\" param.\n const num = params.variant === 'random' ? Math.floor(Math.random() * items.length) : params.variant;\n\n // Replace the original string with the selected variant\n str = str.replace(match[0], items[num]);\n }\n }\n\n // Iterate over all params to replace placeholders in the string.\n for (const f in params) {\n // Create a regular expression to match the placeholder for the current param.\n const re = new RegExp(`{${f}}`, 'g');\n\n //Replace all occurences of the placeholder with the value of the param.\n str = str.replace(re, String(params[f]));\n }\n }\n\n /**\n * Return the final translated string.\n */\n return str;\n }\n\n /**\n * Translates a key into a string (alias for t)\n * @param key The key to translate.\n * @param params The parameters to replace in the string.\n * @param locale The locale to use for translation.\n * @returns The translated string.\n */\n translate(key: LocaleKey, params?: i18nTParams, locale: string = this._locale): string {\n return this.t(key, params, locale);\n }\n\n /**\n * Parses the input string and replaces anything in between {} braces, assuming it is a key in the dictionary.\n * @param {string} input\n * @param locale\n * @returns {string}\n */\n parse(input: string, locale: string = this._locale): string {\n const dict = this._dicts[locale];\n if (!dict) {\n Logger.error(`i18n:: No dictionary loaded for current locale: ${this._locale}`);\n return '';\n }\n let str = input;\n const matches = str.match(/{(.*?)}/g);\n if (matches) {\n matches.forEach((match) => {\n const key = match.slice(1, -1);\n if (dict[key]) {\n str = str.replace(match, dict[key]);\n }\n });\n }\n return str;\n }\n\n /**\n * Loads a locale.\n * @param localeId The locale id to load.\n * @returns Promise<void>\n */\n async loadLocale(localeId: string) {\n const file = this._options.files.find((file) => localeId === file.id);\n if (!file) {\n Logger.error(`i18n:: Could not find locale file for ${localeId}`);\n return;\n }\n this._dicts[localeId] = file.json\n ? await Assets.load(file.json)\n : await getDynamicModuleFromImportListItem(file as ImportListItem<i18nDict>);\n }\n\n protected getCoreFunctions(): string[] {\n return ['t', 'translate', 'setLocale'];\n }\n\n protected getCoreSignals(): string[] {\n return ['onLocaleChanged'];\n }\n\n /**\n * Loads and sets a locale.\n * If the locale is not loaded, it will load it first.\n * @param localeId The locale id to load and set.\n */\n private async _loadAndSetLocale(localeId: string) {\n if (!this._dicts[localeId]) {\n await this.loadLocale(localeId);\n }\n this.onLocaleChanged.emit(localeId);\n }\n}\n","export enum InputControllerTypes {\n Keyboard = 'keyboard',\n GamePad = 'gamepad',\n Mouse = 'mouse',\n Touch = 'touch',\n}\n\nexport type InputController =\n | InputControllerTypes.Keyboard\n | InputControllerTypes.GamePad\n | InputControllerTypes.Mouse\n | InputControllerTypes.Touch;\n","import { IApplication } from '../core';\nimport { Signal } from '../signals';\nimport { isDev, KeyboardKey, Logger } from '../utils';\nimport type { IPlugin } from './Plugin';\nimport { Plugin } from './Plugin';\n\nexport type KeyboardEventType = 'keydown' | 'keyup';\nexport type KeyboardEventDetail = { event: KeyboardEvent; key: string };\nexport type KeySignal = Signal<(detail: KeyboardEventDetail) => void>;\n\nexport interface IKeyboardPlugin extends IPlugin {\n enabled: boolean;\n readonly keysDown: Set<string>;\n\n onKeyDown(key?: KeyboardKey): KeySignal;\n\n onKeyUp(key?: KeyboardKey): KeySignal;\n\n isKeyDown(key: string): boolean;\n}\n\nexport function normalizeKey(key: string | undefined): string {\n if (key === undefined) {\n key = '*undefined*';\n } else if (key === ' ') {\n key = 'Space';\n } else if (key.length === 1) {\n key = key.toUpperCase();\n }\n return key;\n}\n\nexport class KeyboardPlugin extends Plugin implements IKeyboardPlugin {\n public readonly id: string = 'keyboard';\n // global signals\n public onGlobalKeyDown: Signal<(detail: KeyboardEventDetail) => void> = new Signal();\n public onGlobalKeyUp: Signal<(detail: KeyboardEventDetail) => void> = new Signal();\n\n private _keyDownSignals: Map<string | undefined, KeySignal> = new Map();\n private _keyUpSignals: Map<string | undefined, KeySignal> = new Map();\n\n private _keysDown: Set<string> = new Set();\n\n // Dev-only guard: warn once if key events arrive with no consumers connected.\n private _warnedNoConsumers = false;\n\n get keysDown() {\n return this._keysDown;\n }\n\n private _enabled: boolean = true;\n\n public get enabled(): boolean {\n return this._enabled;\n }\n\n public set enabled(value: boolean) {\n this._enabled = value;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public initialize(_options: any, _app: IApplication): void {\n // track which keys are down\n document.addEventListener('keydown', this._handleKeyDown);\n document.addEventListener('keyup', this._handleKeyUp);\n }\n\n public destroy() {\n document.removeEventListener('keydown', this._handleKeyDown);\n document.removeEventListener('keyup', this._handleKeyUp);\n document.removeEventListener('keydown', this._handleEvent);\n document.removeEventListener('keyup', this._handleEvent);\n }\n\n public onKeyDown(key?: KeyboardKey): KeySignal {\n return this._checkAndAddSignal(key || undefined, 'keydown');\n }\n\n public onKeyUp(key?: KeyboardKey): KeySignal {\n return this._checkAndAddSignal(key || undefined, 'keyup');\n }\n\n public isKeyDown(key: KeyboardKey): boolean {\n return this._keysDown.has(key);\n }\n\n _update() {\n //\n }\n\n protected getCoreSignals(): string[] {\n return ['onGlobalKeyDown', 'onGlobalKeyUp'];\n }\n\n protected getCoreFunctions(): string[] {\n return ['onKeyDown', 'onKeyUp', 'isKeyDown'];\n }\n\n private _handleKeyDown(e: KeyboardEvent): void {\n const key = normalizeKey(e.key);\n this._keysDown.add(key);\n this.onGlobalKeyDown.emit({ event: e, key: e.key });\n }\n\n private _handleKeyUp(e: KeyboardEvent): void {\n const key = normalizeKey(e.key);\n this._keysDown.delete(key);\n // DX guard: a key arrived but nothing consumes it (no KeyboardControls / no\n // onKeyDown|onKeyUp subscribers). Almost always an Application subclass whose\n // postInitialize() skipped framework wiring, or controls never connected.\n if (isDev && !this._warnedNoConsumers && this._keyUpSignals.size === 0 && this._keyDownSignals.size === 0) {\n this._warnedNoConsumers = true;\n Logger.warn(\n 'KeyboardPlugin received a key event but no consumers are connected, so keyboard ' +\n 'actions will not fire. Ensure the InputPlugin controls are connected — e.g. an ' +\n 'Application subclass overriding postInitialize() must not skip framework wiring, ' +\n 'or call app.controls.connect().',\n );\n }\n this.onGlobalKeyUp.emit({ event: e, key: e.key });\n }\n\n /**\n * Check if the signal exists and add it if it doesn't\n * Also, if this is the first signal, start listening for the event\n * @param {string} key\n * @param {KeyboardEventType} eventType\n * @returns {KeySignal}\n * @private\n */\n private _checkAndAddSignal(key: string | undefined, eventType: KeyboardEventType): KeySignal {\n const signalMap = eventType === 'keydown' ? this._keyDownSignals : this._keyUpSignals;\n\n if (!signalMap.size) {\n this._listen(eventType);\n }\n\n key = normalizeKey(key);\n\n if (!signalMap.has(key)) {\n signalMap.set(key, new Signal<(detail: KeyboardEventDetail) => void>());\n }\n\n return signalMap.get(key) as KeySignal;\n }\n\n private _listen(eventType: KeyboardEventType): void {\n document.addEventListener(eventType, this._handleEvent);\n }\n\n private _handleEvent(event: KeyboardEvent): void {\n if (!this._enabled) {\n return;\n }\n const signalMap = event.type === 'keydown' ? this._keyDownSignals : this._keyUpSignals;\n const key = normalizeKey(event.key);\n signalMap.get('*undefined*')?.emit({ event, key });\n signalMap.get(key)?.emit({ event, key });\n }\n}\n","import type { ControlsActionMap } from '../..';\nimport { IApplication } from '../../core';\nimport { Application } from '../../core/Application';\n\nexport class AbstractControls {\n protected scheme: any;\n\n get app(): IApplication {\n return Application.getInstance();\n }\n\n initialize(scheme: Partial<ControlsActionMap>) {\n this.scheme = scheme;\n }\n}\n","import { Application } from '../../../core/Application';\nimport { WithSignals } from '../../../mixins';\nimport { bindAllMethods } from '../../../utils';\nimport type { Action } from '../../actions';\nimport { normalizeKey, type KeyboardEventDetail } from '../../KeyboardPlugin';\nimport { AbstractControls } from '../AbstractControls';\nimport type { ControlsActionMap, KeyboardControlsMap, KeyboardControlsScheme } from '../types';\n\nexport class KeyboardControls extends WithSignals(AbstractControls) {\n protected scheme: Partial<KeyboardControlsMap>;\n private _keyDownMap: Partial<KeyboardControlsScheme>;\n private _keyUpMap: Partial<KeyboardControlsScheme>;\n private _keyCombinations: string[][] = [];\n private _singleDownKeys: Set<string> = new Set();\n private _keyCombinationsMap: Map<string[], Action> = new Map();\n private _activeDownKeys: Map<string, Action> = new Map();\n private _activeUpKeys: Map<string, Action> = new Map();\n\n constructor() {\n super();\n bindAllMethods(this);\n }\n\n get app() {\n return Application.getInstance();\n }\n\n isActionActive(action: Action): boolean {\n const controlsAction = this.scheme['down']?.[action] ?? null;\n if (!controlsAction) {\n return false;\n }\n if (Array.isArray(controlsAction)) {\n return (\n this._keyCombinationsMap.has(controlsAction) || controlsAction.some((key) => this._singleDownKeys.has(key))\n );\n } else {\n return this._singleDownKeys.has(controlsAction);\n }\n }\n\n public initialize(scheme: Partial<KeyboardControlsMap>): void {\n super.initialize(scheme as Partial<ControlsActionMap>);\n this._keyDownMap = scheme.down || {};\n this._keyUpMap = scheme.up || {};\n this._sortActions();\n }\n\n public connect() {\n this.addSignalConnection(\n this.app.signal.onActionContextChanged.connect(this._handleContextChanged),\n this.app.keyboard.onKeyDown().connect(this._handleKeyDown),\n this.app.keyboard.onKeyUp().connect(this._handleKeyUp),\n );\n\n this._handleContextChanged();\n this.app.ticker.add(this._update);\n }\n\n private _sortActions() {\n const actions = this.app.actionsPlugin.getActions();\n this._keyCombinations = [];\n this._keyCombinationsMap.clear();\n this._activeDownKeys.clear();\n this._activeUpKeys.clear();\n let keys = Object.keys(this._keyDownMap);\n\n keys.forEach((key) => {\n const item = this._keyDownMap[key];\n const action = actions[key];\n if (\n action.context !== '*' &&\n action.context !== this.app.actionContext &&\n !action.context.includes(this.app.actionContext)\n ) {\n return;\n }\n let input = item;\n if (input) {\n if (!Array.isArray(input)) {\n input = [input];\n }\n input.forEach((inputString: string) => {\n if (inputString.includes('+')) {\n const combo = inputString.split('+');\n this._keyCombinations.push(combo);\n this._keyCombinationsMap.set(combo, key as Action);\n } else {\n this._activeDownKeys.set(inputString, key as Action);\n }\n });\n }\n });\n\n // sort them from the largest to smallest\n this._keyCombinations.sort((a, b) => b.length - a.length);\n\n keys = Object.keys(this._keyUpMap);\n keys.forEach((key) => {\n const item = this._keyUpMap[key];\n let input = item;\n if (input) {\n if (!Array.isArray(input)) {\n input = [input];\n }\n input.forEach((inputString: string) => {\n this._activeUpKeys.set(inputString, key as Action);\n });\n }\n });\n\n //Logger.log('keyDownMap', this._keyDownMap, 'activeDownKeys', this._activeDownKeys);\n //Logger.log('keyUpMap', this._keyUpMap, 'activeUpKeys', this._activeUpKeys);\n }\n\n private _handleContextChanged() {\n this._getPossibleActions();\n }\n\n private _getPossibleActions() {\n this._sortActions();\n }\n\n private _handleKeyDown(detail: KeyboardEventDetail): void {\n const key = normalizeKey(detail.event.key);\n this._singleDownKeys.add(key);\n }\n\n private _handleKeyUp(detail: KeyboardEventDetail): void {\n const key = normalizeKey(detail.event.key);\n this._singleDownKeys.delete(key);\n\n const action = this._activeUpKeys.get(key);\n if (action) {\n this.app.action(action, { combination: false, inputState: 'up', key });\n }\n }\n\n private _update() {\n if (!this.app.keyboard) {\n return;\n }\n const keysDown = this.app.keyboard.keysDown;\n if (keysDown.size === 0) {\n return;\n }\n const eliminated = new Set<string>();\n // this._keyCombinations is already sorted from largest to smallest\n for (let i = 0; i < this._keyCombinations.length; i++) {\n const combination = this._keyCombinations[i];\n // check if all of the keys in the combination are down\n if (combination.some((key) => eliminated.has(key))) {\n continue;\n }\n if (combination.every((key) => keysDown.has(key))) {\n combination.forEach((key) => eliminated.add(key));\n // send the action\n const action = this._keyCombinationsMap.get(combination);\n if (action) {\n this.app.action(action, {\n key: combination,\n combination: true,\n inputState: 'down',\n });\n }\n }\n }\n\n // order doesn't matter here\n this._singleDownKeys.forEach((key) => {\n if (eliminated.has(key)) {\n return;\n }\n if (keysDown.has(key)) {\n const action = this._activeDownKeys.get(key);\n if (action) {\n this.app.action(action, { key, combination: false, inputState: 'down' });\n }\n }\n });\n }\n}\n","import { bindAllMethods } from '../../../utils';\nimport type { ControlsActionMap, JoystickControlsScheme, TouchControlsMap, TouchControlsScheme } from '../types';\n\nimport { JoystickDirection } from '..';\nimport { Application } from '../../../core/Application';\nimport { WithSignals } from '../../../mixins';\nimport { type IButton, type IJoystick } from '../../../ui';\nimport type { Action } from '../../actions';\nimport { AbstractControls } from '../AbstractControls';\n\nexport class VirtualControls extends WithSignals(AbstractControls) {\n protected scheme: Partial<TouchControlsMap>;\n private _buttons: Set<IButton> = new Set();\n private _joystickMap: Partial<JoystickControlsScheme>;\n private _buttonDownMap: Partial<TouchControlsScheme>;\n private _buttonUpMap: Partial<TouchControlsScheme>;\n private _combinations: string[][] = [];\n private _singleDownButtons: Set<string> = new Set();\n private _activeJoystickDirections: Map<JoystickDirection, Action> = new Map();\n private _activeButtonDownIds: Map<string, Action> = new Map();\n private _activeButtonUpIds: Map<string, Action> = new Map();\n private _combinationsMap: Map<string[], Action> = new Map();\n\n constructor() {\n super();\n bindAllMethods(this);\n }\n\n private _joystick: IJoystick;\n\n get joystick(): IJoystick {\n return this._joystick;\n }\n\n set joystick(value: IJoystick) {\n this._joystick = value;\n }\n\n get app() {\n return Application.getInstance();\n }\n\n addButton(button: IButton) {\n if (!button || this._buttons.has(button)) {\n return;\n }\n this.addSignalConnection(\n button.onDown.connect(() => this._handleButtonDown(button)),\n button.onUp.connect(() => this._handleButtonUp(button)),\n button.onUpOutside.connect(() => this._handleButtonUp(button)),\n button.onDestroy.connect(() => this.removeButton(button)),\n );\n this._buttons.add(button);\n }\n\n removeButton(button: IButton) {\n if (!button || !this._buttons.has(button)) {\n return;\n }\n button.onDown.disconnect(() => this._handleButtonDown(button));\n button.onUp.disconnect(() => this._handleButtonUp(button));\n button.onUpOutside.disconnect(() => this._handleButtonUp(button));\n button.onDestroy.disconnect(() => this.removeButton(button));\n this._buttons.delete(button);\n }\n\n public initialize(scheme: Partial<TouchControlsMap>): void {\n super.initialize(scheme as Partial<ControlsActionMap>);\n this._buttonDownMap = scheme.down || {};\n this._buttonUpMap = scheme.up || {};\n this._joystickMap = scheme.joystick || {};\n this.app.signal.onActionContextChanged.connect(this._sortActions);\n this._sortActions();\n }\n\n public connect() {\n this.app.ticker.add(this._update);\n }\n\n isActionActive(action: Action): boolean {\n const buttonAction = this.scheme['down']?.[action] ?? null;\n if (buttonAction) {\n if (Array.isArray(buttonAction)) {\n return this._combinationsMap.has(buttonAction);\n } else {\n return this._singleDownButtons.has(buttonAction);\n }\n } else {\n const joystickAction = this.scheme['joystick']?.[action] ?? null;\n if (this._joystick && joystickAction) {\n if (Array.isArray(joystickAction)) {\n return joystickAction.includes(this._joystick.direction);\n } else {\n return joystickAction === this._joystick?.direction;\n }\n }\n }\n return false;\n }\n\n private _sortActions() {\n const actions = this.app.actionsPlugin.getActions();\n this._combinations = [];\n this._combinationsMap.clear();\n this._activeJoystickDirections.clear();\n this._activeButtonDownIds.clear();\n this._activeButtonUpIds.clear();\n\n let buttons = Object.keys(this._buttonDownMap);\n buttons.forEach((key) => {\n const item = this._buttonDownMap[key];\n const action = actions[key];\n if (\n action.context !== '*' &&\n action.context !== this.app.actionContext &&\n !action.context.includes(this.app.actionContext)\n ) {\n return;\n }\n let input = item;\n if (input) {\n if (!Array.isArray(input)) {\n input = [input];\n }\n input.forEach((inputString) => {\n if (inputString.includes('+')) {\n const combo = inputString.split('+');\n this._combinations.push(combo);\n this._combinationsMap.set(combo, key as Action);\n } else {\n this._activeButtonDownIds.set(inputString, key as Action);\n }\n });\n }\n });\n\n // sort them from the largest to smallest\n this._combinations.sort((a, b) => b.length - a.length);\n\n buttons = Object.keys(this._buttonUpMap);\n buttons.forEach((key) => {\n const item = this._buttonUpMap[key];\n const action = actions[key];\n if (\n action.context !== '*' &&\n action.context !== this.app.actionContext &&\n !action.context.includes(this.app.actionContext)\n ) {\n return;\n }\n this._activeButtonUpIds.set(item as string, key as Action);\n });\n\n const joystickActions = Object.keys(this._joystickMap);\n joystickActions.forEach((key) => {\n const item = this._joystickMap[key];\n let input = item;\n if (input) {\n if (!Array.isArray(input)) {\n input = [input];\n }\n input.forEach((inputString) => {\n this._activeJoystickDirections.set(inputString as JoystickDirection, key as Action);\n });\n }\n });\n }\n\n private _handleButtonDown(button: IButton): void {\n this._singleDownButtons.add(button.id!);\n }\n\n private _handleButtonUp(button: IButton): void {\n this._singleDownButtons.delete(button.id!);\n const action = this._activeButtonUpIds.get(button.id!);\n if (action) {\n this.app.action(action, {\n combination: false,\n inputState: 'up',\n button: button.id!,\n });\n }\n }\n\n private _update() {\n const joystickDirection = this._joystick?.direction ?? null;\n const buttonsDown = this._singleDownButtons;\n const eliminated = new Set<string>();\n // this._combinations is already sorted from largest to smallest\n for (let i = 0; i < this._combinations.length; i++) {\n const combination = this._combinations[i];\n // check if all of the keys in the combination are down\n if (combination.some((key) => eliminated.has(key))) {\n continue;\n }\n if (combination.every((key) => buttonsDown.has(key) || joystickDirection === key)) {\n combination.forEach((key) => eliminated.add(key));\n // send the action\n const action = this._combinationsMap.get(combination);\n if (action) {\n this.app.action(action, {\n button: combination,\n combination: true,\n inputState: 'down',\n });\n }\n }\n }\n\n // order doesn't matter here\n this._singleDownButtons.forEach((id) => {\n if (eliminated.has(id)) {\n return;\n }\n if (buttonsDown.has(id)) {\n const action = this._activeButtonDownIds.get(id);\n if (action) {\n this.app.action(action, {\n button: id,\n combination: false,\n inputState: 'down',\n });\n }\n }\n });\n\n // joustick dir\n if (joystickDirection) {\n const action = this._activeJoystickDirections.get(joystickDirection);\n if (action) {\n this.app.action(action, {\n inputState: 'joystick',\n });\n }\n }\n }\n}\n\n/** @deprecated Use {@link VirtualControls} instead. */\nexport { VirtualControls as TouchControls };\n","import { IApplication } from '../../core';\nimport { Application } from '../../core/Application';\nimport { bindAllMethods } from '../../utils';\nimport { Action } from '../actions';\nimport { IControls, UserControls } from './interfaces';\nimport { KeyboardControls } from './keyboard';\nimport { VirtualControls } from './touch';\n\nexport class Controls implements IControls {\n keyboard: KeyboardControls;\n /** @deprecated Use {@link Controls.virtual} instead. */\n touch: VirtualControls;\n\n constructor() {\n bindAllMethods(this);\n }\n\n get app(): IApplication {\n return Application.getInstance();\n }\n\n /** Virtual on-screen buttons (joystick/buttons) — the same instance as {@link Controls.touch}. */\n get virtual(): VirtualControls {\n return this.touch;\n }\n\n destroy() {\n if (this.keyboard) {\n this.keyboard.destroy();\n }\n if (this.touch) {\n this.touch.destroy();\n }\n }\n\n isActionActive(action: Action): boolean {\n const isActive = this.keyboard?.isActionActive(action) || this.touch?.isActionActive(action) || false;\n return isActive;\n }\n\n initialize(scheme: UserControls) {\n if (scheme.keyboard) {\n this.keyboard = new KeyboardControls();\n this.keyboard.initialize(scheme.keyboard);\n }\n\n if (scheme.touch) {\n this.touch = new VirtualControls();\n this.touch.initialize(scheme.touch);\n }\n }\n\n public connect() {\n if (this.keyboard) {\n this.keyboard.connect();\n }\n if (this.touch) {\n this.touch.connect();\n }\n }\n}\n","import type { ActionsList, IActionsPlugin } from '../actions';\nimport { Action, DefaultActions } from '../actions';\nimport { Controls } from './Controls';\n\nimport { IApplication } from '../../core';\nimport { Signal } from '../../signals';\nimport type { IPlugin } from '../Plugin';\nimport { Plugin } from '../Plugin';\nimport { InputController, InputControllerTypes } from './constants';\nimport { UserControls } from './interfaces';\n\nexport type InputManagerOptions = {\n actions?: ActionsList;\n controls?: UserControls;\n};\n\nexport interface IInputPlugin extends IPlugin<InputManagerOptions> {\n readonly controls: Controls;\n readonly lastUsedController: InputController | null;\n activeGamepads: Map<string, Gamepad>;\n activeControllers: Set<string>;\n options: InputManagerOptions;\n onGamepadConnected: Signal<(gamepad: Gamepad) => void>;\n onGamepadDisconnected: Signal<(gamepad: Gamepad) => void>;\n onControllerActivated: Signal<(controller: string) => void>;\n onControllerDeactivated: Signal<(controller: string) => void>;\n onControllerChanged: Signal<(controller: InputController) => void>;\n\n isControllerActive(controller: InputController): boolean;\n\n isGamepadActive(gamepad: Gamepad): boolean;\n\n isActionActive(action: Action): boolean;\n}\n\nconst defaultOptions = {\n actions: DefaultActions,\n};\n\nexport class InputPlugin extends Plugin<InputManagerOptions> implements IInputPlugin {\n public readonly id = 'input';\n\n // controls\n public readonly controls = new Controls();\n\n // properties\n public activeGamepads = new Map<string, Gamepad>();\n public activeControllers = new Set<string>([]);\n private _lastUsedController: InputController | null = null;\n private _canvas: HTMLCanvasElement | null = null;\n // signals\n public onGamepadConnected: Signal<(gamepad: Gamepad) => void> = new Signal<(gamepad: Gamepad) => void>();\n public onGamepadDisconnected: Signal<(gamepad: Gamepad) => void> = new Signal<(gamepad: Gamepad) => void>();\n public onControllerActivated: Signal<(controller: string) => void> = new Signal<(controller: string) => void>();\n public onControllerDeactivated: Signal<(controller: string) => void> = new Signal<(controller: string) => void>();\n public onControllerChanged: Signal<(controller: InputController) => void> = new Signal<\n (controller: InputController) => void\n >();\n\n get lastUsedController(): InputController | null {\n return this._lastUsedController;\n }\n\n isActionActive(action: Action): boolean {\n return this.controls.isActionActive(action);\n }\n\n async initialize(options: Partial<InputManagerOptions> = defaultOptions, app: IApplication): Promise<void> {\n this._options = { ...defaultOptions, ...options };\n\n app.stage.eventMode = 'static';\n this._canvas = app.canvas as HTMLCanvasElement;\n this._canvas.addEventListener('pointerdown', this._onPointerDown);\n this._canvas.addEventListener('pointermove', this._onPointerMove);\n window.addEventListener('keydown', this._onKeyDown);\n window.addEventListener('gamepadconnected', this._onGamepadConnected);\n window.addEventListener('gamepaddisconnected', this._onGamepadDisconnected);\n\n if (this._options.controls) {\n this.controls.initialize(this._options.controls);\n }\n }\n\n public postInitialize(): void {\n if (this.controls) {\n this.controls.connect();\n }\n }\n\n destroy(): void {\n // unregister all event listeners\n if (this._canvas) {\n this._canvas.removeEventListener('pointerdown', this._onPointerDown);\n this._canvas.removeEventListener('pointermove', this._onPointerMove);\n this._canvas = null;\n }\n window.removeEventListener('keydown', this._onKeyDown);\n window.removeEventListener('gamepadconnected', this._onGamepadConnected);\n window.removeEventListener('gamepaddisconnected', this._onGamepadDisconnected);\n\n this.controls.destroy();\n\n this.onGamepadConnected.disconnectAll();\n this.onGamepadDisconnected.disconnectAll();\n this.onControllerActivated.disconnectAll();\n this.onControllerDeactivated.disconnectAll();\n this.onControllerChanged.disconnectAll();\n\n super.destroy();\n }\n\n isControllerActive(controller: InputController): boolean {\n return this.activeControllers.has(controller);\n }\n\n isGamepadActive(gamepad: Gamepad): boolean {\n return this.activeGamepads.has(gamepad.id);\n }\n\n protected getCoreSignals(): string[] {\n return [\n 'onGamepadConnected',\n 'onGamepadDisconnected',\n 'onControllerActivated',\n 'onControllerDeactivated',\n 'onControllerChanged',\n ];\n }\n\n private _isInputControllerType(value: string): value is InputController {\n return (Object.values(InputControllerTypes) as string[]).includes(value);\n }\n\n private _activateController(inputController: string): void {\n const isNewController = !this.activeControllers.has(inputController);\n if (isNewController) {\n this.activeControllers.add(inputController);\n }\n\n // only the four InputControllerTypes values are valid \"last used\" values —\n // a raw gamepad device id (see _onGamepadConnected) must never land here\n if (this._isInputControllerType(inputController) && inputController !== this._lastUsedController) {\n this._lastUsedController = inputController;\n this.onControllerChanged.emit(inputController);\n }\n\n if (isNewController) {\n // emit the controller activated signal\n this.onControllerActivated.emit(inputController);\n }\n }\n\n private _deactivateController(inputController: InputController): void {\n const wasControllerActive = this.activeControllers.has(inputController);\n if (!wasControllerActive) {\n return;\n }\n this.activeControllers.delete(inputController);\n // emit the controller deactivated signal\n this.onControllerDeactivated.emit(inputController);\n }\n\n private _activateGamepad(gamepad: Gamepad): void {\n this.activeGamepads.set(gamepad.id, gamepad);\n }\n\n private _deactivateGamepad(gamepadId: string): void {\n this.activeGamepads.delete(gamepadId);\n }\n\n private _onPointerDown(event: PointerEvent): void {\n if (event.pointerType === 'touch') {\n this._activateController(InputControllerTypes.Touch);\n }\n }\n\n private _onPointerMove(event: PointerEvent): void {\n if (event.pointerType === 'mouse') {\n this._activateController(InputControllerTypes.Mouse);\n }\n }\n\n private _onKeyDown(): void {\n this._activateController(InputControllerTypes.Keyboard);\n }\n\n private _onGamepadConnected(event: GamepadEvent): void {\n this._activateController(InputControllerTypes.GamePad);\n // add the gamepad id just in case we need it (?)\n this._activateController(event.gamepad.id);\n this._activateGamepad(event.gamepad);\n // emit the gamepad connected signal\n this.onGamepadConnected.emit(event.gamepad);\n }\n\n private _onGamepadDisconnected(event: GamepadEvent): void {\n // remove the gamepad\n this._deactivateGamepad(event.gamepad.id);\n\n // pause the game any time there is a controller disconnect\n this.actionsPlugin.sendAction('pause');\n\n // emit the gamepad disconnected signal\n this.onGamepadDisconnected.emit(event.gamepad);\n\n // check if all gamepads are disconnected\n if (this.activeGamepads.size === 0) {\n this._deactivateController(InputControllerTypes.GamePad);\n }\n }\n\n get actionsPlugin(): IActionsPlugin {\n return this.app.getPlugin('actions') as IActionsPlugin;\n }\n}\n","import { Container as PIXIContainer } from 'pixi.js';\nimport { IPlugin, Plugin } from '.';\nimport { Container } from '../display';\n\n/**\n * Interface for the LookupPlugin providing fast container lookup functionality.\n * Enables O(1) lookups of PIXI containers using hierarchical path strings.\n */\nexport interface ILookupPlugin extends IPlugin {\n /**\n * Retrieves a container at the specified hierarchical path.\n * @param path - Slash-separated path like 'Parent/Child/GrandChild'\n * @returns The container at the path, or undefined if not found\n * @example\n * ```typescript\n * const button = lookupPlugin.getChildAtPath('UI/Menu/StartButton');\n * ```\n */\n getChildAtPath(path: string): PIXIContainer | undefined;\n\n /**\n * Gets the hierarchical path for a given container.\n * @param container - The PIXI container to get the path for\n * @returns The hierarchical path string, or empty string if not tracked\n * @example\n * ```typescript\n * const path = lookupPlugin.getPathForChild(myContainer); // 'Parent/Child'\n * ```\n */\n getPathForChild(container: PIXIContainer): string;\n\n /**\n * Batch retrieval of containers at multiple paths.\n * @param paths - Array of hierarchical paths to look up\n * @returns Array of containers found at the specified paths (undefined entries filtered out)\n * @example\n * ```typescript\n * const [ui, player] = lookupPlugin.getChildrenAtPaths('UI/HUD', 'Game/Player');\n * ```\n */\n getChildrenAtPaths(...paths: string[]): PIXIContainer[];\n\n /**\n * Batch retrieval of paths for multiple containers.\n * @param containers - Array of PIXI containers to get paths for\n * @returns Array of hierarchical paths for the containers\n * @example\n * ```typescript\n * const paths = lookupPlugin.getPathsForChildren(container1, container2);\n * ```\n */\n getPathsForChildren(...containers: PIXIContainer[]): string[];\n\n /**\n * Gets all currently tracked hierarchical paths.\n * @returns Array of all path strings in the lookup system\n * @example\n * ```typescript\n * const allPaths = lookupPlugin.getAllPaths(); // ['UI/Menu', 'Game/Player', ...]\n * ```\n */\n getAllPaths(): string[];\n}\n\n/**\n * High-performance container lookup plugin for PIXI.js applications.\n *\n * Provides O(1) lookup of containers using hierarchical path strings by maintaining\n * bidirectional maps between paths and containers. Automatically tracks container\n * hierarchy changes through global Container events.\n *\n * @example\n * ```typescript\n * // Access containers by path\n * const player = app.lookup.getChildAtPath('Game/Entities/Player');\n * const menuButton = app.lookup.getChildAtPath('UI/MainMenu/StartButton');\n *\n * // Get paths for containers\n * const playerPath = app.lookup.getPathForChild(playerSprite); // 'Game/Entities/Player'\n * ```\n *\n * @remarks\n * - Paths are built using container labels in hierarchical order\n * - Only containers with labels are included in paths\n * - Automatically handles container addition/removal through event listeners\n * - Uses Map data structures for optimal performance\n */\nexport class LookupPlugin extends Plugin implements ILookupPlugin {\n public name = 'lookup';\n\n /** Fast O(1) lookup map: hierarchical path -> container reference */\n private pathToContainer = new Map<string, PIXIContainer>();\n\n /** Reverse lookup for efficient path updates: container reference -> hierarchical path */\n private containerToPath = new Map<PIXIContainer, string>();\n\n /**\n * Core function names exposed by this plugin for framework integration.\n */\n get coreFunctions(): string[] {\n return ['getChildAtPath', 'getPathForChild', 'getChildrenAtPaths', 'getPathsForChildren', 'getAllPaths'];\n }\n\n /**\n * Initializes the lookup plugin by connecting to global container events.\n * Sets up automatic tracking of container hierarchy changes.\n */\n public async initialize() {\n Container.onGlobalChildAdded.connect(this.onChildAdded);\n Container.onGlobalChildRemoved.connect(this.onChildRemoved);\n }\n\n /**\n * Fast O(1) lookup of container by hierarchical path.\n *\n * @param path - Slash-separated path like 'Parent/Child/GrandChild'\n * @returns The container at the specified path, or undefined if not found\n *\n * @example\n * ```typescript\n * // Get a specific UI element\n * const healthBar = lookup.getChildAtPath('UI/HUD/HealthBar');\n * if (healthBar) {\n * // Update health display\n * healthBar.visible = true;\n * }\n * ```\n */\n public getChildAtPath(path: string): PIXIContainer | undefined {\n return this.pathToContainer.get(path);\n }\n\n /**\n * Batch retrieval of containers at multiple paths.\n * Filters out undefined results for convenience.\n *\n * @param paths - Variable number of hierarchical paths to look up\n * @returns Array of found containers (undefined entries filtered out)\n *\n * @example\n * ```typescript\n * // Get multiple UI elements at once\n * const [menu, hud, inventory] = lookup.getChildrenAtPaths(\n * 'UI/MainMenu',\n * 'UI/HUD',\n * 'UI/Inventory'\n * );\n * ```\n */\n public getChildrenAtPaths(...paths: string[]): PIXIContainer[] {\n return paths.map((path) => this.getChildAtPath(path)).filter((container) => container !== undefined);\n }\n\n /**\n * Get the hierarchical path for a given container.\n *\n * @param container - The container to get the path for\n * @returns The hierarchical path or empty string if not tracked\n *\n * @example\n * ```typescript\n * // Get path for debugging or logging\n * const containerPath = lookup.getPathForChild(someSprite);\n * console.log(`Container is at: ${containerPath}`);\n * ```\n */\n public getPathForChild(container: PIXIContainer): string {\n return this.containerToPath.get(container) || '';\n }\n\n /**\n * Batch retrieval of paths for multiple containers.\n *\n * @param containers - Variable number of PIXI containers to get paths for\n * @returns Array of hierarchical paths for the containers\n *\n * @example\n * ```typescript\n * // Get paths for multiple containers for debugging\n * const paths = lookup.getPathsForChildren(sprite1, sprite2, sprite3);\n * console.log('Container paths:', paths);\n * ```\n */\n public getPathsForChildren(...containers: PIXIContainer[]): string[] {\n return containers.map((container) => this.getPathForChild(container));\n }\n\n /**\n * Gets all currently tracked hierarchical paths.\n * Useful for debugging, serialization, or introspection.\n *\n * @returns Array of all path strings in the lookup system\n *\n * @example\n * ```typescript\n * // Debug all tracked containers\n * const allPaths = lookup.getAllPaths();\n * console.log('All tracked containers:', allPaths);\n * ```\n */\n public getAllPaths(): string[] {\n return Array.from(this.pathToContainer.keys());\n }\n\n /**\n * Gets all currently tracked containers.\n * Useful for bulk operations or debugging.\n *\n * @returns Array of all container references in the lookup system\n */\n public getAllChildren(): PIXIContainer[] {\n return Array.from(this.pathToContainer.values());\n }\n\n /**\n * Event handler for when a child is added to any container.\n * Automatically adds the new container to the lookup system.\n *\n * @param child - The newly added container\n */\n private onChildAdded(child: PIXIContainer) {\n this.addToLookup(child);\n }\n\n /**\n * Event handler for when a child is removed from any container.\n * Automatically removes the container from the lookup system.\n *\n * @param child - The removed container\n */\n private onChildRemoved(child: PIXIContainer) {\n this.removeFromLookup(child);\n }\n\n /**\n * Add a container and all its descendants to the lookup system.\n * Recursively processes the entire subtree to maintain lookup integrity.\n *\n * @param container - The container to add (along with all its children)\n */\n private addToLookup(container: PIXIContainer): void {\n const path = this.buildPath(container);\n\n if (path) {\n this.pathToContainer.set(path, container);\n this.containerToPath.set(container, path);\n }\n\n // Recursively add all children to maintain lookup integrity\n if (container.children) {\n for (const child of container.children) {\n this.addToLookup(child as PIXIContainer);\n }\n }\n }\n\n /**\n * Remove a container and all its descendants from the lookup system.\n * Recursively processes the entire subtree to prevent memory leaks.\n *\n * @param container - The container to remove (along with all its children)\n */\n private removeFromLookup(container: PIXIContainer): void {\n // Remove all descendants first\n if (container.children) {\n for (const child of container.children) {\n this.removeFromLookup(child as PIXIContainer);\n }\n }\n\n // Remove this container from lookup\n const path = this.containerToPath.get(container);\n if (path) {\n this.pathToContainer.delete(path);\n this.containerToPath.delete(container);\n }\n }\n\n /**\n * Build the hierarchical path for a container by traversing up the parent chain.\n * Only includes containers with labels in the path, stopping at 'Stage'.\n *\n * @param container - The container to build a path for\n * @returns The hierarchical path string, or empty string if no labeled ancestors\n *\n * @example\n * ```typescript\n * // For a container structure: Stage -> Game -> Player -> HealthBar\n * // Where each has a label, this would return: 'Game/Player/HealthBar'\n * ```\n */\n private buildPath(container: PIXIContainer): string {\n const pathSegments: string[] = [];\n let current: PIXIContainer | null = container;\n\n // Traverse up the parent chain to build path segments\n while (current && current.label) {\n pathSegments.unshift(current.label);\n current = current.parent as PIXIContainer;\n if (current?.label === 'Stage') {\n break;\n }\n }\n\n // Only return a path if we have at least one labeled segment\n return pathSegments.length > 0 ? pathSegments.join('/') : '';\n }\n}\n","import { Container } from '../display';\nimport { Signal } from '../signals';\nimport type { IPopup, PopupConfig, PopupConstructor } from '../ui';\nimport { bindAllMethods, getLastMapEntry } from '../utils';\nimport type { PopupId, PopupInstance, PopupProps } from '../utils';\nimport type { IPlugin } from './Plugin';\nimport { Plugin } from './Plugin';\n\ntype PopupListItem = {\n id: string | number;\n active?: boolean;\n module?: PopupConstructor | (() => Promise<unknown>);\n};\n\n/**`\n * Interface for PopupManager\n */\nexport interface IPopupManagerPlugin extends IPlugin {\n readonly view: Container; // The view of the PopupManager\n readonly current: IPopup | undefined; // The current active popup\n readonly hasActivePopups: boolean; // Whether there are any active popups\n readonly popupCount: number; // The count of popups\n readonly currentPopupId: string | number | undefined; // The id of the current popup\n // signals\n onShowPopup: Signal<(detail: PopupSignalDetail) => void>; // Signal for when a popup is shown\n onHidePopup: Signal<(detail: PopupSignalDetail) => void>; // Signal for when a popup is hidden\n onPopupChanged: Signal<(detail: PopupSignalDetail) => void>; // Signal for when a popup is changed\n\n /**\n * Show a discovered popup by id. The `config.data` field is narrowed to\n * the popup's declared data type (if it extends `Popup<MyData>`). Awaits\n * the full show lifecycle (initialize → beforeShow → show animation).\n */\n showPopup<K extends PopupId>(id: K, config?: PopupProps<K>): Promise<PopupInstance<K> | undefined>;\n\n /** Alias for `showPopup` — shorter when called as `this.popups.show(...)`. */\n show<K extends PopupId>(id: K, config?: PopupProps<K>): Promise<PopupInstance<K> | undefined>;\n\n hidePopup<T = any>(id: string | number, data?: any): Promise<IPopup<T> | undefined>; // Hide a popup\n\n removeAllPopups(animate?: boolean): void; // Remove all popups\n}\n\nexport type PopupSignalDetail<T = any> = { id: string | number; data?: T };\n\n/**\n * PopupManager\n */\n\nexport class PopupManagerPlugin extends Plugin implements IPopupManagerPlugin {\n public readonly id: string = 'popups'; // The id of the PopupManager\n public readonly view = new Container(); // The view of the PopupManager\n\n // signals\n public onShowPopup: Signal<(detail: PopupSignalDetail) => void> = new Signal<(detail: PopupSignalDetail) => void>(); // Signal for when a popup is shown\n public onHidePopup: Signal<(detail: PopupSignalDetail) => void> = new Signal<(detail: PopupSignalDetail) => void>(); // Signal for when a popup is hidden\n public onPopupChanged: Signal<(detail: PopupSignalDetail) => void> = new Signal<\n (detail: PopupSignalDetail) => void\n >(); // Signal for when a popup is changed\n // Map entries may start out as a dynamic-import function (from discovery)\n // and get replaced with the resolved constructor on first `show()` call.\n private _popups: Map<string | number, PopupConstructor | (() => Promise<unknown>)> = new Map();\n private _activePopups: Map<string | number, IPopup> = new Map(); // Map of active popups\n\n private _currentPopupId: string | number | undefined = undefined; // The id of the current popup\n\n get currentPopupId(): string | number | undefined {\n return this._currentPopupId;\n }\n\n get popupCount(): number {\n return this._popups.size;\n }\n\n get current(): IPopup | undefined {\n if (this._currentPopupId === undefined) {\n return undefined;\n }\n return this._activePopups.get(this._currentPopupId);\n }\n\n get hasActivePopups(): boolean {\n return this._activePopups.size > 0;\n }\n\n /**\n * Initialize the PopupManager. Reads the discovered `popupList` from the\n * `caper-runtime` global and pre-registers every active popup. Dynamic\n * imports are stored as-is and resolved on first `show()` call.\n */\n initialize(): void {\n bindAllMethods(this);\n this.view.label = 'PopupManager';\n this._setupAppListeners();\n this._registerDiscoveredPopups();\n }\n\n /**\n * Destroy the PopupManager\n */\n destroy(): void {\n this._activePopups.clear();\n super.destroy();\n }\n\n /**\n * Show a discovered popup by id.\n * @param id - The id of the popup (typed against `AppPopups`).\n * @param config - The configuration for the popup. `config.data` is\n * narrowed via the popup class's `Popup<T>` generic.\n * @returns a promise resolving to the popup instance.\n */\n async showPopup<K extends PopupId>(\n id: K,\n config: PopupProps<K> = {} as PopupProps<K>,\n ): Promise<PopupInstance<K> | undefined> {\n const resolved = await this._resolvePopupCtor(id);\n if (!resolved) return;\n\n const typedConfig = config as Partial<PopupConfig<any>> & { id?: string | number };\n typedConfig.id = id;\n const instance = this.view.add.existing(new resolved(id, typedConfig as Partial<PopupConfig>));\n instance.initialize();\n this.app.focus.clearFocus();\n instance.beforeShow();\n await instance.show();\n\n this.app.focus.setFocusLayer(id);\n instance.afterShow();\n\n this._activePopups.set(id, instance);\n this._currentPopupId = id;\n\n return new Promise((resolve) => {\n this.app.ticker.addOnce(() => {\n this.onShowPopup.emit({ id, data: typedConfig?.data });\n instance.start();\n this.onPopupChanged.emit({ id, data: typedConfig?.data });\n resolve(instance as PopupInstance<K>);\n });\n });\n }\n\n /** Alias for `showPopup`. */\n show<K extends PopupId>(id: K, config?: PopupProps<K>): Promise<PopupInstance<K> | undefined> {\n return this.showPopup(id, config);\n }\n\n /**\n * Hide a popup\n * @param id - The id of the popup\n * @param data\n * @returns a promise resolving to the popup, if it exists\n */\n async hidePopup<T = any>(id: string | number, data?: T): Promise<IPopup<T> | undefined> {\n const popup = this._activePopups.get(id);\n if (popup) {\n popup.beforeHide();\n await popup.hide();\n this.view.removeChild(popup as any);\n this._activePopups.delete(id);\n this._currentPopupId = getLastMapEntry(this._activePopups)?.[0] || undefined;\n return new Promise((resolve) => {\n this.app.ticker.addOnce(() => {\n this.onHidePopup.emit({ id, data });\n popup.end();\n this.onPopupChanged.emit({ id, data });\n resolve(popup);\n popup.restoreActionContext();\n });\n });\n }\n return;\n }\n\n /**\n * Remove all popups\n * @param animate - Whether to animate the removal\n */\n removeAllPopups(animate: boolean = false): void {\n if (animate) {\n this._activePopups.forEach((popup) => {\n popup.hide();\n });\n } else {\n this._activePopups.clear();\n this.view.removeChildren();\n }\n }\n\n protected getCoreFunctions() {\n return ['hidePopup', 'showPopup', 'removeAllPopups'];\n }\n\n protected getCoreSignals() {\n return ['onShowPopup', 'onHidePopup', 'onPopupChanged'];\n }\n\n /**\n * Setup application listeners\n * @private\n */\n private _setupAppListeners(): void {\n this.addSignalConnection(this.app.scenes.onSceneChangeStart.connect(() => this.removeAllPopups()));\n this.app.keyboard.onKeyUp('Escape').connect(this._handleEscape);\n }\n\n /**\n * Pull every active popup off `globalThis.Caper.popupList` (populated by\n * the `caper-runtime` virtual module before the Application starts) and\n * seed the registry. Entries stay as dynamic-import functions until the\n * first `show()` call resolves them.\n */\n private _registerDiscoveredPopups(): void {\n const list: PopupListItem[] =\n ((globalThis as unknown as { Caper?: { get?: (key: string) => unknown } }).Caper?.get?.(\n 'popupList',\n ) as PopupListItem[] | undefined) ?? [];\n for (const item of list) {\n if (item.active === false || !item.module) continue;\n this._popups.set(item.id, item.module);\n }\n }\n\n /**\n * Ensure the popup constructor for `id` is loaded and return it. Resolves\n * dynamic-import functions on first access, caches the result back onto\n * the registry so subsequent shows are synchronous.\n */\n private async _resolvePopupCtor(id: string | number): Promise<PopupConstructor | undefined> {\n const entry = this._popups.get(id);\n if (!entry) {\n const known = [...this._popups.keys()].map((k) => `'${String(k)}'`).join(', ');\n throw new Error(\n `[caper] Unknown popup id '${String(id)}'. ` +\n `Known: ${known.length > 0 ? known : '(none — discovery may have failed)'}`,\n );\n }\n // Already a constructor (has prototype)\n if (typeof entry === 'function' && (entry as PopupConstructor).prototype) {\n return entry as PopupConstructor;\n }\n // Dynamic import function — resolve and cache\n const mod = (await (entry as () => Promise<unknown>)()) as { default?: PopupConstructor };\n const ctor = mod?.default;\n if (!ctor) {\n throw new Error(`[caper] Popup '${String(id)}' module did not export a default class.`);\n }\n this._popups.set(id, ctor);\n return ctor;\n }\n\n /**\n * Handle escape key press\n * if the current popup should close when escape is pressed (true by default), closes it\n * @private\n */\n private _handleEscape() {\n if (this.current && this.current.config.closeOnEscape) {\n void this.hidePopup(this.current.id);\n }\n }\n}\n","import { Graphics } from 'pixi.js';\n\nimport { Container } from '../display';\nimport type { Size } from '../utils';\nimport type { IPlugin } from './Plugin';\nimport { Plugin } from './Plugin';\n\n/**\n * Interface for Resizer module.\n */\nexport interface IResizerPlugin extends IPlugin {\n readonly size: Size;\n readonly scale: number;\n resize(): Promise<Size>;\n}\n\n/**\n * Configuration options for the Resizer plugin\n */\nexport type ResizerPluginOptions = {\n /** Whether to scroll the window to the top when resizing */\n autoScroll: boolean;\n /** The minimum width at which the renderer will resize. Also controls aspect ratio in letterbox mode */\n minWidth: number;\n /** The minimum height of the canvas. Also controls aspect ratio in letterbox mode */\n minHeight: number;\n /** Whether to letterbox the canvas to maintain aspect ratio */\n letterbox: boolean;\n /** Whether to center the canvas (particularly useful in letterbox mode) */\n center: boolean;\n /** Whether to draw debug information for visualizing canvas bounds */\n debug: boolean;\n};\n\n/**\n * Default options for Resizer module.\n */\nconst defaultOptions: ResizerPluginOptions = {\n autoScroll: false,\n minWidth: 0,\n minHeight: 0,\n letterbox: false,\n center: false,\n debug: false,\n};\n\nexport class ResizerPlugin extends Plugin<ResizerPluginOptions> implements IResizerPlugin {\n public readonly id = 'resizer';\n private _debugContainer: Container;\n private _gfx: Graphics;\n private _size: Size;\n private _scale: number;\n private _resizeId: number | null;\n\n get size(): Size {\n return this._size;\n }\n\n get scale(): number {\n return this._scale;\n }\n\n /**\n * Initializes the Resizer module.\n */\n async initialize(options: Partial<ResizerPluginOptions>) {\n this._options = { ...defaultOptions, ...options };\n }\n\n /**\n * Post-initialization of the Resizer module.\n * when this is called, the renderer is already created, and the dom element has been appended\n */\n async postInitialize() {\n this.resize();\n }\n\n async resize(): Promise<Size> {\n this._cancelResize!();\n return new Promise((resolve) => {\n this._resizeId = requestAnimationFrame(() => {\n this._resize();\n resolve(this._size);\n });\n });\n }\n\n _cancelResize = (): void => {\n if (this._resizeId) {\n cancelAnimationFrame(this._resizeId);\n this._resizeId = null;\n }\n };\n\n _resizeInternal(w: number, h: number, minWidth: number, minHeight: number, letterbox: boolean) {\n const aspectRatio = minWidth / minHeight;\n let canvasWidth = w;\n let canvasHeight = h;\n\n if (letterbox) {\n if (minWidth < minHeight) {\n canvasWidth = canvasHeight * aspectRatio;\n } else {\n canvasHeight = canvasWidth / aspectRatio;\n }\n }\n\n const scaleX = canvasWidth < minWidth ? minWidth / canvasWidth : 1;\n const scaleY = canvasHeight < minHeight ? minHeight / canvasHeight : 1;\n const scale = scaleX > scaleY ? scaleX : scaleY;\n const width = Math.floor(canvasWidth * scale);\n const height = Math.floor(canvasHeight * scale);\n\n return { width, height, aspectRatio };\n }\n /**\n * Resizes the application based on window size and module options.\n */\n\n _resize() {\n const minWidth = this._options.minWidth;\n const minHeight = this._options.minHeight;\n const letterbox = this._options.letterbox;\n const center = this._options.center;\n\n let canvasWidth = minWidth;\n let canvasHeight = minHeight;\n\n if (this.app.config.resizeToContainer) {\n const canvas = this.app.renderer.canvas;\n const el = canvas?.parentElement;\n const bounds = el?.getBoundingClientRect();\n if (bounds) {\n canvasWidth = bounds.width;\n canvasHeight = bounds.height;\n }\n }\n\n const { width, height, aspectRatio } = this._resizeInternal(\n canvasWidth,\n canvasHeight,\n minWidth,\n minHeight,\n letterbox,\n );\n\n // Calculate renderer and canvas sizes based on current dimensions\n const scaleX = canvasWidth < minWidth ? minWidth / canvasWidth : 1;\n const scaleY = canvasHeight < minHeight ? minHeight / canvasHeight : 1;\n const scale = scaleX > scaleY ? scaleX : scaleY;\n\n this._scale = scale;\n\n // Update canvas style dimensions and scroll window up to avoid issues on mobile resize\n if (letterbox) {\n if (canvasWidth > canvasHeight) {\n // Calculate dimensions based on width\n let styleWidth = canvasWidth;\n let styleHeight = canvasWidth / aspectRatio;\n\n // Constrain height if it exceeds container\n if (styleHeight > canvasHeight) {\n styleHeight = canvasHeight;\n styleWidth = styleHeight * aspectRatio;\n }\n\n this.app.renderer.canvas.style.width = `${styleWidth}px`;\n this.app.renderer.canvas.style.height = `${styleHeight}px`;\n } else {\n // Calculate dimensions based on height\n let styleHeight = canvasHeight;\n let styleWidth = canvasHeight * aspectRatio;\n\n // Constrain width if it exceeds container\n if (styleWidth > canvasWidth) {\n styleWidth = canvasWidth;\n styleHeight = styleWidth / aspectRatio;\n }\n\n this.app.renderer.canvas.style.height = `${styleHeight}px`;\n this.app.renderer.canvas.style.width = `${styleWidth}px`;\n }\n if (center) {\n this.app.renderer.canvas.style.position = 'absolute';\n this.app.renderer.canvas.style.left = '50%';\n this.app.renderer.canvas.style.top = '50%';\n this.app.renderer.canvas.style.transform = `translate3d(-50%, -50%, 0)`;\n }\n } else {\n this.app.renderer.canvas.style.width = `${canvasWidth}px`;\n this.app.renderer.canvas.style.height = `${canvasHeight}px`;\n }\n\n if (this._options.autoScroll) {\n window?.scrollTo(0, 0);\n }\n\n // Update renderer and navigation screens dimensions\n this.app.renderer.resize(width, height);\n this._size = { width, height };\n\n if (this._options.debug) {\n this._drawDebug();\n }\n }\n\n /**\n * Draws debug information if debug option is enabled.\n */\n private _drawDebug() {\n if (!this._debugContainer) {\n this._debugContainer = this.app.stage.addChild(new Container());\n this._gfx = this._debugContainer.add.graphics();\n }\n\n this._gfx.clear();\n this._gfx.rect(0, 0, this._size.width, this._size.height);\n this._gfx.stroke({ width: 4, color: 0x000fff });\n }\n}\n","import { Container } from 'pixi.js';\nimport type { IApplication, PauseConfig } from '../core';\nimport { Application } from '../core/Application';\nimport type { IScene, ISceneTransition, SceneTransition } from '../display';\nimport { Signal } from '../signals';\nimport {\n type AppTypeOverrides,\n AssetTypes,\n bindAllMethods,\n BundleTypes,\n Constructor,\n createQueue,\n getDynamicModuleFromImportListItem,\n isDev,\n Queue,\n type SceneId,\n SceneImportList,\n SceneImportListItem,\n type SceneLoadArgs,\n} from '../utils';\nimport { triggerViteError } from '../utils/vite';\nimport type { IPlugin } from './Plugin';\nimport { Plugin } from './Plugin';\n\nexport type AppScenes = AppTypeOverrides['Scenes'];\n\nexport interface ISceneManagerPlugin extends IPlugin {\n isFirstScene: boolean;\n onSceneChangeStart: Signal<(detail: { exiting: string | null; entering: string }) => void>;\n onSceneChangeComplete: Signal<(detail: { current: string }) => void>;\n view: Container;\n list: SceneImportList<IScene>;\n splash: { view: ISceneTransition | null; hideWhen: SplashHideWhen; zOrder: SplashZOrder };\n transition?: ISceneTransition;\n currentScene: IScene;\n readonly ids: AppScenes[];\n readonly defaultScene: string;\n readonly debugGroupsList: any[];\n\n setDefaultLoadMethod(method: LoadSceneMethod): void;\n\n loadDefaultScene(): Promise<void>;\n\n /** Typed overload — enforces `props` required when `Scene<Props>` declares a non-void generic. */\n loadScene<K extends SceneId>(id: K, ...args: SceneLoadArgs<K>): Promise<void>;\n loadScene(sceneIdOrLoadSceneConfig: LoadSceneConfig | AppScenes): Promise<void>;\n\n getSceneFromHash(): string | null;\n}\n\nexport type LoadSceneMethod =\n | 'immediate'\n | 'exitEnter'\n | 'enterExit'\n | 'enterBehind'\n | 'transitionExitEnter'\n | 'exitTransitionEnter';\n\nexport type SplashHideWhen = 'firstSceneEnter' | 'requiredAssetsLoaded';\nexport type SplashZOrder = 'top' | 'bottom';\n\nexport type SplashOptions = {\n view: ISceneTransition | typeof SceneTransition | null;\n zOrder: SplashZOrder;\n hideWhen: SplashHideWhen;\n preload?: {\n assets?: AssetTypes;\n bundles?: BundleTypes;\n };\n};\n\nexport type LoadSceneConfig = {\n id: AppScenes;\n method?: LoadSceneMethod;\n};\n\nconst defaultSplashOptions: SplashOptions = {\n view: null,\n hideWhen: 'firstSceneEnter',\n zOrder: 'top',\n preload: {\n assets: [],\n bundles: [],\n },\n};\n\nexport class SceneManagerPlugin extends Plugin implements ISceneManagerPlugin {\n public readonly id: string = 'scenes';\n public onSceneChangeStart: Signal<(detail: { exiting: string | null; entering: string }) => void> = new Signal<\n (detail: { exiting: string | null; entering: string }) => void\n >();\n public onSceneChangeComplete: Signal<(detail: { current: string }) => void> = new Signal<\n (detail: { current: string }) => void\n >();\n public splash: {\n view: ISceneTransition | null;\n hideWhen: SplashHideWhen;\n zOrder: SplashZOrder;\n preload?: { assets?: AssetTypes; bundles?: BundleTypes };\n };\n public transition?: ISceneTransition;\n // view container - gets added to the stage\n public view: Container = new Container();\n // maybe the user wants the enter animation to be different for the first scene\n public isFirstScene: boolean = true;\n\n // scene management\n public list: SceneImportList<IScene> = [];\n public groupOrder: string[] = [];\n public currentScene: IScene;\n public defaultScene: string;\n public debugGroupsList: any[] = [];\n private _sceneModules: Map<string, Constructor<IScene>> = new Map();\n /** Props for the pending `loadScene(id, props)` call, assigned onto the new scene before `initialize()` runs. */\n private _pendingLoadProps: unknown = undefined;\n //\n private _lastScene: IScene | null = null;\n private _queue: Queue<any> | null;\n private _defaultLoadMethod: LoadSceneMethod = 'immediate';\n private _currentSceneId: string;\n // debug\n private _debugVisible: boolean = false;\n private _debugMenu: HTMLDivElement;\n private _useHash: boolean = false;\n\n // debug\n private _sceneSelect: HTMLSelectElement;\n\n constructor() {\n super();\n bindAllMethods(this);\n }\n\n get ids(): string[] {\n return this.list.map((s) => s.id);\n }\n\n public setDefaultLoadMethod(method: LoadSceneMethod) {\n this._defaultLoadMethod = method;\n }\n\n public destroy(): void {}\n\n public async initialize(_options: any, app: IApplication): Promise<void> {\n this._debugVisible =\n this.app.config?.showSceneDebugMenu === true || (isDev && this.app.config?.showSceneDebugMenu !== false);\n this._useHash = app.config?.useHash === true || this._debugVisible;\n this.view.sortableChildren = true;\n const sceneList: SceneImportListItem<IScene>[] = Caper.get('sceneList') || [];\n this.list = sceneList.filter((scene) => scene.active !== false);\n this.groupOrder = app.config?.sceneGroupOrder || [];\n\n if (this._debugVisible || this._useHash) {\n this.defaultScene = this.getSceneFromHash() || '';\n }\n if (!this.splash) {\n this.splash = { view: null, hideWhen: 'firstSceneEnter', zOrder: 'top' };\n const splash = { ...defaultSplashOptions, ...(app.config?.splash ?? {}) };\n if (splash.view) {\n this.splash.view =\n typeof splash.view === 'function' ? new (splash.view as Constructor<ISceneTransition>)() : splash.view;\n }\n this.splash.preload = splash.preload;\n }\n\n this.defaultScene = this.defaultScene || app.config?.defaultScene || this.list?.[0]?.id;\n if (!this.transition && app.config?.sceneTransition) {\n this.transition =\n typeof app.config.sceneTransition === 'function'\n ? new (app.config.sceneTransition as Constructor<ISceneTransition>)()\n : app.config.sceneTransition;\n }\n this._defaultLoadMethod = app.config.defaultSceneLoadMethod || 'immediate';\n\n if (this._debugVisible) {\n this._createDebugMenu();\n }\n if (this._useHash) {\n this._listenForHashChange();\n }\n\n this.app.onPause.connect(this._onPause, 'highest');\n this.app.onResume.connect(this._onResume, 'highest');\n\n return Promise.resolve(undefined);\n }\n\n private _onPause(config: PauseConfig) {\n this.currentScene.onPause(config);\n }\n\n private _onResume(config: PauseConfig) {\n this.currentScene.onResume(config);\n }\n\n public async loadDefaultScene(): Promise<void> {\n if (this.splash) {\n await this._showSplash();\n }\n await this.app.assets.loadRequired();\n if (this.splash.hideWhen === 'requiredAssetsLoaded') {\n await this._hideSplash();\n }\n return this.loadScene(this.defaultScene);\n }\n\n public async loadScene<K extends SceneId>(id: K, ...args: SceneLoadArgs<K>): Promise<void>;\n public async loadScene(sceneIdOrLoadSceneConfig: LoadSceneConfig | string): Promise<void>;\n\n public async loadScene(\n sceneIdOrLoadSceneConfig: LoadSceneConfig | string,\n props?: unknown,\n ): Promise<void> {\n this._pendingLoadProps = props;\n if (this._queue) {\n // An in-flight load is interrupted by the new request: cancel the queue,\n // tear down the mid-transition scene, and proceed with the new load.\n this._queue.cancel();\n this._queue = null;\n if (this.currentScene) {\n this._lastScene = this.currentScene;\n this.currentScene.destroy();\n }\n }\n\n this._lastScene = null;\n const newSceneId =\n typeof sceneIdOrLoadSceneConfig === 'string' ? sceneIdOrLoadSceneConfig : sceneIdOrLoadSceneConfig.id;\n\n const method =\n typeof sceneIdOrLoadSceneConfig === 'string'\n ? this._defaultLoadMethod\n : sceneIdOrLoadSceneConfig?.method || this._defaultLoadMethod;\n\n if (this.currentScene) {\n this._lastScene = this.currentScene;\n }\n\n // check if the scene item exists\n const sceneItem = this.list.find((scene) => scene.id === newSceneId);\n if (!sceneItem) {\n triggerViteError({ message: `Scene item not found for id ${newSceneId}` });\n throw new Error(`Scene item not found for id ${newSceneId}`);\n }\n\n if (sceneItem?.plugins?.length) {\n for (const plugin of sceneItem.plugins) {\n const pluginListItem = this.app.getUnloadedPlugin(plugin);\n if (pluginListItem) {\n await this.app.loadPlugin(pluginListItem);\n }\n }\n }\n\n this._currentSceneId = newSceneId;\n\n // found a scene item\n this._queue = createQueue(this._createCurrentScene);\n\n // Scene bundle loading currently happens inside `_loadCurrentScene` via\n // `app.assets.loadSceneAssets`, not as discrete queue steps. Queue-level\n // asset loading + per-step progress reporting is tracked as a Phase 5 DX\n // improvement (see plan/fork-plan.md §7 — scene-level progress + typed\n // route map) rather than a blocking TODO here.\n switch (method) {\n case 'exitEnter':\n this._queue.add(\n this._exitLastScene,\n this._destroyLastScene,\n this._unloadLastScene,\n this._loadCurrentScene,\n this._initializeCurrentScene,\n this._addCurrentScene,\n this._enterCurrentScene,\n this._startCurrentScene,\n );\n break;\n case 'enterExit':\n this._queue.add(\n this._loadCurrentScene,\n this._initializeCurrentScene,\n this._addCurrentScene,\n this._enterCurrentScene,\n this._startCurrentScene,\n this._destroyLastScene,\n this._unloadLastScene,\n );\n break;\n case 'enterBehind':\n this._queue.add(\n this._loadCurrentScene,\n this._initializeCurrentScene,\n this._addCurrentSceneBehind,\n this._enterCurrentScene,\n this._exitLastScene,\n this._destroyLastScene,\n this._unloadLastScene,\n this._startCurrentScene,\n );\n break;\n case 'transitionExitEnter':\n this._queue.add(\n this._showTransition,\n this._exitLastScene,\n this._destroyLastScene,\n this._unloadLastScene,\n this._loadCurrentScene,\n this._initializeCurrentScene,\n this._addCurrentScene,\n this._hideTransition,\n this._enterCurrentScene,\n this._startCurrentScene,\n );\n break;\n case 'exitTransitionEnter':\n this._queue.add(\n this._exitLastScene,\n this._showTransition,\n this._destroyLastScene,\n this._unloadLastScene,\n this._loadCurrentScene,\n this._initializeCurrentScene,\n this._addCurrentScene,\n this._hideTransition,\n this._enterCurrentScene,\n this._startCurrentScene,\n );\n break;\n case 'immediate':\n default:\n this._queue.add(\n this._destroyLastScene,\n this._unloadLastScene,\n this._loadCurrentScene,\n this._initializeCurrentScene,\n this._addCurrentScene,\n this._enterCurrentScene,\n this._startCurrentScene,\n );\n break;\n }\n\n this._queue.add(this._queueComplete);\n this._queue.start();\n }\n\n public getSceneFromHash(): string | null {\n let hash = window?.location?.hash;\n if (hash) {\n hash = hash.replace('#', '');\n if (hash.length > 0) {\n for (let i = 0; i < this.list.length; i++) {\n if (this.list[i]?.id?.toLowerCase() === hash.toLowerCase()) {\n return this.list[i].id;\n }\n }\n }\n }\n return null;\n }\n\n protected getCoreSignals(): string[] {\n return ['onSceneChangeStart', 'onSceneChangeComplete'];\n }\n\n protected getCoreFunctions(): string[] {\n return ['loadScene'];\n }\n\n private _listenForHashChange() {\n window.addEventListener('hashchange', () => {\n const sceneId = this.getSceneFromHash();\n if (sceneId) {\n void this.loadScene(sceneId);\n }\n });\n }\n\n private async _createCurrentScene() {\n const sceneItem = this.list.find((scene) => scene.id === this._currentSceneId)!;\n let SceneClass: Constructor<IScene> | undefined = undefined;\n\n if (this._sceneModules.has(this._currentSceneId)) {\n SceneClass = this._sceneModules.get(this._currentSceneId);\n } else {\n const module = await getDynamicModuleFromImportListItem(sceneItem);\n if (!module) {\n throw new Error(`Couldn't load ${this._currentSceneId}\"`);\n }\n\n if ((module as any)[this._currentSceneId]) {\n SceneClass = (module as any)[this._currentSceneId];\n } else {\n SceneClass = module;\n }\n\n if (SceneClass) {\n this._sceneModules.set(this._currentSceneId, SceneClass);\n }\n }\n\n if (!SceneClass) {\n throw new Error(`Couldn't load ${this._currentSceneId}\"`);\n }\n\n this.currentScene = new SceneClass();\n this.currentScene.id = this._currentSceneId;\n // Thread the pending load-call props onto the scene. Scenes that don't\n // declare a generic (default `Scene<void>`) just get `undefined`; scenes\n // that declare one read them via `this.props` inside `initialize()`.\n (this.currentScene as unknown as { props: unknown }).props = this._pendingLoadProps;\n this._pendingLoadProps = undefined;\n if (sceneItem?.assets) {\n this.currentScene.assets = sceneItem.assets;\n }\n if (sceneItem.autoUnloadAssets !== undefined) {\n this.currentScene.autoUnloadAssets = sceneItem.autoUnloadAssets;\n }\n\n this.currentScene.label = sceneItem.debugLabel || sceneItem.id;\n\n this.onSceneChangeStart.emit({ exiting: this._lastScene?.id || null, entering: this.currentScene.id });\n }\n\n private _queueComplete() {\n if (this.isFirstScene) {\n // background required assets\n this.app.assets.loadBackground();\n }\n this.isFirstScene = false;\n\n // load any background assets for the current scene\n void this.app.assets.loadSceneAssets(this.currentScene, true);\n\n this._lastScene = null;\n this.onSceneChangeComplete.emit({ current: this.currentScene.id });\n this._queue = null;\n return Promise.resolve();\n }\n\n private async _destroyLastScene(): Promise<void> {\n if (!this._lastScene) {\n return Promise.resolve();\n }\n this.view.removeChild(this._lastScene as any);\n this._lastScene.destroy();\n return Promise.resolve();\n }\n\n private async _exitLastScene(): Promise<void> {\n if (!this._lastScene) {\n return Promise.resolve();\n }\n await this._lastScene.exit();\n return Promise.resolve();\n }\n\n private async _loadCurrentScene(): Promise<any> {\n await this.app.assets.loadSceneAssets(this.currentScene);\n }\n\n private async _unloadLastScene(): Promise<any> {\n if (this._lastScene && this._lastScene.autoUnloadAssets) {\n return this.app.assets.unloadSceneAssets(this._lastScene);\n }\n return Promise.resolve();\n }\n\n private async _initializeCurrentScene(): Promise<void> {\n await this.currentScene.initialize();\n // wait one tick so everything in the scene has had a chance to render before triggering the resize\n this.app.ticker.addOnce(() => {\n this.currentScene.resize(this.app.size);\n });\n\n return Promise.resolve();\n }\n\n private _addCurrentScene(): Promise<void> {\n this.view.addChild(this.currentScene as any);\n return Promise.resolve();\n }\n\n private _addCurrentSceneBehind(): Promise<void> {\n this.view.addChildAt(this.currentScene as any, 0);\n return Promise.resolve();\n }\n\n private async _enterCurrentScene(): Promise<void> {\n await this.currentScene.enter();\n if (this.isFirstScene && this.splash.hideWhen === 'firstSceneEnter') {\n await this._hideSplash();\n }\n return Promise.resolve();\n }\n\n private async _startCurrentScene(): Promise<void> {\n void this.currentScene.start();\n return Promise.resolve();\n }\n\n private async _showTransition(): Promise<void> {\n if (this.isFirstScene) {\n return Promise.resolve();\n }\n if (this.transition) {\n if (!this.transition.initialized) {\n await this.transition.initialize();\n this.transition.initialized = true;\n }\n this.transition.active = true;\n this.transition.renderable = true;\n this.transition.visible = true;\n this.transition.progress = 0;\n await this.transition.enter();\n }\n }\n\n private async _hideTransition(): Promise<void> {\n if (this.isFirstScene) {\n return Promise.resolve();\n }\n if (this.transition) {\n await this.transition.exit();\n this.transition.progress = 0;\n this.transition.visible = false;\n this.transition.renderable = false;\n this.transition.active = false;\n }\n }\n\n private async _showSplash() {\n if (this.splash.preload) {\n if (this.splash.preload.assets) {\n await this.app.assets.loadAssets(this.splash.preload.assets, false);\n }\n if (this.splash.preload.bundles) {\n await this.app.assets.loadBundles(this.splash.preload.bundles, false);\n }\n }\n if (this.splash.view) {\n await this.splash.view.initialize();\n this.splash.view.resize(this.app.size);\n this.splash.view.active = true;\n this.splash.view.initialized = true;\n await this.splash.view.enter();\n }\n }\n\n private async _hideSplash(): Promise<void> {\n if (this.splash.view) {\n await this.splash.view?.exit();\n this.splash.view.active = false;\n this.splash.view.destroy();\n this.splash.view.parent?.removeChild(this.splash.view);\n this.splash.view = null;\n }\n }\n\n private _createDebugMenu() {\n this._debugMenu = document.createElement('div');\n this._debugMenu.id = 'scene-debug';\n this._debugMenu.style.cssText =\n 'position: absolute; bottom: 0; left:0; width:48px; height:48px; z-index: 1000; background-color:rgba(0,0,0,0.8); color:white; border-top-right-radius:8px;';\n const icon = document.createElement('i');\n icon.style.cssText =\n 'cursor:pointer; position:absolute;width:100%; font-style:normal; font-size:20px; top:50%; left:50%; transform:translate(-50%, -50%); text-align:center; pointer-events:none';\n icon.innerHTML = '🎬';\n this._debugMenu.appendChild(icon);\n\n (Application.containerElement || document.body).appendChild(this._debugMenu);\n\n this._sceneSelect = document.createElement('select');\n this._sceneSelect.style.cssText =\n 'padding:0; border-radius:5px; opacity:0; width:48px; height:48px; cursor:pointer';\n this._sceneSelect.value = this.defaultScene || '';\n\n const defaultOption = document.createElement('option');\n defaultOption.value = '';\n defaultOption.innerHTML = 'Select a scene';\n defaultOption.setAttribute('disabled', 'disabled');\n this._sceneSelect.appendChild(defaultOption);\n\n // create option groups\n const groups = new Map<string, HTMLOptGroupElement>();\n const groupsList: any[] = [];\n\n this.list.forEach((item) => {\n if (item.debugGroup) {\n if (!groups.has(item.debugGroup)) {\n const group = document.createElement('optgroup');\n group.label = item.debugGroup;\n groups.set(item.debugGroup, group);\n groupsList.push(group);\n // this._sceneSelect.appendChild(group);\n }\n }\n });\n\n if (groups.size > 0) {\n const nogroups = this.list.filter((item) => !item.debugGroup);\n\n if (nogroups.length) {\n const group = document.createElement('optgroup');\n group.label = 'Other';\n groups.set('Other', group);\n this._sceneSelect.appendChild(group);\n nogroups.forEach((item) => {\n item.debugGroup = 'Other';\n });\n groupsList.push(group);\n }\n }\n\n this.debugGroupsList = groupsList;\n\n this.list.sort((a, b) => {\n return a.debugOrder! - b.debugOrder!;\n });\n\n this.list.forEach((value) => {\n const option = document.createElement('option');\n option.value = value.id;\n option.innerHTML = value?.debugLabel || value.id;\n if (value.id === this.defaultScene) {\n option.selected = true;\n }\n if (value.debugGroup) {\n groups.get(value.debugGroup)?.appendChild(option);\n } else {\n this._sceneSelect.appendChild(option);\n }\n });\n\n // add groups in order\n groupsList.sort((a, b) => {\n return this.groupOrder.indexOf(a.label) - this.groupOrder.indexOf(b.label);\n });\n\n groupsList.forEach((group) => {\n this._sceneSelect.appendChild(group);\n });\n\n this._debugMenu.appendChild(this._sceneSelect);\n\n this._debugMenu.addEventListener('change', (e: Event) => {\n if (this._queue) {\n e.preventDefault();\n return;\n }\n const target = e.target as HTMLSelectElement;\n const sceneId = target.value;\n if (sceneId) {\n window.location.hash = sceneId.toLowerCase();\n }\n });\n\n this.onSceneChangeStart.connect(this._disableDebugMenu);\n this.onSceneChangeComplete.connect(this._enableDebugMenu);\n }\n\n private _enableDebugMenu() {\n this._debugMenu?.querySelector('select')?.removeAttribute('disabled');\n }\n\n private _disableDebugMenu() {\n this._debugMenu?.querySelector('select')?.setAttribute('disabled', 'disabled');\n }\n}\n","import { Signal } from '../signals';\nimport { randomUUID } from '../utils';\nimport { Logger } from '../utils/console/Logger';\nimport { IPlugin, Plugin } from './Plugin';\n\n/**\n * Configuration options for creating a timer.\n */\nexport interface TimerOptions {\n /** Duration in milliseconds. If not provided, timer counts up indefinitely */\n duration?: number;\n /** Whether to start the timer immediately upon creation */\n autoStart?: boolean;\n /** Whether to restart the timer when it completes */\n loop?: boolean;\n /** Run timer in a web worker for better performance and independence from main thread */\n useWorker?: boolean;\n /** Update interval in milliseconds for worker-based timers. Default is 16ms (roughly 60fps) */\n workerInterval?: number;\n /** Callback fired when the timer completes. Not called in count-up mode */\n onComplete?: () => void;\n /** Callback fired on each timer tick with the remaining time (or elapsed time in count-up mode) */\n onTick?: (remaining: number) => void;\n}\n\n// Web Worker message types\ninterface WorkerMessage {\n type: 'tick' | 'complete' | 'reset' | 'adjustTime';\n timerId: string;\n time: number;\n timeAdjustment?: number;\n}\n\nexport type TimeFormat = 'mm:ss' | 'hh:mm:ss' | 'ms';\nexport type TimerObject = { h: number; m: number; s: number; ms: number };\n\nfunction createTimerWorker() {\n try {\n const workerCode = `\n const timers = new Map();\n\n self.onmessage = (e) => {\n const { type, timerId, options, timeAdjustment } = e.data;\n \n switch (type) {\n case 'start': {\n let timer = timers.get(timerId);\n \n if (timer) {\n // Resume existing timer\n timer.startTime = performance.now() - (timer.pausedTime || 0);\n timer.interval = createInterval(timer, options, timerId);\n } else {\n // Create new timer\n timer = {\n startTime: performance.now(),\n duration: options.duration,\n loopCount: 0,\n pausedTime: 0,\n options // Store options with the timer\n };\n timer.interval = createInterval(timer, options, timerId);\n timers.set(timerId, timer);\n }\n break;\n }\n \n case 'stop': {\n const timer = timers.get(timerId);\n if (timer) {\n clearInterval(timer.interval);\n timer.interval = null;\n timer.pausedTime = performance.now() - timer.startTime;\n }\n break;\n }\n\n case 'reset': {\n const timer = timers.get(timerId);\n if (timer) {\n timer.startTime = performance.now();\n timer.loopCount = 0;\n timer.pausedTime = 0;\n }\n break;\n }\n\n case 'adjustTime': {\n const timer = timers.get(timerId);\n if (timer) {\n if (timer.duration !== undefined) {\n // For countdown timers, adjust the duration\n timer.duration = Math.max(0, timer.duration + timeAdjustment);\n } else {\n // For count-up timers, adjust the start time\n timer.startTime -= timeAdjustment;\n }\n }\n break;\n }\n }\n };\n\n function createInterval(timer, options, timerId) {\n return setInterval(() => {\n const currentTime = performance.now();\n const totalElapsed = currentTime - timer.startTime;\n \n if (timer.duration !== undefined) {\n // Calculate elapsed time within the current loop\n const loopElapsed = totalElapsed - (timer.loopCount * timer.duration);\n const remaining = Math.max(0, timer.duration - loopElapsed);\n \n self.postMessage({ type: 'tick', timerId, time: remaining });\n \n if (remaining <= 0) {\n self.postMessage({ type: 'complete', timerId, time: 0 });\n \n if (options.loop) {\n timer.loopCount++;\n } else {\n clearInterval(timer.interval);\n timers.delete(timerId);\n }\n }\n } else {\n self.postMessage({ type: 'tick', timerId, time: totalElapsed });\n }\n }, options.workerInterval || 16);\n }\n `;\n\n const blob = new Blob([workerCode], { type: 'application/javascript' });\n return new Worker(URL.createObjectURL(blob));\n } catch (e) {\n return null;\n }\n}\n\n/**\n * Formats a time duration in milliseconds into a human-readable string or object.\n * Supports multiple time formats and return types for flexible time representation.\n *\n * @param ms - Time duration in milliseconds to format\n * @param format - Output format for string representation\n * - 'mm:ss' (default): Minutes and seconds (e.g., \"02:30\")\n * - 'hh:mm:ss': Hours, minutes, and seconds (e.g., \"01:30:45\")\n * - 'ms': Total seconds with milliseconds (e.g., \"90.50\")\n * @param returnFormat - Determines the return type\n * - 'string' (default): Returns formatted time string\n * - 'object': Returns object with h, m, s, ms properties\n *\n * @returns Formatted time string or object containing time components\n *\n * @example\n * ```typescript\n * // Format as mm:ss string (default)\n * formatTime(150000) // \"02:30\"\n *\n * // Format as hh:mm:ss string\n * formatTime(5430000, 'hh:mm:ss') // \"01:30:30\"\n *\n * // Format as seconds with milliseconds\n * formatTime(90500, 'ms') // \"90.50\"\n *\n * // Get time components as object\n * formatTime(5430000, 'hh:mm:ss', 'object')\n * // Returns: { h: 1, m: 30, s: 30, ms: 0 }\n *\n * // Use in a game timer display\n * timer.onTick = (remaining) => {\n * display.text = formatTime(remaining, 'mm:ss');\n * };\n * ```\n */\nexport function formatTime(ms: number, format?: TimeFormat, returnFormat?: 'object'): TimerObject;\nexport function formatTime(ms: number, format?: TimeFormat, returnFormat?: 'string'): string;\n// Implementation signature\nexport function formatTime(\n ms: number,\n format: TimeFormat = 'mm:ss',\n returnFormat: 'string' | 'object' = 'string',\n): string | TimerObject {\n const totalSeconds = Math.floor(ms / 1000);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n const milliseconds = Math.floor((ms % 1000) / 10);\n\n if (returnFormat === 'string') {\n switch (format) {\n case 'hh:mm:ss':\n return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;\n case 'mm:ss':\n return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;\n case 'ms':\n return `${totalSeconds}.${milliseconds.toString().padStart(2, '0')}`;\n default:\n return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;\n }\n }\n\n return { h: hours, m: minutes, s: seconds, ms: milliseconds };\n}\n\n/**\n * A Timer instance that can count down or up, optionally running in a web worker.\n *\n * Features:\n * - Count down from a duration or count up indefinitely\n * - Run in main thread (synced with Pixi ticker) or web worker\n * - Pause, resume, and reset functionality\n * - Loop option for repeating timers\n * - Tick and completion callbacks\n *\n * @example\n * ```typescript\n * // Create a 10-second countdown timer\n * const timer = new Timer({\n * duration: 10000,\n * autoStart: true,\n * loop: true,\n * onTick: (remaining) => {\n * console.log(`${remaining / 1000} seconds remaining`);\n * },\n * onComplete: () => {\n * console.log('Timer completed!');\n * }\n * }, timerPlugin);\n *\n * // Pause the timer\n * timer.pause();\n *\n * // Resume the timer\n * timer.start();\n *\n * // Reset the timer\n * timer.reset();\n * ```\n */\nexport class Timer {\n private startTime: number = performance.now();\n private pausedTime: number = 0;\n private isPaused: boolean = true;\n private isDestroyed: boolean = false;\n private timerId: string;\n private isWorkerTimer: boolean;\n\n constructor(\n private options: TimerOptions = {},\n private plugin: TimerPlugin,\n ) {\n this.timerId = randomUUID();\n // Check if worker is requested but not available\n if (options.useWorker && !plugin.hasWorkerSupport) {\n Logger.warn('Web Worker support not available, falling back to main thread timer');\n options.useWorker = false;\n }\n this.isWorkerTimer = !!options.useWorker;\n if (options.autoStart) {\n this.start();\n }\n }\n\n /**\n * Starts or resumes the timer.\n * If the timer was paused, it will continue from where it left off.\n */\n public start(): void {\n if (!this.isPaused) return;\n this.isPaused = false;\n\n if (this.isWorkerTimer) {\n this.plugin.startWorkerTimer(this.timerId, this.options);\n } else {\n this.startTime = performance.now() - this.pausedTime;\n }\n }\n\n /**\n * Pauses the timer, maintaining its current state.\n * The timer can be resumed later from the same point.\n */\n public pause(): void {\n if (this.isPaused) return;\n this.isPaused = true;\n\n if (this.isWorkerTimer) {\n this.plugin.stopWorkerTimer(this.timerId);\n } else {\n this.pausedTime = performance.now() - this.startTime;\n }\n }\n\n /**\n * Resets the timer to its initial state.\n * If the timer is not paused, it will start running immediately after reset.\n */\n public reset(): void {\n if (this.isWorkerTimer) {\n this.plugin.resetWorkerTimer(this.timerId);\n } else {\n this.startTime = performance.now();\n this.pausedTime = 0;\n if (!this.isPaused) {\n this.start();\n }\n }\n }\n\n /**\n * Destroys the timer, cleaning up all resources.\n * A destroyed timer cannot be restarted.\n */\n public destroy(): void {\n if (this.isDestroyed) return;\n this._destroy();\n this.plugin.destroyTimer(this);\n }\n\n private _destroy(): void {\n this.isDestroyed = true;\n this.pause();\n }\n\n public update(): void {\n // Skip update for destroyed, paused, or worker timers\n if (this.isDestroyed || this.isPaused || this.isWorkerTimer) return;\n\n const currentTime = performance.now();\n const elapsed = currentTime - this.startTime;\n\n if (this.options.duration !== undefined) {\n const remaining = Math.max(0, this.options.duration - elapsed);\n\n this.options.onTick?.(remaining);\n\n if (remaining <= 0) {\n this.options.onComplete?.();\n\n if (this.options.loop) {\n this.reset();\n } else {\n this.destroy();\n }\n }\n } else {\n // Count up mode\n this.options.onTick?.(elapsed);\n }\n }\n\n /**\n * Gets the current time value (elapsed time for count-up, remaining time for countdown).\n * @returns Time in milliseconds\n */\n public getTime(): number {\n if (this.isPaused) {\n return this.pausedTime;\n }\n return performance.now() - this.startTime;\n }\n\n /**\n * Gets the remaining time for countdown timers.\n * @returns Remaining time in milliseconds, or 0 for count-up timers\n */\n public getRemainingTime(): number {\n if (!this.options.duration) return 0;\n return Math.max(0, this.options.duration - this.getTime());\n }\n\n /**\n * Gets the unique ID of this timer.\n * @returns The timer's UUID\n */\n public getId(): string {\n return this.timerId;\n }\n\n /**\n * Gets the timer's configuration options.\n * @returns The TimerOptions object used to create this timer\n */\n public getOptions(): TimerOptions {\n return this.options;\n }\n\n /**\n * Checks if this timer is running in a web worker.\n * @returns true if the timer is worker-based, false if running on main thread\n */\n public isWorker(): boolean {\n return this.isWorkerTimer;\n }\n\n /**\n * Adds time to the timer. For countdown timers, this increases the duration.\n * For count-up timers, this effectively adds time to the elapsed time.\n *\n * @param ms - Time to add in milliseconds\n * @returns The new time value after adjustment\n *\n * @example\n * ```typescript\n * // Add 5 seconds to a countdown timer\n * timer.addTime(5000);\n *\n * // Add 5 seconds to a count-up timer\n * timer.addTime(5000);\n * ```\n */\n public addTime(ms: number): number {\n if (this.isDestroyed) return 0;\n\n if (this.isWorkerTimer) {\n this.plugin.adjustWorkerTimer(this.timerId, ms);\n return this.getTime();\n }\n\n if (this.options.duration !== undefined) {\n // For countdown timers, increase the duration\n this.options.duration = Math.max(0, this.options.duration + ms);\n return this.getRemainingTime();\n } else {\n // For count-up timers, adjust the start time to add time\n this.startTime -= ms;\n return this.getTime();\n }\n }\n\n /**\n * Removes time from the timer. For countdown timers, this decreases the duration.\n * For count-up timers, this effectively removes time from the elapsed time.\n *\n * @param ms - Time to remove in milliseconds\n * @returns The new time value after adjustment\n *\n * @example\n * ```typescript\n * // Remove 5 seconds from a countdown timer\n * timer.removeTime(5000);\n *\n * // Remove 5 seconds from a count-up timer\n * timer.removeTime(5000);\n * ```\n */\n public removeTime(ms: number): number {\n return this.addTime(-ms);\n }\n}\n\n/**\n * Interface for the Timer Plugin which manages both main-thread and web worker timers.\n *\n * The Timer Plugin provides functionality for:\n * - Creating and managing countdown and count-up timers\n * - Running timers in a web worker for better performance\n * - Pausing and resuming all timers\n * - Handling timer lifecycle events\n *\n * @example\n * ```typescript\n * // Create a 5-second countdown timer\n * const countdown = this.app.timers.createTimer({\n * duration: 5000,\n * autoStart: true,\n * onTick: (remaining) => {\n * console.log(`Time remaining: ${formatTime(remaining, 'mm:ss')}`);\n * },\n * onComplete: () => {\n * console.log('Timer completed!');\n * }\n * });\n *\n * // Create a count-up timer in a web worker\n * const stopwatch = this.app.timers.createTimer({\n * useWorker: true,\n * workerInterval: 100, // Update every 100ms\n * onTick: (elapsed) => {\n * console.log(`Time elapsed: ${formatTime(elapsed, 'mm:ss')}`);\n * }\n * });\n *\n * // Pause all timers\n * this.app.timers.pauseAllTimers();\n *\n * // Resume all timers\n * this.app.timers.resumeAllTimers();\n * ```\n */\nexport interface ITimerPlugin extends IPlugin {\n /**\n * Signal emitted when a new timer is created.\n * @example\n * ```typescript\n * this.app.timers.onTimerCreated.connect((timer) => {\n * console.log(`New timer created with ID: ${timer.getId()}`);\n * });\n * ```\n */\n onTimerCreated: Signal<(timer: Timer) => void>;\n\n /**\n * Signal emitted when a timer is destroyed.\n * @example\n * ```typescript\n * this.app.timers.onTimerDestroyed.connect((timer) => {\n * console.log(`Timer destroyed: ${timer.getId()}`);\n * });\n * ```\n */\n onTimerDestroyed: Signal<(timer: Timer) => void>;\n\n /**\n * Signal emitted when all timers are paused.\n * @example\n * ```typescript\n * this.app.timers.onAllTimersPaused.connect(() => {\n * console.log('All timers paused');\n * });\n * ```\n */\n onAllTimersPaused: Signal<() => void>;\n\n /**\n * Signal emitted when all timers are resumed.\n * @example\n * ```typescript\n * this.app.timers.onAllTimersResumed.connect(() => {\n * console.log('All timers resumed');\n * });\n * ```\n */\n onAllTimersResumed: Signal<() => void>;\n\n /**\n * Creates a new timer with the specified options.\n *\n * @param options - Configuration options for the timer\n * @returns A new Timer instance\n *\n * @example\n * ```typescript\n * // Create a looping timer that runs in a web worker\n * const timer = this.app.timers.createTimer({\n * duration: 1000,\n * loop: true,\n * useWorker: true,\n * onTick: (remaining) => {\n * console.log(`${remaining}ms remaining`);\n * }\n * });\n * ```\n */\n createTimer(options?: TimerOptions): Timer;\n\n /**\n * Destroys a timer, cleaning up all resources and removing it from the plugin.\n *\n * @param timer - The timer instance to destroy\n *\n * @example\n * ```typescript\n * const timer = this.app.timers.createTimer({ duration: 5000 });\n * // ... later ...\n * this.app.timers.destroyTimer(timer);\n * ```\n */\n destroyTimer(timer: Timer): void;\n\n /**\n * Pauses all active timers, both main thread and worker timers.\n * Timers will maintain their current state and can be resumed later.\n *\n * @example\n * ```typescript\n * // Pause all timers when the game loses focus\n * window.onblur = () => {\n * this.app.timers.pauseAllTimers();\n * };\n * ```\n */\n pauseAllTimers(): void;\n\n /**\n * Resumes all paused timers, both main thread and worker timers.\n * Timers will continue from their paused state.\n *\n * @example\n * ```typescript\n * // Resume all timers when the game regains focus\n * window.onfocus = () => {\n * this.app.timers.resumeAllTimers();\n * };\n * ```\n */\n resumeAllTimers(): void;\n\n /**\n * Destroys all active timers, both main thread and worker timers .\n * This will remove all timers from the plugin and stop them.\n *\n * @example\n * ```typescript\n * this.app.timers.destroyAllTimers();\n * ```\n */\n destroyAllTimers(): void;\n\n /**\n * Resets a worker timer to its initial state.\n * This is primarily used internally by the Timer class.\n *\n * @param timerId - The ID of the worker timer to reset\n *\n * @example\n * ```typescript\n * // This is typically called internally by the Timer class\n * this.app.timers.resetWorkerTimer(timer.getId());\n * ```\n */\n resetWorkerTimer(timerId: string): void;\n\n /**\n * Adjusts the time of a worker timer.\n * This is primarily used internally by the Timer class.\n *\n * @param timerId - The ID of the worker timer to adjust\n * @param timeAdjustment - The amount of time to add (positive) or remove (negative) in milliseconds\n *\n * @example\n * ```typescript\n * // This is typically called internally by the Timer class\n * this.app.timers.adjustWorkerTimer(timer.getId(), 5000); // Add 5 seconds\n * ```\n */\n adjustWorkerTimer(timerId: string, timeAdjustment: number): void;\n}\n\nexport class TimerPlugin extends Plugin implements ITimerPlugin {\n private mainThreadTimers: Set<Timer> = new Set();\n private workerTimers: Set<Timer> = new Set();\n private isPageVisible: boolean = true;\n private worker: Worker | null = null;\n private timerCallbacks: Map<string, TimerOptions> = new Map();\n private _hasWorkerSupport: boolean = false;\n\n public get hasWorkerSupport(): boolean {\n return this._hasWorkerSupport;\n }\n\n public readonly onTimerCreated = new Signal<(timer: Timer) => void>();\n public readonly onTimerDestroyed = new Signal<(timer: Timer) => void>();\n public readonly onAllTimersPaused = new Signal<() => void>();\n public readonly onAllTimersResumed = new Signal<() => void>();\n\n constructor() {\n super('timers');\n }\n\n protected getCoreFunctions(): string[] {\n return [\n 'createTimer',\n 'destroyTimer',\n 'pauseAllTimers',\n 'resumeAllTimers',\n 'resetWorkerTimer',\n 'adjustWorkerTimer',\n ];\n }\n\n protected getCoreSignals(): string[] {\n return ['onTimerCreated', 'onTimerDestroyed', 'onAllTimersPaused', 'onAllTimersResumed'];\n }\n\n public postInitialize() {\n // Set up update loop for main thread timers only\n this.app.ticker.add(this.update);\n\n // Initialize worker if needed\n this.initWorker();\n }\n\n private initWorker(): void {\n if (typeof Worker !== 'undefined') {\n this.worker = createTimerWorker();\n if (this.worker) {\n this._hasWorkerSupport = true;\n this.worker.onmessage = this.handleWorkerMessage;\n } else {\n Logger.warn('Failed to create Web Worker for TimerPlugin, all timers will run on main thread');\n this._hasWorkerSupport = false;\n }\n } else {\n Logger.warn('Web Workers not supported in this environment, all timers will run on main thread');\n this._hasWorkerSupport = false;\n }\n }\n\n private handleWorkerMessage = (e: MessageEvent<WorkerMessage>): void => {\n const { type, timerId, time, timeAdjustment } = e.data;\n const options = this.timerCallbacks.get(timerId);\n\n if (!options) return;\n\n switch (type) {\n case 'tick':\n // Directly call onTick from the worker's interval\n options.onTick?.(time);\n break;\n case 'complete':\n options.onComplete?.();\n // Only remove callbacks if not looping\n if (!options.loop) {\n this.timerCallbacks.delete(timerId);\n }\n break;\n case 'adjustTime':\n if (timeAdjustment !== undefined) {\n if (options.duration !== undefined) {\n // For countdown timers, adjust the duration\n options.duration = Math.max(0, options.duration + timeAdjustment);\n }\n // Note: We don't need to handle count-up timers here as they're handled in the worker\n }\n break;\n }\n };\n\n public startWorkerTimer(timerId: string, options: TimerOptions): void {\n if (!this.worker) return;\n\n this.timerCallbacks.set(timerId, options);\n this.worker.postMessage({\n type: 'start',\n timerId,\n options: {\n duration: options.duration,\n loop: options.loop,\n workerInterval: options.workerInterval,\n },\n });\n }\n\n public stopWorkerTimer(timerId: string): void {\n if (!this.worker) return;\n\n this.worker.postMessage({\n type: 'stop',\n timerId,\n });\n this.timerCallbacks.delete(timerId);\n }\n\n public resetWorkerTimer(timerId: string): void {\n if (!this.worker) return;\n\n this.worker.postMessage({\n type: 'reset',\n timerId,\n });\n }\n\n public destroy(): void {\n this.app.ticker.remove(this.update);\n this.worker?.terminate();\n this.worker = null;\n this.timerCallbacks.clear();\n this.mainThreadTimers.clear();\n this.workerTimers.clear();\n super.destroy();\n }\n\n private update() {\n // Only update main thread timers\n for (const timer of this.mainThreadTimers) {\n timer.update();\n }\n }\n\n public createTimer(options?: TimerOptions): Timer {\n const timer = new Timer(options, this);\n\n // Separate management of worker and main thread timers\n if (timer.isWorker()) {\n this.workerTimers.add(timer);\n } else {\n this.mainThreadTimers.add(timer);\n }\n\n this.onTimerCreated.emit(timer);\n return timer;\n }\n\n public destroyTimer(timer: Timer): void {\n const timerSet = timer.isWorker() ? this.workerTimers : this.mainThreadTimers;\n\n if (timerSet.has(timer)) {\n timer.destroy();\n timerSet.delete(timer);\n this.onTimerDestroyed.emit(timer);\n\n if (timer.isWorker()) {\n this.stopWorkerTimer(timer.getId());\n }\n }\n }\n\n public pauseAllTimers(): void {\n // Pause both worker and main thread timers\n for (const timer of [...this.mainThreadTimers, ...this.workerTimers]) {\n timer.pause();\n }\n this.onAllTimersPaused.emit();\n }\n\n public resumeAllTimers(): void {\n // Resume both worker and main thread timers\n for (const timer of [...this.mainThreadTimers, ...this.workerTimers]) {\n timer.start();\n }\n this.onAllTimersResumed.emit();\n }\n\n public destroyAllTimers(): void {\n for (const timer of [...this.mainThreadTimers, ...this.workerTimers]) {\n this.destroyTimer(timer);\n }\n }\n\n public adjustWorkerTimer(timerId: string, timeAdjustment: number): void {\n if (!this.worker) return;\n\n this.worker.postMessage({\n type: 'adjustTime',\n timerId,\n timeAdjustment,\n });\n }\n}\n","import { Application } from '../core/Application';\nimport { Signal } from '../signals';\nimport type { Size } from '../utils';\nimport { bindAllMethods, debounce, getOrientation, type Orientation } from '../utils';\nimport type { IPlugin } from './Plugin';\nimport { Plugin } from './Plugin';\n\nexport interface IWebEventsPlugin extends IPlugin {\n onResize: Signal<(size: { width: number; height: number }) => void>;\n onVisibilityChanged: Signal<(visible: boolean) => void>;\n onOrientationChanged: Signal<\n ({ orientation, screenOrientation }: { orientation: Orientation; screenOrientation: ScreenOrientation }) => void\n >;\n}\n\n/**\n * Maintains a list of callbacks for specific web events and invokes callbacks when event occurs.\n */\nexport class WebEventsPlugin extends Plugin implements IWebEventsPlugin {\n public readonly id = 'webEvents';\n\n // signals\n public onResize: Signal<(size: Size) => void> = new Signal<(size: Size) => void>();\n public onVisibilityChanged: Signal<(visible: boolean) => void> = new Signal<(visible: boolean) => void>();\n public onOrientationChanged: Signal<\n ({ orientation, screenOrientation }: { orientation: Orientation; screenOrientation: ScreenOrientation }) => void\n > = new Signal<\n ({ orientation, screenOrientation }: { orientation: Orientation; screenOrientation: ScreenOrientation }) => void\n >();\n private _debouncedEmitVisibility = debounce((value: boolean) => {\n this.onVisibilityChanged.emit(value);\n }, 1);\n\n /**\n * Creates callback arrays and registers to web events.\n */\n constructor() {\n super();\n bindAllMethods(this);\n }\n\n get app(): Application {\n return Application.getInstance();\n }\n\n public initialize(): void {\n document.addEventListener('visibilitychange', this._onVisibilityChanged, false);\n window.addEventListener('pagehide', this._onPageHide, false);\n window.addEventListener('pageshow', this._onPageShow, false);\n window.addEventListener('resize', this._onResize);\n document.addEventListener('fullscreenchange', this._onResize);\n window.addEventListener('orientationchange', this._onOrientationChanged);\n }\n\n public destroy() {\n document.removeEventListener('visibilitychange', this._onVisibilityChanged, false);\n window.removeEventListener('resize', this._onResize);\n document.removeEventListener('fullscreenchange', this._onResize);\n window.removeEventListener('pagehide', this._onPageHide, false);\n window.removeEventListener('pageshow', this._onPageShow, false);\n }\n\n protected getCoreSignals(): string[] {\n return ['onVisibilityChanged', 'onOrientationChanged'];\n }\n\n /**\n * Called when the browser visibility changes. Passes the `hidden` flag of the document to all callbacks.\n */\n private _onVisibilityChanged(): void {\n this._emitVisibilityChanged(!document.hidden);\n }\n\n /**\n * Called when the browser resizes.\n */\n private _onResize(): void {\n const el = this.app.renderer.canvas?.parentElement;\n let screenWidth = window.innerWidth;\n let screenHeight = window.innerHeight;\n if (el && el?.getBoundingClientRect()) {\n screenWidth = el.offsetWidth;\n screenHeight = el.offsetHeight;\n }\n this.onResize.emit({ width: screenWidth, height: screenHeight });\n }\n\n /**\n * Called when the page is hidden.\n * Some browsers (like Safari) don't support the `visibilitychange` event, so we also listen for `pagehide`.\n * We're just mimicking the `visibilitychange` event here.\n */\n private _onPageHide() {\n this._emitVisibilityChanged(false);\n }\n\n /**\n * Called when the page is shown.\n * Some browsers (like Safari) don't support the `visibilitychange` event, so we also listen for `pageshow`.\n * We're just mimicking the `visibilitychange` event here.\n * @private\n */\n private _onPageShow() {\n this._emitVisibilityChanged(true);\n this._onResize();\n }\n\n private _emitVisibilityChanged(value: boolean) {\n this._debouncedEmitVisibility(value);\n }\n\n private _onOrientationChanged(e: any) {\n let orientation: Orientation | null = null;\n const screenOrientation = e?.target?.screen?.orientation;\n const screenOrientationType = screenOrientation?.type;\n\n if (screenOrientationType) {\n if (screenOrientationType.includes('landscape')) {\n orientation = 'landscape';\n } else {\n orientation = 'portrait';\n }\n this.onOrientationChanged.emit({ orientation, screenOrientation });\n return;\n }\n\n setTimeout(() => {\n orientation = getOrientation();\n this.onOrientationChanged.emit({ orientation, screenOrientation });\n }, 10);\n }\n}\n","import { gsap } from 'gsap';\nimport { Graphics, Text } from 'pixi.js';\nimport { Container } from '../display/Container';\nimport { type TextStyle, WithSignals } from '../mixins';\nimport { Signal } from '../signals';\nimport { Button } from './Button';\nimport { Toaster } from './Toaster';\n\n/**\n * Types of toasts that can be displayed, each with its own color indicator.\n */\nexport type ToastType = 'info' | 'success' | 'warning' | 'error';\n\n/**\n * Position options for the close button within a toast.\n */\nexport type CloseButtonPosition = 'top right' | 'top left';\n\n/**\n * Configuration interface for creating a Toast notification.\n *\n * @example\n * ```typescript\n * // Basic toast with default settings\n * const config: ToastConfig = {\n * message: \"Operation successful!\",\n * type: \"success\"\n * };\n *\n * // Custom styled toast with shadow and close button\n * const config: ToastConfig = {\n * message: \"Custom notification\",\n * backgroundColor: 0x9b59b6,\n * backgroundAlpha: 1,\n * cornerRadius: 8,\n * shadow: {\n * color: 0x000000,\n * alpha: 0.2,\n * offset: { x: 4, y: 4 }\n * },\n * closeButton: {\n * show: true,\n * position: 'top right'\n * }\n * };\n * ```\n */\nexport interface ToastConfig {\n /** Optional custom Toast class to use instead of the default */\n class?: typeof Toast;\n /** The message to display in the toast */\n message: string;\n /** Type of toast, determines the color indicator */\n type?: ToastType;\n /** Duration in milliseconds before auto-closing (if autoClose is true) */\n duration?: number;\n /** Custom text style options */\n style?: TextStyle;\n /** Width of the toast in pixels */\n width?: number;\n /** Height of the toast in pixels */\n height?: number;\n /** Background color in hex format */\n backgroundColor?: number;\n /** Background opacity (0-1) */\n backgroundAlpha?: number;\n /** Corner radius for rounded corners */\n cornerRadius?: number;\n /** Padding around the content */\n padding?: number;\n /** Whether the toast should automatically close after duration */\n autoClose?: boolean;\n /** Custom colors for each toast type's indicator */\n textColors?: Record<ToastType, number>;\n /** Horizontal text alignment */\n textAlign?: 'left' | 'center' | 'right';\n /** Vertical text alignment */\n verticalAlign?: 'top' | 'middle' | 'bottom';\n /** Width of the colored type indicator bar */\n colorBarWidth?: number;\n /** Shadow configuration for depth effect */\n shadow?: {\n /** Shadow color in hex format */\n color?: number;\n /** Shadow opacity (0-1) */\n alpha?: number;\n /** Shadow offset from the toast */\n offset?: { x: number; y: number };\n };\n /** Close button configuration */\n closeButton?: {\n /** Whether to show the close button */\n show?: boolean;\n /** Position of the close button */\n position?: CloseButtonPosition;\n /** Custom button class to use */\n class?: typeof Button;\n /** Size of the close button */\n size?: number;\n /** Offset from the edges */\n offset?: number;\n };\n}\n\nexport const defaultToastConfig: Partial<ToastConfig> = {\n type: 'info',\n duration: 3000,\n width: 300,\n height: 80,\n backgroundColor: 0x000000,\n backgroundAlpha: 0.8,\n cornerRadius: 0,\n padding: 10,\n autoClose: true,\n textAlign: 'center',\n verticalAlign: 'middle',\n colorBarWidth: 6,\n shadow: {\n color: 0x000000,\n alpha: 0.2,\n offset: { x: 1, y: 3 },\n },\n closeButton: {\n show: false,\n position: 'top right',\n size: 12,\n offset: 4,\n },\n style: {\n fill: 0xffffff,\n fontSize: 16,\n wordWrap: true,\n },\n textColors: {\n info: 0x3498db,\n success: 0x2ecc71,\n warning: 0xf1c40f,\n error: 0xe74c3c,\n },\n};\n\nexport class Toast extends WithSignals(Container) {\n public readonly onToastClosed = new Signal<() => void>();\n protected background: Graphics;\n protected shadow: Graphics;\n protected textDisplay: Text;\n protected closeButton?: Button;\n protected config: ToastConfig;\n protected timeline?: gsap.core.Timeline;\n protected closeTimeout?: any;\n protected isHiding: boolean = false;\n\n protected view: Container;\n\n private _toaster: Toaster;\n\n set toaster(value: Toaster) {\n this._toaster = value;\n }\n\n get toaster(): Toaster {\n return this._toaster;\n }\n\n set text(value: string) {\n this.textDisplay.text = value;\n this.alignText();\n }\n\n constructor(config: Partial<ToastConfig> = {}) {\n super();\n this.config = { ...defaultToastConfig, ...config } as ToastConfig;\n this.initialize();\n }\n\n protected initialize(): void {\n this.view = this.add.container();\n // Create shadow first so it's behind everything\n if (this.config.shadow) {\n this.shadow = this.view.add\n .graphics()\n .roundRect(\n this.config.shadow.offset?.x ?? 4,\n this.config.shadow.offset?.y ?? 4,\n this.config.width!,\n this.config.height!,\n this.config.cornerRadius!,\n )\n .fill({\n color: this.config.shadow.color ?? 0x000000,\n alpha: this.config.shadow.alpha ?? 0.2,\n });\n }\n\n // Create background\n this.background = this.view.add\n .graphics()\n .roundRect(0, 0, this.config.width!, this.config.height!, this.config.cornerRadius!)\n .fill({\n color: this.config.backgroundColor!,\n alpha: this.config.backgroundAlpha!,\n });\n\n // Create a container for the colored indicator with mask\n if (this.config.type) {\n // Create a mask with the same rounded rectangle as the background\n const mask = new Graphics()\n .roundRect(0, 0, this.config.width!, this.config.height!, this.config.cornerRadius!)\n .fill({ color: 0xffffff });\n\n // Create the colored indicator\n const indicator = this.view.add\n .graphics()\n .rect(0, 0, this.config.colorBarWidth!, this.config.height!)\n .fill({ color: this.config.textColors![this.config.type] });\n\n // Apply the mask to the indicator\n indicator.mask = mask;\n\n // Add both the mask and indicator to the container\n this.view.addChild(mask);\n this.view.addChild(indicator);\n }\n\n // Add close button if enabled\n if (this.config.closeButton?.show) {\n this.addCloseButton();\n }\n\n // Create text with adjusted padding to account for color bar and close button\n const leftPadding = this.config.type ? this.config.colorBarWidth! + this.config.padding! : this.config.padding!;\n const rightPadding =\n this.config.closeButton?.show && this.config.closeButton.position === 'top right'\n ? this.config.closeButton.size! + this.config.closeButton.offset! * 2\n : this.config.padding!;\n\n this.textDisplay = this.view.add.text({\n text: this.config.message,\n style: {\n ...defaultToastConfig.style,\n ...this.config.style,\n wordWrapWidth: this.config.style?.wordWrapWidth ?? this.config.width! - leftPadding - rightPadding,\n },\n x: leftPadding,\n y: this.config.padding!,\n });\n\n this.alignText();\n\n this.view.pivot.set(this.config.width! * 0.5, this.config.height! * 0.5);\n\n this.view.position.set(this.config.width! * 0.5, this.config.height! * 0.5);\n // Set initial state\n this.alpha = 0;\n\n this.addChild(this.view);\n }\n\n protected addCloseButton(): void {\n const ButtonClass = this.config.closeButton?.class || Button;\n const size = this.config.closeButton?.size ?? 12;\n const offset = this.config.closeButton?.offset ?? 4;\n const position = this.config.closeButton?.position ?? 'top right';\n\n this.closeButton = this.view.add.existing(\n new ButtonClass({\n cursor: 'pointer',\n }),\n );\n\n // Position the close button\n const x = position === 'top right' ? this.config.width! - size * 0.5 - offset : size * 0.5 + offset;\n const y = size * 0.5 + offset;\n\n this.closeButton.position.set(x, y);\n\n // Connect close button to hide\n this.closeButton.onClick.connect(() => {\n void this.hide();\n });\n }\n\n public alignText(): void {\n switch (this.config.textAlign) {\n case 'left':\n this.textDisplay.anchor.set(0, 0.5);\n break;\n case 'center':\n this.textDisplay.anchor.set(0.5, 0.5);\n this.textDisplay.x = this.config.width! / 2;\n break;\n case 'right':\n this.textDisplay.anchor.set(1, 0.5);\n break;\n }\n\n switch (this.config.verticalAlign) {\n case 'top':\n this.textDisplay.y = this.config.padding!;\n break;\n case 'middle':\n this.textDisplay.y = this.config.height! * 0.5;\n break;\n case 'bottom':\n this.textDisplay.y = this.config.height! - this.textDisplay.height - this.config.padding!;\n break;\n }\n }\n\n public getShowAnimation(): gsap.core.Timeline {\n const tl = gsap.timeline({ paused: true });\n tl.to(this, {\n alpha: 1,\n duration: 0.4,\n ease: 'power2.out',\n });\n\n return tl;\n }\n\n public getHideAnimation(): gsap.core.Timeline {\n const tl = gsap.timeline({ paused: true });\n tl.to(this, {\n alpha: 0,\n duration: 0.25,\n ease: 'power2.in',\n });\n\n return tl;\n }\n\n public async show(): Promise<Toast> {\n this.timeline = this.getShowAnimation();\n await this.timeline.play();\n\n if (this.config.autoClose) {\n this.closeTimeout = setTimeout(() => {\n void this.hide();\n }, this.config.duration);\n }\n return this;\n }\n\n public async hide(): Promise<Toast> {\n // Prevent multiple hide calls\n if (this.isHiding || this.destroyed) {\n return this;\n }\n this.isHiding = true;\n\n if (this.closeTimeout) {\n clearTimeout(this.closeTimeout);\n this.closeTimeout = undefined;\n }\n\n try {\n // Create a new timeline for hiding\n const tl = this.getHideAnimation();\n await tl.play();\n // Only emit if we haven't been destroyed during animation\n if (!this.destroyed) {\n this.onToastClosed.emit();\n }\n } catch (error) {\n // Handle any animation errors gracefully\n console.warn('Toast hide animation error:', error);\n if (!this.destroyed) {\n this.onToastClosed.emit();\n }\n }\n\n return this;\n }\n\n public destroy(): void {\n // Prevent any ongoing animations or timeouts\n this.isHiding = true;\n\n if (this.closeTimeout) {\n clearTimeout(this.closeTimeout);\n this.closeTimeout = undefined;\n }\n\n // Kill any active GSAP animations immediately\n gsap.killTweensOf(this);\n\n if (this.timeline) {\n this.timeline.kill();\n this.timeline = undefined;\n }\n\n // Emit close if we're being destroyed without hiding\n if (!this.destroyed && !this.isHiding) {\n this.onToastClosed.emit();\n }\n\n super.destroy({ children: true });\n }\n}\n","import { gsap } from 'gsap';\nimport { Container } from '../display/Container';\nimport { WithSignals } from '../mixins';\nimport { Signal } from '../signals';\nimport { defaultToastConfig, Toast, ToastConfig } from './Toast';\nimport { UICanvasEdge } from './UICanvas';\n\n/**\n * Configuration interface for the Toaster component, which manages toast notifications.\n *\n * @example\n * ```typescript\n * // Basic toaster in top-right corner\n * const config: ToasterConfig = {\n * position: 'top right',\n * maxToasts: 3\n * };\n *\n * // Custom toaster with specific spacing and offset\n * const config: ToasterConfig = {\n * position: 'bottom center',\n * maxToasts: 5,\n * spacing: 15,\n * offset: { x: 20, y: 30 },\n * stackDirection: 'up'\n * };\n * ```\n */\nexport interface ToasterConfig {\n /** Position of toasts relative to the screen edges */\n position?: UICanvasEdge;\n /** Maximum number of toasts to show at once */\n maxToasts?: number;\n /** Vertical spacing between toasts */\n spacing?: number;\n /** Distance from screen edges, can be a number for equal x/y or an object for different values */\n offset?: { x: number; y: number } | number;\n /** Direction in which new toasts should stack */\n stackDirection?: 'up' | 'down';\n\n animationSpeed: number;\n}\n\nconst defaultConfig: ToasterConfig = {\n position: 'bottom right',\n maxToasts: 5,\n spacing: 10,\n offset: { x: 20, y: 20 },\n stackDirection: 'up',\n animationSpeed: 1,\n};\n\n/**\n * Toaster component that manages the display and positioning of toast notifications.\n *\n * @example\n * ```typescript\n * // Create a toaster\n * const toaster = new Toaster({\n * position: 'top right',\n * maxToasts: 3\n * });\n *\n * // Show a basic toast\n * toaster.show({\n * message: \"Operation successful!\",\n * type: \"success\"\n * });\n *\n * // Show a custom toast\n * toaster.show({\n * message: \"Custom notification\",\n * backgroundColor: 0x9b59b6,\n * shadow: {\n * color: 0x000000,\n * alpha: 0.2,\n * offset: { x: 4, y: 4 }\n * }\n * });\n *\n * // Hide all toasts\n * toaster.hideAll();\n * ```\n */\nexport class Toaster extends WithSignals(Container) {\n /** Emitted when a new toast is added */\n public readonly onToastAdded = new Signal<(toast: Toast) => void>();\n /** Emitted when a toast is removed */\n public readonly onToastRemoved = new Signal<(toast: Toast) => void>();\n /** Emitted when all toasts are removed */\n public readonly onAllToastsRemoved = new Signal<() => void>();\n\n public config: ToasterConfig;\n public defaultToastConfig: Partial<ToastConfig>;\n private toasts: Toast[] = [];\n private container: Container;\n\n /**\n * Get the current number of visible toasts\n */\n public get size(): number {\n return this.toasts.length;\n }\n\n get toastPosition(): UICanvasEdge {\n return this.config.position ?? 'top right';\n }\n\n get stackDirection(): 'up' | 'down' {\n return this.config.stackDirection ?? 'up';\n }\n\n get spacing(): number {\n return this.config.spacing ?? 10;\n }\n\n get offset(): { x: number; y: number } | number {\n return this.config.offset ?? { x: 20, y: 20 };\n }\n\n get maxToasts(): number {\n return this.config.maxToasts ?? 5;\n }\n\n get toastConfig(): Partial<ToastConfig> {\n return this.defaultToastConfig ?? {};\n }\n\n /**\n * Create a new Toaster instance to manage toast notifications.\n *\n * @param config - Configuration for the Toaster's position, spacing, and behavior\n * @param defaultToastConfig - Default configuration applied to all toasts shown by this Toaster\n *\n * @example\n * ```typescript\n * // Basic toaster with default settings\n * const toaster = new Toaster();\n *\n * // Toaster with custom position and behavior\n * const toaster = new Toaster({\n * position: 'bottom center',\n * maxToasts: 3,\n * spacing: 15,\n * offset: { x: 20, y: 30 },\n * stackDirection: 'up'\n * });\n *\n * // Toaster with custom defaults for all toasts\n * const toaster = new Toaster(\n * {\n * position: 'top right',\n * maxToasts: 5\n * },\n * {\n * backgroundColor: 0x000000,\n * backgroundAlpha: 0.8,\n * cornerRadius: 8,\n * shadow: {\n * color: 0x000000,\n * alpha: 0.2,\n * offset: { x: 4, y: 4 }\n * },\n * closeButton: {\n * show: true,\n * position: 'top right'\n * }\n * }\n * );\n *\n * // The defaultToastConfig will be applied to all toasts,\n * // but can be overridden per toast:\n * toaster.show({ message: \"Uses default config\" });\n * toaster.show({\n * message: \"Custom config\",\n * backgroundColor: 0x9b59b6 // Overrides default\n * });\n * ```\n */\n constructor(config: Partial<ToasterConfig> = {}, defaultToastConfig: Partial<ToastConfig> = {}) {\n super({ autoResize: true });\n this.config = { ...defaultConfig, ...config } as ToasterConfig;\n this.defaultToastConfig = { ...defaultToastConfig } as Partial<ToastConfig>;\n this.initialize();\n this.resize();\n }\n\n protected initialize(): void {\n this.container = this.add.container();\n }\n\n /**\n * Display a new toast notification\n * @param config Configuration for the toast to display\n * @returns Promise that resolves with the created toast\n */\n public async show(\n config: Partial<ToastConfig> = this.defaultToastConfig,\n overrideDefaults: boolean = false,\n ): Promise<Toast> {\n // Remove oldest toast if we exceed max before creating new one\n if (this.size >= this.config.maxToasts!) {\n const oldestToast = this.toasts[0];\n // Wait for the hide animation to complete\n await oldestToast.hide();\n // Wait for removal to complete\n await this.removeToast(oldestToast);\n }\n\n if (!overrideDefaults && this.defaultToastConfig) {\n config = {\n ...this.defaultToastConfig,\n ...config,\n style:\n this.defaultToastConfig.style || config.style\n ? { ...(this.defaultToastConfig.style ?? {}), ...(config.style ?? {}) }\n : this.defaultToastConfig.style,\n textColors:\n this.defaultToastConfig.textColors || config.textColors\n ? { ...(this.defaultToastConfig.textColors ?? {}), ...(config.textColors ?? {}) }\n : defaultToastConfig.textColors,\n shadow:\n this.defaultToastConfig.shadow || config.shadow\n ? { ...(this.defaultToastConfig.shadow ?? {}), ...(config.shadow ?? {}) }\n : this.defaultToastConfig.shadow,\n closeButton:\n this.defaultToastConfig.closeButton || config.closeButton\n ? { ...(this.defaultToastConfig.closeButton ?? {}), ...(config.closeButton ?? {}) }\n : defaultToastConfig.closeButton,\n } as ToastConfig;\n }\n // Create new toast\n const ToastClass = config.class ?? Toast;\n const toast = new ToastClass(config);\n\n toast.toaster = this;\n\n // Add to container and array first\n this.container.addChild(toast);\n this.toasts.push(toast);\n this.positionToast(toast, this.toasts.length - 1, false);\n\n // Connect to close signal\n toast.onToastClosed.connectOnce(() => this.removeToast(toast));\n\n // Position all toasts including the new one\n this.positionToasts();\n\n // Emit signal\n this.onToastAdded.emit(toast);\n\n // Show the toast and return it\n return toast.show();\n }\n\n /**\n * Hide all currently visible toasts with animation\n * @returns Promise that resolves when all toasts are hidden\n */\n public async hideAll(): Promise<void> {\n // Create a copy of the array to avoid modification during iteration\n const toastsToHide = [...this.toasts];\n\n // Hide all toasts simultaneously\n await Promise.all(toastsToHide.map((toast) => toast.hide()));\n\n this.onAllToastsRemoved.emit();\n }\n\n /**\n * Remove all toasts (alias for hideAll)\n */\n public async removeAll(): Promise<void> {\n return this.hideAll();\n }\n\n protected async removeToast(toast: Toast): Promise<void> {\n const index = this.toasts.indexOf(toast);\n if (index === -1 || toast.destroyed) {\n return;\n }\n\n // Remove from array first\n this.toasts.splice(index, 1);\n\n // Position remaining toasts\n this.positionToasts();\n\n // Remove from container and destroy\n if (!toast.destroyed) {\n this.container.removeChild(toast);\n toast.destroy();\n }\n\n // Emit signal\n this.onToastRemoved.emit(toast);\n }\n\n /**\n * Update positions of all toasts\n * @param animate Whether to animate the position changes\n * @param skipLast Whether to skip positioning the last toast\n */\n public positionToasts(animate: boolean = true, skipLast: boolean = false): void {\n // Create a copy of the array to avoid modification during iteration\n const validToasts = this.toasts.filter(\n (toast, index) => toast && !toast.destroyed && (skipLast ? index !== this.toasts.length - 1 : true),\n );\n\n validToasts.forEach((toast, index) => {\n this.positionToast(toast, index, animate);\n });\n }\n\n /**\n * Position a single toast\n * @param toast The toast to position\n * @param index The index of the toast in the toasts array\n * @param animate Whether to animate the position changes\n */\n protected positionToast(toast: Toast, index: number, animate: boolean = true): void {\n // Early return if toast is destroyed or invalid\n if (!toast?.parent || toast.destroyed) {\n return;\n }\n\n const { position, spacing, offset, stackDirection } = this.config;\n const offsetX = typeof offset === 'number' ? offset : offset!.x;\n const offsetY = typeof offset === 'number' ? offset : offset!.y;\n let x = this.app.size.width * 0.5;\n let y = this.app.size.height * 0.5;\n\n // Calculate base position\n switch (position) {\n case 'top right':\n case 'right top':\n x += this.app.size.width * 0.5 - toast.width - offsetX;\n y -= this.app.size.height * 0.5 - offsetY;\n break;\n case 'top left':\n case 'left top':\n x -= this.app.size.width * 0.5 - offsetX;\n y -= this.app.size.height * 0.5 - offsetY;\n break;\n case 'bottom right':\n case 'right bottom':\n x += this.app.size.width * 0.5 - toast.width - offsetX;\n y += this.app.size.height * 0.5 - toast.height - offsetY;\n break;\n case 'bottom left':\n case 'left bottom':\n x -= this.app.size.width * 0.5 - offsetX;\n y += this.app.size.height * 0.5 - toast.height - offsetY;\n break;\n case 'top':\n case 'top center':\n x += -toast.width * 0.5;\n y -= this.app.size.height * 0.5 - offsetY;\n break;\n case 'bottom':\n case 'bottom center':\n x += -toast.width * 0.5;\n y += this.app.size.height * 0.5 - toast.height - offsetY;\n break;\n }\n\n // Apply stacking offset\n if (stackDirection === 'down') {\n y += index * (toast.height + spacing!);\n } else {\n y -= index * (toast.height + spacing!);\n }\n\n try {\n // Animate to position\n if (animate) {\n gsap.to(toast, {\n x,\n y,\n duration: 0.3 / this.config.animationSpeed,\n ease: 'power2.out',\n });\n } else {\n toast.position.set(x, y);\n }\n } catch (error) {\n console.warn('Error positioning toast:', error);\n }\n }\n\n /**\n * Handle window resize events\n */\n public resize(): void {\n this.position.set(-this.app.size.width * 0.5, -this.app.size.height * 0.5);\n this.positionToasts(false); // Don't animate on resize\n }\n\n public destroy(): void {\n // Kill any active GSAP animations\n this.toasts.forEach((toast) => {\n gsap.killTweensOf(toast);\n });\n\n this.hideAll();\n this.toasts = [];\n super.destroy({ children: true });\n }\n}\n","import type { LayoutOptions } from '@pixi/layout';\nimport { ContainerChild, Graphics, RenderLayer, Container as PIXIContainer, Text } from 'pixi.js';\nimport { Application } from '../core/Application';\nimport { Container } from '../display';\nimport { Factory, WithSignals } from '../mixins';\nimport type { AppTypeOverrides, Padding, PointLike, Size, SizeLike } from '../utils';\nimport {\n bindAllMethods,\n createDebugGraphics,\n createDebugLabel,\n DebugAlpha,\n DebugColors,\n ensurePadding,\n Logger,\n registerDebug,\n resolveSizeLike,\n unregisterDebug,\n} from '../utils';\nimport { FlexContainer } from './FlexContainer';\n\nexport type UICanvasEdge =\n | 'top right'\n | 'top left'\n | 'top center'\n | 'top'\n | 'bottom right'\n | 'bottom left'\n | 'bottom center'\n | 'bottom'\n | 'left top'\n | 'left bottom'\n | 'left center'\n | 'left'\n | 'right top'\n | 'right bottom'\n | 'right center'\n | 'right'\n | 'center';\n\nexport interface UICanvasChildSettings {\n align: UICanvasEdge;\n padding: Padding;\n}\n\n/** Anchor box handed to a binding's placement callback, in canvas-local space\n * (origin = canvas top-left), derived from the anchor's computed layout so it\n * never lags the render transform. */\nexport interface UICanvasBindRect {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\n/** Places a bound (free-floating) element from its anchor's rect. Both the\n * rect and the element's `position` are in canvas-local space. */\nexport type UICanvasBindFn = (rect: UICanvasBindRect, child: PIXIContainer) => void;\n\ninterface UICanvasBinding {\n child: PIXIContainer;\n anchor: PIXIContainer;\n place: UICanvasBindFn;\n}\n\nexport interface UICanvasChildProps {\n align: UICanvasEdge;\n padding: Partial<Padding> | PointLike;\n}\n\nexport type UICanvasConfig = {\n debug: boolean;\n padding: Padding;\n size: Size;\n useAppSize: boolean;\n layout?: Omit<LayoutOptions, 'target'> | null | boolean;\n autoLayoutChildren?: boolean;\n};\n\nexport const UICanvasConfigKeys: (keyof UICanvasConfig)[] = ['debug', 'padding', 'size', 'useAppSize', 'layout'];\n\nexport type UICanvasProps = {\n debug: boolean;\n padding: Partial<Padding> | PointLike;\n size?: SizeLike;\n useAppSize?: boolean;\n layout?: Omit<LayoutOptions, 'target'> | null | boolean;\n autoLayoutChildren?: boolean;\n};\n\nconst defaultLayout = {\n flexGrow: 0,\n flexShrink: 0,\n autoLayoutChildren: true,\n};\n\nconst _UICanvas = WithSignals(Factory());\n\nexport class UICanvas extends _UICanvas {\n public config: UICanvasConfig;\n protected settingsMap = new Map<PIXIContainer, UICanvasChildSettings>();\n protected _childMap = new Map<PIXIContainer, PIXIContainer>();\n protected _debugGraphics: Graphics | null = null;\n protected _debugLabel: Text | null = null;\n protected _regionLabels: Text[] = [];\n private _disableAddChildError: boolean = false;\n private _positionContainers: Map<UICanvasEdge, Container>;\n private _bindings: UICanvasBinding[] = [];\n\n public topRow: FlexContainer;\n public middleRow: FlexContainer;\n public bottomRow: FlexContainer;\n\n constructor(config: Partial<UICanvasProps>) {\n super();\n\n if (!this.app.config.useLayout) {\n throw new Error('You must set useLayout to true in your app config to use UICanvas');\n }\n\n bindAllMethods(this);\n this._positionContainers = new Map();\n this.config = {\n debug: config.debug === true,\n padding: ensurePadding(config?.padding ?? 0),\n size: config.size !== undefined ? resolveSizeLike(config.size) : { width: 0, height: 0 },\n useAppSize: config.useAppSize === true,\n autoLayoutChildren: config.autoLayoutChildren ?? true,\n };\n\n if (config.layout) {\n if (typeof config.layout === 'boolean') {\n this.config.layout = config.layout;\n } else {\n this.config.layout = { ...defaultLayout, ...config.layout };\n }\n } else {\n this.config.layout = { ...defaultLayout };\n }\n\n if (this.config.useAppSize) {\n this.config.size = this.app.size;\n }\n this.layout = {\n width: this.config.size.width,\n height: this.config.size.height,\n flexDirection: 'column',\n justifyContent: 'space-between',\n ...(typeof this.config.layout === 'object' ? this.config.layout : {}),\n };\n\n this.on('childRemoved', this._childRemoved);\n this.once('added', this._added);\n\n this.addSignalConnection(this.app.onResize.connect(this.resize));\n\n this._initializeLayout();\n this._updateLayout();\n\n if (this.config.debug) {\n registerDebug(`UICanvas:${this.uid}`, this.label || 'UICanvas', DebugColors.outerBounds);\n }\n }\n\n private _updateLayout() {\n this.app.ticker.addOnce(this.updateLayout);\n }\n\n private _initializeLayout() {\n this._disableAddChildError = true;\n // Create top row\n this.topRow = this.add.flexContainer({\n label: 'Top',\n layout: {\n width: '100%',\n height: 'auto',\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'flex-start',\n },\n });\n\n // Create middle row\n this.middleRow = this.add.flexContainer({\n label: 'Middle',\n layout: {\n width: '100%',\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n },\n });\n\n // Create bottom row\n this.bottomRow = this.add.flexContainer({\n label: 'Bottom',\n layout: {\n width: '100%',\n height: 'auto',\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'flex-end',\n },\n });\n\n this._disableAddChildError = false;\n\n // Create the 9 actual position containers\n const topLeft = this._createPositionContainer(\n this.topRow,\n {\n justifyContent: 'flex-start',\n alignItems: 'flex-start',\n flexGrow: 0,\n flexShrink: 0,\n },\n 'Left',\n );\n const topCenter = this._createPositionContainer(\n this.topRow,\n {\n justifyContent: 'center',\n alignItems: 'flex-start',\n flexGrow: 1,\n flexShrink: 0,\n },\n 'Center',\n );\n const topRight = this._createPositionContainer(\n this.topRow,\n {\n justifyContent: 'flex-end',\n alignItems: 'flex-start',\n flexGrow: 0,\n flexShrink: 0,\n },\n 'Right',\n );\n\n const middleLeft = this._createPositionContainer(\n this.middleRow,\n {\n justifyContent: 'flex-start',\n alignItems: 'center',\n flexDirection: 'row',\n flexGrow: 0,\n flexShrink: 0,\n },\n 'Left',\n );\n const center = this._createPositionContainer(\n this.middleRow,\n {\n justifyContent: 'center',\n alignItems: 'center',\n flexDirection: 'row',\n flexGrow: 1,\n flexShrink: 0,\n },\n 'Center',\n );\n const middleRight = this._createPositionContainer(\n this.middleRow,\n {\n justifyContent: 'flex-end',\n alignItems: 'center',\n flexDirection: 'row',\n flexGrow: 0,\n flexShrink: 0,\n },\n 'Right',\n );\n\n const bottomLeft = this._createPositionContainer(\n this.bottomRow,\n {\n justifyContent: 'flex-start',\n alignItems: 'flex-end',\n flexDirection: 'row',\n flexGrow: 0,\n flexShrink: 0,\n },\n 'Left',\n );\n const bottomCenter = this._createPositionContainer(\n this.bottomRow,\n {\n justifyContent: 'center',\n alignItems: 'flex-end',\n flexGrow: 1,\n flexShrink: 0,\n flexDirection: 'row',\n },\n 'Center',\n );\n const bottomRight = this._createPositionContainer(\n this.bottomRow,\n {\n justifyContent: 'flex-end',\n alignItems: 'flex-end',\n flexDirection: 'row',\n flexGrow: 0,\n flexShrink: 0,\n },\n 'Right',\n );\n\n // Map all edge variants to the appropriate containers\n this._positionContainers.set('top left', topLeft);\n this._positionContainers.set('left top', topLeft);\n\n this._positionContainers.set('top center', topCenter);\n this._positionContainers.set('top', topCenter);\n\n this._positionContainers.set('top right', topRight);\n this._positionContainers.set('right top', topRight);\n\n this._positionContainers.set('left center', middleLeft);\n this._positionContainers.set('left', middleLeft);\n this._positionContainers.set('left bottom', bottomLeft);\n\n this._positionContainers.set('center', center);\n\n this._positionContainers.set('right center', middleRight);\n this._positionContainers.set('right', middleRight);\n this._positionContainers.set('right bottom', bottomRight);\n\n this._positionContainers.set('bottom left', bottomLeft);\n\n this._positionContainers.set('bottom center', bottomCenter);\n this._positionContainers.set('bottom', bottomCenter);\n\n this._positionContainers.set('bottom right', bottomRight);\n }\n\n private _createPositionContainer(parent: FlexContainer, layout: Partial<LayoutOptions>, label: string): Container {\n const container = parent.add.container({\n layout: {\n width: 'auto',\n height: 'auto',\n ...layout,\n },\n });\n container.label = label;\n container.on('childAdded', this._updateLayout);\n container.on('childRemoved', this._updateLayout);\n container.on('layout', this._updateLayout);\n return container;\n }\n\n protected _canvasChildren: PIXIContainer[] = [];\n\n public get canvasChildren(): PIXIContainer[] {\n return this._canvasChildren;\n }\n\n /**\n * Get the application instance.\n */\n public get app(): AppTypeOverrides['App'] {\n return Application.getInstance();\n }\n\n destroy() {\n // Must be set before any child.destroy() call — PixiJS's destroy cascade\n // calls child.removeFromParent() → parent.removeChild() internally.\n this._disableAddChildError = true;\n\n // Clean up debug\n if (this.config.debug) {\n unregisterDebug(`UICanvas:${this.uid}`);\n }\n if (this._debugGraphics) {\n this._debugGraphics.destroy();\n this._debugGraphics = null;\n }\n if (this._debugLabel) {\n this._debugLabel.destroy();\n this._debugLabel = null;\n }\n for (const rl of this._regionLabels) {\n rl.destroy();\n }\n this._regionLabels = [];\n\n this.canvasChildren?.forEach((child) => {\n child.off('layout', this._updateLayout);\n });\n\n this.children.forEach((child) => {\n child.off('layout', this._updateLayout);\n });\n\n this.off('childAdded', this._updateLayout);\n this.off('childRemoved', this._updateLayout);\n\n this._positionContainers.forEach((container) => {\n container.off('childAdded', this._updateLayout);\n container.off('childRemoved', this._updateLayout);\n });\n\n this._bindings = [];\n\n super.destroy();\n }\n\n set size(value: SizeLike) {\n this.config.size = value === undefined ? { width: 0, height: 0 } : resolveSizeLike(value);\n\n this.layout = { width: this.config.size.width, height: this.config.size.height };\n\n this.updateLayout();\n }\n\n set padding(value: Partial<Padding> | PointLike) {\n this.config.padding = ensurePadding(value);\n // Update position to account for padding\n this.layout = {\n paddingLeft: this.config.padding.left,\n paddingTop: this.config.padding.top,\n paddingRight: this.config.padding.right,\n paddingBottom: this.config.padding.bottom,\n };\n this._updateLayout();\n }\n\n private static isFlexContainer(child: PIXIContainer): boolean {\n return child instanceof FlexContainer;\n }\n\n /**\n * Removes all the children from the container\n */\n public removeChildren = (beginIndex?: number, endIndex?: number): PIXIContainer[] => {\n return super.removeChildren(beginIndex, endIndex) as PIXIContainer[];\n };\n\n /**\n * Removes a child from the container at the specified index\n */\n public removeChildAt = <U extends PIXIContainer | RenderLayer>(index: number): U => {\n return super.removeChildAt(index) as U;\n };\n\n /**\n * Adds a child to the container at the specified index\n */\n public addChildAt = <U extends PIXIContainer | RenderLayer>(_child: U, _index: number): U => {\n throw new Error(\n `UICanvas: Do not call addChildAt() directly. Use addElement(child, { align }) instead.\\n` +\n `Example: uiCanvas.addElement(myChild, { align: 'top right' })`,\n );\n };\n\n /**\n * Sets the index of the child in the container\n */\n public setChildIndex = <U extends PIXIContainer>(child: U, index: number): void => {\n super.setChildIndex(child, index);\n this._updateLayout();\n };\n\n /**\n * Gets the index of a child in the container\n */\n public getChildIndex = <U extends PIXIContainer>(child: U): number => {\n return super.getChildIndex(child);\n };\n\n /**\n * Gets the child at the specified index\n */\n public getChildAt = <U extends PIXIContainer | RenderLayer>(index: number): U => {\n return super.getChildAt(index) as U;\n };\n\n public addChild<U extends (ContainerChild | RenderLayer)[]>(...children: U): U[0] {\n if (this._disableAddChildError) {\n return super.addChild(...children);\n }\n throw new Error(\n `UICanvas: Do not call addChild() directly. Use addElement(child, { align }) instead.\\n` +\n `Example: uiCanvas.addElement(myChild, { align: 'top right' })`,\n );\n }\n\n /**\n * Removes one or more children from the container\n */\n public removeChild(..._children: (PIXIContainer | RenderLayer)[]): PIXIContainer {\n if (this._disableAddChildError) {\n return super.removeChild(...(_children as PIXIContainer[]));\n }\n throw new Error(`UICanvas: Do not call removeChild() directly. Use removeElement(child) instead.`);\n }\n\n public resize() {\n if (this.config.useAppSize) {\n this.size = { width: this.app.size.width, height: this.app.size.height };\n this.position.set(-this.app.size.width * 0.5, -this.app.size.height * 0.5);\n } else {\n this._updateLayout();\n }\n }\n\n public updateLayout() {\n if (this.destroyed || !this.layout || !this.app?.renderer.layout) return;\n this.app.renderer.layout.update(this);\n\n this._positionContainers.forEach((container) => {\n this.app.renderer.layout.update(container);\n });\n\n if (this.config.useAppSize) {\n this.position.set(-this.config.size.width * 0.5, -this.config.size.height * 0.5);\n }\n\n this._updateBindings();\n\n if (this.config.debug) {\n this.app.ticker.addOnce(this.drawDebug);\n }\n }\n\n /**\n * Bind a free-floating element to a UICanvas-managed anchor without adding it\n * to the flex flow. The element is parented to the canvas as a `layout: false`\n * child (so it never re-measures a region — it can't \"shift everything left\"),\n * and `place` re-runs on every layout pass with the anchor's current box in\n * canvas-local space. Use it for popovers, tooltips, and dropdowns anchored to\n * laid-out chrome. Idempotent per child — binding the same child again replaces\n * the previous binding.\n *\n * The bound element must NOT be a `@pixi/layout` node: re-enabling `.layout` on\n * it (a layout-enabled direct child of the canvas joins the column flow and\n * bottom-docks + reflows the canvas). Position its own subtree manually.\n */\n public bindElement(child: PIXIContainer, anchor: PIXIContainer, place: UICanvasBindFn): void {\n if (child.parent !== this) {\n this._disableAddChildError = true;\n super.addChild(child);\n this._disableAddChildError = false;\n }\n child.layout = false;\n this._bindings = this._bindings.filter((b) => b.child !== child);\n this._bindings.push({ child, anchor, place });\n this._updateLayout();\n }\n\n /** Remove a binding created by `bindElement` and detach the element. */\n public unbindElement(child: PIXIContainer): void {\n const had = this._bindings.some((b) => b.child === child);\n this._bindings = this._bindings.filter((b) => b.child !== child);\n if (had && child.parent === this) {\n this._disableAddChildError = true;\n super.removeChild(child);\n this._disableAddChildError = false;\n }\n }\n\n private _updateBindings(): void {\n for (const { child, anchor, place } of this._bindings) {\n const rect = this._anchorRect(anchor);\n if (rect) place(rect, child);\n }\n }\n\n /** The anchor's box in canvas-local space, summed from the computed-layout\n * offsets up to this canvas — deterministic and free of render-transform lag\n * (the same source the debug overlay uses to draw regions). */\n private _anchorRect(anchor: PIXIContainer): UICanvasBindRect | null {\n const own = anchor.layout?.computedLayout;\n if (!own) return null;\n let left = 0;\n let top = 0;\n for (let node: PIXIContainer | null = anchor; node && node !== this; node = node.parent) {\n const cl = node.layout?.computedLayout;\n if (cl) {\n left += cl.left;\n top += cl.top;\n }\n }\n return { left, top, width: own.width, height: own.height };\n }\n\n public addElement<U extends PIXIContainer = PIXIContainer>(\n child: PIXIContainer,\n settings?: Partial<UICanvasChildProps>,\n ): U {\n const position = settings?.align ?? 'top left';\n const container = this._positionContainers.get(position);\n\n if (!container) {\n Logger.error(`UICanvas:: Invalid position \"${position}\" for element`);\n return child as U;\n }\n\n if (UICanvas.isFlexContainer(child as PIXIContainer)) {\n this.addSignalConnection((child as unknown as FlexContainer).onLayoutComplete.connect(this._updateLayout));\n }\n\n this.settingsMap.set(child, {\n align: position,\n padding: settings?.padding ? ensurePadding(settings.padding) : { top: 0, left: 0, bottom: 0, right: 0 },\n });\n\n this._childMap.set(child, container);\n this._canvasChildren = Array.from(this._childMap.keys());\n\n container.add.existing(child);\n this._childAdded(child);\n\n return child as U;\n }\n\n public removeElement(child: PIXIContainer): PIXIContainer {\n const container = this._childMap.get(child);\n if (!container) {\n throw new Error(\n `UICanvas: Cannot remove element — it was not added via addElement().\\n` +\n `Child label: \"${child.label ?? '(unlabeled)'}\"`,\n );\n }\n\n container.removeChild(child);\n child.off('layout', this._updateLayout);\n this.settingsMap.delete(child);\n this._childMap.delete(child);\n this._canvasChildren = Array.from(this._childMap.keys());\n this._updateLayout();\n return child;\n }\n\n private _childAdded(child: PIXIContainer) {\n if (this.config.autoLayoutChildren) {\n if (!child.layout) {\n child.layout = true;\n }\n if (!child.layout?.style?.width) {\n child.layout = { width: 'auto' };\n }\n if (!child.layout?.style?.height) {\n child.layout = { height: 'auto' };\n }\n }\n child.on('layout', this._updateLayout);\n Container.childAdded(child);\n this._updateLayout();\n }\n\n private _childRemoved(child: any) {\n this.settingsMap.delete(child);\n this._childMap.delete(child as PIXIContainer);\n this._canvasChildren = Array.from(this._childMap.keys());\n Container.childRemoved(child);\n }\n\n private _added() {\n this._updateLayout();\n }\n\n // --- Debug visualization ---\n get debug(): boolean {\n return this.config.debug;\n }\n\n set debug(value: boolean) {\n this.config.debug = value;\n if (value) {\n const uid = `UICanvas:${this.uid}`;\n registerDebug(uid, this.label || 'UICanvas', DebugColors.outerBounds);\n this.drawDebug();\n } else {\n unregisterDebug(`UICanvas:${this.uid}`);\n if (this._debugGraphics) {\n this._debugGraphics.clear();\n }\n if (this._debugLabel) {\n this._debugLabel.visible = false;\n }\n for (const rl of this._regionLabels) {\n rl.visible = false;\n }\n }\n }\n\n private drawDebug() {\n // Lazily create debug graphics as a child of this canvas\n if (!this._debugGraphics) {\n this._disableAddChildError = true;\n this._debugGraphics = createDebugGraphics(`${this.label ?? 'UICanvas'}:debug`);\n super.addChild(this._debugGraphics);\n this._debugGraphics.layout = false;\n this._disableAddChildError = false;\n }\n\n if (!this._debugLabel) {\n this._disableAddChildError = true;\n this._debugLabel = createDebugLabel(this.label || 'UICanvas', DebugColors.outerBounds);\n super.addChild(this._debugLabel);\n this._debugLabel.layout = false;\n this._disableAddChildError = false;\n }\n\n this._debugLabel.text = this.label || 'UICanvas';\n this._debugLabel.visible = true;\n this._debugLabel.position.set(2, 2);\n\n this._debugGraphics.clear();\n\n const w = this.config.size.width;\n const h = this.config.size.height;\n const pad = this.config.padding;\n\n // 1. Outer bounds (red)\n this._debugGraphics\n .rect(0, 0, w, h)\n .stroke({ width: 1, color: DebugColors.outerBounds, alpha: DebugAlpha.stroke, pixelLine: true });\n\n // 2. Padding areas (red subtle fill)\n if (pad.top > 0) {\n this._debugGraphics.rect(0, 0, w, pad.top).fill({ color: DebugColors.outerBounds, alpha: DebugAlpha.fill });\n }\n if (pad.bottom > 0) {\n this._debugGraphics\n .rect(0, h - pad.bottom, w, pad.bottom)\n .fill({ color: DebugColors.outerBounds, alpha: DebugAlpha.fill });\n }\n if (pad.left > 0) {\n this._debugGraphics\n .rect(0, pad.top, pad.left, h - pad.top - pad.bottom)\n .fill({ color: DebugColors.outerBounds, alpha: DebugAlpha.fill });\n }\n if (pad.right > 0) {\n this._debugGraphics\n .rect(w - pad.right, pad.top, pad.right, h - pad.top - pad.bottom)\n .fill({ color: DebugColors.outerBounds, alpha: DebugAlpha.fill });\n }\n\n // 3. Inner bounds (green)\n const innerX = pad.left;\n const innerY = pad.top;\n const innerW = w - pad.left - pad.right;\n const innerH = h - pad.top - pad.bottom;\n this._debugGraphics\n .rect(innerX, innerY, innerW, innerH)\n .stroke({ width: 1, color: DebugColors.innerBounds, alpha: DebugAlpha.stroke, pixelLine: true });\n\n // 4. 9-grid region visualization\n // Build a name map from edge → container for labeling\n const edgeNames = new Map<Container, string>();\n this._positionContainers.forEach((container, edge) => {\n // Use the shortest edge name for each unique container\n if (!edgeNames.has(container) || edge.length < edgeNames.get(container)!.length) {\n edgeNames.set(container, edge);\n }\n });\n\n const uniqueContainers = [...new Set(this._positionContainers.values())];\n\n // Ensure we have enough region labels\n while (this._regionLabels.length < uniqueContainers.length) {\n this._disableAddChildError = true;\n const rl = createDebugLabel('', DebugColors.region);\n super.addChild(rl);\n rl.layout = false;\n this._regionLabels.push(rl);\n this._disableAddChildError = false;\n }\n\n uniqueContainers.forEach((container, i) => {\n if (!container.layout?.computedLayout) return;\n const cl = container.layout.computedLayout;\n const parent = container.parent;\n if (!parent?.layout?.computedLayout) return;\n const parentCL = parent.layout.computedLayout;\n\n const rx = parentCL.left + cl.left;\n const ry = parentCL.top + cl.top;\n const rw = cl.width;\n const rh = cl.height;\n const hasChildren = container.children.length > 0;\n\n // Region fill (different alpha for occupied vs empty)\n this._debugGraphics!\n .rect(rx, ry, rw, rh)\n .fill({ color: DebugColors.region, alpha: hasChildren ? DebugAlpha.fillActive : DebugAlpha.fill })\n .stroke({ width: 1, color: DebugColors.region, alpha: 0.3, pixelLine: true });\n\n // Region label\n const rl = this._regionLabels[i];\n rl.text = edgeNames.get(container) ?? '';\n rl.visible = true;\n rl.position.set(rx + 2, ry + 2);\n });\n\n // Hide unused region labels\n for (let i = uniqueContainers.length; i < this._regionLabels.length; i++) {\n this._regionLabels[i].visible = false;\n }\n\n // 5. Center crosshairs\n const centerX = w / 2;\n const centerY = h / 2;\n this._debugGraphics\n .moveTo(centerX, centerY - 10)\n .lineTo(centerX, centerY + 10)\n .stroke({ width: 1, color: DebugColors.outerBounds, alpha: DebugAlpha.crosshair, pixelLine: true })\n .moveTo(centerX - 10, centerY)\n .lineTo(centerX + 10, centerY)\n .stroke({ width: 1, color: DebugColors.outerBounds, alpha: DebugAlpha.crosshair, pixelLine: true });\n }\n}\n","/**\n * Runtime registry for `this.add.entity(id, props)` lookups.\n *\n * The Vite plugin's entity discovery emits a `virtual:caper-entities` module\n * with static imports by default (`defaultDynamic: false` in\n * `discoverLocalClassFiles`). The `caper-runtime` virtual module pulls that\n * list onto `globalThis.Caper.entityList` before the Application starts, so\n * by the time any scene fires `initialize()` and calls `this.add.entity`,\n * the list is in place.\n *\n * This registry is populated lazily on first lookup — no explicit bootstrap\n * step needed. Entities declared with `defineEntity({ dynamic: true })` have\n * an async `module` function and are skipped: the sync factory API can't\n * wait for them. That's an intentional tradeoff — if a project needs code-\n * split entities, they use `add.existing(new Foo(...), props)` with a\n * manual lazy import instead.\n */\n\ntype EntityConstructor = new (props?: unknown) => unknown;\n\ntype EntityListItem = {\n id: string;\n active?: boolean;\n module?: EntityConstructor | (() => Promise<unknown>);\n};\n\nlet registry: Map<string, EntityConstructor> | null = null;\n\nfunction ensureRegistry(): Map<string, EntityConstructor> {\n if (registry) return registry;\n registry = new Map();\n const list: EntityListItem[] =\n (globalThis as unknown as { Caper?: { get?: (key: string) => unknown } }).Caper?.get?.(\n 'entityList',\n ) as EntityListItem[] | undefined ?? [];\n for (const item of list) {\n if (item.active === false) continue;\n if (typeof item.module === 'function' && item.module.prototype) {\n registry.set(item.id, item.module as EntityConstructor);\n }\n // Dynamic (arrow-function) modules have no prototype — skipped, since\n // `this.add.entity` is sync and can't await a dynamic import.\n }\n return registry;\n}\n\nexport function getEntityCtor(id: string): EntityConstructor | undefined {\n return ensureRegistry().get(id);\n}\n\nexport function getRegisteredEntityIds(): string[] {\n return [...ensureRegistry().keys()];\n}\n\n/**\n * Reset the registry. Test-only — production code should rely on the lazy\n * initialization from `globalThis.Caper.entityList`.\n */\nexport function _resetEntityRegistry(): void {\n registry = null;\n}\n","/**\n * Runtime registry for `this.add.ui(id, props)` lookups.\n *\n * Mirrors the entity registry pattern exactly. The Vite plugin's UI\n * discovery emits a `virtual:caper-uis` module with static imports by\n * default (`defaultDynamic: false`). The `caper-runtime` virtual module\n * pulls that list onto `globalThis.Caper.uiList` before the Application\n * starts.\n *\n * Populated lazily on first lookup — no explicit bootstrap step needed.\n */\n\ntype UIConstructor = new (props?: unknown) => unknown;\n\ntype UIListItem = {\n id: string;\n active?: boolean;\n module?: UIConstructor | (() => Promise<unknown>);\n};\n\nlet registry: Map<string, UIConstructor> | null = null;\n\nfunction ensureRegistry(): Map<string, UIConstructor> {\n if (registry) return registry;\n registry = new Map();\n const list: UIListItem[] =\n (globalThis as unknown as { Caper?: { get?: (key: string) => unknown } }).Caper?.get?.(\n 'uiList',\n ) as UIListItem[] | undefined ?? [];\n for (const item of list) {\n if (item.active === false) continue;\n if (typeof item.module === 'function' && item.module.prototype) {\n registry.set(item.id, item.module as UIConstructor);\n }\n // Dynamic (arrow-function) modules have no prototype — skipped, since\n // `this.add.ui` is sync and can't await a dynamic import.\n }\n return registry;\n}\n\nexport function getUICtor(id: string): UIConstructor | undefined {\n return ensureRegistry().get(id);\n}\n\nexport function getRegisteredUIIds(): string[] {\n return [...ensureRegistry().keys()];\n}\n\n/**\n * Reset the registry. Test-only.\n */\nexport function _resetUIRegistry(): void {\n registry = null;\n}\n","import { Assets, Graphics, Sprite, Spritesheet, Texture } from 'pixi.js';\nimport { Logger, PointLike, resolvePointLike } from '../../utils';\n\nimport { Application } from '../../core/Application';\nimport { PositionProps, ScaleProps, TextureProps } from './props';\n\nlet errorTexture: Texture | undefined;\n\nexport function resolveUnknownKeys(props: any, entity: any) {\n for (const key in props) {\n try {\n (entity as any)[key] = props[key];\n } catch (e) {\n Logger.warn(`Error setting property ${key}`, e);\n }\n }\n}\n\nexport function getErrorTexture() {\n if (!errorTexture) {\n const gfx = new Graphics();\n gfx.rect(0, 0, 100, 100);\n gfx.fill({ color: 0xff0000 });\n gfx.stroke({ color: 0xffffff, width: 1, alignment: 0 });\n // draw an X across the rectangle\n gfx.moveTo(0, 0);\n gfx.lineTo(100, 100);\n gfx.moveTo(100, 0);\n gfx.lineTo(0, 100);\n gfx.stroke({ color: 0xffffff, width: 2, alignment: 0.5 });\n errorTexture = Application.getInstance().renderer.generateTexture(gfx);\n gfx.destroy();\n }\n return errorTexture;\n}\n\nexport function resolveTexture(props?: Partial<TextureProps>): Texture {\n let texture: Texture | undefined;\n const asset = props?.asset;\n const assetAsString = asset as string;\n const sheet = props?.sheet;\n if (asset instanceof Texture) {\n texture = asset;\n } else if (!sheet || sheet?.length === 0) {\n if (Assets.cache.has(assetAsString)) {\n texture = Assets.get(assetAsString)!;\n } else if (Assets.get(assetAsString)) {\n texture = Assets.get(assetAsString).texture!;\n } else {\n Logger.error('Asset \"' + asset + '\" not loaded into Pixi cache');\n texture = getErrorTexture();\n //throw new Error('Asset \"' + asset + '\" not loaded into Pixi cache');\n }\n } else {\n if (!Assets.get(sheet)) {\n // throw new Error('Spritesheet \"' + sheet + '\" not loaded into Pixi cache');\n Logger.error('Spritesheet \"' + sheet + '\" not loaded into Pixi cache');\n return getErrorTexture();\n } else {\n const spriteSheet: Spritesheet = Assets.get(sheet) as Spritesheet;\n const textures = spriteSheet.textures;\n if (textures !== undefined) {\n // eslint-disable-next-line no-prototype-builtins\n if (textures.hasOwnProperty(assetAsString)) {\n texture = textures[assetAsString];\n } else if (spriteSheet.linkedSheets !== undefined && spriteSheet.linkedSheets.length > 0) {\n for (const linkedSheet of spriteSheet.linkedSheets) {\n // eslint-disable-next-line no-prototype-builtins\n if (linkedSheet.textures !== undefined && linkedSheet.textures.hasOwnProperty(assetAsString)) {\n texture = linkedSheet.textures[assetAsString];\n break;\n }\n }\n if (texture === undefined) {\n Logger.error(\n 'Asset \"' + asset + '\" not found inside spritesheet \"' + asset + \"' or any of its linked sheets\",\n );\n texture = getErrorTexture();\n }\n } else {\n Logger.error('Asset \"' + asset + '\" not found inside spritesheet \"' + sheet + \"'\");\n texture = getErrorTexture();\n }\n } else {\n Logger.error('Spritesheet \"' + sheet + '\" loaded but textures arent?!');\n texture = getErrorTexture();\n }\n }\n }\n return texture || new Sprite().texture;\n}\n\nexport function resolvePosition(props: Partial<PositionProps>, entity: any) {\n const pos = resolvePointLike(props.position, false, props.x, props.y);\n entity.x = pos.x;\n entity.y = pos.y;\n}\n\nexport function resolveScale(props: Partial<ScaleProps>, entity: any) {\n if (!props) {\n return;\n }\n if (props.scale === undefined) {\n if (props.scaleX === undefined && props.scaleY === undefined) {\n return;\n }\n if (props.scaleX === undefined) {\n props.scaleX = 1;\n }\n if (props.scaleY === undefined) {\n props.scaleY = 1;\n }\n }\n const scale = resolvePointLike(props.scale, false, props.scaleX, props.scaleY);\n entity.scale.set(scale.x, scale.y);\n}\n\nexport function resolveAnchor(anchor: PointLike | undefined, entity: any) {\n if (anchor !== undefined) {\n const anchorPoint = resolvePointLike(anchor);\n entity.anchor.set(anchorPoint.x, anchorPoint.y);\n }\n}\n\nexport function resolvePivot(pivot: PointLike | undefined, entity: any) {\n if (pivot !== undefined) {\n const pivotPoint = resolvePointLike(pivot);\n entity.pivot.set(pivotPoint.x, pivotPoint.y);\n }\n}\n","// Import from source files directly (not via the `../../utils` barrel) so\n// the test runtime doesn't transitively pull in display/Container → the\n// Factory mixin chain → const.ts. That cycle is fine for bundled builds\n// but breaks vitest module evaluation when the test imports from here.\nimport { omitKeys } from '../../utils/object';\nimport {\n resolveAnchor,\n resolvePivot,\n resolvePosition,\n resolveScale,\n resolveUnknownKeys,\n} from './utils';\n\n/**\n * Common prop resolvers the schema helper can apply after constructing an\n * instance. Each entry corresponds to one of the `resolveXxx` utilities and\n * reads its inputs from the raw props object — so `'position'` consumes\n * `{ position, x, y }`, `'scale'` consumes `{ scale, scaleX, scaleY }`,\n * etc.\n */\nexport type FactoryApply = 'position' | 'scale' | 'pivot' | 'anchor';\n\n/**\n * Schema describing a single factory method. Owned by the method's entry in\n * `defaultFactoryMethods`; `buildFactoryMethod` consumes it to produce a\n * typed `(props?: Props) => Instance` function with the standard\n * resolve-position / resolve-scale / resolve-pivot / resolve-anchor\n * post-construct pipeline and an automatic unknown-keys passthrough.\n *\n * The point of pushing every method through this shape is to collapse the\n * copy-paste construction boilerplate in [const.ts](./const.ts): each\n * method becomes (a) `build` — the bespoke constructor call that may\n * reshape the props before handing them to Pixi — and (b) a list of which\n * common resolvers to run. Everything else (unknowns passthrough, optional\n * props guard, etc.) is centralized.\n */\nexport interface FactorySchema<Props, Instance> {\n /**\n * Bespoke construction. Receives the raw Caper-shaped props (possibly\n * undefined) and returns a new instance. Any reshaping Caper does for DX\n * — Sprite's `{asset, sheet}` → texture resolution, Text's top-level\n * style flattening, Container's config/extras split — lives here.\n */\n build: (props: Props | undefined) => Instance;\n\n /**\n * Which common resolvers to run on the instance after `build` returns.\n * Defaults to `['position', 'scale', 'pivot']` when omitted — the lowest\n * common denominator that every display object supports. Classes with an\n * `anchor` field (Sprite, Text, AnimatedSprite, Spine) opt in to\n * `'anchor'` explicitly.\n */\n applies?: readonly FactoryApply[];\n\n /**\n * Keys the `build` callback already consumed — excluded from the\n * unknown-keys passthrough so Caper doesn't try to set them on the\n * instance a second time. For example, Sprite's schema excludes `asset`\n * and `sheet` (consumed by `resolveTexture`), Text's schema excludes\n * `text`, `roundPixels`, `resolution`, `style`, `anchor`, and `pivot`.\n */\n exclude?: readonly string[];\n}\n\nconst DEFAULT_APPLIES: readonly FactoryApply[] = ['position', 'scale', 'pivot'];\n\n/**\n * Keys automatically excluded from the unknown-keys passthrough because\n * they're either consumed by a resolver listed in `applies` or are a\n * shorthand alias for one that is. Listed here so individual schemas don't\n * have to re-declare them.\n */\nconst RESOLVER_KEYS: readonly string[] = [\n 'position',\n 'x',\n 'y',\n 'scale',\n 'scaleX',\n 'scaleY',\n 'pivot',\n 'anchor',\n];\n\n/**\n * Build a typed factory method from a schema. The return type preserves\n * the `(props?: Props) => Instance` shape TypeScript uses to drive\n * autocomplete on `this.add.*({...})` call sites.\n *\n * Behavior mirrors the hand-written factory method pattern:\n * 1. Call `schema.build(props)` to get the instance.\n * 2. If props were passed, apply each resolver in `schema.applies`\n * (position / scale / pivot / anchor).\n * 3. Forward any remaining keys to `resolveUnknownKeys` for the common\n * pass-through surface (`alpha`, `visible`, `label`, `eventMode`, etc.)\n * minus any keys the `build` callback already consumed.\n *\n * @example\n * ```ts\n * sprite: buildFactoryMethod<Partial<SpriteProps>, Sprite>({\n * build: (props) => new Sprite(props ? resolveTexture(props) : undefined),\n * applies: ['position', 'scale', 'pivot', 'anchor'],\n * exclude: ['asset', 'sheet'],\n * }),\n * ```\n */\nexport function buildFactoryMethod<Props, Instance>(\n schema: FactorySchema<Props, Instance>,\n): (props?: Props) => Instance {\n const applies = schema.applies ?? DEFAULT_APPLIES;\n const applyPosition = applies.includes('position');\n const applyScale = applies.includes('scale');\n const applyPivot = applies.includes('pivot');\n const applyAnchor = applies.includes('anchor');\n const excludeKeys = [...RESOLVER_KEYS, ...(schema.exclude ?? [])];\n\n return (props?: Props): Instance => {\n const instance = schema.build(props);\n if (props === undefined || props === null) return instance;\n\n // Post-construct resolvers. Each reads from the raw props object so the\n // schema doesn't have to pre-extract them.\n const rawProps = props as unknown as Record<string, unknown>;\n if (applyPosition) {\n resolvePosition(\n { position: rawProps.position as never, x: rawProps.x as never, y: rawProps.y as never },\n instance as unknown as object,\n );\n }\n if (applyScale) {\n resolveScale(\n {\n scale: rawProps.scale as never,\n scaleX: rawProps.scaleX as never,\n scaleY: rawProps.scaleY as never,\n },\n instance as unknown as object,\n );\n }\n if (applyPivot) {\n resolvePivot(rawProps.pivot as never, instance as unknown as object);\n }\n if (applyAnchor) {\n resolveAnchor(rawProps.anchor as never, instance as unknown as object);\n }\n\n // Forward any remaining keys via the passthrough. Excludes the keys\n // already handled by the resolvers above plus anything the schema's\n // `build` callback consumed.\n const rest = omitKeys(excludeKeys, rawProps);\n resolveUnknownKeys(rest, instance);\n return instance;\n };\n}\n","import { BitmapText, Graphics, HTMLText, Sprite, Text, TilingSprite } from 'pixi.js';\n\nimport { AnimatedSprite, Container, ContainerConfigKeys, SpineAnimation, Svg } from '../../display';\nimport { ParticleContainer, ParticleContainerConfigKeys } from '../../display/ParticleContainer';\nimport {\n Button,\n ButtonConfigKeys,\n FlexContainer,\n FlexContainerConfigKeys,\n Toaster,\n UICanvas,\n UICanvasConfigKeys,\n} from '../../ui';\nimport type { ButtonConfig, FlexContainerConfig, ToastConfig, ToasterConfig, UICanvasProps } from '../../ui';\nimport type { EntityId, EntityInstance, EntityProps, UIId, UIInstance, UIProps } from '../../utils';\nimport { pluck, resolvePointLike, Spine, WithRequiredProps } from '../../utils';\n\nimport type { EntityFactoryProps } from './props';\nimport {\n AnimatedSpriteProps,\n BitmapTextProps,\n ButtonProps,\n ContainerProps,\n ExistingProps,\n FlexContainerProps,\n GraphicsProps,\n HTMLTextProps,\n ParticleContainerProps,\n SpineProps,\n SpriteProps,\n SvgProps,\n TextProps,\n TilingSpriteProps,\n UICanvasFactoryProps,\n} from './props';\nimport { getEntityCtor, getRegisteredEntityIds } from './registry';\nimport { getUICtor, getRegisteredUIIds } from './ui-registry';\nimport { buildFactoryMethod } from './schema';\nimport {\n resolveAnchor,\n resolvePivot,\n resolvePosition,\n resolveScale,\n resolveTexture,\n resolveUnknownKeys,\n} from './utils';\n\n/**\n * Keys consumed by text-family factory builds (`text`, `htmlText`,\n * `bitmapText`). Shared here so the three schemas don't drift — each one\n * flattens `{text, style, roundPixels, resolution, anchor, pivot}` into\n * the Pixi constructor options in `build`, so all those keys must be\n * excluded from the schema's unknown-keys passthrough.\n */\nconst TEXT_CONSUMED_KEYS = ['text', 'roundPixels', 'resolution', 'style', 'anchor', 'pivot'] as const;\n\n/**\n * Factory method table consumed by the `Factory()` mixin. Almost every\n * entry is built via `buildFactoryMethod({ build, applies, exclude })`:\n * the `build` callback owns the bespoke constructor call (including any\n * DX reshaping Caper applies — asset-name resolution, text style\n * flattening, config-vs-extras splits), and the helper centralizes\n * position/scale/pivot/anchor + unknown-keys passthrough.\n *\n * The five bespoke entries (`existing`, `texture`, `svg`, `toaster`,\n * `entity`) don't fit the `(props?) → instance` shape — `existing` takes\n * `(entity, props)`, `texture` is a plain resolver re-bind, `svg` takes\n * a required `ctx` field, `toaster` takes two config objects, and\n * `entity` takes `(id, props)` with a generic narrowed to discovered\n * entity ids — so they stay hand-written.\n */\nexport const defaultFactoryMethods = {\n existing: <TEntity>(entity: TEntity, props?: Partial<ExistingProps>): TEntity => {\n if (!props) return entity;\n const { position, x, y, pivot, scale, scaleX, scaleY, ...rest } = props;\n resolvePosition({ position, x, y }, entity);\n resolveScale({ scale, scaleX, scaleY }, entity);\n resolvePivot(pivot, entity);\n resolveUnknownKeys(rest, entity);\n return entity;\n },\n\n container: buildFactoryMethod({\n build: (props?: Partial<ContainerProps>): Container =>\n new Container(props ? pluck(props, ContainerConfigKeys) : undefined),\n applies: ['position', 'scale', 'pivot'],\n exclude: ContainerConfigKeys as readonly string[],\n }),\n\n particleContainer: buildFactoryMethod({\n build: (props?: Partial<ParticleContainerProps>): ParticleContainer =>\n new ParticleContainer(props ? pluck(props, ParticleContainerConfigKeys) : undefined),\n applies: ['position', 'scale', 'pivot'],\n exclude: ParticleContainerConfigKeys as readonly string[],\n }),\n\n texture: resolveTexture,\n\n sprite: buildFactoryMethod({\n build: (props?: Partial<SpriteProps>) =>\n new Sprite(props ? resolveTexture(props) : undefined),\n applies: ['position', 'scale', 'pivot', 'anchor'],\n exclude: ['asset', 'sheet'],\n }),\n\n tilingSprite: buildFactoryMethod({\n build: (props?: Partial<TilingSpriteProps>) =>\n new TilingSprite(props ? resolveTexture(props) : undefined),\n applies: ['position', 'scale', 'pivot', 'anchor'],\n exclude: ['asset', 'sheet'],\n }),\n\n animatedSprite: buildFactoryMethod({\n // AnimatedSprite's Caper-side constructor consumes the full props bag\n // (animations, autoPlay, autoUpdate, sheet, texturePrefix, etc.), so\n // the schema's `build` just forwards them. Position/scale/pivot are\n // applied by the helper from the same object.\n build: (props?: Partial<AnimatedSpriteProps>): AnimatedSprite => new AnimatedSprite(props),\n applies: ['position', 'scale', 'pivot'],\n exclude: [\n 'sheet',\n 'texturePrefix',\n 'zeroPad',\n 'animations',\n 'autoPlay',\n 'autoUpdate',\n 'defaultAnimation',\n 'reversible',\n 'animationSpeed',\n 'startIndex',\n 'animation',\n ],\n }),\n\n graphics: buildFactoryMethod({\n build: (_props?: Partial<GraphicsProps>) => new Graphics(),\n applies: ['position', 'scale', 'pivot'],\n }),\n\n svg(props: WithRequiredProps<SvgProps, 'ctx'>) {\n const entity = new Svg(props.ctx);\n const { position, x, y, pivot, scale, scaleX, scaleY, ctx: _ctx, ...rest } = props;\n resolvePosition({ position, x, y }, entity);\n resolveScale({ scale, scaleX, scaleY }, entity);\n resolvePivot(pivot, entity);\n resolveUnknownKeys(rest, entity);\n return entity;\n },\n\n text: buildFactoryMethod({\n // Text flattens Pixi's nested `style: {...}` into top-level props for\n // DX (e.g. `{fontFamily, fontSize, fill}` without the `style:` wrapper\n // — see TextStyle type in props.ts). The build callback rebuilds the\n // Pixi-shape options object, including `anchor`/`pivot` pre-resolved\n // via `resolvePointLike(..., true)` the way the hand-written method\n // did. Post-construct resolvers handle position/scale/pivot.\n build: (props?: Partial<TextProps>) =>\n new Text(\n props\n ? {\n text: props.text,\n roundPixels: props.roundPixels,\n resolution: props.resolution,\n style: props.style,\n anchor: props.anchor ? resolvePointLike(props.anchor, true) : undefined,\n pivot: props.pivot ? resolvePointLike(props.pivot, true) : undefined,\n }\n : {},\n ),\n applies: ['position', 'scale', 'pivot'],\n exclude: [...TEXT_CONSUMED_KEYS],\n }),\n\n htmlText: buildFactoryMethod({\n build: (props?: Partial<HTMLTextProps>) =>\n new HTMLText(\n props\n ? {\n text: props.text,\n roundPixels: props.roundPixels,\n resolution: props.resolution,\n style: props.style,\n anchor: props.anchor ? resolvePointLike(props.anchor, true) : undefined,\n pivot: props.pivot ? resolvePointLike(props.pivot, true) : undefined,\n }\n : {},\n ),\n applies: ['position', 'scale', 'pivot'],\n exclude: [...TEXT_CONSUMED_KEYS],\n }),\n\n bitmapText: buildFactoryMethod({\n // BitmapText's ctor doesn't take `resolution` — that's the only field\n // that differs from Text/HTMLText here.\n build: (props?: Partial<BitmapTextProps>) =>\n new BitmapText(\n props\n ? {\n text: props.text,\n roundPixels: props.roundPixels,\n style: props.style,\n anchor: props.anchor ? resolvePointLike(props.anchor, true) : undefined,\n pivot: props.pivot ? resolvePointLike(props.pivot, true) : undefined,\n }\n : {},\n ),\n applies: ['position', 'scale', 'pivot'],\n exclude: [...TEXT_CONSUMED_KEYS],\n }),\n\n button: buildFactoryMethod({\n build: (props?: Partial<ButtonProps>): Button =>\n new Button((props ? pluck(props, ButtonConfigKeys) : undefined) as Partial<ButtonConfig>),\n applies: ['position', 'scale', 'pivot'],\n exclude: ButtonConfigKeys as readonly string[],\n }),\n\n flexContainer: buildFactoryMethod({\n // FlexContainer takes the full props bag (minus position/scale/pivot)\n // as its constructor config — historical: the hand-written method\n // passed `props as Partial<FlexContainerConfig>` directly rather than\n // plucking FlexContainerConfigKeys. Preserving that shape.\n build: (props?: Partial<FlexContainerProps>): FlexContainer =>\n new FlexContainer(props as Partial<FlexContainerConfig>),\n applies: ['position', 'scale', 'pivot'],\n exclude: FlexContainerConfigKeys as readonly string[],\n }),\n\n uiCanvas: buildFactoryMethod({\n build: (props?: Partial<UICanvasFactoryProps>): UICanvas =>\n // UICanvas's ctor takes Partial<UICanvasProps>, which is a superset\n // of UICanvasConfig — the pluck narrows, so cast back.\n new UICanvas(props ? (pluck(props, UICanvasConfigKeys) as Partial<UICanvasProps>) : ({} as Partial<UICanvasProps>)),\n applies: ['position', 'scale', 'pivot'],\n exclude: UICanvasConfigKeys as readonly string[],\n }),\n\n spine: buildFactoryMethod({\n build: (props?: Partial<SpineProps>): Spine => {\n // Resolve Caper's `{data: 'spine/foo'}` shorthand into the Pixi\n // `{skeleton, atlas}` pair expected by Spine.from().\n let spineData: { skeleton: string; atlas: string } | string = '';\n const data = props?.data;\n if (typeof data === 'string') {\n // If the asset name is missing an extension, default to .json. If\n // it has one, strip it so we can re-append both skeleton + atlas\n // paths from the base name.\n let ext = data.slice(-5);\n if (ext !== '.json' && ext !== '.skel') {\n ext = '.json';\n } else {\n spineData = data.substring(0, data.length - 5);\n }\n spineData = { skeleton: data + ext, atlas: data + '.atlas' };\n }\n const entity: Spine = (window as unknown as { Spine: { from: (d: unknown) => Spine } }).Spine.from(\n spineData,\n );\n // Spine-specific post-construct setup. Has to happen here (not in\n // `applies`) because the helper doesn't know about spine state.\n if (props?.autoUpdate !== undefined) entity.autoUpdate = props.autoUpdate;\n if (props?.animationName) {\n entity.state.setAnimation(props.trackIndex ?? 0, props.animationName, props.loop);\n }\n return entity;\n },\n applies: ['position', 'scale', 'pivot', 'anchor'],\n exclude: ['data', 'autoUpdate', 'animationName', 'trackIndex', 'loop'],\n }),\n\n spineAnimation: <ANames extends string = string>(\n props?: Partial<SpineProps>,\n ): SpineAnimation<ANames> => {\n // Hand-written rather than schema-driven because `buildFactoryMethod`\n // can't carry the `<ANames>` generic through to the call site —\n // kitchen-sink's SpineScene narrows the animation-name union via\n // `this.add.spineAnimation<CharacterAnimations>({...})`, which\n // requires the method itself to declare the generic.\n const entity = new SpineAnimation<ANames>(props);\n if (!props) return entity;\n const { position, x, y, anchor, pivot, scale, scaleX, scaleY, ...rest } = props;\n resolvePosition({ position, x, y }, entity);\n resolveScale({ scale, scaleX, scaleY }, entity);\n resolveAnchor(anchor, entity);\n resolvePivot(pivot, entity);\n resolveUnknownKeys(rest, entity);\n return entity;\n },\n\n toaster: (toasterConfig?: Partial<ToasterConfig>, defaultToastConfig: Partial<ToastConfig> = {}): Toaster => {\n return new Toaster(toasterConfig, defaultToastConfig);\n },\n\n /**\n * Construct an entity from the auto-discovered registry. `id` is narrowed\n * to the union of entity ids declared under `src/entities/` (see the\n * generated `caper-app.d.ts`), and `props` is typed from the entity's\n * constructor signature via `ConstructorParameters<typeof Entity>[0]`.\n *\n * Throws if `id` isn't registered. Discovery runs at build time, so the\n * only way to hit this at runtime is a stale virtual module — fail loud\n * and list the known ids so the user can see what's wrong.\n *\n * @example\n * this.add.entity('actor', { color: 0xff0000, x: 50, y: 100 });\n */\n entity: <K extends EntityId>(\n id: K,\n props?: EntityProps<K> & EntityFactoryProps,\n ): EntityInstance<K> => {\n const Ctor = getEntityCtor(id as string);\n if (!Ctor) {\n const known = getRegisteredEntityIds();\n throw new Error(\n `[caper] Unknown entity id '${String(id)}'. ` +\n `Known: ${known.length > 0 ? known.map((k) => `'${k}'`).join(', ') : '(none — discovery may have failed)'}`,\n );\n }\n const instance = new (Ctor as new (props?: EntityProps<K>) => EntityInstance<K>)(props);\n if (props) {\n const { position, x, y, pivot, scale, scaleX, scaleY, alpha, visible } = props as EntityFactoryProps;\n resolvePosition({ position, x, y }, instance);\n resolveScale({ scale, scaleX, scaleY }, instance);\n resolvePivot(pivot, instance);\n if (alpha !== undefined) (instance as unknown as { alpha: number }).alpha = alpha;\n if (visible !== undefined) (instance as unknown as { visible: boolean }).visible = visible;\n }\n return instance;\n },\n\n /**\n * Construct a UI element from the auto-discovered registry. `id` is\n * narrowed to the union of UI ids declared under `src/ui/` (see the\n * generated `caper-app.d.ts`), and `props` is typed from the UI\n * element's constructor signature via `ConstructorParameters<...>[0]`.\n *\n * @example\n * this.add.ui('close-button', { x: 100, y: 50 });\n */\n ui: <K extends UIId>(\n id: K,\n props?: UIProps<K> & EntityFactoryProps,\n ): UIInstance<K> => {\n const Ctor = getUICtor(id as string);\n if (!Ctor) {\n const known = getRegisteredUIIds();\n throw new Error(\n `[caper] Unknown ui id '${String(id)}'. ` +\n `Known: ${known.length > 0 ? known.map((k) => `'${k}'`).join(', ') : '(none — discovery may have failed)'}`,\n );\n }\n const instance = new (Ctor as new (props?: UIProps<K>) => UIInstance<K>)(props);\n if (props) {\n const { position, x, y, pivot, scale, scaleX, scaleY, alpha, visible } = props as EntityFactoryProps;\n resolvePosition({ position, x, y }, instance);\n resolveScale({ scale, scaleX, scaleY }, instance);\n resolvePivot(pivot, instance);\n if (alpha !== undefined) (instance as unknown as { alpha: number }).alpha = alpha;\n if (visible !== undefined) (instance as unknown as { visible: boolean }).visible = visible;\n }\n return instance;\n },\n};\n","import { Container as PIXIContainer } from 'pixi.js';\nimport { defaultFactoryMethods } from './index';\nimport { createFactoryMethods } from './methods';\n\nexport interface IFactory<T extends typeof defaultFactoryMethods = typeof defaultFactoryMethods> extends PIXIContainer {\n add: T;\n make: T;\n}\n\nexport function Factory<T extends typeof defaultFactoryMethods = typeof defaultFactoryMethods>(\n extensions?: Partial<T>,\n): new () => IFactory<T> {\n return class ExtendedContainer extends PIXIContainer implements IFactory<T> {\n add: T;\n make: T;\n\n constructor() {\n super();\n extensions = Object.assign(defaultFactoryMethods, extensions);\n this.make = createFactoryMethods(extensions, this, false);\n this.add = createFactoryMethods(extensions, this, true);\n }\n };\n}\n","import type { ImportList } from '../utils';\nimport { AssetsPlugin } from './AssetsPlugin';\nimport { FullScreenPlugin } from './FullScreenPlugin';\nimport { KeyboardPlugin } from './KeyboardPlugin';\nimport { LookupPlugin } from './LookupPlugin';\nimport type { IPlugin } from './Plugin';\nimport { PopupManagerPlugin } from './PopupManagerPlugin';\nimport { ResizerPlugin } from './ResizerPlugin';\nimport { SceneManagerPlugin } from './SceneManagerPlugin';\nimport { TimerPlugin } from './TimerPlugin';\nimport { WebEventsPlugin } from './WebEventsPlugin';\nimport { ActionsPlugin } from './actions';\nimport { AudioManagerPlugin } from './audio';\nimport { BreakpointPlugin } from './breakpoints';\nimport { FocusManagerPlugin } from './focus';\nimport { GesturePlugin } from './gesture';\nimport { i18nPlugin } from './i18nPlugin';\nimport { InputPlugin } from './input';\n\nexport const defaultPlugins: ImportList<IPlugin> = [\n {\n id: 'lookup',\n module: LookupPlugin,\n namedExport: 'LookupPlugin',\n },\n {\n id: 'webEvents',\n module: WebEventsPlugin,\n namedExport: 'WebEventsPlugin',\n },\n {\n id: 'fullscreen',\n module: FullScreenPlugin,\n namedExport: 'FullScreenPlugin',\n },\n {\n id: 'resizer',\n module: ResizerPlugin,\n namedExport: 'ResizerPlugin',\n },\n {\n id: 'breakpoints',\n module: BreakpointPlugin,\n namedExport: 'BreakpointPlugin',\n },\n {\n id: 'assets',\n module: AssetsPlugin,\n namedExport: 'AssetsPlugin',\n },\n {\n id: 'scenes',\n module: SceneManagerPlugin,\n namedExport: 'SceneManagerPlugin',\n },\n {\n id: 'actions',\n module: ActionsPlugin,\n namedExport: 'ActionsPlugin',\n },\n {\n id: 'input',\n module: InputPlugin,\n namedExport: 'InputPlugin',\n },\n {\n id: 'gesture',\n module: GesturePlugin,\n namedExport: 'GesturePlugin',\n },\n {\n id: 'keyboard',\n module: KeyboardPlugin,\n namedExport: 'KeyboardPlugin',\n },\n {\n id: 'focus',\n module: FocusManagerPlugin,\n namedExport: 'FocusManagerPlugin',\n },\n {\n id: 'popups',\n module: PopupManagerPlugin,\n namedExport: 'PopupManagerPlugin',\n },\n {\n id: 'audio',\n module: AudioManagerPlugin,\n namedExport: 'AudioManagerPlugin',\n },\n {\n id: 'i18n',\n module: i18nPlugin,\n namedExport: 'i18nPlugin',\n },\n {\n id: 'timers',\n module: TimerPlugin,\n namedExport: 'TimerPlugin',\n },\n] as const;\n","import { gsap } from 'gsap';\nimport type {\n AppConfig,\n IApplication,\n IApplicationOptions,\n ICaperAutomation,\n ICoreFunctions,\n ICoreSignals,\n PauseConfig,\n} from '.';\nimport { coreFunctionRegistry, coreSignalRegistry, generatePluginList, sortPluginsByRequires } from '.';\nimport type {\n ActionSignal,\n AppScenes,\n IAssetsPlugin,\n IAudioManagerPlugin,\n IBreakpointPlugin,\n IControls,\n IFocusManagerPlugin,\n Ii18nPlugin,\n IInputPlugin,\n IKeyboardPlugin,\n IPlugin,\n IPopupManagerPlugin,\n IResizerPlugin,\n ISceneManagerPlugin,\n IWebEventsPlugin,\n LoadSceneConfig,\n} from '../plugins';\n\nimport type {\n AssetInitOptions,\n AssetsManifest,\n DestroyOptions,\n RendererDestroyOptions,\n} from 'pixi.js';\nimport { Assets, Container as PIXIContainer, isMobile, Application as PIXIPApplication, Point, TextStyle } from 'pixi.js';\nimport type { IDataAdapter } from '../plugins/DataAdapter';\nimport type { IStore } from '../store';\nimport { Store } from '../store';\nimport type {\n AppTypeOverrides,\n Eases,\n ImportList,\n ImportListItem,\n SceneId,\n SceneLoadArgs,\n Size,\n} from '../utils';\nimport { bindAllMethods, deepMerge, getDynamicModuleFromImportListItem, isDev, isPromise, Logger } from '../utils';\nimport { triggerViteError } from '../utils/vite';\n\nimport { createFactoryMethods, defaultFactoryMethods } from '../mixins';\nimport type { IActionsPlugin } from '../plugins/actions';\nimport type { IVoiceOverPlugin } from '../plugins/audio/VoiceOverPlugin';\nimport type { ICaptionsPlugin } from '../plugins/captions';\nimport { defaultPlugins } from '../plugins/defaults';\nimport { type IDevToolsPlugin } from '../plugins/DevToolsPlugin';\nimport { IFullScreenPlugin } from '../plugins/FullScreenPlugin';\nimport { type IGSAPPlugin } from '../plugins/GSAPPlugin';\nimport { ILookupPlugin } from '../plugins/LookupPlugin';\nimport { ITimerPlugin } from '../plugins/TimerPlugin';\nimport { Signal } from '../signals';\n\ntype App = AppTypeOverrides['App'];\ntype AppContexts = AppTypeOverrides['Contexts'];\ntype AppActions = AppTypeOverrides['Actions'];\ntype AppPlugins = AppTypeOverrides['Plugins'];\n\nfunction getDefaultResolution() {\n return typeof window !== 'undefined' ? (window.devicePixelRatio > 1 ? 2 : 1) : 2;\n}\n\nconst defaultApplicationOptions: Partial<IApplicationOptions> = {\n antialias: false,\n autoStart: true,\n resizeToContainer: true,\n backgroundColor: 0x0,\n backgroundAlpha: 1,\n clearBeforeRender: false,\n context: null,\n eventFeatures: undefined,\n eventMode: undefined,\n hello: false,\n powerPreference: 'high-performance',\n premultipliedAlpha: false,\n preserveDrawingBuffer: false,\n resizeTo: undefined,\n sharedTicker: true,\n view: undefined,\n autoDensity: false,\n defaultTextStyle: {\n fontFamily: 'Arial',\n fontSize: 20,\n fontWeight: 'normal',\n fontStyle: 'normal',\n align: 'left',\n breakWords: false,\n fill: 0,\n fontVariant: 'normal',\n leading: 0,\n letterSpacing: 0,\n lineHeight: 0,\n padding: 0,\n stroke: undefined,\n textBaseline: 'alphabetic',\n trim: false,\n whiteSpace: 'pre',\n wordWrap: false,\n wordWrapWidth: 100,\n },\n resolution: getDefaultResolution(), // must be 1 or 2\n useHash: isDev,\n showSceneDebugMenu: isDev,\n showStats: isDev,\n useStore: true,\n useSpine: false,\n useLayout: false,\n useVoiceover: false,\n plugins: [],\n scenes: [],\n defaultSceneLoadMethod: 'immediate',\n assets: {\n manifest: './assets.json',\n },\n};\n\nconst defaultPauseConfig: PauseConfig = {\n pauseAudio: false,\n pauseAnimations: false,\n pauseTicker: false,\n pauseTimers: false,\n};\n\nexport class Application extends PIXIPApplication implements IApplication {\n // static properties\n public static containerElement: HTMLElement;\n\n // singleton instance\n public static instance: IApplication;\n\n // method binding root\n private static readonly __caper_method_binding_root = true;\n\n // debug overlay (lazy, see getter)\n private _debugContainer: PIXIContainer;\n\n // config\n public config: Partial<IApplicationOptions>;\n /**\n * Automation facade for Playwright / agent drivers. Only assigned when\n * automation is enabled (dev env, `config.automation === true`, or\n * `VITE_CAPER_AUTOMATION === 'true'`); otherwise undefined.\n */\n public automation?: ICaperAutomation;\n public plugins: ImportList<IPlugin>;\n public manifest: string | AssetsManifest | undefined;\n public onPause = new Signal<(config: PauseConfig) => void>();\n public onResume = new Signal<(config: PauseConfig) => void>();\n // signals\n public onResize = new Signal<(size: Size) => void>();\n /**\n * Emitted when a plugin throws during initialize/postInitialize. Previously\n * these failures bricked the app silently.\n */\n public onPluginError = new Signal<\n (detail: { id: string; phase: 'initialize' | 'postInitialize'; error: unknown }) => void\n >();\n // plugins\n public readonly _plugins: Map<string, IPlugin> = new Map();\n // default plugins\n protected _assetManager: IAssetsPlugin;\n protected _lookup: ILookupPlugin;\n protected _sceneManager: ISceneManagerPlugin;\n protected _webEventsManager: IWebEventsPlugin;\n protected _fullScreenPlugin: IFullScreenPlugin;\n protected _keyboardManager: IKeyboardPlugin;\n protected _focusManager: IFocusManagerPlugin;\n protected _popupManager: IPopupManagerPlugin;\n protected _timerPlugin: ITimerPlugin;\n protected _audioManager: IAudioManagerPlugin;\n protected _voiceoverPlugin: IVoiceOverPlugin;\n protected _captionsPlugin: ICaptionsPlugin;\n protected _actions: ActionSignal;\n protected _isBooting: boolean = true;\n\n protected _env: Record<string, string> = (import.meta as any).env || {};\n protected _makeFactory: typeof defaultFactoryMethods;\n\n protected _isFullScreen: boolean = false;\n protected _fullScreenElement: HTMLElement | Window | null = null;\n\n get make(): typeof defaultFactoryMethods {\n if (!this._makeFactory) {\n this._makeFactory = createFactoryMethods(defaultFactoryMethods, this, false);\n }\n return this._makeFactory;\n }\n\n get env() {\n return this._env;\n }\n\n get debugContainer(): PIXIContainer {\n if (!this._debugContainer) {\n this._debugContainer = new PIXIContainer();\n this._debugContainer.label = 'DebugOverlay';\n this._debugContainer.eventMode = 'none';\n this._debugContainer.interactiveChildren = false;\n this.stage.addChild(this._debugContainer);\n }\n return this._debugContainer;\n }\n\n protected _paused: boolean = false;\n protected _pauseConfig: Partial<PauseConfig> = {};\n\n public get paused(): boolean {\n return this._paused;\n }\n\n public pause(config?: Partial<PauseConfig>) {\n this._paused = true;\n this._pauseConfig = { ...defaultPauseConfig, ...config };\n if (config?.pauseAudio) {\n this.audio.pause();\n }\n if (config?.pauseAnimations) {\n gsap?.globalTimeline?.pause();\n }\n if (config?.pauseTicker) {\n this.ticker.stop();\n }\n if (config?.pauseTimers) {\n this.timers.pauseAllTimers();\n }\n if (config?.pauseOther) {\n config.pauseOther.forEach((thing) => {\n if (typeof thing?.pause === 'function') {\n thing.pause();\n }\n });\n }\n this.onPause.emit(this._pauseConfig);\n }\n\n public resume() {\n this._paused = false;\n if (this._pauseConfig.pauseAudio) {\n if (this.audio.paused) {\n this.audio.resume();\n }\n }\n if (this._pauseConfig.pauseAnimations) {\n if (gsap?.globalTimeline?.paused()) {\n gsap?.globalTimeline?.resume();\n }\n }\n if (this._pauseConfig.pauseTicker) {\n if (!this.ticker.started) {\n this.ticker.start();\n }\n }\n if (this._pauseConfig.pauseTimers) {\n this.timers.resumeAllTimers();\n }\n if (this._pauseConfig.pauseOther) {\n this._pauseConfig.pauseOther.forEach((thing) => {\n if (typeof thing?.resume === 'function') {\n thing.resume();\n }\n });\n }\n if (this._pauseConfig.clearOnResume) {\n this._pauseConfig = {};\n }\n this.onResume.emit(this._pauseConfig);\n }\n\n public togglePause(config?: Partial<PauseConfig>) {\n this._paused = !this._paused;\n if (this._paused) {\n this.pause(config);\n } else {\n this.resume();\n }\n }\n\n constructor() {\n super();\n bindAllMethods(this);\n }\n\n protected _appVersion: string | number;\n\n public get appVersion() {\n try {\n this._appVersion = __CAPER_APP_VERSION;\n } catch (e) {\n this._appVersion = -1;\n }\n\n return this._appVersion;\n }\n\n protected _appName: string;\n\n public get appName(): string {\n if (!this._appName) {\n try {\n this._appName = __CAPER_APP_NAME;\n } catch (e) {\n this._appName = 'n/a';\n }\n }\n return this._appName;\n }\n\n protected _i18n: Ii18nPlugin;\n\n public get i18n(): Ii18nPlugin {\n if (!this._i18n) {\n this._i18n = this.getPlugin<Ii18nPlugin>('i18n');\n }\n return this._i18n;\n }\n\n protected _resizer: IResizerPlugin;\n\n public get resizer(): IResizerPlugin {\n if (!this._resizer) {\n this._resizer = this.getPlugin<IResizerPlugin>('resizer');\n }\n return this._resizer;\n }\n\n protected _breakpoints: IBreakpointPlugin;\n\n public get breakpoints(): IBreakpointPlugin {\n if (!this._breakpoints) {\n this._breakpoints = this.getPlugin<IBreakpointPlugin>('breakpoints');\n }\n return this._breakpoints;\n }\n\n // actions\n protected _actionsPlugin: IActionsPlugin<AppContexts>;\n\n public get actionsPlugin(): IActionsPlugin<AppContexts> {\n if (!this._actionsPlugin) {\n this._actionsPlugin = this.getPlugin<IActionsPlugin<AppContexts>>('actions');\n }\n return this._actionsPlugin;\n }\n\n // input\n protected _input: IInputPlugin;\n\n public get input(): IInputPlugin {\n if (!this._input) {\n this._input = this.getPlugin<IInputPlugin>('input');\n }\n return this._input;\n }\n\n // controls\n public get controls(): IControls {\n if (!this._input) {\n this._input = this.getPlugin<IInputPlugin>('input');\n }\n return this._input.controls;\n }\n\n // animation\n /**\n * The GSAP plugin.\n * @returns The GSAP plugin.\n */\n public get animation(): IGSAPPlugin {\n return this.getPlugin<IGSAPPlugin>('GSAPPlugin');\n }\n\n /**\n * The GSAP instance.\n * @returns The GSAP instance.\n */\n public get anim(): typeof gsap {\n return this.getPlugin<IGSAPPlugin>('GSAPPlugin').anim;\n }\n /**\n * Adds one or more GSAP tweens or timelines to a specified animation context.\n * This uses the GSAPPlugin's custom animation context (a Set of tweens/timelines),\n * not a `gsap.Context` instance. If no contextId is provided, animations are added\n * to the plugin's global collection.\n * @param animation - A single GSAP tween/timeline or an array of them.\n * @param contextId - Optional ID of the animation context. Defaults to the global context.\n * @returns The animation(s) that were added.\n */\n public addAnimation(\n animation: gsap.core.Tween | gsap.core.Timeline | (gsap.core.Tween | gsap.core.Timeline)[],\n contextId?: string,\n ): gsap.core.Tween | gsap.core.Timeline | (gsap.core.Tween | gsap.core.Timeline)[] {\n return this.getPlugin<IGSAPPlugin>('GSAPPlugin').addAnimation(animation, contextId);\n }\n\n /**\n * Returns the registered eases or ease names.\n * @param namesOnly - If true, returns only the ease names.\n * @returns The registered eases or ease names.\n */\n public eases(namesOnly: boolean = false): Eases | string[] {\n const plugin = this.getPlugin<IGSAPPlugin>('GSAPPlugin');\n return namesOnly ? plugin.easeNames : plugin.eases;\n }\n\n // store\n protected _store: IStore;\n\n public get store(): IStore {\n return this._store;\n }\n\n // size\n protected _center = new Point(0, 0);\n public get center(): Point {\n return this._center;\n }\n\n get lookup(): ILookupPlugin {\n if (!this._lookup) {\n this._lookup = this.getPlugin<ILookupPlugin>('lookup');\n }\n return this._lookup;\n }\n\n public getChildAtPath(path: string): PIXIContainer | undefined {\n return this.lookup.getChildAtPath(path);\n }\n\n public getPathForChild(container: PIXIContainer): string {\n return this.lookup.getPathForChild(container);\n }\n\n public getChildrenAtPaths(...paths: string[]): PIXIContainer[] {\n return this.lookup.getChildrenAtPaths(...paths);\n }\n\n public getPathsForChildren(...containers: PIXIContainer[]): string[] {\n return this.lookup.getPathsForChildren(...containers);\n }\n\n public getAllPaths(): string[] {\n return this.lookup.getAllPaths();\n }\n\n public get assets(): IAssetsPlugin {\n if (!this._assetManager) {\n this._assetManager = this.getPlugin<IAssetsPlugin>('assets');\n }\n return this._assetManager;\n }\n\n public get scenes(): ISceneManagerPlugin {\n if (!this._sceneManager) {\n this._sceneManager = this.getPlugin<ISceneManagerPlugin>('scenes');\n }\n return this._sceneManager;\n }\n\n public loadScene<K extends SceneId>(id: K, ...args: SceneLoadArgs<K>): void;\n public loadScene(scene: LoadSceneConfig | AppScenes): void;\n public loadScene(sceneOrId: LoadSceneConfig | AppScenes | SceneId, ...args: unknown[]): void {\n // The plugin's `loadScene` is overloaded — forward args directly.\n (this.scenes.loadScene as (...a: unknown[]) => unknown)(sceneOrId, ...args);\n }\n\n public get webEvents(): IWebEventsPlugin {\n if (!this._webEventsManager) {\n this._webEventsManager = this.getPlugin<IWebEventsPlugin>('webEvents');\n }\n return this._webEventsManager;\n }\n\n public get keyboard(): IKeyboardPlugin {\n if (!this._keyboardManager) {\n this._keyboardManager = this.getPlugin<IKeyboardPlugin>('keyboard');\n }\n return this._keyboardManager;\n }\n\n public get focus(): IFocusManagerPlugin {\n if (!this._focusManager) {\n this._focusManager = this.getPlugin<IFocusManagerPlugin>('focus');\n }\n return this._focusManager;\n }\n\n get size() {\n return this.resizer.size;\n }\n\n public get popups(): IPopupManagerPlugin {\n if (!this._popupManager) {\n this._popupManager = this.getPlugin<IPopupManagerPlugin>('popups');\n }\n return this._popupManager;\n }\n\n public get timers(): ITimerPlugin {\n if (!this._timerPlugin) {\n this._timerPlugin = this.getPlugin<ITimerPlugin>('timers');\n }\n return this._timerPlugin;\n }\n\n public get audio(): IAudioManagerPlugin {\n if (!this._audioManager) {\n this._audioManager = this.getPlugin<IAudioManagerPlugin>('audio');\n }\n return this._audioManager;\n }\n\n public get actionContext(): AppContexts {\n return this.actionsPlugin.context;\n }\n\n public set actionContext(context: AppContexts) {\n this.actionsPlugin.context = context;\n }\n\n public get voiceover(): IVoiceOverPlugin {\n if (!this._voiceoverPlugin) {\n this._voiceoverPlugin = this.getPlugin<IVoiceOverPlugin>('voiceover', this.config.useVoiceover);\n }\n return this._voiceoverPlugin;\n }\n\n public get captions(): ICaptionsPlugin {\n if (!this._captionsPlugin) {\n this._captionsPlugin = this.getPlugin<ICaptionsPlugin>('captions', this.config.useVoiceover);\n }\n return this._captionsPlugin;\n }\n /** Fullscreen plugin */\n public get fullScreen(): IFullScreenPlugin {\n if (!this._fullScreenPlugin) {\n this._fullScreenPlugin = this.getPlugin<IFullScreenPlugin>('fullscreen');\n }\n return this._fullScreenPlugin;\n }\n\n get fullScreenElement(): HTMLElement | Window | null {\n return this.fullScreen.fullScreenElement;\n }\n\n get isFullScreen(): boolean {\n return this.fullScreen.isFullScreen;\n }\n\n get canFullscreen(): boolean {\n return this.fullScreen.canFullscreen;\n }\n\n public setFullScreenElement(value: HTMLElement | Window | null) {\n this.fullScreen.setFullScreenElement(value);\n }\n\n public setFullScreen(value: boolean) {\n this.fullScreen.setFullScreen(value);\n }\n\n public toggleFullScreen() {\n this.fullScreen.toggleFullScreen();\n }\n /** End Fullscreen plugin */\n\n get isMobile() {\n return isMobile.any;\n }\n\n get isTouch() {\n return 'ontouchstart' in window || navigator.maxTouchPoints > 0;\n }\n\n get signal(): ICoreSignals {\n return coreSignalRegistry;\n }\n\n get signals(): ICoreSignals {\n return this.signal;\n }\n\n get func(): ICoreFunctions {\n return coreFunctionRegistry;\n }\n\n get exec(): ICoreFunctions {\n return this.func;\n }\n\n // views\n protected _views: any[];\n\n public get views(): any[] {\n if (!this._views) {\n this._views = [this.scenes.view, this.popups.view];\n if (this.scenes.splash.view) {\n this._views.push(this.scenes.splash.view);\n }\n if (this.scenes.transition) {\n this._views.push(this.scenes.transition);\n }\n if (this.captions?.view) {\n this._views.push(this.captions.view);\n }\n }\n\n return this._views;\n }\n\n public static getInstance<T extends App = App>(): T {\n if (!Application.instance) {\n Logger.warn('Application not created yet');\n }\n\n return Application.instance as T;\n }\n\n /**\n * Destroy the application\n * This will destroy all plugins and the store\n * @param {RendererDestroyOptions} rendererDestroyOptions\n * @param {DestroyOptions} options\n */\n public destroy(rendererDestroyOptions?: RendererDestroyOptions, options?: DestroyOptions) {\n this._plugins.forEach((plugin) => {\n plugin.destroy();\n });\n this.store.destroy();\n super.destroy(rendererDestroyOptions, options);\n }\n\n public setContainer(container: HTMLElement) {\n Application.containerElement = container;\n }\n\n public async initialize(config: Partial<AppConfig>, el?: HTMLElement): Promise<AppTypeOverrides['App']> {\n if (Application.instance) {\n throw new Error('Application is already initialized');\n }\n Application.instance = this as unknown as IApplication;\n\n this.config = deepMerge(defaultApplicationOptions, config);\n this.signals.onResize = this.onResize;\n\n if (config.container) {\n Application.containerElement = config.container;\n }\n // initialize the logger\n Logger.initialize(this.config.logger);\n\n // ensure the resolution is 1 or 2\n if (this.config.resolution !== 1 && this.config.resolution !== 2) {\n const userResolution = this.config.resolution;\n this.config.resolution = getDefaultResolution();\n Logger.warn(\n `App resolution must be 1 or 2, setting to ${this.config.resolution} instead of ${userResolution}. Modify your app config to set the resolution to 1 or 2.`,\n );\n }\n\n await this.boot(this.config);\n await this.initAssets();\n\n // initialize the pixi application\n await this.init(this.config);\n this.stage.label = 'Stage';\n\n if (this.config.defaultTextStyle) {\n const style = { ...defaultApplicationOptions.defaultTextStyle, ...this.config.defaultTextStyle };\n TextStyle.defaultTextStyle = style;\n }\n if (this.config.defaultDropShadow) {\n TextStyle.defaultDropShadow = this.config.defaultDropShadow;\n }\n if (el) {\n el.appendChild(this.canvas as HTMLCanvasElement);\n this.setContainer(el);\n } else {\n throw new Error('No element found to append the view to.');\n }\n await this.registerDefaultPlugins();\n\n if (isDev) {\n this.getPlugin<IDevToolsPlugin>('DevToolsPlugin').initializeDevTools(this);\n }\n\n this.signals.onLoadRequiredComplete.connectOnce(this.requiredAssetsLoaded);\n\n // internal setup\n await this._setup();\n\n this.plugins = await generatePluginList(this.config.plugins || []);\n\n // register the applications custom plugins (storage-capable or not — one pipeline)\n await this.registerPlugins();\n\n await this.setup();\n await this.loadDefaultScene();\n\n // focus the canvas\n this.renderer.canvas.focus();\n\n if (this.config.container) {\n this.config.container.classList.add('loaded');\n }\n\n this._isBooting = false;\n // return the Application instance to the create method, if needed\n return Application.instance as unknown as App;\n }\n\n public getPlugin<T extends IPlugin>(pluginName: AppPlugins, debug: boolean = false): T {\n const plugin = this._plugins.get(pluginName) as T;\n if (!plugin && debug) {\n Logger.warn(`Plugin with name \"${pluginName}\" not found.`);\n }\n return plugin;\n }\n\n /**\n * Framework post-initialization. Always runs the plugin `postInitialize` loop and\n * core wiring, then invokes the user-overridable {@link postInitialize} hook last.\n * The runtime (`create()`) calls this — apps should not call it directly, and must\n * NOT need to call `super` from their own `postInitialize` override to get wired up.\n */\n async _postInitialize(): Promise<void> {\n // start plugins\n for (const plugin of this._plugins.values()) {\n try {\n await plugin.postInitialize(this as unknown as IApplication);\n } catch (error) {\n // Surfaced (not just logged) so a plugin that silently fails to wire up —\n // e.g. InputPlugin's controls.connect() — is visible in dev, not invisible.\n triggerViteError({\n message: `Plugin \"${plugin.id}\" failed in postInitialize: ${error instanceof Error ? error.message : String(error)}`,\n stack: error instanceof Error ? error.stack : undefined,\n });\n this.onPluginError.emit({ id: plugin.id, phase: 'postInitialize', error });\n }\n }\n\n this.webEvents.onVisibilityChanged.connect((visible) => {\n if (visible) {\n this.audio.restore();\n this.timers.resumeAllTimers();\n } else {\n this.audio.suspend();\n this.timers.pauseAllTimers();\n }\n });\n\n // User hook, run last. Framework wiring above always runs regardless of whether\n // a subclass override calls super, so overriding `postInitialize` is footgun-free.\n await this.postInitialize();\n }\n\n /**\n * User-overridable post-initialization hook, invoked after all framework wiring is\n * complete. Override to perform app setup that depends on a fully initialized\n * environment. Safe to override WITHOUT calling `super` — framework post-init lives\n * in {@link _postInitialize}, which the runtime calls.\n */\n async postInitialize(): Promise<void> {}\n\n public getUnloadedPlugin(id: string): ImportListItem<IPlugin> | undefined {\n return this.plugins.find((pluginItem) => pluginItem.id === id);\n }\n\n async loadPlugin(listItem: ImportListItem, isDefault: boolean = false) {\n if (this._plugins.has(listItem.id)) {\n return await this.registerPlugin(this._plugins.get(listItem.id)!, listItem.options);\n }\n const plugin = await getDynamicModuleFromImportListItem(listItem);\n const pluginInstance = new plugin(listItem.id);\n if (pluginInstance.id !== listItem.id) {\n pluginInstance.id = listItem.id;\n }\n let opts = listItem.options;\n if (isDefault && !opts) {\n opts = this.config[pluginInstance.id as keyof IApplicationOptions];\n }\n return await this.registerPlugin(pluginInstance, opts);\n }\n\n /**\n * Gets an ActionSignal for the specified action type\n * @template TActionData - The type of data associated with the action\n * @param {A} action - The action to get the signal for\n * @returns {ActionSignal<TActionData>} A signal that can be used to listen for the action\n * @example\n * // Listen for a 'jump' action\n * app.actions('jump').connect((data) => {\n * player.jump(data.power);\n * });\n */\n public actions<TActionData = any>(action: AppActions): ActionSignal<TActionData> {\n return this.actionsPlugin.getAction<TActionData>(action as string);\n }\n\n /**\n * Dispatches an action with optional data\n * @template TActionData - The type of data to send with the action\n * @param {A} action - The action to dispatch\n * @param {TActionData} [data] - Optional data to send with the action\n * @example\n * // Send a 'jump' action with power data\n * app.sendAction('jump', { power: 100 });\n */\n public sendAction<TActionData = any>(action: AppActions, data?: TActionData) {\n this.actionsPlugin.sendAction<TActionData>(action as string, data);\n }\n\n /**\n * Dispatches an action with optional data\n * alias for sendAction\n * @template TActionData - The type of data to send with the action\n * @param {A} action - The action to dispatch\n * @param {TActionData} [data] - Optional data to send with the action\n * @example\n * // Send a 'jump' action with power data\n * app.action('jump', { power: 100 });\n */\n public action<TActionData = any>(action: AppActions, data?: TActionData) {\n this.sendAction(action, data);\n }\n\n /**\n * Checks if an action is currently active\n * @param {A} action - The action to check\n * @returns {boolean} True if the action is active, false otherwise\n * @example\n * // Check if the 'run' action is active\n * if (app.isActionActive('run')) {\n * player.updateSpeed(runningSpeed);\n * }\n */\n public isActionActive(action: AppActions): boolean {\n return this.actionsPlugin.getActions()[action as string] !== undefined;\n }\n\n /**\n * The built-in DataAdapter plugin (in-memory game data with optional\n * localStorage backup). Routed through the plugin registry, not `store` —\n * its API is richer than generic save/load.\n */\n public get data(): IDataAdapter {\n return this.getPlugin<IPlugin & IDataAdapter>('data');\n }\n\n protected async boot(config?: Partial<IApplicationOptions>): Promise<void> {\n this.config = { ...defaultApplicationOptions, ...config };\n await this.preInitialize(this.config);\n }\n\n protected async preInitialize(config: Partial<IApplicationOptions>): Promise<void> {\n const { id } = config;\n this._appName = id!;\n\n if (isDev) {\n await this.loadPlugin({\n id: 'DevToolsPlugin',\n module: () => import('../plugins/DevToolsPlugin'),\n namedExport: 'DevToolsPlugin',\n });\n }\n\n if (config.useLayout) {\n await this.loadPlugin({\n id: 'LayoutPlugin',\n module: () => import('../plugins/LayoutPlugin'),\n namedExport: 'LayoutPlugin',\n });\n }\n await this.loadPlugin({\n id: 'GSAPPlugin',\n module: () => import('../plugins/GSAPPlugin'),\n namedExport: 'GSAPPlugin',\n });\n if (config.useSpine) {\n await this.loadPlugin({\n id: 'SpinePlugin',\n module: () => import('../plugins/spine/SpinePlugin'),\n namedExport: 'SpinePlugin',\n });\n }\n\n if (this.config.useStore) {\n this._store = new Store();\n this._store.initialize(this as unknown as IApplication);\n // Register the built-in DataAdapter as a normal plugin so it lives in\n // `_plugins` alongside everything else.\n await this.loadPlugin({\n id: 'data',\n module: () => import('../plugins/DataAdapter'),\n namedExport: 'DataAdapter',\n options: this.config.data,\n });\n }\n }\n\n // plugins\n protected async registerPlugin(plugin: IPlugin, options?: any) {\n if (this._plugins.has(plugin.id)) {\n Logger.warn(`Plugin with id \"${plugin.id}\" already registered. Not registering.`);\n return plugin.initialize(options, this as unknown as IApplication);\n }\n plugin.registerCoreFunctions();\n plugin.registerCoreSignals();\n this._plugins.set(plugin.id, plugin);\n try {\n return await plugin.initialize(options, this as unknown as IApplication);\n } catch (error) {\n triggerViteError({\n message: `Plugin \"${plugin.id}\" failed to initialize: ${error instanceof Error ? error.message : String(error)}`,\n stack: error instanceof Error ? error.stack : undefined,\n });\n this.onPluginError.emit({ id: plugin.id, phase: 'initialize', error });\n return undefined;\n }\n }\n\n protected async registerDefaultPlugins() {\n for (let i = 0; i < defaultPlugins.length; i++) {\n const listItem = defaultPlugins[i];\n await this.loadPlugin(listItem, true);\n }\n const showStats = this.config.showStats === true || (isDev && this.config.showStats !== false);\n if (showStats) {\n await this.loadPlugin({\n id: 'stats',\n module: () => import('../plugins/StatsPlugin'),\n namedExport: 'StatsPlugin',\n });\n }\n if (this.config.useVoiceover) {\n await this.loadPlugin({\n id: 'voiceover',\n module: () => import('../plugins/audio/VoiceOverPlugin'),\n namedExport: 'VoiceOverPlugin',\n options: this.config['voiceover' as keyof IApplicationOptions] || undefined,\n });\n await this.loadPlugin({\n id: 'captions',\n module: () => import('../plugins/captions/CaptionsPlugin'),\n namedExport: 'CaptionsPlugin',\n options: this.config['captions' as keyof IApplicationOptions] || undefined,\n });\n }\n }\n\n protected async registerPlugins() {\n if (!this.plugins?.length) {\n return;\n }\n\n // Topologically sort by `requires` so a plugin's dependencies always\n // initialize first, regardless of the order in caper.config.ts. Fails\n // bootstrap loudly on missing required plugins or dependency cycles —\n // see Plugin docs for the rationale (we want the config file to be\n // the single source of truth for active plugins, not auto-resolve).\n const sorted = sortPluginsByRequires(this.plugins);\n\n for (const p of sorted) {\n if (p.autoLoad) {\n await this.loadPlugin(p);\n }\n }\n }\n\n /**\n * This is called after the required assets are loaded\n * You can be sure that all the assets on the assets.preload from caper.config are loaded\n * @protected\n */\n protected requiredAssetsLoaded(): Promise<void> | void;\n\n protected async requiredAssetsLoaded(): Promise<void> {\n // override me\n }\n /**\n * This is called after the application is initialized\n * You can be sure that\n * - all plugins are registered\n * - the store is created, with all storage adapters registered\n * @protected\n */\n protected setup(): Promise<void> | void;\n\n protected async setup(): Promise<void> {\n // override me to set up application specific stuff\n }\n\n protected async initAssets(): Promise<void> {\n const opts: Partial<AssetInitOptions> = this.config.assets?.initOptions || {};\n let manifest = this.config.assets?.manifest || opts.manifest;\n if (isPromise(manifest)) {\n manifest = await manifest;\n }\n opts.manifest = manifest as AssetsManifest;\n opts.basePath = opts.basePath || './assets';\n await Assets.init(opts);\n /** @ts-expect-error manifest is not a public property */\n this.manifest = Assets.resolver._manifest;\n }\n\n protected async loadDefaultScene(): Promise<void> {\n return this.scenes.loadDefaultScene();\n }\n\n private async _resize(): Promise<Size> {\n // Wait for DOM content to be loaded\n if (document.readyState !== 'complete') {\n await new Promise<void>((resolve) => {\n window.addEventListener('load', () => resolve(), { once: true });\n });\n }\n\n // Add a small delay to ensure canvas dimensions are set\n await new Promise((resolve) => setTimeout(resolve, 50));\n\n return new Promise((resolve) => {\n this.resizer.resize().then((size) => {\n this._center.set(size.width * 0.5, size.height * 0.5);\n\n this.views.forEach((view) => {\n if (!view || !view.position) {\n return;\n }\n view.position.set(this._center.x, this._center.y);\n });\n this.onResize.emit(this.size);\n resolve(size);\n });\n });\n }\n /**\n * Called after the application is initialized\n * Here we add application specific signal listeners, etc\n * @returns {Promise<void>}\n * @private\n */\n private async _setup(): Promise<void> {\n // connect onResize signal\n this.webEvents.onResize.connect(this._resize, -1);\n\n await this._resize();\n\n if (this.scenes.splash?.view && this.scenes.splash.zOrder === 'bottom') {\n this._addSplash();\n }\n // scene manager\n this.scenes.view.label = 'SceneManager';\n this.stage.addChild(this.scenes.view);\n\n if (this.scenes.splash?.view && this.scenes.splash.zOrder === 'top') {\n this._addSplash();\n }\n\n if (this.scenes.transition) {\n this.scenes.transition.label = 'Transition';\n this.stage.addChild(this.scenes.transition);\n }\n\n // popup manager\n this.stage.addChild(this.popups.view);\n\n // focus manager\n this.focus.view.label = 'FocusManager';\n this.stage.addChild(this.focus.view);\n\n // is touch device\n return Promise.resolve();\n }\n\n private _addSplash() {\n if (this.scenes.splash.view) {\n this.scenes.splash.view.label = 'Splash';\n this.stage.addChild(this.scenes.splash.view);\n }\n }\n}\n","import type { ICoreFunctions, ICoreSignals } from './interfaces';\n\n// @ts-expect-error - we don't know what the keys are, so we can't type them\nexport const coreSignalRegistry: { [K in keyof ICoreSignals]: ICoreSignals[K] } = {};\n\n// @ts-expect-error - we don't know what the keys are, so we can't type them\nexport const coreFunctionRegistry: { [K in keyof ICoreFunctions]: ICoreFunctions[K] } = {};\n"],"x_google_ignoreList":[21,22,23,24,25,26,27,28,29,30,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71],"mappings":"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"}