@rb-games/core 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-JHN6RF66.js +1580 -0
- package/dist/chunk-JHN6RF66.js.map +1 -0
- package/dist/chunk-NAQG7TMS.js +5517 -0
- package/dist/chunk-NAQG7TMS.js.map +1 -0
- package/dist/{chunk-KOHCRCV3.js → chunk-YSLGJAV6.js} +11 -9
- package/dist/chunk-YSLGJAV6.js.map +1 -0
- package/dist/helpers/index.js +9 -6
- package/dist/helpers/index.js.map +1 -1
- package/dist/plugins/index.js +6 -3
- package/dist/plugins/index.js.map +1 -1
- package/dist/state-machine/index.js +5 -3
- package/dist/state-machine/index.js.map +1 -1
- package/dist/ui/index.js +28 -10
- package/dist/ui/index.js.map +1 -1
- package/dist/utils/index.js +2 -1
- package/dist/vite/index.js +5 -3
- package/dist/vite/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-KOHCRCV3.js.map +0 -1
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { require_lodash } from './chunk-NAQG7TMS.js';
|
|
2
|
+
import { __toESM } from './chunk-G3PMV62Z.js';
|
|
2
3
|
import { Rectangle, Color } from 'pixi.js';
|
|
3
4
|
|
|
4
5
|
// utils/DataInjector.ts
|
|
6
|
+
var import_lodash = __toESM(require_lodash(), 1);
|
|
5
7
|
function DataInjector(obj, path, data, replace = false) {
|
|
6
|
-
const result = cloneDeep(obj);
|
|
8
|
+
const result = (0, import_lodash.cloneDeep)(obj);
|
|
7
9
|
if (path === "" || path === void 0 || path === null) {
|
|
8
|
-
return merge({}, result, cloneDeep(data));
|
|
10
|
+
return (0, import_lodash.merge)({}, result, (0, import_lodash.cloneDeep)(data));
|
|
9
11
|
}
|
|
10
12
|
if (replace) {
|
|
11
|
-
set(result, path, cloneDeep(data));
|
|
13
|
+
(0, import_lodash.set)(result, path, (0, import_lodash.cloneDeep)(data));
|
|
12
14
|
return result;
|
|
13
15
|
}
|
|
14
|
-
const current = get(result, path);
|
|
15
|
-
const merged = merge({}, current ?? {}, data);
|
|
16
|
-
set(result, path, merged);
|
|
16
|
+
const current = (0, import_lodash.get)(result, path);
|
|
17
|
+
const merged = (0, import_lodash.merge)({}, current ?? {}, data);
|
|
18
|
+
(0, import_lodash.set)(result, path, merged);
|
|
17
19
|
return result;
|
|
18
20
|
}
|
|
19
21
|
function adjustColor(color, amount, sign) {
|
|
@@ -486,5 +488,5 @@ function throttle(func, wait, options = {}) {
|
|
|
486
488
|
}
|
|
487
489
|
|
|
488
490
|
export { DataInjector, NumberFormatter, __arrayUtilsLoaded, applyAnchor, applyCommonProperties, applyScale, calculateAnimationSpeed, darkenColor, debounce, lightenColor, throttle, updateBounds };
|
|
489
|
-
//# sourceMappingURL=chunk-
|
|
490
|
-
//# sourceMappingURL=chunk-
|
|
491
|
+
//# sourceMappingURL=chunk-YSLGJAV6.js.map
|
|
492
|
+
//# sourceMappingURL=chunk-YSLGJAV6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../utils/DataInjector.ts","../utils/ColorUtils.ts","../utils/NumberFormatter.ts","../utils/ArrayUtils.ts","../utils/PixiUtils.ts","../utils/Throttle.ts"],"names":[],"mappings":"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","file":"chunk-YSLGJAV6.js","sourcesContent":["import { cloneDeep, get, merge, set } from 'lodash';\n\n/**\n * Injects data into a nested object path.\n *\n * DataInjector is a utility function for safely modifying nested object properties.\n * It creates a deep clone of the original object and injects data at the specified path.\n *\n * ## Features\n *\n * - **Deep Cloning**: Original object is never mutated\n * - **Nested Path Support**: Use dot notation (e.g., 'ui.button.color')\n * - **Merge or Replace**: Choose to merge with existing data or replace it\n * - **Type-Safe**: Preserves TypeScript types\n *\n * ## Usage with Skins\n *\n * Commonly used to patch skin data with specific values while keeping the rest intact.\n *\n * @typeParam T - The type of the object being modified\n * @param obj - Source object to modify\n * @param path - Dot-notation path to the property (e.g., 'options.buttonSkin.up')\n * @param data - Data to inject at the path\n * @param replace - If true, replaces the value; if false, merges with existing (default: false)\n * @returns New object with injected data\n *\n * @example\n * Merge data (default):\n * ```typescript\n * const skinData = {\n * button: { color: 0xFF0000, size: 100 },\n * text: { fontSize: 24 }\n * };\n *\n * const updated = DataInjector(skinData, 'button', { size: 150 });\n * // Result: { button: { color: 0xFF0000, size: 150 }, text: { fontSize: 24 } }\n * ```\n *\n * @example\n * Replace data:\n * ```typescript\n * const updated = DataInjector(skinData, 'button', { size: 150 }, true);\n * // Result: { button: { size: 150 }, text: { fontSize: 24 } }\n * // Note: color is removed because we replaced the entire button object\n * ```\n *\n * @example\n * Real-world example:\n * ```typescript\n * let autoplaySkin = defaultAutoplayMenuSkin;\n *\n * // Inject checkbox textures\n * autoplaySkin = DataInjector(autoplaySkin, 'options.buttonSkin', {\n * up: { background: { texture: 'btn_checkbox_up' } },\n * over: { background: { texture: 'btn_checkbox_over' } },\n * down: { background: { texture: 'btn_checkbox_down' } }\n * });\n *\n * // Inject slider textures\n * autoplaySkin = DataInjector(autoplaySkin, 'count.sliderSkin', {\n * up: { knob: { texture: 'icon_autoplay_slider_up' } },\n * over: { knob: { texture: 'icon_autoplay_slider_over' } }\n * });\n * ```\n *\n * @public\n */\nexport function DataInjector<T extends object>(\n obj: T,\n path: string,\n data: unknown,\n replace = false,\n): T {\n const result = cloneDeep(obj);\n\n // Handle empty path - merge at root level\n if (path === '' || path === undefined || path === null) {\n return merge({}, result, cloneDeep(data)) as T;\n }\n\n if (replace) {\n set(result, path, cloneDeep(data));\n return result;\n }\n const current = get(result, path);\n const merged = merge({}, current ?? {}, data);\n set(result, path, merged);\n return result;\n}\n","import { Color, type ColorSource } from 'pixi.js';\n\n/**\n * Utility functions for color manipulation.\n *\n * Provides functions for lightening and darkening colors.\n * Uses PixiJS Color and ColorSource for better type safety and compatibility with PixiJS v8.\n *\n * @example\n * ```typescript\n * import { lightenColor, darkenColor } from '@rb-games/core/utils';\n *\n * // Lighten a color\n * const lighter = lightenColor('#4CAF50', 0.2);\n * const lighter2 = lightenColor(0x4CAF50, 0.2);\n *\n * // Darken a color\n * const darker = darkenColor('#4CAF50', 0.2);\n *\n * // Use with PixiJS\n * sprite.tint = lighter; // Direct usage\n * const hex = lighter.toHex(); // Convert to hex if needed\n * const num = lighter.toNumber(); // Convert to number if needed\n * ```\n *\n * @public\n */\n\n/**\n * Adjusts a color's brightness by a specified percentage.\n * Internal helper function used by lightenColor and darkenColor.\n *\n * @param color - Color value (hex string, number, or any PixiJS ColorSource)\n * @param amount - Amount to adjust (0-1)\n * @param sign - Direction of adjustment (1 for lighten, -1 for darken)\n * @returns Adjusted color as PixiJS Color instance\n */\nfunction adjustColor(color: ColorSource, amount: number, sign: 1 | -1): Color {\n const colorObj = new Color(color);\n const rgb = {\n r: colorObj.red * 255,\n g: colorObj.green * 255,\n b: colorObj.blue * 255,\n };\n\n const delta = 255 * amount * sign;\n const newR = Math.max(0, Math.min(255, rgb.r + delta));\n const newG = Math.max(0, Math.min(255, rgb.g + delta));\n const newB = Math.max(0, Math.min(255, rgb.b + delta));\n\n return new Color([newR / 255, newG / 255, newB / 255]);\n}\n\n/**\n * Lightens a color by a specified percentage.\n *\n * @param color - Color value (hex string, number, or any PixiJS ColorSource)\n * @param amount - Amount to lighten (0-1, where 0.2 = 20% lighter)\n * @returns Lightened color as PixiJS Color instance\n *\n * @example\n * ```typescript\n * const lighter = lightenColor('#4CAF50', 0.15);\n * const lighter2 = lightenColor(0x4CAF50, 0.15);\n * // Can be used directly with PixiJS: sprite.tint = lighter;\n * // Or as hex string: lighter.toHex()\n * ```\n */\nexport function lightenColor(color: ColorSource, amount: number): Color {\n return adjustColor(color, amount, 1);\n}\n\n/**\n * Darkens a color by a specified percentage.\n *\n * @param color - Color value (hex string, number, or any PixiJS ColorSource)\n * @param amount - Amount to darken (0-1, where 0.2 = 20% darker)\n * @returns Darkened color as PixiJS Color instance\n *\n * @example\n * ```typescript\n * const darker = darkenColor('#4CAF50', 0.15);\n * const darker2 = darkenColor(0x4CAF50, 0.15);\n * // Can be used directly with PixiJS: sprite.tint = darker;\n * // Or as hex string: darker.toHex()\n * ```\n */\nexport function darkenColor(color: ColorSource, amount: number): Color {\n return adjustColor(color, amount, -1);\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Configuration options for NumberFormatter.\n *\n * @public\n */\nexport interface NumberFormatterConfig {\n /** Number format mask (e.g., '$ #,##0.##', '#,##0.00 TL') */\n mask: string;\n /** Denomination multiplier for currency conversion */\n denom: number;\n /** Threshold for express mode (values above this will be shortened) */\n expressThreshold: number;\n /** Units for express mode (K, M, B, T, etc.) */\n expressUnits: string[];\n /** Decimal precision for express mode */\n decimalPrecision: number;\n /** Symbol to show when number is rounded in express mode */\n roundedSymbol: string;\n}\n\n/**\n * Options for format and express methods.\n *\n * @public\n */\nexport interface FormatOptions {\n /** Prefix to add before the formatted number */\n prefix?: string;\n /** Force showing decimal places even for whole numbers */\n forceDecimals?: boolean;\n /** Ignore denomination multiplier */\n ignoreDenom?: boolean;\n /** Custom threshold for express mode (overrides config) */\n threshold?: number;\n}\n\n/**\n * Parsed mask information.\n *\n * @internal\n */\ninterface ParsedMask {\n /** Mask pattern without prefix/suffix */\n pattern: string;\n /** Currency symbol or prefix */\n prefix: string;\n /** Currency symbol or suffix */\n suffix: string;\n /** Decimal separator */\n decimal: string;\n /** Group separator (thousands) */\n group: string;\n /** Decimal places */\n decimalPlaces: number;\n /** Position of leading zeros */\n posLeadZero: number;\n /** Group size (e.g., 3 for thousands) */\n groupSize: number;\n}\n\n/**\n * Number formatter for slot games with denomination and express mode support.\n *\n * NumberFormatter provides a unified number formatting system with:\n * - Mask-based formatting (e.g., '$ #,##0.##', '#,##0.00 TL')\n * - Denomination support for currency conversion\n * - Express mode for large numbers (1.5K, 2.3M, etc.)\n * - Configurable decimal precision and separators\n * - Type-safe API with TypeScript\n *\n * ## Features\n *\n * - **Mask-Based Formatting**: Industry-standard mask patterns\n * - **Denomination Support**: Automatic currency conversion with denom multiplier\n * - **Express Mode**: Shorten large numbers (1000 → 1K, 1500000 → 1.5M)\n * - **Flexible Configuration**: Configure globally or per-call\n * - **Type-Safe**: Full TypeScript support\n * - **Performance**: Mask parsing is cached for efficiency\n *\n * ## Mask Format\n *\n * - `#` - Optional digit\n * - `0` - Required digit (shows leading/trailing zeros)\n * - `,` - Group separator (thousands)\n * - `.` - Decimal separator\n * - Any other characters are treated as prefix/suffix\n *\n * @example\n * Basic usage:\n * ```typescript\n * import { NumberFormatter } from '@rb-games/core/utils';\n *\n * // Configure formatter\n * const formatter = NumberFormatter.configure({\n * mask: '$ #,##0.##',\n * denom: 100,\n * expressThreshold: 1000,\n * expressUnits: ['K', 'M', 'B', 'T'],\n * decimalPrecision: 2\n * });\n *\n * // Format numbers\n * formatter.format(1500); // \"$ 15.00\"\n * formatter.format(250000); // \"$ 2,500.00\"\n *\n * // Express mode for large numbers\n * formatter.express(150000); // \"$ 1.5K\"\n * formatter.express(2500000); // \"$ 2.5M\"\n * ```\n *\n * @example\n * Different currency formats:\n * ```typescript\n * // USD format\n * const usdFormatter = NumberFormatter.configure({\n * mask: '$ #,##0.00',\n * denom: 100\n * });\n * usdFormatter.format(1000); // \"$ 10.00\"\n *\n * // TRY format (suffix)\n * const tryFormatter = NumberFormatter.configure({\n * mask: '#,##0.## TL',\n * denom: 100\n * });\n * tryFormatter.format(1000); // \"10.00 TL\"\n *\n * // IDR format (high denom)\n * const idrFormatter = NumberFormatter.configure({\n * mask: 'Rp #,##0',\n * denom: 1000,\n * expressThreshold: 100000\n * });\n * idrFormatter.express(15000000); // \"Rp 15K\"\n * ```\n *\n * @example\n * Per-call options:\n * ```typescript\n * const formatter = NumberFormatter.configure({\n * mask: '$ #,##0.##',\n * denom: 100\n * });\n *\n * // Force decimals\n * formatter.format(1000, { forceDecimals: true }); // \"$ 10.00\"\n *\n * // Ignore denom\n * formatter.format(1000, { ignoreDenom: true }); // \"$ 1,000.00\"\n *\n * // Custom threshold\n * formatter.express(500, { threshold: 100 }); // \"$ 0.5K\"\n * ```\n *\n * @category Utils\n * @public\n */\n/**\n * Default configuration for NumberFormatter.\n * @internal\n */\nconst DEFAULT_CONFIG: NumberFormatterConfig = {\n mask: '#,##0.##',\n denom: 1,\n expressThreshold: 1000,\n expressUnits: ['K', 'M', 'B', 'T', 'Q'],\n decimalPrecision: 2,\n roundedSymbol: '+',\n};\n\nexport class NumberFormatter {\n private static instance: NumberFormatter;\n private config: NumberFormatterConfig;\n private maskCache: Map<string, ParsedMask> = new Map();\n\n /**\n * Private constructor for singleton pattern\n */\n private constructor(config: NumberFormatterConfig) {\n this.config = config;\n }\n\n /**\n * Configure the NumberFormatter singleton.\n *\n * @param config - Configuration options\n * @returns NumberFormatter instance\n */\n public static configure(config: Partial<NumberFormatterConfig>): NumberFormatter {\n const finalConfig = { ...DEFAULT_CONFIG, ...config };\n\n if (!NumberFormatter.instance) {\n NumberFormatter.instance = new NumberFormatter(finalConfig);\n } else {\n NumberFormatter.instance.config = finalConfig;\n NumberFormatter.instance.maskCache.clear();\n }\n\n return NumberFormatter.instance;\n }\n\n /**\n * Get the singleton instance.\n *\n * If not configured yet, initializes with default configuration.\n *\n * @returns NumberFormatter instance\n */\n public static getInstance(): NumberFormatter {\n if (!NumberFormatter.instance) {\n NumberFormatter.instance = new NumberFormatter(DEFAULT_CONFIG);\n }\n return NumberFormatter.instance;\n }\n\n /**\n * Format a number using the configured mask.\n *\n * @param value - Number to format\n * @param options - Optional formatting options\n * @returns Formatted string\n *\n * @example\n * ```typescript\n * formatter.format(1500); // \"$ 15.00\"\n * formatter.format(1500, { forceDecimals: true }); // \"$ 15.00\"\n * formatter.format(1500, { ignoreDenom: true }); // \"$ 1,500.00\"\n * ```\n */\n public format(value: number, options: FormatOptions = {}): string {\n const { prefix = '', forceDecimals = false, ignoreDenom = false } = options;\n\n const actualValue = ignoreDenom ? value : value * this.config.denom;\n\n let mask = this.config.mask;\n\n if (forceDecimals) {\n mask = mask.replace(/\\.##/g, '.00');\n }\n\n return this.applyMask(mask, actualValue) + prefix;\n }\n\n /**\n * Format a number in express mode (shortened with K/M/B/T).\n *\n * @param value - Number to format\n * @param options - Optional formatting options\n * @returns Formatted string with unit suffix\n *\n * @example\n * ```typescript\n * formatter.express(150000); // \"$ 1.5K\"\n * formatter.express(2500000); // \"$ 2.5M\"\n * formatter.express(500, { threshold: 100 }); // \"$ 0.5K\"\n * ```\n */\n public express(value: number, options: FormatOptions = {}): string {\n const {\n prefix = '',\n forceDecimals = false,\n ignoreDenom = false,\n threshold = this.config.expressThreshold,\n } = options;\n\n const actualValue = ignoreDenom ? value : value * this.config.denom;\n\n if (actualValue < threshold) {\n return this.format(value, { prefix, forceDecimals, ignoreDenom });\n }\n\n let unitIndex = -1;\n let shortenedNum = actualValue;\n\n while (shortenedNum >= 1000 && unitIndex < this.config.expressUnits.length - 1) {\n shortenedNum /= 1000;\n unitIndex++;\n }\n\n const factor = Math.pow(10, this.config.decimalPrecision);\n const roundedNum = Math.floor(shortenedNum * factor) / factor;\n const isRounded = roundedNum < shortenedNum;\n\n let mask = this.config.mask;\n\n if (forceDecimals) {\n mask = mask.replace(/\\.##/g, '.00');\n }\n\n const parsed = this.parseMask(mask);\n const formattedNumber =\n this.applyMask(parsed.pattern, roundedNum) +\n (this.config.expressUnits[unitIndex] || '') +\n (isRounded ? this.config.roundedSymbol : '');\n\n return parsed.prefix + formattedNumber + parsed.suffix + prefix;\n }\n\n /**\n * Parse a mask string into its components.\n *\n * @param mask - Mask string to parse\n * @returns Parsed mask information\n * @internal\n */\n private parseMask(mask: string): ParsedMask {\n if (this.maskCache.has(mask)) {\n return this.maskCache.get(mask)!;\n }\n\n const maskCharacters = /[#0-9,.]/;\n const len = mask.length;\n const start = mask.search(/[0-9\\-\\+#]/);\n const prefix = start > 0 ? mask.substring(0, start).trim() : '';\n\n const str = mask.split('').reverse().join('');\n const end = str.search(/[0-9\\-\\+#]/);\n const offset = len - end;\n const indx = offset + (mask.substring(offset, offset + 1) === '.' ? 1 : 0);\n const suffix = end > 0 ? mask.substring(indx, len).trim() : '';\n\n const pattern = mask.substring(start, indx);\n\n const result = pattern.match(/[^\\d\\-\\+#]/g);\n const decimal = (result && result[result.length - 1]) || '.';\n const group = (result && result[1] && result[0]) || ',';\n\n const parts = pattern.split(decimal);\n const decimalPlaces = parts[1] ? parts[1].length : 0;\n\n const szSep = parts[0].split(group);\n const groupSize = szSep[1] ? szSep[szSep.length - 1].length : 0;\n\n const cleanPattern = parts[0].replace(new RegExp(`\\\\${group}`, 'g'), '');\n const posLeadZero = cleanPattern.indexOf('0');\n\n const parsed: ParsedMask = {\n pattern,\n prefix,\n suffix,\n decimal,\n group,\n decimalPlaces,\n posLeadZero,\n groupSize,\n };\n\n this.maskCache.set(mask, parsed);\n return parsed;\n }\n\n /**\n * Apply a mask to a number value.\n *\n * @param mask - Mask pattern\n * @param value - Number to format\n * @returns Formatted string\n * @internal\n */\n private applyMask(mask: string, value: any): string {\n if (!mask || isNaN(+value) || value === '') return value;\n\n const parsed = this.parseMask(mask);\n let isNegative = value < 0;\n value = Math.abs(value);\n\n const maskParts = parsed.pattern.split(parsed.decimal);\n value = value.toFixed(maskParts[1] ? maskParts[1].length : 0);\n value = +value + '';\n\n const posTrailZero = maskParts[1] ? maskParts[1].lastIndexOf('0') : -1;\n let parts = value.split('.');\n\n if (!parts[1] || (parts[1] && parts[1].length <= posTrailZero)) {\n value = (+value).toFixed(posTrailZero + 1);\n }\n\n const szSep = maskParts[0].split(parsed.group);\n const cleanMask = szSep.join('');\n\n if (parsed.posLeadZero > -1) {\n while (parts[0].length < cleanMask.length - parsed.posLeadZero) {\n parts[0] = '0' + parts[0];\n }\n } else if (+parts[0] === 0) {\n parts[0] = '';\n }\n\n const valueParts = value.split('.');\n valueParts[0] = parts[0];\n\n if (parsed.groupSize) {\n const integer = valueParts[0];\n let str = '';\n const offset = integer.length % parsed.groupSize;\n const len = integer.length;\n\n for (let i = 0; i < len; i++) {\n str += integer.charAt(i);\n if (!((i - offset + 1) % parsed.groupSize) && i < len - parsed.groupSize) {\n str += parsed.group;\n }\n }\n valueParts[0] = str;\n }\n\n valueParts[1] = maskParts[1] && valueParts[1] ? parsed.decimal + valueParts[1] : '';\n\n const result = valueParts.join('');\n if (result === '0' || result === '') {\n isNegative = false;\n }\n\n return parsed.prefix + (isNegative ? '-' : '') + result + parsed.suffix;\n }\n\n /**\n * Decimal/group separators and fraction length from the configured mask.\n * Use for free-form numeric inputs (e.g. bet multipliers) that are not currency amounts.\n */\n public getMaskLocale(): { decimal: string; group: string; decimalPlaces: number } {\n const parsed = this.parseMask(this.config.mask);\n return {\n decimal: parsed.decimal,\n group: parsed.group,\n decimalPlaces:\n parsed.decimalPlaces > 0 ? parsed.decimalPlaces : this.config.decimalPrecision,\n };\n }\n\n /**\n * Format a number using only the numeric portion of the mask (no prefix/suffix, no denom).\n * Suitable for multipliers and limits (e.g. autoplay 10.5× bet).\n */\n public formatPlainNumber(value: number, options: Pick<FormatOptions, 'forceDecimals'> = {}): string {\n const { forceDecimals = false } = options;\n const parsed = this.parseMask(this.config.mask);\n let pattern = parsed.pattern;\n if (forceDecimals) {\n pattern = pattern.replace(/\\.##/g, '.00');\n }\n return this.applyMask(pattern, value);\n }\n\n /**\n * Get current configuration.\n *\n * @returns Current configuration\n */\n public getConfig(): Readonly<NumberFormatterConfig> {\n return { ...this.config };\n }\n}\n","/**\n * Array prototype extensions for game utilities.\n *\n * ⚠️ WARNING: This file modifies Array.prototype globally.\n * It must be imported early in the application lifecycle.\n *\n * Usage:\n * - array.shuffle() - Returns shuffled copy\n * - array.random() - Returns random element\n * - array.clone() - Returns shallow copy\n * - array.exclude(1, 2) - Returns array without indices 1, 2\n */\n\nObject.defineProperty(Array.prototype, 'exclude', {\n value: function <T>(this: T[], ...indexToExclude: number[]): T[] {\n return this.filter((_, index) => !indexToExclude.includes(index));\n },\n enumerable: false,\n});\n\nObject.defineProperty(Array.prototype, 'random', {\n value: function <T>(): T {\n const randomIndex = Math.floor(Math.random() * this.length);\n return this[randomIndex];\n },\n enumerable: false,\n});\n\nObject.defineProperty(Array.prototype, 'lastItem', {\n value: function <T>(): T {\n return this[this.length - 1];\n },\n enumerable: false,\n});\n\nObject.defineProperty(Array.prototype, 'firstItem', {\n value: function <T>(): T {\n return this[0];\n },\n enumerable: false,\n});\n\nObject.defineProperty(Array.prototype, 'clone', {\n value: function <T>(): T[] {\n return [...this];\n },\n enumerable: false,\n});\n\nObject.defineProperty(Array.prototype, 'shuffle', {\n value: function <T>(this: T[]): T[] {\n const array = [...this];\n for (let i = array.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [array[i], array[j]] = [array[j], array[i]];\n }\n return array;\n },\n enumerable: false,\n});\n\ndeclare global {\n interface Array<T> {\n random(): T;\n clone(): T[];\n exclude(...indexToExclude: number[]): T[];\n shuffle(): T[];\n lastItem(): T | undefined;\n firstItem(): T | undefined;\n }\n}\n\n// Export a dummy value to ensure this module is not tree-shaken\nexport const __arrayUtilsLoaded = true;\n","import { Container, Rectangle } from 'pixi.js';\n\n/**\n * Type helper for elements that have an anchor property\n */\nexport type HasAnchor<T> = T & { anchor: { set(x: number, y: number): void } };\n\n/**\n * Calculate animation speed from FPS for PixiJS AnimatedSprite\n *\n * Converts animation FPS to PixiJS animationSpeed value. Default is 12 FPS because\n * animation sequences are typically exported from animation tools at 12 FPS,\n * while PixiJS runs at 60 FPS (requiring conversion: exportedFps / 60).\n *\n * @param exportedFps - Frames per second of the exported animation sequence (default: 12)\n * @param speed - Speed multiplier for playback (default: 1)\n * @returns Animation speed value for PixiJS AnimatedSprite (exportedFps / 60 * speed)\n *\n * @example\n * ```ts\n * const animSprite = new AnimatedSprite(frames);\n * // For 12 FPS animation (standard export)\n * animSprite.animationSpeed = calculateAnimationSpeed(12); // 0.2\n * // For 24 FPS animation\n * animSprite.animationSpeed = calculateAnimationSpeed(24); // 0.4\n * // For 12 FPS animation with 2x playback speed\n * animSprite.animationSpeed = calculateAnimationSpeed(12, 2); // 0.4\n * ```\n */\nexport function calculateAnimationSpeed(exportedFps: number = 12, speed: number = 1): number {\n return (exportedFps / 60) * speed;\n}\n\n/**\n * Apply anchor to a PixiJS element that supports anchor property\n *\n * @param element - Container element (Sprite, AnimatedSprite, Text, etc.)\n * @param anchor - Anchor point to set\n * @param defaultAnchor - Default anchor if anchor is not provided\n *\n * @example\n * ```ts\n * const sprite = new Sprite(texture);\n * applyAnchor(sprite, { x: 0.5, y: 0.5 });\n * ```\n */\nexport function applyAnchor(\n element: Container,\n anchor?: { x: number; y: number },\n defaultAnchor?: { x: number; y: number },\n): void {\n if (!('anchor' in element)) return;\n\n const elementWithAnchor = element as HasAnchor<Container>;\n\n if (anchor) {\n elementWithAnchor.anchor.set(anchor.x, anchor.y);\n } else if (defaultAnchor) {\n elementWithAnchor.anchor.set(defaultAnchor.x, defaultAnchor.y);\n }\n}\n\n/**\n * Apply scale to a PixiJS Container element\n * Supports both uniform (number) and non-uniform ({ x, y }) scaling\n *\n * @param element - Container element to scale\n * @param scale - Scale value (number for uniform, object for non-uniform)\n *\n * @example\n * ```ts\n * // Uniform scale\n * applyScale(sprite, 2);\n *\n * // Non-uniform scale\n * applyScale(sprite, { x: 2, y: 1.5 });\n * ```\n */\nexport function applyScale(element: Container, scale?: number | { x: number; y: number }): void {\n if (scale === undefined) return;\n\n if (typeof scale === 'number') {\n element.scale.set(scale);\n } else {\n element.scale.set(scale.x, scale.y);\n }\n}\n\n/**\n * Apply common visual properties to a PixiJS Container element\n * Includes alpha, blendMode, and scale\n *\n * @param element - Container element\n * @param config - Configuration object with optional properties\n *\n * @example\n * ```ts\n * applyCommonProperties(sprite, {\n * alpha: 0.8,\n * blendMode: 'add',\n * scale: 1.5\n * });\n * ```\n */\nexport function applyCommonProperties(\n element: Container,\n config: {\n alpha?: number;\n blendMode?: string;\n scale?: number | { x: number; y: number };\n },\n): void {\n if (config.alpha !== undefined) {\n element.alpha = config.alpha;\n }\n\n if (config.blendMode) {\n element.blendMode = config.blendMode as any;\n }\n\n applyScale(element, config.scale);\n}\n\n/**\n * Update or create a Rectangle for bounds\n * Reuses existing Rectangle instance to prevent memory leaks\n *\n * @param existingBounds - Existing Rectangle instance or undefined\n * @param x - X position\n * @param y - Y position\n * @param width - Width\n * @param height - Height\n * @returns Updated or new Rectangle instance\n *\n * @example\n * ```ts\n * // First call - creates new Rectangle\n * this.boundsArea = updateBounds(this.boundsArea, 0, 0, 100, 100);\n *\n * // Subsequent calls - reuses existing Rectangle\n * this.boundsArea = updateBounds(this.boundsArea, 0, 0, 200, 200);\n * ```\n */\nexport function updateBounds(\n existingBounds: Rectangle | undefined,\n x: number,\n y: number,\n width: number,\n height: number,\n): Rectangle {\n if (existingBounds instanceof Rectangle) {\n existingBounds.x = x;\n existingBounds.y = y;\n existingBounds.width = width;\n existingBounds.height = height;\n return existingBounds;\n }\n return new Rectangle(x, y, width, height);\n}\n","interface DebounceSettings {\n /** Specify invoking on the leading edge of the timeout. */\n leading?: boolean | undefined;\n /** The maximum time func is allowed to be delayed before it's invoked. */\n maxWait?: number | undefined;\n /** Specify invoking on the trailing edge of the timeout. */\n trailing?: boolean | undefined;\n}\n\ninterface DebounceSettingsLeading extends DebounceSettings {\n leading: true;\n}\n\nexport interface DebouncedFunc<T extends (...args: any[]) => any> {\n /**\n * Call the original function, but applying the debounce rules.\n *\n * If the debounced function can be run immediately, this calls it and returns\n * its return value.\n *\n * Otherwise, it returns the return value of the last invocation, or undefined\n * if the debounced function was not invoked yet.\n */\n (...args: Parameters<T>): ReturnType<T> | undefined;\n\n /** Throw away any pending invocation of the debounced function. */\n cancel(): void;\n\n /**\n * If there is a pending invocation of the debounced function, invoke it\n * immediately and return its return value.\n *\n * Otherwise, return the value from the last invocation, or undefined if the\n * debounced function was never invoked.\n */\n flush(): ReturnType<T> | undefined;\n\n /** Check if there is a pending invocation. */\n pending(): boolean;\n}\n\ninterface DebouncedFuncLeading<T extends (...args: any[]) => any> extends DebouncedFunc<T> {\n (...args: Parameters<T>): ReturnType<T>;\n flush(): ReturnType<T>;\n}\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked, or until the next browser frame is drawn. The debounced function\n * comes with a `cancel` method to cancel delayed `func` invocations and a\n * `flush` method to immediately invoke them. Provide `options` to indicate\n * whether `func` should be invoked on the leading and/or trailing edge of the\n * `wait` timeout. The `func` is invoked with the last arguments provided to the\n * debounced function. Subsequent calls to the debounced function return the\n * result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n * on the trailing edge of the timeout only if the debounced function is invoked\n * more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * If `wait` is omitted in an environment with `requestAnimationFrame`, `func`\n * invocation will be deferred until the next frame is drawn (typically about\n * 16ms).\n *\n * @param func The function to debounce.\n * @param wait The number of milliseconds to delay. Default is `0`.\n * @param options The options object. Default is `{}`.\n * @returns Returns the new debounced function.\n */\nexport function debounce<T extends (...args: any) => any>(\n func: T,\n wait: number | undefined,\n options: DebounceSettingsLeading,\n): DebouncedFuncLeading<T>;\nexport function debounce<T extends (...args: any) => any>(\n func: T,\n wait?: number,\n options?: DebounceSettings,\n): DebouncedFunc<T>;\nexport function debounce<T extends (...args: any) => any>(\n func: T,\n wait = 0,\n options: DebounceSettingsLeading | DebounceSettings = {},\n): DebouncedFunc<T> | DebouncedFuncLeading<T> {\n let lastArgs: Parameters<T> | undefined;\n let lastThis: any;\n const maxWait = options.maxWait ? options.maxWait : wait;\n let result: ReturnType<T> | undefined;\n let timerId: ReturnType<typeof setTimeout> | ReturnType<typeof globalThis.requestAnimationFrame> | undefined;\n let lastCallTime: number | undefined;\n let lastInvokeTime = 0;\n const leading = !!options.leading;\n const maxing = 'maxWait' in options;\n const trailing = options.trailing ?? true;\n\n // Bypass `requestAnimationFrame` by explicitly setting `wait=0`.\n const useRAF = wait !== 0 && typeof globalThis.requestAnimationFrame === 'function';\n\n if (typeof func !== 'function') {\n throw new TypeError('Expected a function');\n }\n\n function invokeFunc(time: number) {\n const args = lastArgs;\n const thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args!);\n\n return result;\n }\n\n function startTimer(pendingFunc: () => ReturnType<T> | undefined, milliseconds: number) {\n if (useRAF) {\n if (typeof timerId === 'number') {\n globalThis.cancelAnimationFrame(timerId);\n }\n\n return globalThis.requestAnimationFrame(pendingFunc);\n }\n\n return setTimeout(pendingFunc, milliseconds);\n }\n\n function cancelTimer(id: number | ReturnType<typeof setTimeout>) {\n if (useRAF) {\n globalThis.cancelAnimationFrame(id as number);\n\n return;\n }\n clearTimeout(id);\n }\n\n function leadingEdge(time: number) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = startTimer(timerExpired, wait);\n\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time: number) {\n const timeSinceLastCall = time - (lastCallTime || 0);\n const timeSinceLastInvoke = time - lastInvokeTime;\n const timeWaiting = wait - timeSinceLastCall;\n\n return maxing ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting;\n }\n\n function shouldInvoke(time: number) {\n const timeSinceLastCall = time - (lastCallTime || 0);\n const timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (\n lastCallTime === undefined ||\n timeSinceLastCall >= wait ||\n timeSinceLastCall < 0 ||\n (maxing && timeSinceLastInvoke >= maxWait)\n );\n }\n\n function timerExpired() {\n const time = Date.now();\n\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = startTimer(timerExpired, remainingWait(time));\n\n return undefined;\n }\n\n function trailingEdge(time: number) {\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n cancelTimer(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(Date.now());\n }\n\n function pending() {\n return timerId !== undefined;\n }\n\n function debounced(this: any, ...args: Parameters<T>) {\n const time = Date.now();\n const isInvoking = shouldInvoke(time);\n\n lastArgs = args;\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n timerId = startTimer(timerExpired, wait);\n\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = startTimer(timerExpired, wait);\n }\n\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n debounced.pending = pending;\n\n return debounced;\n}\n\nexport interface ThrottleSettings {\n /** Specify invoking on the leading edge of the timeout. */\n leading?: boolean | undefined;\n /** Specify invoking on the trailing edge of the timeout. */\n trailing?: boolean | undefined;\n}\n\n/**\n * Creates a throttled function that only invokes `func` at most once per every\n * `wait` milliseconds (or once per browser frame). The throttled function comes\n * with a `cancel` method to cancel delayed `func` invocations and a `flush`\n * method to immediately invoke them. Provide `options` to indicate whether\n * `func` should be invoked on the leading and/or trailing edge of the `wait`\n * timeout. The `func` is invoked with the last arguments provided to the\n * throttled function. Subsequent calls to the throttled function return the\n * result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n * on the trailing edge of the timeout only if the throttled function is invoked\n * more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * If `wait` is omitted in an environment with `requestAnimationFrame`, `func`\n * invocation will be deferred until the next frame is drawn (typically about\n * 16ms).\n *\n * @param func The function to throttle.\n * @param wait The number of milliseconds to throttle invocations to. Default is `0`.\n * @param options The options object. Default is `{}`.\n * @returns Returns the new throttled function.\n */\nexport function throttle<T extends (...args: any) => any>(\n func: T,\n wait?: number,\n options: ThrottleSettings = {},\n): DebouncedFunc<T> {\n const leading = options.leading ?? true;\n const trailing = options.trailing ?? true;\n\n if (typeof func !== 'function') {\n throw new TypeError('Expected a function');\n }\n\n return debounce(func, wait, {\n leading,\n trailing,\n maxWait: wait,\n });\n}\n"]}
|
package/dist/helpers/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export { resolvePublicPath } from '../chunk-NQMORMNP.js';
|
|
2
|
-
import { darkenColor, lightenColor } from '../chunk-
|
|
2
|
+
import { darkenColor, lightenColor } from '../chunk-YSLGJAV6.js';
|
|
3
3
|
import '../chunk-DOHQE2YZ.js';
|
|
4
4
|
import '../chunk-5BLUF2HG.js';
|
|
5
|
-
import '../chunk-
|
|
5
|
+
import { require_lodash } from '../chunk-NAQG7TMS.js';
|
|
6
|
+
import { __toESM } from '../chunk-G3PMV62Z.js';
|
|
6
7
|
import { ExtensionType, Assets, Color, Cache, Texture, TextureSource } from 'pixi.js';
|
|
7
8
|
import { minimatch } from 'minimatch';
|
|
8
|
-
import { mergeWith, isPlainObject } from 'lodash';
|
|
9
9
|
|
|
10
10
|
var parserConfig = {};
|
|
11
11
|
function manipulateSVG(svgString, data) {
|
|
@@ -643,9 +643,12 @@ function createTypedEventBridge(source, target, config) {
|
|
|
643
643
|
};
|
|
644
644
|
return createEventBridge(source, target, bridgeConfig);
|
|
645
645
|
}
|
|
646
|
+
|
|
647
|
+
// helpers/mergeUtils.ts
|
|
648
|
+
var import_lodash = __toESM(require_lodash(), 1);
|
|
646
649
|
var REMOVE = Symbol("REMOVE");
|
|
647
650
|
var mergeWithRemove = (base, ...overrides) => {
|
|
648
|
-
const result = mergeWith({}, base, ...overrides, (_objValue, srcValue) => {
|
|
651
|
+
const result = (0, import_lodash.mergeWith)({}, base, ...overrides, (_objValue, srcValue) => {
|
|
649
652
|
if (srcValue === REMOVE) {
|
|
650
653
|
return REMOVE;
|
|
651
654
|
}
|
|
@@ -655,11 +658,11 @@ var mergeWithRemove = (base, ...overrides) => {
|
|
|
655
658
|
return void 0;
|
|
656
659
|
});
|
|
657
660
|
const cleanRemoved = (obj) => {
|
|
658
|
-
if (!isPlainObject(obj)) return obj;
|
|
661
|
+
if (!(0, import_lodash.isPlainObject)(obj)) return obj;
|
|
659
662
|
for (const key of Object.keys(obj)) {
|
|
660
663
|
if (obj[key] === REMOVE) {
|
|
661
664
|
delete obj[key];
|
|
662
|
-
} else if (isPlainObject(obj[key])) {
|
|
665
|
+
} else if ((0, import_lodash.isPlainObject)(obj[key])) {
|
|
663
666
|
cleanRemoved(obj[key]);
|
|
664
667
|
}
|
|
665
668
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../helpers/SVGParser.ts","../../helpers/SVGLoader.ts","../../helpers/SVGAssetHelper.ts","../../helpers/AssetHelper.ts","../../helpers/eventBridge.ts","../../helpers/mergeUtils.ts"],"names":["Assets","Texture"],"mappings":"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","file":"index.js","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Texture, TextureSource, LoaderParser, ExtensionType, ResolvedAsset } from 'pixi.js';\n// @ts-ignore\nimport { minimatch } from 'minimatch';\n\n/**\n * Style definitions for SVG elements using CSS selectors.\n *\n * Maps CSS selectors to attribute-value pairs that will be applied to matching SVG elements.\n * Commonly used for dynamic theming and color changes.\n *\n * @example\n * ```typescript\n * const styles: SVGStyleData = {\n * '#primary': { fill: '#4CAF50', stroke: '#388E3C' },\n * '.icon': { fill: '#FFFFFF' },\n * 'circle': { opacity: '0.8' }\n * };\n * ```\n *\n * @public\n */\nexport interface SVGStyleData {\n /** CSS selector as key, attributes as value */\n [selector: string]: {\n /** SVG attribute name (e.g., 'fill', 'stroke', 'opacity') */\n [attribute: string]: string;\n };\n}\n\n/**\n * Configuration data for loading and processing SVG files.\n *\n * This interface defines all options available when loading an SVG asset,\n * including styling, sizing, and resolution settings.\n *\n * @example\n * ```typescript\n * const loadData: SVGLoadData = {\n * styles: {\n * '#background': { fill: '#4CAF50' },\n * '#icon': { fill: '#FFFFFF' }\n * },\n * size: { width: 128, height: 128 },\n * resolution: 2\n * };\n * ```\n *\n * @public\n */\nexport interface SVGLoadData {\n /** Style definitions to apply to SVG elements */\n styles?: SVGStyleData;\n /** Target size for rasterization (width and height in pixels) */\n size?: { width: number; height: number };\n /** Resolution multiplier for high-DPI displays (default: 1) */\n resolution?: number;\n /** Button states for multi-state assets (used by SVGAssetHelper) */\n states?: string[];\n}\n\n/**\n * Global configuration for the SVG parser.\n *\n * @public\n */\nexport interface SVGParserConfig {\n /** Glob pattern to match SVG files (uses minimatch) */\n testPattern?: string;\n}\n\n// Parser global configuration\nlet parserConfig: SVGParserConfig = {};\n\n/**\n * Manipulates SVG string by applying styles and size modifications.\n *\n * This function parses the SVG string, applies CSS selector-based styles,\n * and optionally resizes the SVG before returning the modified string.\n *\n * @param svgString - Raw SVG file content as string\n * @param data - Optional load data with styles and size\n * @returns Modified SVG string\n *\n * @internal\n */\nfunction manipulateSVG(svgString: string, data?: SVGLoadData): string {\n const parser = new DOMParser();\n const svgDoc = parser.parseFromString(svgString, 'image/svg+xml');\n const svgElement = svgDoc.documentElement;\n\n // Apply styles\n if (data?.styles) {\n Object.entries(data.styles).forEach(([selector, styles]) => {\n const elements = svgDoc.querySelectorAll(selector);\n elements.forEach((element) => {\n Object.entries(styles).forEach(([attr, value]) => {\n element.setAttribute(attr, value);\n });\n });\n });\n }\n\n // Set size\n if (data?.size) {\n svgElement.setAttribute('width', data.size.width.toString());\n svgElement.setAttribute('height', data.size.height.toString());\n\n // Optionally update the viewBox as well\n // const viewBox = svgElement.getAttribute('viewBox');\n // if (viewBox) {\n // const [x, y] = viewBox.split(' ');\n // svgElement.setAttribute('viewBox', `${x} ${y} ${data.size.width} ${data.size.height}`);\n // }\n }\n\n return new XMLSerializer().serializeToString(svgDoc);\n}\n\n/**\n * Converts an SVG string to a PixiJS Texture by rasterizing it to a canvas.\n *\n * This function creates an Image element from the SVG, draws it to a canvas,\n * and generates a PixiJS Texture from the canvas. Supports resolution scaling\n * for high-DPI displays.\n *\n * @param svgString - SVG content as string\n * @param data - Optional load data with resolution settings\n * @returns Promise that resolves to a PixiJS Texture\n *\n * @internal\n */\nasync function createTextureFromSVG(svgString: string, data?: SVGLoadData): Promise<Texture> {\n const blob = new Blob([svgString], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n\n const img = new Image();\n img.src = url;\n\n return new Promise((resolve, reject) => {\n img.onload = () => {\n try {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n\n if (!ctx) {\n reject(new Error('Could not get canvas context'));\n return;\n }\n\n const resolution = data?.resolution || 1;\n canvas.width = img.width * resolution;\n canvas.height = img.height * resolution;\n\n //ctx.scale(resolution, resolution);\n ctx.drawImage(img, 0, 0);\n\n const source = TextureSource.from(canvas);\n const texture = new Texture(source);\n resolve(texture);\n URL.revokeObjectURL(url);\n } catch (error) {\n reject(error);\n }\n };\n\n img.onerror = () => {\n URL.revokeObjectURL(url);\n reject(new Error('Failed to load SVG image'));\n };\n });\n}\n\n/**\n * PixiJS LoaderParser implementation for SVG files.\n *\n * This parser integrates with PixiJS Assets system to automatically detect,\n * load, and process SVG files as textures. It handles:\n * - SVG file detection via URL pattern matching\n * - Style manipulation using CSS selectors\n * - Size and resolution configuration\n * - Canvas rasterization for texture generation\n *\n * The parser is registered with PixiJS Assets via SVGLoader.install().\n *\n * @remarks\n * This parser uses DOMParser and Canvas API to convert SVG to raster textures.\n * All SVG manipulations happen before rasterization, ensuring clean output.\n *\n * @example\n * ```typescript\n * // Parser is automatically used after SVGLoader.install()\n * await Assets.load({\n * alias: 'icon',\n * src: 'assets/icon.svg',\n * data: {\n * styles: { '#primary': { fill: '#4CAF50' } },\n * size: { width: 64, height: 64 },\n * resolution: 2\n * }\n * });\n * ```\n *\n * @public\n */\nexport const SVGParser: LoaderParser<Texture, SVGLoadData> = {\n /**\n * Extension metadata for the parser.\n *\n * @internal\n */\n extension: {\n type: ExtensionType.LoadParser,\n name: 'svgParser',\n priority: 0,\n },\n\n /**\n * Unique identifier for the parser.\n *\n * @internal\n */\n id: 'svgParser',\n\n /**\n * Tests if a URL should be handled by this parser.\n *\n * By default, matches files ending with .svg extension.\n * Can be customized via configureSVGParser() with a glob pattern.\n *\n * @param url - Asset URL to test\n * @returns True if this parser should handle the URL\n */\n test: (url: string) => {\n // If a custom pattern is provided, use it\n if (parserConfig.testPattern) {\n try {\n const urlObj = new URL(url);\n const pathname = urlObj.pathname.startsWith('/')\n ? urlObj.pathname.slice(1)\n : urlObj.pathname;\n return minimatch(pathname, parserConfig.testPattern, { partial: true });\n } catch {\n // If URL parsing fails, try with the original string\n return minimatch(url, parserConfig.testPattern, { partial: true });\n }\n }\n\n // Default: check that the file actually ends with .svg\n return /\\.svg$/i.test(url);\n },\n\n /**\n * Loads and processes an SVG file into a PixiJS Texture.\n *\n * This method:\n * 1. Fetches the SVG file from the URL\n * 2. Applies style and size manipulations\n * 3. Rasterizes the SVG to a canvas\n * 4. Creates a PixiJS Texture from the canvas\n *\n * @param url - URL of the SVG file to load\n * @param resolvedAsset - Resolved asset with optional load data\n * @returns Promise that resolves to a PixiJS Texture\n */\n async load(url: string, resolvedAsset?: ResolvedAsset<SVGLoadData>): Promise<Texture> {\n // Fetch the SVG file\n const response = await fetch(url);\n const svgString = await response.text();\n\n // Manipulate the SVG\n const manipulatedSVG = manipulateSVG(svgString, resolvedAsset?.data);\n\n // Convert to Texture\n const texture = await createTextureFromSVG(manipulatedSVG, resolvedAsset?.data);\n texture.label = resolvedAsset?.src ?? 'unknown';\n return texture;\n },\n};\n\n/**\n * Configures the SVG parser with global settings.\n *\n * This function allows customization of the parser behavior, such as\n * specifying custom glob patterns for SVG file matching.\n *\n * Typically called by SVGLoader.install() but can be used independently.\n *\n * @param config - Parser configuration options\n *\n * @example\n * ```typescript\n * configureSVGParser({\n * testPattern: 'assets/svg/*.svg'\n * });\n * ```\n *\n * @public\n */\nexport function configureSVGParser(config: SVGParserConfig): void {\n parserConfig = { ...parserConfig, ...config };\n}\n","import { Assets } from 'pixi.js';\nimport { SVGParser, configureSVGParser } from './SVGParser';\n\n/**\n * Configuration options for the SVG loader.\n */\nexport interface SVGLoaderConfig {\n /** Glob pattern to match SVG files (uses minimatch) */\n testPattern?: string;\n}\n\n/**\n * SVG loader plugin for PixiJS Assets system.\n *\n * SVGLoader integrates the SVG parser into PixiJS asset loading pipeline,\n * enabling automatic loading and processing of SVG files as textures.\n *\n * @remarks\n * Install once at application startup using SVGLoader.install().\n * After installation, SVG files can be loaded using PixiJS Assets API or SVGAssetHelper.\n *\n * @public\n */\nexport class SVGLoader {\n private static installed = false;\n\n /**\n * Installs the SVG loader into the PixiJS Assets system.\n *\n * This method must be called once at application startup before loading any SVG assets.\n * It registers the SVG parser with PixiJS, enabling automatic SVG file processing.\n * This method is idempotent - calling it multiple times is safe but only the first call will take effect.\n *\n * @param config - Optional configuration for SVG file matching\n */\n static install(config?: SVGLoaderConfig): void {\n if (this.installed) {\n console.warn('SVGLoader is already installed');\n return;\n }\n\n // Configure parser if options provided\n if (config) {\n configureSVGParser(config);\n }\n\n // Add parser to Assets loader\n Assets.loader.parsers.unshift(SVGParser);\n\n this.installed = true;\n console.log('SVG Loader installed successfully');\n }\n\n /**\n * Checks if the SVG loader has been installed.\n *\n * @returns True if the loader is installed, false otherwise\n */\n static isInstalled(): boolean {\n return this.installed;\n }\n\n /**\n * Uninstalls the SVG loader from the PixiJS Assets system.\n *\n * This method is primarily intended for testing purposes.\n * In production, you typically install the loader once and never uninstall it.\n */\n static uninstall(): void {\n if (!this.installed) {\n return;\n }\n\n // Remove parser from Assets loader\n const index = Assets.loader.parsers.indexOf(SVGParser);\n if (index > -1) {\n Assets.loader.parsers.splice(index, 1);\n }\n\n this.installed = false;\n console.log('SVG Loader uninstalled');\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Assets, Cache, Color, type ColorSource } from 'pixi.js';\nimport { SVGLoadData, SVGStyleData } from './SVGParser';\nimport type { ButtonStateKey } from '../ui/components/ButtonComp';\nimport { lightenColor, darkenColor } from '../utils';\n\n/**\n * Button state styles for SVG assets.\n *\n * Defines the visual appearance of buttons in different interaction states.\n * Each state contains CSS-like style definitions for SVG elements.\n * Uses ButtonComp state names: up, down, over, disabled.\n *\n * @example\n * ```typescript\n * const buttonStyles: ButtonState = {\n * up: { '#primary': { fill: '#4CAF50' } },\n * over: { '#primary': { fill: '#66BB6A' } },\n * down: { '#primary': { fill: '#388E3C' } },\n * disabled: { '#primary': { fill: '#CCCCCC' } }\n * };\n * ```\n */\nexport interface ButtonState {\n /** Up/default state styles */\n up: SVGStyleData;\n /** Over/hover state styles */\n over: SVGStyleData;\n /** Down/pressed state styles */\n down: SVGStyleData;\n /** Disabled state styles (optional) */\n disabled?: SVGStyleData;\n /** Selected up state styles */\n selected_up?: SVGStyleData;\n /** Selected over state styles */\n selected_over?: SVGStyleData;\n /** Selected down state styles */\n selected_down?: SVGStyleData;\n /** Selected disabled state styles */\n selected_disabled?: SVGStyleData;\n}\n\n/**\n * Configuration for loading SVG assets.\n *\n * @example\n * ```typescript\n * const config: SVGAssetConfig = {\n * alias: 'play_button',\n * src: 'assets/svg/buttons/play.svg',\n * size: { width: 120, height: 120 },\n * resolution: 2,\n * themeColor: '#4CAF50',\n * states: ['up', 'over', 'down']\n * };\n * ```\n */\nexport interface SVGAssetConfig {\n /** Unique identifier for the asset */\n alias: string;\n /** Path to the SVG file */\n src: string;\n /** Target size for rasterization */\n size?: { width: number; height: number };\n /** Resolution multiplier for high-DPI displays */\n resolution?: number;\n /** Theme color for styling (supports all PixiJS ColorSource formats) */\n themeColor?: ColorSource;\n /** Button states to generate (e.g., ['up', 'over', 'down', 'disabled']) */\n states?: ButtonStateKey[];\n}\n\n/**\n * High-level utility for loading and managing SVG assets in PixiJS.\n *\n * SVGAssetHelper provides a convenient API for loading SVG files as PixiJS textures\n * with automatic theming, button state management, and batch loading capabilities.\n *\n * ## Features\n *\n * - **Theme Support**: Global and per-asset theme colors\n * - **Button States**: Automatic generation of up, over, down, disabled states\n * - **Batch Loading**: Load multiple assets efficiently\n * - **Color Manipulation**: Automatic lighten/darken for button states\n * - **Cache Management**: Check and clear loaded assets\n * - **Custom Styles**: Create custom style configurations\n *\n * ## Workflow\n *\n * 1. **Initialize**: Set global theme color (optional)\n * 2. **Load**: Load SVG assets with configuration\n * 3. **Use**: Retrieve textures and create sprites\n * 4. **Manage**: Check cache and clear unused assets\n *\n * @example\n * ```typescript\n * import { SVGAssetHelper, SVGLoader } from '@rb-games/core/helpers';\n * import { Sprite } from 'pixi.js';\n *\n * // Initialize SVG system\n * SVGLoader.install();\n * SVGAssetHelper.setThemeColor('#4CAF50');\n *\n * // Load a simple icon\n * await SVGAssetHelper.loadSVGAsset({\n * alias: 'settings_icon',\n * src: 'assets/svg/settings.svg',\n * size: { width: 48, height: 48 },\n * themeColor: '#2196F3'\n * });\n *\n * // Create sprite\n * const icon = new Sprite(SVGAssetHelper.getAsset('settings_icon'));\n * ```\n *\n * @example\n * ```typescript\n * // Load button with states\n * await SVGAssetHelper.loadButtonAsset({\n * alias: 'play_btn',\n * src: 'assets/svg/play.svg',\n * size: { width: 120, height: 120 },\n * themeColor: '#4CAF50',\n * states: ['up', 'over', 'down']\n * });\n *\n * // Create interactive button\n * const button = new Sprite(SVGAssetHelper.getAsset('play_btn', 'up'));\n * button.eventMode = 'static';\n * button.cursor = 'pointer';\n *\n * button.on('pointerover', () => {\n * button.texture = SVGAssetHelper.getAsset('play_btn', 'over');\n * });\n *\n * button.on('pointerout', () => {\n * button.texture = SVGAssetHelper.getAsset('play_btn', 'up');\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Batch load multiple assets\n * await SVGAssetHelper.loadBatchAssets([\n * {\n * alias: 'star_icon',\n * src: 'assets/svg/icons/star.svg',\n * size: { width: 32, height: 32 },\n * themeColor: '#FFD700'\n * },\n * {\n * alias: 'close_btn',\n * src: 'assets/svg/buttons/close.svg',\n * size: { width: 40, height: 40 },\n * states: ['up', 'over'],\n * themeColor: '#F44336'\n * }\n * ]);\n * ```\n *\n * @public\n */\nexport class SVGAssetHelper {\n private static themeColor: ColorSource = '#4CAF50';\n\n /**\n * Sets the global theme color for all SVG assets.\n *\n * This color will be used as the default for all assets unless overridden\n * in individual asset configurations.\n *\n * @param color - Theme color (supports all PixiJS ColorSource formats)\n *\n * @example\n * ```typescript\n * // Set theme with hex string\n * SVGAssetHelper.setThemeColor('#4CAF50');\n *\n * // Set theme with number\n * SVGAssetHelper.setThemeColor(0x4CAF50);\n *\n * // Set theme with RGB array\n * SVGAssetHelper.setThemeColor([0.3, 0.69, 0.31]);\n * ```\n */\n static setThemeColor(color: ColorSource): void {\n this.themeColor = color;\n }\n\n /**\n * Gets the current global theme color.\n *\n * @returns The current theme color as ColorSource\n *\n * @example\n * ```typescript\n * const currentTheme = SVGAssetHelper.getThemeColor();\n * // Can be used directly or converted as needed\n * const hex = new Color(currentTheme).toHex();\n * ```\n */\n static getThemeColor(): ColorSource {\n return this.themeColor;\n }\n\n /**\n * Create button state styles based on theme color\n */\n static createButtonStyles(\n themeColor?: ColorSource,\n variations?: { /** lighten amount */ over: number; /** darken amount */ down: number },\n ): ButtonState {\n const baseColor = themeColor || this.themeColor;\n const baseColorHex = new Color(baseColor).toHex();\n\n return {\n up: {\n '#primary': { fill: baseColorHex },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: baseColorHex },\n },\n over: {\n '#primary': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n },\n down: {\n '#primary': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n },\n disabled: {\n '#primary': { fill: '#cccccc' },\n '#secondary': { fill: '#999999' },\n '#background': { fill: '#cccccc' },\n },\n selected_up: {\n '#primary': { fill: baseColorHex },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: baseColorHex },\n },\n selected_over: {\n '#primary': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n },\n selected_down: {\n '#primary': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n },\n selected_disabled: {\n '#primary': { fill: '#cccccc' },\n '#secondary': { fill: '#999999' },\n '#background': { fill: '#cccccc' },\n },\n };\n }\n\n /**\n * Create custom styles\n */\n static createCustomStyles(config: {\n selectors: string[];\n colors: { [state: string]: string[] };\n }): { [state: string]: SVGStyleData } {\n const result: { [state: string]: SVGStyleData } = {};\n\n Object.entries(config.colors).forEach(([state, colors]) => {\n result[state] = {};\n config.selectors.forEach((selector, index) => {\n if (colors[index]) {\n result[state][selector] = { fill: colors[index] };\n }\n });\n });\n\n return result;\n }\n\n /**\n * Loads a single SVG asset as a PixiJS texture.\n *\n * This method loads an SVG file, applies optional theme colors and styles,\n * and registers it with the PixiJS Assets system for later retrieval.\n *\n * @param config - Asset configuration\n * @returns Promise that resolves when the asset is loaded\n *\n * @example\n * ```typescript\n * // Load a simple icon\n * await SVGAssetHelper.loadSVGAsset({\n * alias: 'home_icon',\n * src: 'assets/svg/home.svg',\n * size: { width: 64, height: 64 },\n * resolution: 2\n * });\n *\n * // Load with theme color\n * await SVGAssetHelper.loadSVGAsset({\n * alias: 'settings_icon',\n * src: 'assets/svg/settings.svg',\n * size: { width: 48, height: 48 },\n * themeColor: '#2196F3'\n * });\n * ```\n */\n static async loadSVGAsset(config: SVGAssetConfig): Promise<void> {\n const loadData: SVGLoadData = {\n size: config.size,\n resolution: config.resolution || 1,\n };\n\n if (config.themeColor) {\n const styles = this.createButtonStyles(config.themeColor);\n loadData.styles = styles.up;\n }\n\n await Assets.load({\n alias: config.alias,\n src: `${config.src}`,\n data: loadData,\n });\n }\n\n /**\n * Loads a button SVG asset with multiple interaction states.\n *\n * Automatically generates up, over, down, and optionally disabled states\n * by applying color variations (lighten for over, darken for down).\n * Each state is loaded as a separate texture with the naming convention `{alias}_{state}`.\n *\n * @param config - Button asset configuration\n * @returns Promise that resolves when all button states are loaded\n *\n * @example\n * ```typescript\n * // Load button with default states\n * await SVGAssetHelper.loadButtonAsset({\n * alias: 'play_btn',\n * src: 'assets/svg/play.svg',\n * size: { width: 120, height: 120 },\n * themeColor: '#4CAF50'\n * });\n *\n * // Access different states\n * const upTexture = SVGAssetHelper.getAsset('play_btn', 'up');\n * const overTexture = SVGAssetHelper.getAsset('play_btn', 'over');\n * const downTexture = SVGAssetHelper.getAsset('play_btn', 'down');\n * ```\n *\n * @example\n * ```typescript\n * // Custom states\n * await SVGAssetHelper.loadButtonAsset({\n * alias: 'custom_btn',\n * src: 'assets/svg/button.svg',\n * size: { width: 100, height: 40 },\n * themeColor: '#E91E63',\n * states: ['up', 'over', 'down', 'disabled']\n * });\n * ```\n */\n static async loadButtonAsset(config: SVGAssetConfig): Promise<void> {\n const styles = this.createButtonStyles(\n config.themeColor\n ? typeof config.themeColor === 'number'\n ? new Color(config.themeColor).toHex()\n : config.themeColor\n : undefined,\n );\n\n const states = config.states || ['up', 'over', 'down'];\n\n for (const state of states) {\n const stateStyles = styles[state as keyof ButtonState];\n if (stateStyles) {\n const loadData: SVGLoadData = {\n styles: stateStyles,\n size: config.size,\n resolution: config.resolution || 1,\n };\n\n const hash = await this.generateAssetHash(config.src, loadData);\n\n await Assets.load({\n alias: `${config.alias}_${state}`,\n src: `${config.src}?hash=${hash}`,\n data: loadData,\n });\n }\n }\n }\n\n /**\n * Loads multiple SVG assets in parallel for efficient batch loading.\n *\n * Automatically determines whether to load each asset as a simple SVG or\n * as a button with states based on the states property.\n *\n * @param basePath - Base directory path for all assets (assets without src will use basePath/alias.svg)\n * @param assets - Array of asset configurations (strings, objects, or mixed)\n * @param defaults - Optional default configuration applied to all assets\n * @returns Promise that resolves when all assets are loaded\n *\n * @example\n * ```typescript\n * // Simple string array (most convenient)\n * await SVGAssetHelper.loadBatchAssets(\n * 'assets/svg/desktop',\n * ['btn_bet_minus', 'btn_bet_plus', 'btn_spin'],\n * {\n * size: { width: 100, height: 100 },\n * states: ['up', 'over', 'down', 'disabled']\n * }\n * );\n *\n * // Mixed array (strings and objects for customization)\n * await SVGAssetHelper.loadBatchAssets(\n * 'assets/svg/desktop',\n * [\n * 'btn_bet_minus', // uses default size\n * 'btn_bet_plus', // uses default size\n * { alias: 'btn_spin', size: { width: 120, height: 120 } } // custom size\n * ],\n * {\n * size: { width: 80, height: 80 },\n * states: ['up', 'over', 'down', 'disabled']\n * }\n * );\n *\n * // All objects (full customization)\n * await SVGAssetHelper.loadBatchAssets(\n * 'assets/svg/desktop',\n * [\n * { alias: 'btn_bet_minus', size: { width: 90, height: 90 } },\n * { alias: 'btn_bet_plus' }, // uses default size\n * { alias: 'btn_spin', states: ['up', 'over'] } // custom states\n * ],\n * {\n * size: { width: 100, height: 100 },\n * states: ['up', 'over', 'down', 'disabled']\n * }\n * );\n *\n * // With full src paths (when assets are in different directories)\n * await SVGAssetHelper.loadBatchAssets(\n * '',\n * [\n * {\n * alias: 'star_icon',\n * src: 'assets/svg/icons/star.svg',\n * size: { width: 32, height: 32 },\n * themeColor: '#FFD700'\n * },\n * {\n * alias: 'close_btn',\n * src: 'assets/svg/buttons/close.svg',\n * size: { width: 40, height: 40 },\n * states: ['up', 'over'],\n * themeColor: '#F44336'\n * }\n * ]\n * );\n * ```\n */\n static async loadBatchAssets(\n basePath: string,\n assets: Array<string | Partial<SVGAssetConfig>>,\n defaults?: Partial<SVGAssetConfig>,\n ): Promise<void> {\n const defaultConfig = defaults || {};\n\n // Convert string array to asset configs\n const assetConfigs: Array<Partial<SVGAssetConfig>> = assets.map((asset) =>\n typeof asset === 'string' ? { alias: asset } : asset,\n );\n\n const configs: SVGAssetConfig[] = assetConfigs.map((asset) => ({\n alias: asset.alias!,\n src: asset.src || (basePath ? `${basePath}/${asset.alias}.svg` : asset.alias!),\n size: asset.size || defaultConfig.size,\n states: asset.states || defaultConfig.states,\n themeColor: asset.themeColor || defaultConfig.themeColor,\n resolution: asset.resolution || defaultConfig.resolution,\n })) as SVGAssetConfig[];\n\n const promises = configs.map((config) => {\n if (config.states && config.states.length > 1) {\n return this.loadButtonAsset(config);\n } else {\n return this.loadSVGAsset(config);\n }\n });\n\n await Promise.all(promises);\n }\n\n /**\n * Retrieves a loaded SVG asset texture.\n *\n * For button assets with states, specify the state parameter to get\n * the specific state texture.\n *\n * @param alias - Asset alias used during loading\n * @param state - Button state (for button assets)\n * @returns The PixiJS texture\n *\n * @example\n * ```typescript\n * // Get simple asset\n * const iconTexture = SVGAssetHelper.getAsset('home_icon');\n * const sprite = new Sprite(iconTexture);\n *\n * // Get button state\n * const upTexture = SVGAssetHelper.getAsset('play_btn', 'up');\n * const overTexture = SVGAssetHelper.getAsset('play_btn', 'over');\n * ```\n */\n static getAsset(alias: string, state?: string): any {\n const fullAlias = state ? `${alias}_${state}` : alias;\n return Assets.get(fullAlias);\n }\n\n /**\n * Check if asset exists in cache\n */\n static hasAsset(alias: string, state?: string): boolean {\n const fullAlias = state ? `${alias}_${state}` : alias;\n return Cache.has(fullAlias);\n }\n\n /**\n * Clear specific asset from cache\n */\n static clearAsset(alias: string, state?: string): void {\n const fullAlias = state ? `${alias}_${state}` : alias;\n if (Cache.has(fullAlias)) {\n Cache.remove(fullAlias);\n }\n }\n\n /**\n * Generate SHA-256 hash for asset configuration.\n * This creates a unique identifier based on the actual asset properties (src, styles, size, resolution)\n * rather than the state name, enabling efficient cache reuse when multiple states have identical configurations.\n *\n * @param src - Source path of the SVG\n * @param data - Load data containing styles, size, and resolution\n * @returns SHA-256 hash string\n */\n private static async generateAssetHash(src: string, data: SVGLoadData): Promise<string> {\n const configString = JSON.stringify({\n src,\n styles: data.styles || {},\n size: data.size || {},\n resolution: data.resolution || 1,\n });\n\n const encoder = new TextEncoder();\n const dataBuffer = encoder.encode(configString);\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n\n return hashHex.substring(0, 12);\n }\n}\n","import { Assets, Spritesheet, Texture } from 'pixi.js';\nimport type { ButtonCompSkinData, ButtonStateKey } from '../ui/components';\n\n/**\n * Generates ButtonComp skin data from asset alias and states.\n *\n * Uses ButtonComp state keys directly (up, over, down, disabled) without any mapping.\n * Creates texture references for each state with the naming convention `{alias}_{state}`.\n *\n * @param alias - Asset alias used in texture names (e.g., 'btn_bet_minus')\n * @param states - Array of ButtonComp state names (default: ['up', 'over', 'down', 'disabled'])\n * @returns ButtonComp skin data with texture references for each state\n *\n * @example\n * ```typescript\n * // Generate skin for a button with all states\n * const decreaseButtonSkin = generateButtonSkinFromAsset('btn_bet_minus');\n * // Result: { up: { background: { texture: 'btn_bet_minus_up' } }, over: ..., down: ..., disabled: ... }\n *\n * // Generate skin for a button with custom states (only up and over)\n * const playButtonSkin = generateButtonSkinFromAsset('btn_play', undefined, ['up', 'over']);\n * // Result: { up: { background: { texture: 'btn_play_up' } }, over: { background: { texture: 'btn_play_over' } } }\n * ```\n */\nexport function generateButtonSkinFromAsset(\n backgroundName: string,\n iconName?: string,\n buttonStates: ButtonStateKey[] = ['up', 'over', 'down', 'disabled'],\n iconStates?: ButtonStateKey[],\n): ButtonCompSkinData {\n const skinData: Record<string, any> = {};\n\n // Background\n buttonStates.forEach((state) => {\n skinData[state] = {\n ...(skinData[state] ?? {}),\n background: { texture: `${backgroundName}_${state}` },\n };\n });\n\n // Icon (optional)\n if (iconName) {\n if (iconStates === undefined) {\n // Non-variant icon: apply to the same states we generated for the background\n buttonStates.forEach((state) => {\n skinData[state] = {\n ...(skinData[state] ?? {}),\n icon: { texture: iconName },\n };\n });\n } else {\n // Variant icon: only for provided icon states\n iconStates.forEach((state) => {\n skinData[state] = {\n ...(skinData[state] ?? {}),\n icon: { texture: `${iconName}_${state}` },\n };\n });\n }\n }\n\n return skinData as ButtonCompSkinData;\n}\n\n/**\n * Retrieves animation frames as PixiJS textures from various definition formats.\n *\n * This helper function supports three input formats:\n * 1. **Single texture name**: String identifier for a static sprite\n * 2. **Array of texture names**: Direct list of texture identifiers for animation\n * 3. **Spritesheet reference**: Object with `sheet` (spritesheet asset name) and `anim` (animation name)\n *\n * The function handles spritesheet parsing automatically and safely returns an empty array\n * if the definition is invalid or assets are not found.\n *\n * @param def - Animation definition in one of the supported formats:\n * - `string`: Single texture name for static sprite\n * - `string[]`: Array of texture names to load directly\n * - `{ sheet: string; anim: string }`: Reference to a spritesheet animation\n * - `undefined`: Returns empty array\n * @returns Array of PixiJS Texture objects for the animation frames. Returns empty array if:\n * - Definition is undefined\n * - Spritesheet is not found\n * - Animation name doesn't exist in the spritesheet\n * - Animation data is invalid\n *\n * @example\n * Using single texture name:\n * ```typescript\n * const frames = getAnimationFrames('logo_static');\n * const sprite = new Sprite(frames[0]);\n * ```\n *\n * @example\n * Using array of texture names:\n * ```typescript\n * const frames = getAnimationFrames([\n * 'symbol_cherry_0',\n * 'symbol_cherry_1',\n * 'symbol_cherry_2'\n * ]);\n * const sprite = new AnimatedSprite(frames);\n * ```\n *\n * @example\n * Using spritesheet reference:\n * ```typescript\n * const frames = getAnimationFrames({\n * sheet: 'symbols_spritesheet',\n * anim: 'cherry_win'\n * });\n * const sprite = new AnimatedSprite(frames);\n * ```\n *\n * @example\n * Usage in SlotSymbol component:\n * ```typescript\n * private getAnimationTextures(type: string): Texture[] {\n * const key = this.resolveAssetKey(type);\n * const animations = skin?.sources?.animations || {};\n * const def = animations[key] as string[] | { sheet: string; anim: string } | undefined;\n * return getAnimationFrames(def);\n * }\n * ```\n *\n * @public\n */\nexport function getAnimationFrames(\n def: string | string[] | { sheet: string; anim: string } | undefined,\n): Texture[] {\n const names = getAnimationFrameNames(def);\n return names.map((n) => Texture.from(n));\n}\n\n/**\n * Retrieves animation frame names as strings from various definition formats.\n * Similar to getAnimationFrames but returns string[] instead of Texture[].\n * Useful for particle systems that need texture names rather than Texture objects.\n *\n * @param def - Animation definition in one of the supported formats:\n * - `string`: Single texture name\n * - `string[]`: Array of texture names (returned as-is)\n * - `{ sheet: string; anim: string }`: Reference to a spritesheet animation\n * - `undefined`: Returns empty array\n * @returns Array of texture name strings\n *\n * @example\n * ```typescript\n * const frameNames = getAnimationFrameNames({\n * sheet: 'symbols',\n * anim: 'symbols/pic1'\n * });\n * // Returns: ['pic1_0', 'pic1_1', 'pic1_2', ...]\n * ```\n */\nexport function getAnimationFrameNames(\n def: string | string[] | { sheet: string; anim: string } | undefined,\n): string[] {\n if (!def) return [];\n if (typeof def === 'string') return [def];\n if (Array.isArray(def)) return def;\n const sheetRes = Assets.get(def.sheet) as Spritesheet | undefined;\n if (!sheetRes) return [];\n sheetRes.parse?.();\n const nameList: string[] | undefined = sheetRes.data?.animations?.[def.anim];\n if (!nameList || !Array.isArray(nameList)) return [];\n return nameList;\n}\n","import type { EventEmitter } from 'pixi.js';\n\n/**\n * Extract namespace prefix from event names (supports nested namespaces)\n * Example: ExtractNamespace<'hud:spin'> = 'hud'\n * Example: ExtractNamespace<'menu:autoplay:start'> = 'menu:autoplay'\n */\ntype ExtractNamespace<T extends string> = T extends `${infer Prefix}:${infer Rest}`\n ? Rest extends `${string}:${string}`\n ? `${Prefix}:${ExtractNamespace<Rest>}`\n : Prefix\n : never;\n\n/**\n * Get all unique namespaces from event map (supports nested namespaces)\n * Example: GetNamespaces<{'hud:spin': ..., 'menu:autoplay:start': ...}> = 'hud' | 'menu:autoplay'\n */\ntype GetNamespaces<T> = ExtractNamespace<Extract<keyof T, string>>;\n\n/**\n * Filter events by namespace\n * Example: FilterByNamespace<SlotBaseEvents, 'hud'> = { 'hud:spin': () => void, ... }\n */\ntype FilterByNamespace<T, NS extends string> = {\n [K in Extract<keyof T, `${NS}:${string}`>]: T[K];\n};\n\n/**\n * Remove namespace prefix from event names (supports nested namespaces)\n * Example: StripNamespace<'hud:spin', 'hud'> = 'spin'\n * Example: StripNamespace<'menu:autoplay:start', 'menu:autoplay'> = 'start'\n */\ntype StripNamespace<T extends string, NS extends string> = T extends `${NS}:${infer Rest}`\n ? Rest\n : T;\n\n/**\n * Transform event map by removing namespace prefix\n * Example: TransformEventMap<{ 'hud:spin': () => void }, 'hud'> = { 'spin': () => void }\n */\ntype TransformEventMap<T, NS extends string> = {\n [K in Extract<keyof T, string> as StripNamespace<K, NS>]: K extends keyof T ? T[K] : never;\n};\n\n/**\n * Configuration for event bridge\n */\nexport interface EventBridgeConfig {\n /**\n * Namespace prefix to add to forwarded events\n * Example: 'hud' will transform 'spin' to 'hud:spin'\n */\n namespace?: string;\n\n /**\n * Custom transform function for event name and arguments\n * Takes precedence over namespace if provided\n */\n transform?: (event: string, ...args: any[]) => [string, ...any[]];\n\n /**\n * Filter function to selectively forward events\n * Return true to forward, false to skip\n */\n filter?: (event: string) => boolean;\n\n /**\n * Intercept function for side effects before forwarding\n * Useful for UI state changes, logging, etc.\n */\n intercept?: (event: string, ...args: any[]) => void;\n}\n\n/**\n * Event bridge handle for cleanup\n */\nexport interface EventBridgeHandle {\n /**\n * Disconnect the bridge and restore original emit behavior\n */\n disconnect: () => void;\n}\n\n/**\n * Type-safe event bridge configuration\n */\nexport interface TypedEventBridgeConfig<\n TSource extends Record<string, any>,\n TTarget extends Record<string, any>,\n NS extends GetNamespaces<TTarget>,\n> extends Omit<EventBridgeConfig, 'namespace' | 'filter' | 'intercept'> {\n namespace: NS;\n filter?: (event: keyof TSource) => boolean;\n intercept?: <K extends keyof TSource>(event: K, ...args: Parameters<TSource[K]>) => void;\n}\n\n/**\n * Creates an event bridge that automatically forwards all emitted events from source to target.\n * This eliminates the need for manual event binding boilerplate.\n *\n * **Auto-cleanup:** If the source component has a `destroy()` method, the bridge will\n * automatically clean up when the component is destroyed, preventing memory leaks.\n * You can also manually disconnect using the returned handle.\n *\n * @example\n * // Simple namespace forwarding\n * createEventBridge(this.gameHud, this.eventBusPlugin, {\n * namespace: 'hud'\n * });\n * // Now: gameHud.emit('spin') → eventBus.emit('hud:spin')\n * // Auto-cleanup when gameHud.destroy() is called\n *\n * @example\n * // With side effects\n * createEventBridge(this.gameHud, this.eventBusPlugin, {\n * namespace: 'hud',\n * intercept: (event) => {\n * if (event === 'autoplay') this.autoplayMenu.visible = !this.autoplayMenu.visible;\n * }\n * });\n *\n * @example\n * // Manual cleanup (optional)\n * const handle = createEventBridge(this.component, this.eventBus, {\n * transform: (event, ...args) => [`custom:${event}`, ...args]\n * });\n * // Later...\n * handle.disconnect(); // Manual cleanup if needed\n *\n * @param source - The EventEmitter to bridge from\n * @param target - The EventEmitter to forward events to\n * @param config - Bridge configuration options\n * @returns Handle with disconnect method for manual cleanup\n */\nexport function createEventBridge(\n source: EventEmitter,\n target: { emit(event: any, ...args: any[]): boolean },\n config: EventBridgeConfig = {},\n): EventBridgeHandle {\n // Store original methods\n const originalEmit = source.emit.bind(source);\n const originalDestroy = (source as any).destroy?.bind(source);\n\n // Override emit to intercept and forward\n source.emit = function (event: string | symbol, ...args: any[]): boolean {\n // Call original emit first\n const result = originalEmit(event, ...args);\n\n // Only process string events\n if (typeof event !== 'string') {\n return result;\n }\n\n // Apply filter if provided\n if (config.filter && !config.filter(event)) {\n return result;\n }\n\n // Execute intercept for side effects\n if (config.intercept) {\n config.intercept(event, ...args);\n }\n\n // Transform event name and args\n let forwardEvent: string;\n let forwardArgs: any[];\n\n if (config.transform) {\n // Use custom transform\n [forwardEvent, ...forwardArgs] = config.transform(event, ...args);\n } else if (config.namespace) {\n // Use namespace prefix\n forwardEvent = `${config.namespace}:${event}`;\n forwardArgs = args;\n } else {\n // No transformation\n forwardEvent = event;\n forwardArgs = args;\n }\n\n // Forward to target\n target.emit(forwardEvent, ...forwardArgs);\n\n return result;\n };\n\n // Auto-cleanup: Hook into destroy method if it exists\n if (typeof (source as any).destroy === 'function') {\n (source as any).destroy = function (options?: any): void {\n // Restore original emit before destroying\n source.emit = originalEmit;\n\n // Restore original destroy\n if (originalDestroy) {\n (source as any).destroy = originalDestroy;\n }\n\n // Call original destroy\n if (originalDestroy) {\n originalDestroy(options);\n }\n };\n }\n\n // Return cleanup handle for manual disconnect if needed\n return {\n disconnect: () => {\n source.emit = originalEmit;\n if (originalDestroy) {\n (source as any).destroy = originalDestroy;\n }\n },\n };\n}\n\n/**\n * Type-safe event bridge creator\n * Ensures source events match target events after namespace transformation\n *\n * @example\n * // Define source events (without namespace)\n * interface HudEvents {\n * spin: () => void;\n * autoplay: () => void;\n * }\n *\n * // Define target events (with namespace)\n * interface GameEvents {\n * 'hud:spin': () => void;\n * 'hud:autoplay': () => void;\n * 'menu:close': () => void;\n * }\n *\n * // Type-safe bridge - TypeScript validates that HudEvents matches 'hud' namespace in GameEvents\n * createTypedEventBridge<GameEvents, 'hud', HudEvents>(\n * hudComponent,\n * eventBus,\n * { namespace: 'hud' }\n * );\n *\n * @param source - The EventEmitter to bridge from\n * @param target - The EventEmitter to forward events to\n * @param config - Type-safe bridge configuration\n * @returns Handle with disconnect method for manual cleanup\n */\nexport function createTypedEventBridge<\n TTarget extends Record<string, any>,\n NS extends GetNamespaces<TTarget>,\n TSource extends TransformEventMap<FilterByNamespace<TTarget, NS>, NS>,\n>(\n source: EventEmitter,\n target: { emit(event: any, ...args: any[]): boolean },\n config: TypedEventBridgeConfig<TSource, TTarget, NS>,\n): EventBridgeHandle {\n const bridgeConfig: EventBridgeConfig = {\n namespace: config.namespace,\n filter: config.filter as ((event: string) => boolean) | undefined,\n intercept: config.intercept as ((event: string, ...args: any[]) => void) | undefined,\n transform: config.transform,\n };\n\n return createEventBridge(source, target, bridgeConfig);\n}\n","import { mergeWith, isPlainObject } from 'lodash';\n\n/**\n * Sentinel symbol to mark properties for removal during merge.\n * Use this in override objects to explicitly remove a property from the base.\n *\n * @example\n * const base = { a: 1, b: 2 };\n * mergeWithRemove(base, { b: REMOVE }); // → { a: 1 }\n */\nexport const REMOVE = Symbol('REMOVE');\n\n/**\n * Deep merge with support for removing properties using REMOVE symbol.\n * Similar to lodash.merge but:\n * - REMOVE symbol removes the property entirely\n * - Arrays are replaced, not merged\n *\n * @example\n * const base = { a: 1, b: { c: 2, d: 3 } };\n * mergeWithRemove(base, { b: { c: REMOVE } }); // → { a: 1, b: { d: 3 } }\n */\nexport const mergeWithRemove = <T extends object>(base: T, ...overrides: object[]): T => {\n const result = mergeWith({}, base, ...overrides, (_objValue: unknown, srcValue: unknown) => {\n if (srcValue === REMOVE) {\n return REMOVE;\n }\n if (Array.isArray(srcValue)) {\n return srcValue;\n }\n return undefined;\n });\n\n const cleanRemoved = (obj: Record<string, unknown>): Record<string, unknown> => {\n if (!isPlainObject(obj)) return obj;\n for (const key of Object.keys(obj)) {\n if (obj[key] === REMOVE) {\n delete obj[key];\n } else if (isPlainObject(obj[key])) {\n cleanRemoved(obj[key] as Record<string, unknown>);\n }\n }\n return obj;\n };\n\n return cleanRemoved(result) as T;\n};\n\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../../helpers/SVGParser.ts","../../helpers/SVGLoader.ts","../../helpers/SVGAssetHelper.ts","../../helpers/AssetHelper.ts","../../helpers/eventBridge.ts","../../helpers/mergeUtils.ts"],"names":["Assets","Texture"],"mappings":"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","file":"index.js","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Texture, TextureSource, LoaderParser, ExtensionType, ResolvedAsset } from 'pixi.js';\n// @ts-ignore\nimport { minimatch } from 'minimatch';\n\n/**\n * Style definitions for SVG elements using CSS selectors.\n *\n * Maps CSS selectors to attribute-value pairs that will be applied to matching SVG elements.\n * Commonly used for dynamic theming and color changes.\n *\n * @example\n * ```typescript\n * const styles: SVGStyleData = {\n * '#primary': { fill: '#4CAF50', stroke: '#388E3C' },\n * '.icon': { fill: '#FFFFFF' },\n * 'circle': { opacity: '0.8' }\n * };\n * ```\n *\n * @public\n */\nexport interface SVGStyleData {\n /** CSS selector as key, attributes as value */\n [selector: string]: {\n /** SVG attribute name (e.g., 'fill', 'stroke', 'opacity') */\n [attribute: string]: string;\n };\n}\n\n/**\n * Configuration data for loading and processing SVG files.\n *\n * This interface defines all options available when loading an SVG asset,\n * including styling, sizing, and resolution settings.\n *\n * @example\n * ```typescript\n * const loadData: SVGLoadData = {\n * styles: {\n * '#background': { fill: '#4CAF50' },\n * '#icon': { fill: '#FFFFFF' }\n * },\n * size: { width: 128, height: 128 },\n * resolution: 2\n * };\n * ```\n *\n * @public\n */\nexport interface SVGLoadData {\n /** Style definitions to apply to SVG elements */\n styles?: SVGStyleData;\n /** Target size for rasterization (width and height in pixels) */\n size?: { width: number; height: number };\n /** Resolution multiplier for high-DPI displays (default: 1) */\n resolution?: number;\n /** Button states for multi-state assets (used by SVGAssetHelper) */\n states?: string[];\n}\n\n/**\n * Global configuration for the SVG parser.\n *\n * @public\n */\nexport interface SVGParserConfig {\n /** Glob pattern to match SVG files (uses minimatch) */\n testPattern?: string;\n}\n\n// Parser global configuration\nlet parserConfig: SVGParserConfig = {};\n\n/**\n * Manipulates SVG string by applying styles and size modifications.\n *\n * This function parses the SVG string, applies CSS selector-based styles,\n * and optionally resizes the SVG before returning the modified string.\n *\n * @param svgString - Raw SVG file content as string\n * @param data - Optional load data with styles and size\n * @returns Modified SVG string\n *\n * @internal\n */\nfunction manipulateSVG(svgString: string, data?: SVGLoadData): string {\n const parser = new DOMParser();\n const svgDoc = parser.parseFromString(svgString, 'image/svg+xml');\n const svgElement = svgDoc.documentElement;\n\n // Apply styles\n if (data?.styles) {\n Object.entries(data.styles).forEach(([selector, styles]) => {\n const elements = svgDoc.querySelectorAll(selector);\n elements.forEach((element) => {\n Object.entries(styles).forEach(([attr, value]) => {\n element.setAttribute(attr, value);\n });\n });\n });\n }\n\n // Set size\n if (data?.size) {\n svgElement.setAttribute('width', data.size.width.toString());\n svgElement.setAttribute('height', data.size.height.toString());\n\n // Optionally update the viewBox as well\n // const viewBox = svgElement.getAttribute('viewBox');\n // if (viewBox) {\n // const [x, y] = viewBox.split(' ');\n // svgElement.setAttribute('viewBox', `${x} ${y} ${data.size.width} ${data.size.height}`);\n // }\n }\n\n return new XMLSerializer().serializeToString(svgDoc);\n}\n\n/**\n * Converts an SVG string to a PixiJS Texture by rasterizing it to a canvas.\n *\n * This function creates an Image element from the SVG, draws it to a canvas,\n * and generates a PixiJS Texture from the canvas. Supports resolution scaling\n * for high-DPI displays.\n *\n * @param svgString - SVG content as string\n * @param data - Optional load data with resolution settings\n * @returns Promise that resolves to a PixiJS Texture\n *\n * @internal\n */\nasync function createTextureFromSVG(svgString: string, data?: SVGLoadData): Promise<Texture> {\n const blob = new Blob([svgString], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n\n const img = new Image();\n img.src = url;\n\n return new Promise((resolve, reject) => {\n img.onload = () => {\n try {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n\n if (!ctx) {\n reject(new Error('Could not get canvas context'));\n return;\n }\n\n const resolution = data?.resolution || 1;\n canvas.width = img.width * resolution;\n canvas.height = img.height * resolution;\n\n //ctx.scale(resolution, resolution);\n ctx.drawImage(img, 0, 0);\n\n const source = TextureSource.from(canvas);\n const texture = new Texture(source);\n resolve(texture);\n URL.revokeObjectURL(url);\n } catch (error) {\n reject(error);\n }\n };\n\n img.onerror = () => {\n URL.revokeObjectURL(url);\n reject(new Error('Failed to load SVG image'));\n };\n });\n}\n\n/**\n * PixiJS LoaderParser implementation for SVG files.\n *\n * This parser integrates with PixiJS Assets system to automatically detect,\n * load, and process SVG files as textures. It handles:\n * - SVG file detection via URL pattern matching\n * - Style manipulation using CSS selectors\n * - Size and resolution configuration\n * - Canvas rasterization for texture generation\n *\n * The parser is registered with PixiJS Assets via SVGLoader.install().\n *\n * @remarks\n * This parser uses DOMParser and Canvas API to convert SVG to raster textures.\n * All SVG manipulations happen before rasterization, ensuring clean output.\n *\n * @example\n * ```typescript\n * // Parser is automatically used after SVGLoader.install()\n * await Assets.load({\n * alias: 'icon',\n * src: 'assets/icon.svg',\n * data: {\n * styles: { '#primary': { fill: '#4CAF50' } },\n * size: { width: 64, height: 64 },\n * resolution: 2\n * }\n * });\n * ```\n *\n * @public\n */\nexport const SVGParser: LoaderParser<Texture, SVGLoadData> = {\n /**\n * Extension metadata for the parser.\n *\n * @internal\n */\n extension: {\n type: ExtensionType.LoadParser,\n name: 'svgParser',\n priority: 0,\n },\n\n /**\n * Unique identifier for the parser.\n *\n * @internal\n */\n id: 'svgParser',\n\n /**\n * Tests if a URL should be handled by this parser.\n *\n * By default, matches files ending with .svg extension.\n * Can be customized via configureSVGParser() with a glob pattern.\n *\n * @param url - Asset URL to test\n * @returns True if this parser should handle the URL\n */\n test: (url: string) => {\n // If a custom pattern is provided, use it\n if (parserConfig.testPattern) {\n try {\n const urlObj = new URL(url);\n const pathname = urlObj.pathname.startsWith('/')\n ? urlObj.pathname.slice(1)\n : urlObj.pathname;\n return minimatch(pathname, parserConfig.testPattern, { partial: true });\n } catch {\n // If URL parsing fails, try with the original string\n return minimatch(url, parserConfig.testPattern, { partial: true });\n }\n }\n\n // Default: check that the file actually ends with .svg\n return /\\.svg$/i.test(url);\n },\n\n /**\n * Loads and processes an SVG file into a PixiJS Texture.\n *\n * This method:\n * 1. Fetches the SVG file from the URL\n * 2. Applies style and size manipulations\n * 3. Rasterizes the SVG to a canvas\n * 4. Creates a PixiJS Texture from the canvas\n *\n * @param url - URL of the SVG file to load\n * @param resolvedAsset - Resolved asset with optional load data\n * @returns Promise that resolves to a PixiJS Texture\n */\n async load(url: string, resolvedAsset?: ResolvedAsset<SVGLoadData>): Promise<Texture> {\n // Fetch the SVG file\n const response = await fetch(url);\n const svgString = await response.text();\n\n // Manipulate the SVG\n const manipulatedSVG = manipulateSVG(svgString, resolvedAsset?.data);\n\n // Convert to Texture\n const texture = await createTextureFromSVG(manipulatedSVG, resolvedAsset?.data);\n texture.label = resolvedAsset?.src ?? 'unknown';\n return texture;\n },\n};\n\n/**\n * Configures the SVG parser with global settings.\n *\n * This function allows customization of the parser behavior, such as\n * specifying custom glob patterns for SVG file matching.\n *\n * Typically called by SVGLoader.install() but can be used independently.\n *\n * @param config - Parser configuration options\n *\n * @example\n * ```typescript\n * configureSVGParser({\n * testPattern: 'assets/svg/*.svg'\n * });\n * ```\n *\n * @public\n */\nexport function configureSVGParser(config: SVGParserConfig): void {\n parserConfig = { ...parserConfig, ...config };\n}\n","import { Assets } from 'pixi.js';\nimport { SVGParser, configureSVGParser } from './SVGParser';\n\n/**\n * Configuration options for the SVG loader.\n */\nexport interface SVGLoaderConfig {\n /** Glob pattern to match SVG files (uses minimatch) */\n testPattern?: string;\n}\n\n/**\n * SVG loader plugin for PixiJS Assets system.\n *\n * SVGLoader integrates the SVG parser into PixiJS asset loading pipeline,\n * enabling automatic loading and processing of SVG files as textures.\n *\n * @remarks\n * Install once at application startup using SVGLoader.install().\n * After installation, SVG files can be loaded using PixiJS Assets API or SVGAssetHelper.\n *\n * @public\n */\nexport class SVGLoader {\n private static installed = false;\n\n /**\n * Installs the SVG loader into the PixiJS Assets system.\n *\n * This method must be called once at application startup before loading any SVG assets.\n * It registers the SVG parser with PixiJS, enabling automatic SVG file processing.\n * This method is idempotent - calling it multiple times is safe but only the first call will take effect.\n *\n * @param config - Optional configuration for SVG file matching\n */\n static install(config?: SVGLoaderConfig): void {\n if (this.installed) {\n console.warn('SVGLoader is already installed');\n return;\n }\n\n // Configure parser if options provided\n if (config) {\n configureSVGParser(config);\n }\n\n // Add parser to Assets loader\n Assets.loader.parsers.unshift(SVGParser);\n\n this.installed = true;\n console.log('SVG Loader installed successfully');\n }\n\n /**\n * Checks if the SVG loader has been installed.\n *\n * @returns True if the loader is installed, false otherwise\n */\n static isInstalled(): boolean {\n return this.installed;\n }\n\n /**\n * Uninstalls the SVG loader from the PixiJS Assets system.\n *\n * This method is primarily intended for testing purposes.\n * In production, you typically install the loader once and never uninstall it.\n */\n static uninstall(): void {\n if (!this.installed) {\n return;\n }\n\n // Remove parser from Assets loader\n const index = Assets.loader.parsers.indexOf(SVGParser);\n if (index > -1) {\n Assets.loader.parsers.splice(index, 1);\n }\n\n this.installed = false;\n console.log('SVG Loader uninstalled');\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Assets, Cache, Color, type ColorSource } from 'pixi.js';\nimport { SVGLoadData, SVGStyleData } from './SVGParser';\nimport type { ButtonStateKey } from '../ui/components/ButtonComp';\nimport { lightenColor, darkenColor } from '../utils';\n\n/**\n * Button state styles for SVG assets.\n *\n * Defines the visual appearance of buttons in different interaction states.\n * Each state contains CSS-like style definitions for SVG elements.\n * Uses ButtonComp state names: up, down, over, disabled.\n *\n * @example\n * ```typescript\n * const buttonStyles: ButtonState = {\n * up: { '#primary': { fill: '#4CAF50' } },\n * over: { '#primary': { fill: '#66BB6A' } },\n * down: { '#primary': { fill: '#388E3C' } },\n * disabled: { '#primary': { fill: '#CCCCCC' } }\n * };\n * ```\n */\nexport interface ButtonState {\n /** Up/default state styles */\n up: SVGStyleData;\n /** Over/hover state styles */\n over: SVGStyleData;\n /** Down/pressed state styles */\n down: SVGStyleData;\n /** Disabled state styles (optional) */\n disabled?: SVGStyleData;\n /** Selected up state styles */\n selected_up?: SVGStyleData;\n /** Selected over state styles */\n selected_over?: SVGStyleData;\n /** Selected down state styles */\n selected_down?: SVGStyleData;\n /** Selected disabled state styles */\n selected_disabled?: SVGStyleData;\n}\n\n/**\n * Configuration for loading SVG assets.\n *\n * @example\n * ```typescript\n * const config: SVGAssetConfig = {\n * alias: 'play_button',\n * src: 'assets/svg/buttons/play.svg',\n * size: { width: 120, height: 120 },\n * resolution: 2,\n * themeColor: '#4CAF50',\n * states: ['up', 'over', 'down']\n * };\n * ```\n */\nexport interface SVGAssetConfig {\n /** Unique identifier for the asset */\n alias: string;\n /** Path to the SVG file */\n src: string;\n /** Target size for rasterization */\n size?: { width: number; height: number };\n /** Resolution multiplier for high-DPI displays */\n resolution?: number;\n /** Theme color for styling (supports all PixiJS ColorSource formats) */\n themeColor?: ColorSource;\n /** Button states to generate (e.g., ['up', 'over', 'down', 'disabled']) */\n states?: ButtonStateKey[];\n}\n\n/**\n * High-level utility for loading and managing SVG assets in PixiJS.\n *\n * SVGAssetHelper provides a convenient API for loading SVG files as PixiJS textures\n * with automatic theming, button state management, and batch loading capabilities.\n *\n * ## Features\n *\n * - **Theme Support**: Global and per-asset theme colors\n * - **Button States**: Automatic generation of up, over, down, disabled states\n * - **Batch Loading**: Load multiple assets efficiently\n * - **Color Manipulation**: Automatic lighten/darken for button states\n * - **Cache Management**: Check and clear loaded assets\n * - **Custom Styles**: Create custom style configurations\n *\n * ## Workflow\n *\n * 1. **Initialize**: Set global theme color (optional)\n * 2. **Load**: Load SVG assets with configuration\n * 3. **Use**: Retrieve textures and create sprites\n * 4. **Manage**: Check cache and clear unused assets\n *\n * @example\n * ```typescript\n * import { SVGAssetHelper, SVGLoader } from '@rb-games/core/helpers';\n * import { Sprite } from 'pixi.js';\n *\n * // Initialize SVG system\n * SVGLoader.install();\n * SVGAssetHelper.setThemeColor('#4CAF50');\n *\n * // Load a simple icon\n * await SVGAssetHelper.loadSVGAsset({\n * alias: 'settings_icon',\n * src: 'assets/svg/settings.svg',\n * size: { width: 48, height: 48 },\n * themeColor: '#2196F3'\n * });\n *\n * // Create sprite\n * const icon = new Sprite(SVGAssetHelper.getAsset('settings_icon'));\n * ```\n *\n * @example\n * ```typescript\n * // Load button with states\n * await SVGAssetHelper.loadButtonAsset({\n * alias: 'play_btn',\n * src: 'assets/svg/play.svg',\n * size: { width: 120, height: 120 },\n * themeColor: '#4CAF50',\n * states: ['up', 'over', 'down']\n * });\n *\n * // Create interactive button\n * const button = new Sprite(SVGAssetHelper.getAsset('play_btn', 'up'));\n * button.eventMode = 'static';\n * button.cursor = 'pointer';\n *\n * button.on('pointerover', () => {\n * button.texture = SVGAssetHelper.getAsset('play_btn', 'over');\n * });\n *\n * button.on('pointerout', () => {\n * button.texture = SVGAssetHelper.getAsset('play_btn', 'up');\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Batch load multiple assets\n * await SVGAssetHelper.loadBatchAssets([\n * {\n * alias: 'star_icon',\n * src: 'assets/svg/icons/star.svg',\n * size: { width: 32, height: 32 },\n * themeColor: '#FFD700'\n * },\n * {\n * alias: 'close_btn',\n * src: 'assets/svg/buttons/close.svg',\n * size: { width: 40, height: 40 },\n * states: ['up', 'over'],\n * themeColor: '#F44336'\n * }\n * ]);\n * ```\n *\n * @public\n */\nexport class SVGAssetHelper {\n private static themeColor: ColorSource = '#4CAF50';\n\n /**\n * Sets the global theme color for all SVG assets.\n *\n * This color will be used as the default for all assets unless overridden\n * in individual asset configurations.\n *\n * @param color - Theme color (supports all PixiJS ColorSource formats)\n *\n * @example\n * ```typescript\n * // Set theme with hex string\n * SVGAssetHelper.setThemeColor('#4CAF50');\n *\n * // Set theme with number\n * SVGAssetHelper.setThemeColor(0x4CAF50);\n *\n * // Set theme with RGB array\n * SVGAssetHelper.setThemeColor([0.3, 0.69, 0.31]);\n * ```\n */\n static setThemeColor(color: ColorSource): void {\n this.themeColor = color;\n }\n\n /**\n * Gets the current global theme color.\n *\n * @returns The current theme color as ColorSource\n *\n * @example\n * ```typescript\n * const currentTheme = SVGAssetHelper.getThemeColor();\n * // Can be used directly or converted as needed\n * const hex = new Color(currentTheme).toHex();\n * ```\n */\n static getThemeColor(): ColorSource {\n return this.themeColor;\n }\n\n /**\n * Create button state styles based on theme color\n */\n static createButtonStyles(\n themeColor?: ColorSource,\n variations?: { /** lighten amount */ over: number; /** darken amount */ down: number },\n ): ButtonState {\n const baseColor = themeColor || this.themeColor;\n const baseColorHex = new Color(baseColor).toHex();\n\n return {\n up: {\n '#primary': { fill: baseColorHex },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: baseColorHex },\n },\n over: {\n '#primary': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n },\n down: {\n '#primary': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n },\n disabled: {\n '#primary': { fill: '#cccccc' },\n '#secondary': { fill: '#999999' },\n '#background': { fill: '#cccccc' },\n },\n selected_up: {\n '#primary': { fill: baseColorHex },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: baseColorHex },\n },\n selected_over: {\n '#primary': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n },\n selected_down: {\n '#primary': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n },\n selected_disabled: {\n '#primary': { fill: '#cccccc' },\n '#secondary': { fill: '#999999' },\n '#background': { fill: '#cccccc' },\n },\n };\n }\n\n /**\n * Create custom styles\n */\n static createCustomStyles(config: {\n selectors: string[];\n colors: { [state: string]: string[] };\n }): { [state: string]: SVGStyleData } {\n const result: { [state: string]: SVGStyleData } = {};\n\n Object.entries(config.colors).forEach(([state, colors]) => {\n result[state] = {};\n config.selectors.forEach((selector, index) => {\n if (colors[index]) {\n result[state][selector] = { fill: colors[index] };\n }\n });\n });\n\n return result;\n }\n\n /**\n * Loads a single SVG asset as a PixiJS texture.\n *\n * This method loads an SVG file, applies optional theme colors and styles,\n * and registers it with the PixiJS Assets system for later retrieval.\n *\n * @param config - Asset configuration\n * @returns Promise that resolves when the asset is loaded\n *\n * @example\n * ```typescript\n * // Load a simple icon\n * await SVGAssetHelper.loadSVGAsset({\n * alias: 'home_icon',\n * src: 'assets/svg/home.svg',\n * size: { width: 64, height: 64 },\n * resolution: 2\n * });\n *\n * // Load with theme color\n * await SVGAssetHelper.loadSVGAsset({\n * alias: 'settings_icon',\n * src: 'assets/svg/settings.svg',\n * size: { width: 48, height: 48 },\n * themeColor: '#2196F3'\n * });\n * ```\n */\n static async loadSVGAsset(config: SVGAssetConfig): Promise<void> {\n const loadData: SVGLoadData = {\n size: config.size,\n resolution: config.resolution || 1,\n };\n\n if (config.themeColor) {\n const styles = this.createButtonStyles(config.themeColor);\n loadData.styles = styles.up;\n }\n\n await Assets.load({\n alias: config.alias,\n src: `${config.src}`,\n data: loadData,\n });\n }\n\n /**\n * Loads a button SVG asset with multiple interaction states.\n *\n * Automatically generates up, over, down, and optionally disabled states\n * by applying color variations (lighten for over, darken for down).\n * Each state is loaded as a separate texture with the naming convention `{alias}_{state}`.\n *\n * @param config - Button asset configuration\n * @returns Promise that resolves when all button states are loaded\n *\n * @example\n * ```typescript\n * // Load button with default states\n * await SVGAssetHelper.loadButtonAsset({\n * alias: 'play_btn',\n * src: 'assets/svg/play.svg',\n * size: { width: 120, height: 120 },\n * themeColor: '#4CAF50'\n * });\n *\n * // Access different states\n * const upTexture = SVGAssetHelper.getAsset('play_btn', 'up');\n * const overTexture = SVGAssetHelper.getAsset('play_btn', 'over');\n * const downTexture = SVGAssetHelper.getAsset('play_btn', 'down');\n * ```\n *\n * @example\n * ```typescript\n * // Custom states\n * await SVGAssetHelper.loadButtonAsset({\n * alias: 'custom_btn',\n * src: 'assets/svg/button.svg',\n * size: { width: 100, height: 40 },\n * themeColor: '#E91E63',\n * states: ['up', 'over', 'down', 'disabled']\n * });\n * ```\n */\n static async loadButtonAsset(config: SVGAssetConfig): Promise<void> {\n const styles = this.createButtonStyles(\n config.themeColor\n ? typeof config.themeColor === 'number'\n ? new Color(config.themeColor).toHex()\n : config.themeColor\n : undefined,\n );\n\n const states = config.states || ['up', 'over', 'down'];\n\n for (const state of states) {\n const stateStyles = styles[state as keyof ButtonState];\n if (stateStyles) {\n const loadData: SVGLoadData = {\n styles: stateStyles,\n size: config.size,\n resolution: config.resolution || 1,\n };\n\n const hash = await this.generateAssetHash(config.src, loadData);\n\n await Assets.load({\n alias: `${config.alias}_${state}`,\n src: `${config.src}?hash=${hash}`,\n data: loadData,\n });\n }\n }\n }\n\n /**\n * Loads multiple SVG assets in parallel for efficient batch loading.\n *\n * Automatically determines whether to load each asset as a simple SVG or\n * as a button with states based on the states property.\n *\n * @param basePath - Base directory path for all assets (assets without src will use basePath/alias.svg)\n * @param assets - Array of asset configurations (strings, objects, or mixed)\n * @param defaults - Optional default configuration applied to all assets\n * @returns Promise that resolves when all assets are loaded\n *\n * @example\n * ```typescript\n * // Simple string array (most convenient)\n * await SVGAssetHelper.loadBatchAssets(\n * 'assets/svg/desktop',\n * ['btn_bet_minus', 'btn_bet_plus', 'btn_spin'],\n * {\n * size: { width: 100, height: 100 },\n * states: ['up', 'over', 'down', 'disabled']\n * }\n * );\n *\n * // Mixed array (strings and objects for customization)\n * await SVGAssetHelper.loadBatchAssets(\n * 'assets/svg/desktop',\n * [\n * 'btn_bet_minus', // uses default size\n * 'btn_bet_plus', // uses default size\n * { alias: 'btn_spin', size: { width: 120, height: 120 } } // custom size\n * ],\n * {\n * size: { width: 80, height: 80 },\n * states: ['up', 'over', 'down', 'disabled']\n * }\n * );\n *\n * // All objects (full customization)\n * await SVGAssetHelper.loadBatchAssets(\n * 'assets/svg/desktop',\n * [\n * { alias: 'btn_bet_minus', size: { width: 90, height: 90 } },\n * { alias: 'btn_bet_plus' }, // uses default size\n * { alias: 'btn_spin', states: ['up', 'over'] } // custom states\n * ],\n * {\n * size: { width: 100, height: 100 },\n * states: ['up', 'over', 'down', 'disabled']\n * }\n * );\n *\n * // With full src paths (when assets are in different directories)\n * await SVGAssetHelper.loadBatchAssets(\n * '',\n * [\n * {\n * alias: 'star_icon',\n * src: 'assets/svg/icons/star.svg',\n * size: { width: 32, height: 32 },\n * themeColor: '#FFD700'\n * },\n * {\n * alias: 'close_btn',\n * src: 'assets/svg/buttons/close.svg',\n * size: { width: 40, height: 40 },\n * states: ['up', 'over'],\n * themeColor: '#F44336'\n * }\n * ]\n * );\n * ```\n */\n static async loadBatchAssets(\n basePath: string,\n assets: Array<string | Partial<SVGAssetConfig>>,\n defaults?: Partial<SVGAssetConfig>,\n ): Promise<void> {\n const defaultConfig = defaults || {};\n\n // Convert string array to asset configs\n const assetConfigs: Array<Partial<SVGAssetConfig>> = assets.map((asset) =>\n typeof asset === 'string' ? { alias: asset } : asset,\n );\n\n const configs: SVGAssetConfig[] = assetConfigs.map((asset) => ({\n alias: asset.alias!,\n src: asset.src || (basePath ? `${basePath}/${asset.alias}.svg` : asset.alias!),\n size: asset.size || defaultConfig.size,\n states: asset.states || defaultConfig.states,\n themeColor: asset.themeColor || defaultConfig.themeColor,\n resolution: asset.resolution || defaultConfig.resolution,\n })) as SVGAssetConfig[];\n\n const promises = configs.map((config) => {\n if (config.states && config.states.length > 1) {\n return this.loadButtonAsset(config);\n } else {\n return this.loadSVGAsset(config);\n }\n });\n\n await Promise.all(promises);\n }\n\n /**\n * Retrieves a loaded SVG asset texture.\n *\n * For button assets with states, specify the state parameter to get\n * the specific state texture.\n *\n * @param alias - Asset alias used during loading\n * @param state - Button state (for button assets)\n * @returns The PixiJS texture\n *\n * @example\n * ```typescript\n * // Get simple asset\n * const iconTexture = SVGAssetHelper.getAsset('home_icon');\n * const sprite = new Sprite(iconTexture);\n *\n * // Get button state\n * const upTexture = SVGAssetHelper.getAsset('play_btn', 'up');\n * const overTexture = SVGAssetHelper.getAsset('play_btn', 'over');\n * ```\n */\n static getAsset(alias: string, state?: string): any {\n const fullAlias = state ? `${alias}_${state}` : alias;\n return Assets.get(fullAlias);\n }\n\n /**\n * Check if asset exists in cache\n */\n static hasAsset(alias: string, state?: string): boolean {\n const fullAlias = state ? `${alias}_${state}` : alias;\n return Cache.has(fullAlias);\n }\n\n /**\n * Clear specific asset from cache\n */\n static clearAsset(alias: string, state?: string): void {\n const fullAlias = state ? `${alias}_${state}` : alias;\n if (Cache.has(fullAlias)) {\n Cache.remove(fullAlias);\n }\n }\n\n /**\n * Generate SHA-256 hash for asset configuration.\n * This creates a unique identifier based on the actual asset properties (src, styles, size, resolution)\n * rather than the state name, enabling efficient cache reuse when multiple states have identical configurations.\n *\n * @param src - Source path of the SVG\n * @param data - Load data containing styles, size, and resolution\n * @returns SHA-256 hash string\n */\n private static async generateAssetHash(src: string, data: SVGLoadData): Promise<string> {\n const configString = JSON.stringify({\n src,\n styles: data.styles || {},\n size: data.size || {},\n resolution: data.resolution || 1,\n });\n\n const encoder = new TextEncoder();\n const dataBuffer = encoder.encode(configString);\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n\n return hashHex.substring(0, 12);\n }\n}\n","import { Assets, Spritesheet, Texture } from 'pixi.js';\nimport type { ButtonCompSkinData, ButtonStateKey } from '../ui/components';\n\n/**\n * Generates ButtonComp skin data from asset alias and states.\n *\n * Uses ButtonComp state keys directly (up, over, down, disabled) without any mapping.\n * Creates texture references for each state with the naming convention `{alias}_{state}`.\n *\n * @param alias - Asset alias used in texture names (e.g., 'btn_bet_minus')\n * @param states - Array of ButtonComp state names (default: ['up', 'over', 'down', 'disabled'])\n * @returns ButtonComp skin data with texture references for each state\n *\n * @example\n * ```typescript\n * // Generate skin for a button with all states\n * const decreaseButtonSkin = generateButtonSkinFromAsset('btn_bet_minus');\n * // Result: { up: { background: { texture: 'btn_bet_minus_up' } }, over: ..., down: ..., disabled: ... }\n *\n * // Generate skin for a button with custom states (only up and over)\n * const playButtonSkin = generateButtonSkinFromAsset('btn_play', undefined, ['up', 'over']);\n * // Result: { up: { background: { texture: 'btn_play_up' } }, over: { background: { texture: 'btn_play_over' } } }\n * ```\n */\nexport function generateButtonSkinFromAsset(\n backgroundName: string,\n iconName?: string,\n buttonStates: ButtonStateKey[] = ['up', 'over', 'down', 'disabled'],\n iconStates?: ButtonStateKey[],\n): ButtonCompSkinData {\n const skinData: Record<string, any> = {};\n\n // Background\n buttonStates.forEach((state) => {\n skinData[state] = {\n ...(skinData[state] ?? {}),\n background: { texture: `${backgroundName}_${state}` },\n };\n });\n\n // Icon (optional)\n if (iconName) {\n if (iconStates === undefined) {\n // Non-variant icon: apply to the same states we generated for the background\n buttonStates.forEach((state) => {\n skinData[state] = {\n ...(skinData[state] ?? {}),\n icon: { texture: iconName },\n };\n });\n } else {\n // Variant icon: only for provided icon states\n iconStates.forEach((state) => {\n skinData[state] = {\n ...(skinData[state] ?? {}),\n icon: { texture: `${iconName}_${state}` },\n };\n });\n }\n }\n\n return skinData as ButtonCompSkinData;\n}\n\n/**\n * Retrieves animation frames as PixiJS textures from various definition formats.\n *\n * This helper function supports three input formats:\n * 1. **Single texture name**: String identifier for a static sprite\n * 2. **Array of texture names**: Direct list of texture identifiers for animation\n * 3. **Spritesheet reference**: Object with `sheet` (spritesheet asset name) and `anim` (animation name)\n *\n * The function handles spritesheet parsing automatically and safely returns an empty array\n * if the definition is invalid or assets are not found.\n *\n * @param def - Animation definition in one of the supported formats:\n * - `string`: Single texture name for static sprite\n * - `string[]`: Array of texture names to load directly\n * - `{ sheet: string; anim: string }`: Reference to a spritesheet animation\n * - `undefined`: Returns empty array\n * @returns Array of PixiJS Texture objects for the animation frames. Returns empty array if:\n * - Definition is undefined\n * - Spritesheet is not found\n * - Animation name doesn't exist in the spritesheet\n * - Animation data is invalid\n *\n * @example\n * Using single texture name:\n * ```typescript\n * const frames = getAnimationFrames('logo_static');\n * const sprite = new Sprite(frames[0]);\n * ```\n *\n * @example\n * Using array of texture names:\n * ```typescript\n * const frames = getAnimationFrames([\n * 'symbol_cherry_0',\n * 'symbol_cherry_1',\n * 'symbol_cherry_2'\n * ]);\n * const sprite = new AnimatedSprite(frames);\n * ```\n *\n * @example\n * Using spritesheet reference:\n * ```typescript\n * const frames = getAnimationFrames({\n * sheet: 'symbols_spritesheet',\n * anim: 'cherry_win'\n * });\n * const sprite = new AnimatedSprite(frames);\n * ```\n *\n * @example\n * Usage in SlotSymbol component:\n * ```typescript\n * private getAnimationTextures(type: string): Texture[] {\n * const key = this.resolveAssetKey(type);\n * const animations = skin?.sources?.animations || {};\n * const def = animations[key] as string[] | { sheet: string; anim: string } | undefined;\n * return getAnimationFrames(def);\n * }\n * ```\n *\n * @public\n */\nexport function getAnimationFrames(\n def: string | string[] | { sheet: string; anim: string } | undefined,\n): Texture[] {\n const names = getAnimationFrameNames(def);\n return names.map((n) => Texture.from(n));\n}\n\n/**\n * Retrieves animation frame names as strings from various definition formats.\n * Similar to getAnimationFrames but returns string[] instead of Texture[].\n * Useful for particle systems that need texture names rather than Texture objects.\n *\n * @param def - Animation definition in one of the supported formats:\n * - `string`: Single texture name\n * - `string[]`: Array of texture names (returned as-is)\n * - `{ sheet: string; anim: string }`: Reference to a spritesheet animation\n * - `undefined`: Returns empty array\n * @returns Array of texture name strings\n *\n * @example\n * ```typescript\n * const frameNames = getAnimationFrameNames({\n * sheet: 'symbols',\n * anim: 'symbols/pic1'\n * });\n * // Returns: ['pic1_0', 'pic1_1', 'pic1_2', ...]\n * ```\n */\nexport function getAnimationFrameNames(\n def: string | string[] | { sheet: string; anim: string } | undefined,\n): string[] {\n if (!def) return [];\n if (typeof def === 'string') return [def];\n if (Array.isArray(def)) return def;\n const sheetRes = Assets.get(def.sheet) as Spritesheet | undefined;\n if (!sheetRes) return [];\n sheetRes.parse?.();\n const nameList: string[] | undefined = sheetRes.data?.animations?.[def.anim];\n if (!nameList || !Array.isArray(nameList)) return [];\n return nameList;\n}\n","import type { EventEmitter } from 'pixi.js';\n\n/**\n * Extract namespace prefix from event names (supports nested namespaces)\n * Example: ExtractNamespace<'hud:spin'> = 'hud'\n * Example: ExtractNamespace<'menu:autoplay:start'> = 'menu:autoplay'\n */\ntype ExtractNamespace<T extends string> = T extends `${infer Prefix}:${infer Rest}`\n ? Rest extends `${string}:${string}`\n ? `${Prefix}:${ExtractNamespace<Rest>}`\n : Prefix\n : never;\n\n/**\n * Get all unique namespaces from event map (supports nested namespaces)\n * Example: GetNamespaces<{'hud:spin': ..., 'menu:autoplay:start': ...}> = 'hud' | 'menu:autoplay'\n */\ntype GetNamespaces<T> = ExtractNamespace<Extract<keyof T, string>>;\n\n/**\n * Filter events by namespace\n * Example: FilterByNamespace<SlotBaseEvents, 'hud'> = { 'hud:spin': () => void, ... }\n */\ntype FilterByNamespace<T, NS extends string> = {\n [K in Extract<keyof T, `${NS}:${string}`>]: T[K];\n};\n\n/**\n * Remove namespace prefix from event names (supports nested namespaces)\n * Example: StripNamespace<'hud:spin', 'hud'> = 'spin'\n * Example: StripNamespace<'menu:autoplay:start', 'menu:autoplay'> = 'start'\n */\ntype StripNamespace<T extends string, NS extends string> = T extends `${NS}:${infer Rest}`\n ? Rest\n : T;\n\n/**\n * Transform event map by removing namespace prefix\n * Example: TransformEventMap<{ 'hud:spin': () => void }, 'hud'> = { 'spin': () => void }\n */\ntype TransformEventMap<T, NS extends string> = {\n [K in Extract<keyof T, string> as StripNamespace<K, NS>]: K extends keyof T ? T[K] : never;\n};\n\n/**\n * Configuration for event bridge\n */\nexport interface EventBridgeConfig {\n /**\n * Namespace prefix to add to forwarded events\n * Example: 'hud' will transform 'spin' to 'hud:spin'\n */\n namespace?: string;\n\n /**\n * Custom transform function for event name and arguments\n * Takes precedence over namespace if provided\n */\n transform?: (event: string, ...args: any[]) => [string, ...any[]];\n\n /**\n * Filter function to selectively forward events\n * Return true to forward, false to skip\n */\n filter?: (event: string) => boolean;\n\n /**\n * Intercept function for side effects before forwarding\n * Useful for UI state changes, logging, etc.\n */\n intercept?: (event: string, ...args: any[]) => void;\n}\n\n/**\n * Event bridge handle for cleanup\n */\nexport interface EventBridgeHandle {\n /**\n * Disconnect the bridge and restore original emit behavior\n */\n disconnect: () => void;\n}\n\n/**\n * Type-safe event bridge configuration\n */\nexport interface TypedEventBridgeConfig<\n TSource extends Record<string, any>,\n TTarget extends Record<string, any>,\n NS extends GetNamespaces<TTarget>,\n> extends Omit<EventBridgeConfig, 'namespace' | 'filter' | 'intercept'> {\n namespace: NS;\n filter?: (event: keyof TSource) => boolean;\n intercept?: <K extends keyof TSource>(event: K, ...args: Parameters<TSource[K]>) => void;\n}\n\n/**\n * Creates an event bridge that automatically forwards all emitted events from source to target.\n * This eliminates the need for manual event binding boilerplate.\n *\n * **Auto-cleanup:** If the source component has a `destroy()` method, the bridge will\n * automatically clean up when the component is destroyed, preventing memory leaks.\n * You can also manually disconnect using the returned handle.\n *\n * @example\n * // Simple namespace forwarding\n * createEventBridge(this.gameHud, this.eventBusPlugin, {\n * namespace: 'hud'\n * });\n * // Now: gameHud.emit('spin') → eventBus.emit('hud:spin')\n * // Auto-cleanup when gameHud.destroy() is called\n *\n * @example\n * // With side effects\n * createEventBridge(this.gameHud, this.eventBusPlugin, {\n * namespace: 'hud',\n * intercept: (event) => {\n * if (event === 'autoplay') this.autoplayMenu.visible = !this.autoplayMenu.visible;\n * }\n * });\n *\n * @example\n * // Manual cleanup (optional)\n * const handle = createEventBridge(this.component, this.eventBus, {\n * transform: (event, ...args) => [`custom:${event}`, ...args]\n * });\n * // Later...\n * handle.disconnect(); // Manual cleanup if needed\n *\n * @param source - The EventEmitter to bridge from\n * @param target - The EventEmitter to forward events to\n * @param config - Bridge configuration options\n * @returns Handle with disconnect method for manual cleanup\n */\nexport function createEventBridge(\n source: EventEmitter,\n target: { emit(event: any, ...args: any[]): boolean },\n config: EventBridgeConfig = {},\n): EventBridgeHandle {\n // Store original methods\n const originalEmit = source.emit.bind(source);\n const originalDestroy = (source as any).destroy?.bind(source);\n\n // Override emit to intercept and forward\n source.emit = function (event: string | symbol, ...args: any[]): boolean {\n // Call original emit first\n const result = originalEmit(event, ...args);\n\n // Only process string events\n if (typeof event !== 'string') {\n return result;\n }\n\n // Apply filter if provided\n if (config.filter && !config.filter(event)) {\n return result;\n }\n\n // Execute intercept for side effects\n if (config.intercept) {\n config.intercept(event, ...args);\n }\n\n // Transform event name and args\n let forwardEvent: string;\n let forwardArgs: any[];\n\n if (config.transform) {\n // Use custom transform\n [forwardEvent, ...forwardArgs] = config.transform(event, ...args);\n } else if (config.namespace) {\n // Use namespace prefix\n forwardEvent = `${config.namespace}:${event}`;\n forwardArgs = args;\n } else {\n // No transformation\n forwardEvent = event;\n forwardArgs = args;\n }\n\n // Forward to target\n target.emit(forwardEvent, ...forwardArgs);\n\n return result;\n };\n\n // Auto-cleanup: Hook into destroy method if it exists\n if (typeof (source as any).destroy === 'function') {\n (source as any).destroy = function (options?: any): void {\n // Restore original emit before destroying\n source.emit = originalEmit;\n\n // Restore original destroy\n if (originalDestroy) {\n (source as any).destroy = originalDestroy;\n }\n\n // Call original destroy\n if (originalDestroy) {\n originalDestroy(options);\n }\n };\n }\n\n // Return cleanup handle for manual disconnect if needed\n return {\n disconnect: () => {\n source.emit = originalEmit;\n if (originalDestroy) {\n (source as any).destroy = originalDestroy;\n }\n },\n };\n}\n\n/**\n * Type-safe event bridge creator\n * Ensures source events match target events after namespace transformation\n *\n * @example\n * // Define source events (without namespace)\n * interface HudEvents {\n * spin: () => void;\n * autoplay: () => void;\n * }\n *\n * // Define target events (with namespace)\n * interface GameEvents {\n * 'hud:spin': () => void;\n * 'hud:autoplay': () => void;\n * 'menu:close': () => void;\n * }\n *\n * // Type-safe bridge - TypeScript validates that HudEvents matches 'hud' namespace in GameEvents\n * createTypedEventBridge<GameEvents, 'hud', HudEvents>(\n * hudComponent,\n * eventBus,\n * { namespace: 'hud' }\n * );\n *\n * @param source - The EventEmitter to bridge from\n * @param target - The EventEmitter to forward events to\n * @param config - Type-safe bridge configuration\n * @returns Handle with disconnect method for manual cleanup\n */\nexport function createTypedEventBridge<\n TTarget extends Record<string, any>,\n NS extends GetNamespaces<TTarget>,\n TSource extends TransformEventMap<FilterByNamespace<TTarget, NS>, NS>,\n>(\n source: EventEmitter,\n target: { emit(event: any, ...args: any[]): boolean },\n config: TypedEventBridgeConfig<TSource, TTarget, NS>,\n): EventBridgeHandle {\n const bridgeConfig: EventBridgeConfig = {\n namespace: config.namespace,\n filter: config.filter as ((event: string) => boolean) | undefined,\n intercept: config.intercept as ((event: string, ...args: any[]) => void) | undefined,\n transform: config.transform,\n };\n\n return createEventBridge(source, target, bridgeConfig);\n}\n","import { mergeWith, isPlainObject } from 'lodash';\n\n/**\n * Sentinel symbol to mark properties for removal during merge.\n * Use this in override objects to explicitly remove a property from the base.\n *\n * @example\n * const base = { a: 1, b: 2 };\n * mergeWithRemove(base, { b: REMOVE }); // → { a: 1 }\n */\nexport const REMOVE = Symbol('REMOVE');\n\n/**\n * Deep merge with support for removing properties using REMOVE symbol.\n * Similar to lodash.merge but:\n * - REMOVE symbol removes the property entirely\n * - Arrays are replaced, not merged\n *\n * @example\n * const base = { a: 1, b: { c: 2, d: 3 } };\n * mergeWithRemove(base, { b: { c: REMOVE } }); // → { a: 1, b: { d: 3 } }\n */\nexport const mergeWithRemove = <T extends object>(base: T, ...overrides: object[]): T => {\n const result = mergeWith({}, base, ...overrides, (_objValue: unknown, srcValue: unknown) => {\n if (srcValue === REMOVE) {\n return REMOVE;\n }\n if (Array.isArray(srcValue)) {\n return srcValue;\n }\n return undefined;\n });\n\n const cleanRemoved = (obj: Record<string, unknown>): Record<string, unknown> => {\n if (!isPlainObject(obj)) return obj;\n for (const key of Object.keys(obj)) {\n if (obj[key] === REMOVE) {\n delete obj[key];\n } else if (isPlainObject(obj[key])) {\n cleanRemoved(obj[key] as Record<string, unknown>);\n }\n }\n return obj;\n };\n\n return cleanRemoved(result) as T;\n};\n\n\n"]}
|
package/dist/plugins/index.js
CHANGED
|
@@ -2,12 +2,12 @@ import { initSlotI18n, t, changeLanguage, getCurrentLanguage, isI18nReady, getI1
|
|
|
2
2
|
import { ENGINE_HOOKS } from '../chunk-MI6BP7A6.js';
|
|
3
3
|
import { resolvePublicPath } from '../chunk-NQMORMNP.js';
|
|
4
4
|
import { getLogger } from '../chunk-DOHQE2YZ.js';
|
|
5
|
-
import '../chunk-
|
|
5
|
+
import { require_lodash } from '../chunk-NAQG7TMS.js';
|
|
6
|
+
import { __toESM } from '../chunk-G3PMV62Z.js';
|
|
6
7
|
import { EventEmitter, detectWebp, isMobile, Assets, Container, VERSION } from 'pixi.js';
|
|
7
8
|
import '@esotericsoftware/spine-pixi-v8';
|
|
8
9
|
import gsap2, { gsap } from 'gsap';
|
|
9
10
|
import * as Sentry from '@sentry/browser';
|
|
10
|
-
import { merge } from 'lodash';
|
|
11
11
|
import { sound } from '@pixi/sound';
|
|
12
12
|
|
|
13
13
|
var DeviceOptimizerPlugin = class {
|
|
@@ -3289,6 +3289,9 @@ var DevAdapter = class extends RGSAdapter {
|
|
|
3289
3289
|
});
|
|
3290
3290
|
}
|
|
3291
3291
|
};
|
|
3292
|
+
|
|
3293
|
+
// plugins/skin/Skin.ts
|
|
3294
|
+
var import_lodash = __toESM(require_lodash(), 1);
|
|
3292
3295
|
var Skin = class extends EventEmitter {
|
|
3293
3296
|
data;
|
|
3294
3297
|
currentTheme;
|
|
@@ -3372,7 +3375,7 @@ var Skin = class extends EventEmitter {
|
|
|
3372
3375
|
} else if (!currentData) {
|
|
3373
3376
|
mergedData = defaultData;
|
|
3374
3377
|
} else {
|
|
3375
|
-
mergedData = merge({}, defaultData, currentData);
|
|
3378
|
+
mergedData = (0, import_lodash.merge)({}, defaultData, currentData);
|
|
3376
3379
|
}
|
|
3377
3380
|
const injectedData = ((_a = this.plugin) == null ? void 0 : _a.injectGlobalData) ? this.plugin.injectGlobalData(mergedData) : mergedData;
|
|
3378
3381
|
return Object.freeze(injectedData);
|