@rb-games/core 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-5BLUF2HG.js +25 -0
- package/dist/chunk-5BLUF2HG.js.map +1 -0
- package/dist/chunk-DOHQE2YZ.js +392 -0
- package/dist/chunk-DOHQE2YZ.js.map +1 -0
- package/dist/chunk-FOZO6TLY.js +673 -0
- package/dist/chunk-FOZO6TLY.js.map +1 -0
- package/dist/chunk-G3PMV62Z.js +33 -0
- package/dist/chunk-G3PMV62Z.js.map +1 -0
- package/dist/chunk-KOHCRCV3.js +490 -0
- package/dist/chunk-KOHCRCV3.js.map +1 -0
- package/dist/chunk-MI6BP7A6.js +11 -0
- package/dist/chunk-MI6BP7A6.js.map +1 -0
- package/dist/chunk-NQMORMNP.js +15 -0
- package/dist/chunk-NQMORMNP.js.map +1 -0
- package/dist/chunk-RAEOBW6E.js +133 -0
- package/dist/chunk-RAEOBW6E.js.map +1 -0
- package/dist/chunk-UE7T7Z45.js +884 -0
- package/dist/chunk-UE7T7Z45.js.map +1 -0
- package/dist/devtools/index.js +2 -882
- package/dist/devtools/index.js.map +1 -1
- package/dist/engine/index.js +6 -1267
- package/dist/engine/index.js.map +1 -1
- package/dist/filters/index.js +1 -1
- package/dist/helpers/index.js +6 -35
- package/dist/helpers/index.js.map +1 -1
- package/dist/i18n/index.js +4 -525
- package/dist/i18n/index.js.map +1 -1
- package/dist/layout/index.js +2 -671
- package/dist/layout/index.js.map +1 -1
- package/dist/particle/index.js +1 -6
- package/dist/particle/index.js.map +1 -1
- package/dist/plugins/Plugin.types.d.ts +4 -2
- package/dist/plugins/Plugin.types.d.ts.map +1 -1
- package/dist/plugins/index.js +6 -521
- package/dist/plugins/index.js.map +1 -1
- package/dist/state-machine/index.js +1 -1
- package/dist/store/index.js +1 -1
- package/dist/ui/index.js +5 -531
- package/dist/ui/index.js.map +1 -1
- package/dist/utils/index.js +4 -897
- package/dist/utils/index.js.map +1 -1
- package/dist/vite/index.js +1 -1
- package/package.json +3 -15
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
import { cloneDeep, merge, set, get } from 'lodash';
|
|
2
|
+
import { Rectangle, Color } from 'pixi.js';
|
|
3
|
+
|
|
4
|
+
// utils/DataInjector.ts
|
|
5
|
+
function DataInjector(obj, path, data, replace = false) {
|
|
6
|
+
const result = cloneDeep(obj);
|
|
7
|
+
if (path === "" || path === void 0 || path === null) {
|
|
8
|
+
return merge({}, result, cloneDeep(data));
|
|
9
|
+
}
|
|
10
|
+
if (replace) {
|
|
11
|
+
set(result, path, cloneDeep(data));
|
|
12
|
+
return result;
|
|
13
|
+
}
|
|
14
|
+
const current = get(result, path);
|
|
15
|
+
const merged = merge({}, current ?? {}, data);
|
|
16
|
+
set(result, path, merged);
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
function adjustColor(color, amount, sign) {
|
|
20
|
+
const colorObj = new Color(color);
|
|
21
|
+
const rgb = {
|
|
22
|
+
r: colorObj.red * 255,
|
|
23
|
+
g: colorObj.green * 255,
|
|
24
|
+
b: colorObj.blue * 255
|
|
25
|
+
};
|
|
26
|
+
const delta = 255 * amount * sign;
|
|
27
|
+
const newR = Math.max(0, Math.min(255, rgb.r + delta));
|
|
28
|
+
const newG = Math.max(0, Math.min(255, rgb.g + delta));
|
|
29
|
+
const newB = Math.max(0, Math.min(255, rgb.b + delta));
|
|
30
|
+
return new Color([newR / 255, newG / 255, newB / 255]);
|
|
31
|
+
}
|
|
32
|
+
function lightenColor(color, amount) {
|
|
33
|
+
return adjustColor(color, amount, 1);
|
|
34
|
+
}
|
|
35
|
+
function darkenColor(color, amount) {
|
|
36
|
+
return adjustColor(color, amount, -1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// utils/NumberFormatter.ts
|
|
40
|
+
var DEFAULT_CONFIG = {
|
|
41
|
+
mask: "#,##0.##",
|
|
42
|
+
denom: 1,
|
|
43
|
+
expressThreshold: 1e3,
|
|
44
|
+
expressUnits: ["K", "M", "B", "T", "Q"],
|
|
45
|
+
decimalPrecision: 2,
|
|
46
|
+
roundedSymbol: "+"
|
|
47
|
+
};
|
|
48
|
+
var NumberFormatter = class _NumberFormatter {
|
|
49
|
+
static instance;
|
|
50
|
+
config;
|
|
51
|
+
maskCache = /* @__PURE__ */ new Map();
|
|
52
|
+
/**
|
|
53
|
+
* Private constructor for singleton pattern
|
|
54
|
+
*/
|
|
55
|
+
constructor(config) {
|
|
56
|
+
this.config = config;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Configure the NumberFormatter singleton.
|
|
60
|
+
*
|
|
61
|
+
* @param config - Configuration options
|
|
62
|
+
* @returns NumberFormatter instance
|
|
63
|
+
*/
|
|
64
|
+
static configure(config) {
|
|
65
|
+
const finalConfig = { ...DEFAULT_CONFIG, ...config };
|
|
66
|
+
if (!_NumberFormatter.instance) {
|
|
67
|
+
_NumberFormatter.instance = new _NumberFormatter(finalConfig);
|
|
68
|
+
} else {
|
|
69
|
+
_NumberFormatter.instance.config = finalConfig;
|
|
70
|
+
_NumberFormatter.instance.maskCache.clear();
|
|
71
|
+
}
|
|
72
|
+
return _NumberFormatter.instance;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get the singleton instance.
|
|
76
|
+
*
|
|
77
|
+
* If not configured yet, initializes with default configuration.
|
|
78
|
+
*
|
|
79
|
+
* @returns NumberFormatter instance
|
|
80
|
+
*/
|
|
81
|
+
static getInstance() {
|
|
82
|
+
if (!_NumberFormatter.instance) {
|
|
83
|
+
_NumberFormatter.instance = new _NumberFormatter(DEFAULT_CONFIG);
|
|
84
|
+
}
|
|
85
|
+
return _NumberFormatter.instance;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Format a number using the configured mask.
|
|
89
|
+
*
|
|
90
|
+
* @param value - Number to format
|
|
91
|
+
* @param options - Optional formatting options
|
|
92
|
+
* @returns Formatted string
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* formatter.format(1500); // "$ 15.00"
|
|
97
|
+
* formatter.format(1500, { forceDecimals: true }); // "$ 15.00"
|
|
98
|
+
* formatter.format(1500, { ignoreDenom: true }); // "$ 1,500.00"
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
format(value, options = {}) {
|
|
102
|
+
const { prefix = "", forceDecimals = false, ignoreDenom = false } = options;
|
|
103
|
+
const actualValue = ignoreDenom ? value : value * this.config.denom;
|
|
104
|
+
let mask = this.config.mask;
|
|
105
|
+
if (forceDecimals) {
|
|
106
|
+
mask = mask.replace(/\.##/g, ".00");
|
|
107
|
+
}
|
|
108
|
+
return this.applyMask(mask, actualValue) + prefix;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Format a number in express mode (shortened with K/M/B/T).
|
|
112
|
+
*
|
|
113
|
+
* @param value - Number to format
|
|
114
|
+
* @param options - Optional formatting options
|
|
115
|
+
* @returns Formatted string with unit suffix
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* formatter.express(150000); // "$ 1.5K"
|
|
120
|
+
* formatter.express(2500000); // "$ 2.5M"
|
|
121
|
+
* formatter.express(500, { threshold: 100 }); // "$ 0.5K"
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
express(value, options = {}) {
|
|
125
|
+
const {
|
|
126
|
+
prefix = "",
|
|
127
|
+
forceDecimals = false,
|
|
128
|
+
ignoreDenom = false,
|
|
129
|
+
threshold = this.config.expressThreshold
|
|
130
|
+
} = options;
|
|
131
|
+
const actualValue = ignoreDenom ? value : value * this.config.denom;
|
|
132
|
+
if (actualValue < threshold) {
|
|
133
|
+
return this.format(value, { prefix, forceDecimals, ignoreDenom });
|
|
134
|
+
}
|
|
135
|
+
let unitIndex = -1;
|
|
136
|
+
let shortenedNum = actualValue;
|
|
137
|
+
while (shortenedNum >= 1e3 && unitIndex < this.config.expressUnits.length - 1) {
|
|
138
|
+
shortenedNum /= 1e3;
|
|
139
|
+
unitIndex++;
|
|
140
|
+
}
|
|
141
|
+
const factor = Math.pow(10, this.config.decimalPrecision);
|
|
142
|
+
const roundedNum = Math.floor(shortenedNum * factor) / factor;
|
|
143
|
+
const isRounded = roundedNum < shortenedNum;
|
|
144
|
+
let mask = this.config.mask;
|
|
145
|
+
if (forceDecimals) {
|
|
146
|
+
mask = mask.replace(/\.##/g, ".00");
|
|
147
|
+
}
|
|
148
|
+
const parsed = this.parseMask(mask);
|
|
149
|
+
const formattedNumber = this.applyMask(parsed.pattern, roundedNum) + (this.config.expressUnits[unitIndex] || "") + (isRounded ? this.config.roundedSymbol : "");
|
|
150
|
+
return parsed.prefix + formattedNumber + parsed.suffix + prefix;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Parse a mask string into its components.
|
|
154
|
+
*
|
|
155
|
+
* @param mask - Mask string to parse
|
|
156
|
+
* @returns Parsed mask information
|
|
157
|
+
* @internal
|
|
158
|
+
*/
|
|
159
|
+
parseMask(mask) {
|
|
160
|
+
if (this.maskCache.has(mask)) {
|
|
161
|
+
return this.maskCache.get(mask);
|
|
162
|
+
}
|
|
163
|
+
const len = mask.length;
|
|
164
|
+
const start = mask.search(/[0-9\-\+#]/);
|
|
165
|
+
const prefix = start > 0 ? mask.substring(0, start).trim() : "";
|
|
166
|
+
const str = mask.split("").reverse().join("");
|
|
167
|
+
const end = str.search(/[0-9\-\+#]/);
|
|
168
|
+
const offset = len - end;
|
|
169
|
+
const indx = offset + (mask.substring(offset, offset + 1) === "." ? 1 : 0);
|
|
170
|
+
const suffix = end > 0 ? mask.substring(indx, len).trim() : "";
|
|
171
|
+
const pattern = mask.substring(start, indx);
|
|
172
|
+
const result = pattern.match(/[^\d\-\+#]/g);
|
|
173
|
+
const decimal = result && result[result.length - 1] || ".";
|
|
174
|
+
const group = result && result[1] && result[0] || ",";
|
|
175
|
+
const parts = pattern.split(decimal);
|
|
176
|
+
const decimalPlaces = parts[1] ? parts[1].length : 0;
|
|
177
|
+
const szSep = parts[0].split(group);
|
|
178
|
+
const groupSize = szSep[1] ? szSep[szSep.length - 1].length : 0;
|
|
179
|
+
const cleanPattern = parts[0].replace(new RegExp(`\\${group}`, "g"), "");
|
|
180
|
+
const posLeadZero = cleanPattern.indexOf("0");
|
|
181
|
+
const parsed = {
|
|
182
|
+
pattern,
|
|
183
|
+
prefix,
|
|
184
|
+
suffix,
|
|
185
|
+
decimal,
|
|
186
|
+
group,
|
|
187
|
+
decimalPlaces,
|
|
188
|
+
posLeadZero,
|
|
189
|
+
groupSize
|
|
190
|
+
};
|
|
191
|
+
this.maskCache.set(mask, parsed);
|
|
192
|
+
return parsed;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Apply a mask to a number value.
|
|
196
|
+
*
|
|
197
|
+
* @param mask - Mask pattern
|
|
198
|
+
* @param value - Number to format
|
|
199
|
+
* @returns Formatted string
|
|
200
|
+
* @internal
|
|
201
|
+
*/
|
|
202
|
+
applyMask(mask, value) {
|
|
203
|
+
if (!mask || isNaN(+value) || value === "") return value;
|
|
204
|
+
const parsed = this.parseMask(mask);
|
|
205
|
+
let isNegative = value < 0;
|
|
206
|
+
value = Math.abs(value);
|
|
207
|
+
const maskParts = parsed.pattern.split(parsed.decimal);
|
|
208
|
+
value = value.toFixed(maskParts[1] ? maskParts[1].length : 0);
|
|
209
|
+
value = +value + "";
|
|
210
|
+
const posTrailZero = maskParts[1] ? maskParts[1].lastIndexOf("0") : -1;
|
|
211
|
+
let parts = value.split(".");
|
|
212
|
+
if (!parts[1] || parts[1] && parts[1].length <= posTrailZero) {
|
|
213
|
+
value = (+value).toFixed(posTrailZero + 1);
|
|
214
|
+
}
|
|
215
|
+
const szSep = maskParts[0].split(parsed.group);
|
|
216
|
+
const cleanMask = szSep.join("");
|
|
217
|
+
if (parsed.posLeadZero > -1) {
|
|
218
|
+
while (parts[0].length < cleanMask.length - parsed.posLeadZero) {
|
|
219
|
+
parts[0] = "0" + parts[0];
|
|
220
|
+
}
|
|
221
|
+
} else if (+parts[0] === 0) {
|
|
222
|
+
parts[0] = "";
|
|
223
|
+
}
|
|
224
|
+
const valueParts = value.split(".");
|
|
225
|
+
valueParts[0] = parts[0];
|
|
226
|
+
if (parsed.groupSize) {
|
|
227
|
+
const integer = valueParts[0];
|
|
228
|
+
let str = "";
|
|
229
|
+
const offset = integer.length % parsed.groupSize;
|
|
230
|
+
const len = integer.length;
|
|
231
|
+
for (let i = 0; i < len; i++) {
|
|
232
|
+
str += integer.charAt(i);
|
|
233
|
+
if (!((i - offset + 1) % parsed.groupSize) && i < len - parsed.groupSize) {
|
|
234
|
+
str += parsed.group;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
valueParts[0] = str;
|
|
238
|
+
}
|
|
239
|
+
valueParts[1] = maskParts[1] && valueParts[1] ? parsed.decimal + valueParts[1] : "";
|
|
240
|
+
const result = valueParts.join("");
|
|
241
|
+
if (result === "0" || result === "") {
|
|
242
|
+
isNegative = false;
|
|
243
|
+
}
|
|
244
|
+
return parsed.prefix + (isNegative ? "-" : "") + result + parsed.suffix;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Decimal/group separators and fraction length from the configured mask.
|
|
248
|
+
* Use for free-form numeric inputs (e.g. bet multipliers) that are not currency amounts.
|
|
249
|
+
*/
|
|
250
|
+
getMaskLocale() {
|
|
251
|
+
const parsed = this.parseMask(this.config.mask);
|
|
252
|
+
return {
|
|
253
|
+
decimal: parsed.decimal,
|
|
254
|
+
group: parsed.group,
|
|
255
|
+
decimalPlaces: parsed.decimalPlaces > 0 ? parsed.decimalPlaces : this.config.decimalPrecision
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Format a number using only the numeric portion of the mask (no prefix/suffix, no denom).
|
|
260
|
+
* Suitable for multipliers and limits (e.g. autoplay 10.5× bet).
|
|
261
|
+
*/
|
|
262
|
+
formatPlainNumber(value, options = {}) {
|
|
263
|
+
const { forceDecimals = false } = options;
|
|
264
|
+
const parsed = this.parseMask(this.config.mask);
|
|
265
|
+
let pattern = parsed.pattern;
|
|
266
|
+
if (forceDecimals) {
|
|
267
|
+
pattern = pattern.replace(/\.##/g, ".00");
|
|
268
|
+
}
|
|
269
|
+
return this.applyMask(pattern, value);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Get current configuration.
|
|
273
|
+
*
|
|
274
|
+
* @returns Current configuration
|
|
275
|
+
*/
|
|
276
|
+
getConfig() {
|
|
277
|
+
return { ...this.config };
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
// utils/ArrayUtils.ts
|
|
282
|
+
Object.defineProperty(Array.prototype, "exclude", {
|
|
283
|
+
value: function(...indexToExclude) {
|
|
284
|
+
return this.filter((_, index) => !indexToExclude.includes(index));
|
|
285
|
+
},
|
|
286
|
+
enumerable: false
|
|
287
|
+
});
|
|
288
|
+
Object.defineProperty(Array.prototype, "random", {
|
|
289
|
+
value: function() {
|
|
290
|
+
const randomIndex = Math.floor(Math.random() * this.length);
|
|
291
|
+
return this[randomIndex];
|
|
292
|
+
},
|
|
293
|
+
enumerable: false
|
|
294
|
+
});
|
|
295
|
+
Object.defineProperty(Array.prototype, "lastItem", {
|
|
296
|
+
value: function() {
|
|
297
|
+
return this[this.length - 1];
|
|
298
|
+
},
|
|
299
|
+
enumerable: false
|
|
300
|
+
});
|
|
301
|
+
Object.defineProperty(Array.prototype, "firstItem", {
|
|
302
|
+
value: function() {
|
|
303
|
+
return this[0];
|
|
304
|
+
},
|
|
305
|
+
enumerable: false
|
|
306
|
+
});
|
|
307
|
+
Object.defineProperty(Array.prototype, "clone", {
|
|
308
|
+
value: function() {
|
|
309
|
+
return [...this];
|
|
310
|
+
},
|
|
311
|
+
enumerable: false
|
|
312
|
+
});
|
|
313
|
+
Object.defineProperty(Array.prototype, "shuffle", {
|
|
314
|
+
value: function() {
|
|
315
|
+
const array = [...this];
|
|
316
|
+
for (let i = array.length - 1; i > 0; i--) {
|
|
317
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
318
|
+
[array[i], array[j]] = [array[j], array[i]];
|
|
319
|
+
}
|
|
320
|
+
return array;
|
|
321
|
+
},
|
|
322
|
+
enumerable: false
|
|
323
|
+
});
|
|
324
|
+
var __arrayUtilsLoaded = true;
|
|
325
|
+
function calculateAnimationSpeed(exportedFps = 12, speed = 1) {
|
|
326
|
+
return exportedFps / 60 * speed;
|
|
327
|
+
}
|
|
328
|
+
function applyAnchor(element, anchor, defaultAnchor) {
|
|
329
|
+
if (!("anchor" in element)) return;
|
|
330
|
+
const elementWithAnchor = element;
|
|
331
|
+
if (anchor) {
|
|
332
|
+
elementWithAnchor.anchor.set(anchor.x, anchor.y);
|
|
333
|
+
} else if (defaultAnchor) {
|
|
334
|
+
elementWithAnchor.anchor.set(defaultAnchor.x, defaultAnchor.y);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
function applyScale(element, scale) {
|
|
338
|
+
if (scale === void 0) return;
|
|
339
|
+
if (typeof scale === "number") {
|
|
340
|
+
element.scale.set(scale);
|
|
341
|
+
} else {
|
|
342
|
+
element.scale.set(scale.x, scale.y);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function applyCommonProperties(element, config) {
|
|
346
|
+
if (config.alpha !== void 0) {
|
|
347
|
+
element.alpha = config.alpha;
|
|
348
|
+
}
|
|
349
|
+
if (config.blendMode) {
|
|
350
|
+
element.blendMode = config.blendMode;
|
|
351
|
+
}
|
|
352
|
+
applyScale(element, config.scale);
|
|
353
|
+
}
|
|
354
|
+
function updateBounds(existingBounds, x, y, width, height) {
|
|
355
|
+
if (existingBounds instanceof Rectangle) {
|
|
356
|
+
existingBounds.x = x;
|
|
357
|
+
existingBounds.y = y;
|
|
358
|
+
existingBounds.width = width;
|
|
359
|
+
existingBounds.height = height;
|
|
360
|
+
return existingBounds;
|
|
361
|
+
}
|
|
362
|
+
return new Rectangle(x, y, width, height);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// utils/Throttle.ts
|
|
366
|
+
function debounce(func, wait = 0, options = {}) {
|
|
367
|
+
let lastArgs;
|
|
368
|
+
let lastThis;
|
|
369
|
+
const maxWait = options.maxWait ? options.maxWait : wait;
|
|
370
|
+
let result;
|
|
371
|
+
let timerId;
|
|
372
|
+
let lastCallTime;
|
|
373
|
+
let lastInvokeTime = 0;
|
|
374
|
+
const leading = !!options.leading;
|
|
375
|
+
const maxing = "maxWait" in options;
|
|
376
|
+
const trailing = options.trailing ?? true;
|
|
377
|
+
const useRAF = wait !== 0 && typeof globalThis.requestAnimationFrame === "function";
|
|
378
|
+
if (typeof func !== "function") {
|
|
379
|
+
throw new TypeError("Expected a function");
|
|
380
|
+
}
|
|
381
|
+
function invokeFunc(time) {
|
|
382
|
+
const args = lastArgs;
|
|
383
|
+
const thisArg = lastThis;
|
|
384
|
+
lastArgs = lastThis = void 0;
|
|
385
|
+
lastInvokeTime = time;
|
|
386
|
+
result = func.apply(thisArg, args);
|
|
387
|
+
return result;
|
|
388
|
+
}
|
|
389
|
+
function startTimer(pendingFunc, milliseconds) {
|
|
390
|
+
if (useRAF) {
|
|
391
|
+
if (typeof timerId === "number") {
|
|
392
|
+
globalThis.cancelAnimationFrame(timerId);
|
|
393
|
+
}
|
|
394
|
+
return globalThis.requestAnimationFrame(pendingFunc);
|
|
395
|
+
}
|
|
396
|
+
return setTimeout(pendingFunc, milliseconds);
|
|
397
|
+
}
|
|
398
|
+
function cancelTimer(id) {
|
|
399
|
+
if (useRAF) {
|
|
400
|
+
globalThis.cancelAnimationFrame(id);
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
clearTimeout(id);
|
|
404
|
+
}
|
|
405
|
+
function leadingEdge(time) {
|
|
406
|
+
lastInvokeTime = time;
|
|
407
|
+
timerId = startTimer(timerExpired, wait);
|
|
408
|
+
return leading ? invokeFunc(time) : result;
|
|
409
|
+
}
|
|
410
|
+
function remainingWait(time) {
|
|
411
|
+
const timeSinceLastCall = time - (lastCallTime || 0);
|
|
412
|
+
const timeSinceLastInvoke = time - lastInvokeTime;
|
|
413
|
+
const timeWaiting = wait - timeSinceLastCall;
|
|
414
|
+
return maxing ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting;
|
|
415
|
+
}
|
|
416
|
+
function shouldInvoke(time) {
|
|
417
|
+
const timeSinceLastCall = time - (lastCallTime || 0);
|
|
418
|
+
const timeSinceLastInvoke = time - lastInvokeTime;
|
|
419
|
+
return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait;
|
|
420
|
+
}
|
|
421
|
+
function timerExpired() {
|
|
422
|
+
const time = Date.now();
|
|
423
|
+
if (shouldInvoke(time)) {
|
|
424
|
+
return trailingEdge(time);
|
|
425
|
+
}
|
|
426
|
+
timerId = startTimer(timerExpired, remainingWait(time));
|
|
427
|
+
return void 0;
|
|
428
|
+
}
|
|
429
|
+
function trailingEdge(time) {
|
|
430
|
+
timerId = void 0;
|
|
431
|
+
if (trailing && lastArgs) {
|
|
432
|
+
return invokeFunc(time);
|
|
433
|
+
}
|
|
434
|
+
lastArgs = lastThis = void 0;
|
|
435
|
+
return result;
|
|
436
|
+
}
|
|
437
|
+
function cancel() {
|
|
438
|
+
if (timerId !== void 0) {
|
|
439
|
+
cancelTimer(timerId);
|
|
440
|
+
}
|
|
441
|
+
lastInvokeTime = 0;
|
|
442
|
+
lastArgs = lastCallTime = lastThis = timerId = void 0;
|
|
443
|
+
}
|
|
444
|
+
function flush() {
|
|
445
|
+
return timerId === void 0 ? result : trailingEdge(Date.now());
|
|
446
|
+
}
|
|
447
|
+
function pending() {
|
|
448
|
+
return timerId !== void 0;
|
|
449
|
+
}
|
|
450
|
+
function debounced(...args) {
|
|
451
|
+
const time = Date.now();
|
|
452
|
+
const isInvoking = shouldInvoke(time);
|
|
453
|
+
lastArgs = args;
|
|
454
|
+
lastThis = this;
|
|
455
|
+
lastCallTime = time;
|
|
456
|
+
if (isInvoking) {
|
|
457
|
+
if (timerId === void 0) {
|
|
458
|
+
return leadingEdge(lastCallTime);
|
|
459
|
+
}
|
|
460
|
+
if (maxing) {
|
|
461
|
+
timerId = startTimer(timerExpired, wait);
|
|
462
|
+
return invokeFunc(lastCallTime);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (timerId === void 0) {
|
|
466
|
+
timerId = startTimer(timerExpired, wait);
|
|
467
|
+
}
|
|
468
|
+
return result;
|
|
469
|
+
}
|
|
470
|
+
debounced.cancel = cancel;
|
|
471
|
+
debounced.flush = flush;
|
|
472
|
+
debounced.pending = pending;
|
|
473
|
+
return debounced;
|
|
474
|
+
}
|
|
475
|
+
function throttle(func, wait, options = {}) {
|
|
476
|
+
const leading = options.leading ?? true;
|
|
477
|
+
const trailing = options.trailing ?? true;
|
|
478
|
+
if (typeof func !== "function") {
|
|
479
|
+
throw new TypeError("Expected a function");
|
|
480
|
+
}
|
|
481
|
+
return debounce(func, wait, {
|
|
482
|
+
leading,
|
|
483
|
+
trailing,
|
|
484
|
+
maxWait: wait
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
export { DataInjector, NumberFormatter, __arrayUtilsLoaded, applyAnchor, applyCommonProperties, applyScale, calculateAnimationSpeed, darkenColor, debounce, lightenColor, throttle, updateBounds };
|
|
489
|
+
//# sourceMappingURL=chunk-KOHCRCV3.js.map
|
|
490
|
+
//# sourceMappingURL=chunk-KOHCRCV3.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":";;;;AAmEO,SAAS,YAAA,CACd,GAAA,EACA,IAAA,EACA,IAAA,EACA,UAAU,KAAA,EACP;AACH,EAAA,MAAM,MAAA,GAAS,UAAU,GAAG,CAAA;AAG5B,EAAA,IAAI,IAAA,KAAS,EAAA,IAAM,IAAA,KAAS,MAAA,IAAa,SAAS,IAAA,EAAM;AACtD,IAAA,OAAO,MAAM,EAAC,EAAG,MAAA,EAAQ,SAAA,CAAU,IAAI,CAAC,CAAA;AAAA,EAC1C;AAEA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,SAAA,CAAU,IAAI,CAAC,CAAA;AACjC,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,MAAA,EAAQ,IAAI,CAAA;AAChC,EAAA,MAAM,SAAS,KAAA,CAAM,IAAI,OAAA,IAAW,IAAI,IAAI,CAAA;AAC5C,EAAA,GAAA,CAAI,MAAA,EAAQ,MAAM,MAAM,CAAA;AACxB,EAAA,OAAO,MAAA;AACT;ACnDA,SAAS,WAAA,CAAY,KAAA,EAAoB,MAAA,EAAgB,IAAA,EAAqB;AAC5E,EAAA,MAAM,QAAA,GAAW,IAAI,KAAA,CAAM,KAAK,CAAA;AAChC,EAAA,MAAM,GAAA,GAAM;AAAA,IACV,CAAA,EAAG,SAAS,GAAA,GAAM,GAAA;AAAA,IAClB,CAAA,EAAG,SAAS,KAAA,GAAQ,GAAA;AAAA,IACpB,CAAA,EAAG,SAAS,IAAA,GAAO;AAAA,GACrB;AAEA,EAAA,MAAM,KAAA,GAAQ,MAAM,MAAA,GAAS,IAAA;AAC7B,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,GAAA,EAAK,GAAA,CAAI,CAAA,GAAI,KAAK,CAAC,CAAA;AACrD,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,GAAA,EAAK,GAAA,CAAI,CAAA,GAAI,KAAK,CAAC,CAAA;AACrD,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,GAAA,EAAK,GAAA,CAAI,CAAA,GAAI,KAAK,CAAC,CAAA;AAErD,EAAA,OAAO,IAAI,MAAM,CAAC,IAAA,GAAO,KAAK,IAAA,GAAO,GAAA,EAAK,IAAA,GAAO,GAAG,CAAC,CAAA;AACvD;AAiBO,SAAS,YAAA,CAAa,OAAoB,MAAA,EAAuB;AACtE,EAAA,OAAO,WAAA,CAAY,KAAA,EAAO,MAAA,EAAQ,CAAC,CAAA;AACrC;AAiBO,SAAS,WAAA,CAAY,OAAoB,MAAA,EAAuB;AACrE,EAAA,OAAO,WAAA,CAAY,KAAA,EAAO,MAAA,EAAQ,EAAE,CAAA;AACtC;;;ACyEA,IAAM,cAAA,GAAwC;AAAA,EAC5C,IAAA,EAAM,UAAA;AAAA,EACN,KAAA,EAAO,CAAA;AAAA,EACP,gBAAA,EAAkB,GAAA;AAAA,EAClB,cAAc,CAAC,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,KAAK,GAAG,CAAA;AAAA,EACtC,gBAAA,EAAkB,CAAA;AAAA,EAClB,aAAA,EAAe;AACjB,CAAA;AAEO,IAAM,eAAA,GAAN,MAAM,gBAAA,CAAgB;AAAA,EAC3B,OAAe,QAAA;AAAA,EACP,MAAA;AAAA,EACA,SAAA,uBAAyC,GAAA,EAAI;AAAA;AAAA;AAAA;AAAA,EAK7C,YAAY,MAAA,EAA+B;AACjD,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAc,UAAU,MAAA,EAAyD;AAC/E,IAAA,MAAM,WAAA,GAAc,EAAE,GAAG,cAAA,EAAgB,GAAG,MAAA,EAAO;AAEnD,IAAA,IAAI,CAAC,iBAAgB,QAAA,EAAU;AAC7B,MAAA,gBAAA,CAAgB,QAAA,GAAW,IAAI,gBAAA,CAAgB,WAAW,CAAA;AAAA,IAC5D,CAAA,MAAO;AACL,MAAA,gBAAA,CAAgB,SAAS,MAAA,GAAS,WAAA;AAClC,MAAA,gBAAA,CAAgB,QAAA,CAAS,UAAU,KAAA,EAAM;AAAA,IAC3C;AAEA,IAAA,OAAO,gBAAA,CAAgB,QAAA;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAc,WAAA,GAA+B;AAC3C,IAAA,IAAI,CAAC,iBAAgB,QAAA,EAAU;AAC7B,MAAA,gBAAA,CAAgB,QAAA,GAAW,IAAI,gBAAA,CAAgB,cAAc,CAAA;AAAA,IAC/D;AACA,IAAA,OAAO,gBAAA,CAAgB,QAAA;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBO,MAAA,CAAO,KAAA,EAAe,OAAA,GAAyB,EAAC,EAAW;AAChE,IAAA,MAAM,EAAE,MAAA,GAAS,EAAA,EAAI,gBAAgB,KAAA,EAAO,WAAA,GAAc,OAAM,GAAI,OAAA;AAEpE,IAAA,MAAM,WAAA,GAAc,WAAA,GAAc,KAAA,GAAQ,KAAA,GAAQ,KAAK,MAAA,CAAO,KAAA;AAE9D,IAAA,IAAI,IAAA,GAAO,KAAK,MAAA,CAAO,IAAA;AAEvB,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,KAAK,CAAA;AAAA,IACpC;AAEA,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,WAAW,CAAA,GAAI,MAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBO,OAAA,CAAQ,KAAA,EAAe,OAAA,GAAyB,EAAC,EAAW;AACjE,IAAA,MAAM;AAAA,MACJ,MAAA,GAAS,EAAA;AAAA,MACT,aAAA,GAAgB,KAAA;AAAA,MAChB,WAAA,GAAc,KAAA;AAAA,MACd,SAAA,GAAY,KAAK,MAAA,CAAO;AAAA,KAC1B,GAAI,OAAA;AAEJ,IAAA,MAAM,WAAA,GAAc,WAAA,GAAc,KAAA,GAAQ,KAAA,GAAQ,KAAK,MAAA,CAAO,KAAA;AAE9D,IAAA,IAAI,cAAc,SAAA,EAAW;AAC3B,MAAA,OAAO,KAAK,MAAA,CAAO,KAAA,EAAO,EAAE,MAAA,EAAQ,aAAA,EAAe,aAAa,CAAA;AAAA,IAClE;AAEA,IAAA,IAAI,SAAA,GAAY,EAAA;AAChB,IAAA,IAAI,YAAA,GAAe,WAAA;AAEnB,IAAA,OAAO,gBAAgB,GAAA,IAAQ,SAAA,GAAY,KAAK,MAAA,CAAO,YAAA,CAAa,SAAS,CAAA,EAAG;AAC9E,MAAA,YAAA,IAAgB,GAAA;AAChB,MAAA,SAAA,EAAA;AAAA,IACF;AAEA,IAAA,MAAM,SAAS,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,IAAA,CAAK,OAAO,gBAAgB,CAAA;AACxD,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,KAAA,CAAM,YAAA,GAAe,MAAM,CAAA,GAAI,MAAA;AACvD,IAAA,MAAM,YAAY,UAAA,GAAa,YAAA;AAE/B,IAAA,IAAI,IAAA,GAAO,KAAK,MAAA,CAAO,IAAA;AAEvB,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,KAAK,CAAA;AAAA,IACpC;AAEA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AAClC,IAAA,MAAM,kBACJ,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,OAAA,EAAS,UAAU,CAAA,IACxC,IAAA,CAAK,MAAA,CAAO,YAAA,CAAa,SAAS,CAAA,IAAK,EAAA,CAAA,IACvC,SAAA,GAAY,IAAA,CAAK,OAAO,aAAA,GAAgB,EAAA,CAAA;AAE3C,IAAA,OAAO,MAAA,CAAO,MAAA,GAAS,eAAA,GAAkB,MAAA,CAAO,MAAA,GAAS,MAAA;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,UAAU,IAAA,EAA0B;AAC1C,IAAA,IAAI,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA,EAAG;AAC5B,MAAA,OAAO,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA;AAAA,IAChC;AAGA,IAAA,MAAM,MAAM,IAAA,CAAK,MAAA;AACjB,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,MAAA,CAAO,YAAY,CAAA;AACtC,IAAA,MAAM,MAAA,GAAS,QAAQ,CAAA,GAAI,IAAA,CAAK,UAAU,CAAA,EAAG,KAAK,CAAA,CAAE,IAAA,EAAK,GAAI,EAAA;AAE7D,IAAA,MAAM,GAAA,GAAM,KAAK,KAAA,CAAM,EAAE,EAAE,OAAA,EAAQ,CAAE,KAAK,EAAE,CAAA;AAC5C,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,MAAA,CAAO,YAAY,CAAA;AACnC,IAAA,MAAM,SAAS,GAAA,GAAM,GAAA;AACrB,IAAA,MAAM,IAAA,GAAO,UAAU,IAAA,CAAK,SAAA,CAAU,QAAQ,MAAA,GAAS,CAAC,CAAA,KAAM,GAAA,GAAM,CAAA,GAAI,CAAA,CAAA;AACxE,IAAA,MAAM,MAAA,GAAS,MAAM,CAAA,GAAI,IAAA,CAAK,UAAU,IAAA,EAAM,GAAG,CAAA,CAAE,IAAA,EAAK,GAAI,EAAA;AAE5D,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO,IAAI,CAAA;AAE1C,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,aAAa,CAAA;AAC1C,IAAA,MAAM,UAAW,MAAA,IAAU,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAC,CAAA,IAAM,GAAA;AACzD,IAAA,MAAM,QAAS,MAAA,IAAU,MAAA,CAAO,CAAC,CAAA,IAAK,MAAA,CAAO,CAAC,CAAA,IAAM,GAAA;AAEpD,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,OAAO,CAAA;AACnC,IAAA,MAAM,gBAAgB,KAAA,CAAM,CAAC,IAAI,KAAA,CAAM,CAAC,EAAE,MAAA,GAAS,CAAA;AAEnD,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,CAAC,CAAA,CAAE,MAAM,KAAK,CAAA;AAClC,IAAA,MAAM,SAAA,GAAY,MAAM,CAAC,CAAA,GAAI,MAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,CAAE,MAAA,GAAS,CAAA;AAE9D,IAAA,MAAM,YAAA,GAAe,KAAA,CAAM,CAAC,CAAA,CAAE,OAAA,CAAQ,IAAI,MAAA,CAAO,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,EAAI,GAAG,CAAA,EAAG,EAAE,CAAA;AACvE,IAAA,MAAM,WAAA,GAAc,YAAA,CAAa,OAAA,CAAQ,GAAG,CAAA;AAE5C,IAAA,MAAM,MAAA,GAAqB;AAAA,MACzB,OAAA;AAAA,MACA,MAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAA;AAAA,MACA,KAAA;AAAA,MACA,aAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,IAAA,EAAM,MAAM,CAAA;AAC/B,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,SAAA,CAAU,MAAc,KAAA,EAAoB;AAClD,IAAA,IAAI,CAAC,QAAQ,KAAA,CAAM,CAAC,KAAK,CAAA,IAAK,KAAA,KAAU,IAAI,OAAO,KAAA;AAEnD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AAClC,IAAA,IAAI,aAAa,KAAA,GAAQ,CAAA;AACzB,IAAA,KAAA,GAAQ,IAAA,CAAK,IAAI,KAAK,CAAA;AAEtB,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,OAAA,CAAQ,KAAA,CAAM,OAAO,OAAO,CAAA;AACrD,IAAA,KAAA,GAAQ,KAAA,CAAM,QAAQ,SAAA,CAAU,CAAC,IAAI,SAAA,CAAU,CAAC,CAAA,CAAE,MAAA,GAAS,CAAC,CAAA;AAC5D,IAAA,KAAA,GAAQ,CAAC,KAAA,GAAQ,EAAA;AAEjB,IAAA,MAAM,YAAA,GAAe,UAAU,CAAC,CAAA,GAAI,UAAU,CAAC,CAAA,CAAE,WAAA,CAAY,GAAG,CAAA,GAAI,EAAA;AACpE,IAAA,IAAI,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA;AAE3B,IAAA,IAAI,CAAC,KAAA,CAAM,CAAC,CAAA,IAAM,KAAA,CAAM,CAAC,CAAA,IAAK,KAAA,CAAM,CAAC,CAAA,CAAE,MAAA,IAAU,YAAA,EAAe;AAC9D,MAAA,KAAA,GAAA,CAAS,CAAC,KAAA,EAAO,OAAA,CAAQ,YAAA,GAAe,CAAC,CAAA;AAAA,IAC3C;AAEA,IAAA,MAAM,QAAQ,SAAA,CAAU,CAAC,CAAA,CAAE,KAAA,CAAM,OAAO,KAAK,CAAA;AAC7C,IAAA,MAAM,SAAA,GAAY,KAAA,CAAM,IAAA,CAAK,EAAE,CAAA;AAE/B,IAAA,IAAI,MAAA,CAAO,cAAc,EAAA,EAAI;AAC3B,MAAA,OAAO,MAAM,CAAC,CAAA,CAAE,SAAS,SAAA,CAAU,MAAA,GAAS,OAAO,WAAA,EAAa;AAC9D,QAAA,KAAA,CAAM,CAAC,CAAA,GAAI,GAAA,GAAM,KAAA,CAAM,CAAC,CAAA;AAAA,MAC1B;AAAA,IACF,CAAA,MAAA,IAAW,CAAC,KAAA,CAAM,CAAC,MAAM,CAAA,EAAG;AAC1B,MAAA,KAAA,CAAM,CAAC,CAAA,GAAI,EAAA;AAAA,IACb;AAEA,IAAA,MAAM,UAAA,GAAa,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA;AAClC,IAAA,UAAA,CAAW,CAAC,CAAA,GAAI,KAAA,CAAM,CAAC,CAAA;AAEvB,IAAA,IAAI,OAAO,SAAA,EAAW;AACpB,MAAA,MAAM,OAAA,GAAU,WAAW,CAAC,CAAA;AAC5B,MAAA,IAAI,GAAA,GAAM,EAAA;AACV,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,MAAA,GAAS,MAAA,CAAO,SAAA;AACvC,MAAA,MAAM,MAAM,OAAA,CAAQ,MAAA;AAEpB,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,CAAA,EAAA,EAAK;AAC5B,QAAA,GAAA,IAAO,OAAA,CAAQ,OAAO,CAAC,CAAA;AACvB,QAAA,IAAI,EAAA,CAAG,IAAI,MAAA,GAAS,CAAA,IAAK,OAAO,SAAA,CAAA,IAAc,CAAA,GAAI,GAAA,GAAM,MAAA,CAAO,SAAA,EAAW;AACxE,UAAA,GAAA,IAAO,MAAA,CAAO,KAAA;AAAA,QAChB;AAAA,MACF;AACA,MAAA,UAAA,CAAW,CAAC,CAAA,GAAI,GAAA;AAAA,IAClB;AAEA,IAAA,UAAA,CAAW,CAAC,CAAA,GAAI,SAAA,CAAU,CAAC,CAAA,IAAK,UAAA,CAAW,CAAC,CAAA,GAAI,MAAA,CAAO,OAAA,GAAU,UAAA,CAAW,CAAC,CAAA,GAAI,EAAA;AAEjF,IAAA,MAAM,MAAA,GAAS,UAAA,CAAW,IAAA,CAAK,EAAE,CAAA;AACjC,IAAA,IAAI,MAAA,KAAW,GAAA,IAAO,MAAA,KAAW,EAAA,EAAI;AACnC,MAAA,UAAA,GAAa,KAAA;AAAA,IACf;AAEA,IAAA,OAAO,OAAO,MAAA,IAAU,UAAA,GAAa,GAAA,GAAM,EAAA,CAAA,GAAM,SAAS,MAAA,CAAO,MAAA;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,aAAA,GAA2E;AAChF,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,OAAO,IAAI,CAAA;AAC9C,IAAA,OAAO;AAAA,MACL,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,eACE,MAAA,CAAO,aAAA,GAAgB,IAAI,MAAA,CAAO,aAAA,GAAgB,KAAK,MAAA,CAAO;AAAA,KAClE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,iBAAA,CAAkB,KAAA,EAAe,OAAA,GAAgD,EAAC,EAAW;AAClG,IAAA,MAAM,EAAE,aAAA,GAAgB,KAAA,EAAM,GAAI,OAAA;AAClC,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,OAAO,IAAI,CAAA;AAC9C,IAAA,IAAI,UAAU,MAAA,CAAO,OAAA;AACrB,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,OAAA,EAAS,KAAK,CAAA;AAAA,IAC1C;AACA,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,OAAA,EAAS,KAAK,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,SAAA,GAA6C;AAClD,IAAA,OAAO,EAAE,GAAG,IAAA,CAAK,MAAA,EAAO;AAAA,EAC1B;AACF;;;ACxbA,MAAA,CAAO,cAAA,CAAe,KAAA,CAAM,SAAA,EAAW,SAAA,EAAW;AAAA,EAChD,KAAA,EAAO,YAA2B,cAAA,EAA+B;AAC/D,IAAA,OAAO,IAAA,CAAK,OAAO,CAAC,CAAA,EAAG,UAAU,CAAC,cAAA,CAAe,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,EAClE,CAAA;AAAA,EACA,UAAA,EAAY;AACd,CAAC,CAAA;AAED,MAAA,CAAO,cAAA,CAAe,KAAA,CAAM,SAAA,EAAW,QAAA,EAAU;AAAA,EAC/C,OAAO,WAAkB;AACvB,IAAA,MAAM,cAAc,IAAA,CAAK,KAAA,CAAM,KAAK,MAAA,EAAO,GAAI,KAAK,MAAM,CAAA;AAC1D,IAAA,OAAO,KAAK,WAAW,CAAA;AAAA,EACzB,CAAA;AAAA,EACA,UAAA,EAAY;AACd,CAAC,CAAA;AAED,MAAA,CAAO,cAAA,CAAe,KAAA,CAAM,SAAA,EAAW,UAAA,EAAY;AAAA,EACjD,OAAO,WAAkB;AACvB,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AAAA,EAC7B,CAAA;AAAA,EACA,UAAA,EAAY;AACd,CAAC,CAAA;AAED,MAAA,CAAO,cAAA,CAAe,KAAA,CAAM,SAAA,EAAW,WAAA,EAAa;AAAA,EAClD,OAAO,WAAkB;AACvB,IAAA,OAAO,KAAK,CAAC,CAAA;AAAA,EACf,CAAA;AAAA,EACA,UAAA,EAAY;AACd,CAAC,CAAA;AAED,MAAA,CAAO,cAAA,CAAe,KAAA,CAAM,SAAA,EAAW,OAAA,EAAS;AAAA,EAC9C,OAAO,WAAoB;AACzB,IAAA,OAAO,CAAC,GAAG,IAAI,CAAA;AAAA,EACjB,CAAA;AAAA,EACA,UAAA,EAAY;AACd,CAAC,CAAA;AAED,MAAA,CAAO,cAAA,CAAe,KAAA,CAAM,SAAA,EAAW,SAAA,EAAW;AAAA,EAChD,OAAO,WAA6B;AAClC,IAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,IAAI,CAAA;AACtB,IAAA,KAAA,IAAS,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,CAAA,GAAI,GAAG,CAAA,EAAA,EAAK;AACzC,MAAA,MAAM,IAAI,IAAA,CAAK,KAAA,CAAM,KAAK,MAAA,EAAO,IAAK,IAAI,CAAA,CAAE,CAAA;AAC5C,MAAA,CAAC,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,CAAM,CAAC,CAAC,CAAA,GAAI,CAAC,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,IAC5C;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AAAA,EACA,UAAA,EAAY;AACd,CAAC,CAAA;AAcM,IAAM,kBAAA,GAAqB;AC5C3B,SAAS,uBAAA,CAAwB,WAAA,GAAsB,EAAA,EAAI,KAAA,GAAgB,CAAA,EAAW;AAC3F,EAAA,OAAQ,cAAc,EAAA,GAAM,KAAA;AAC9B;AAeO,SAAS,WAAA,CACd,OAAA,EACA,MAAA,EACA,aAAA,EACM;AACN,EAAA,IAAI,EAAE,YAAY,OAAA,CAAA,EAAU;AAE5B,EAAA,MAAM,iBAAA,GAAoB,OAAA;AAE1B,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,iBAAA,CAAkB,MAAA,CAAO,GAAA,CAAI,MAAA,CAAO,CAAA,EAAG,OAAO,CAAC,CAAA;AAAA,EACjD,WAAW,aAAA,EAAe;AACxB,IAAA,iBAAA,CAAkB,MAAA,CAAO,GAAA,CAAI,aAAA,CAAc,CAAA,EAAG,cAAc,CAAC,CAAA;AAAA,EAC/D;AACF;AAkBO,SAAS,UAAA,CAAW,SAAoB,KAAA,EAAiD;AAC9F,EAAA,IAAI,UAAU,MAAA,EAAW;AAEzB,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAA,CAAQ,KAAA,CAAM,IAAI,KAAK,CAAA;AAAA,EACzB,CAAA,MAAO;AACL,IAAA,OAAA,CAAQ,KAAA,CAAM,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,MAAM,CAAC,CAAA;AAAA,EACpC;AACF;AAkBO,SAAS,qBAAA,CACd,SACA,MAAA,EAKM;AACN,EAAA,IAAI,MAAA,CAAO,UAAU,MAAA,EAAW;AAC9B,IAAA,OAAA,CAAQ,QAAQ,MAAA,CAAO,KAAA;AAAA,EACzB;AAEA,EAAA,IAAI,OAAO,SAAA,EAAW;AACpB,IAAA,OAAA,CAAQ,YAAY,MAAA,CAAO,SAAA;AAAA,EAC7B;AAEA,EAAA,UAAA,CAAW,OAAA,EAAS,OAAO,KAAK,CAAA;AAClC;AAsBO,SAAS,YAAA,CACd,cAAA,EACA,CAAA,EACA,CAAA,EACA,OACA,MAAA,EACW;AACX,EAAA,IAAI,0BAA0B,SAAA,EAAW;AACvC,IAAA,cAAA,CAAe,CAAA,GAAI,CAAA;AACnB,IAAA,cAAA,CAAe,CAAA,GAAI,CAAA;AACnB,IAAA,cAAA,CAAe,KAAA,GAAQ,KAAA;AACvB,IAAA,cAAA,CAAe,MAAA,GAAS,MAAA;AACxB,IAAA,OAAO,cAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAI,SAAA,CAAU,CAAA,EAAG,CAAA,EAAG,OAAO,MAAM,CAAA;AAC1C;;;AC3EO,SAAS,SACd,IAAA,EACA,IAAA,GAAO,CAAA,EACP,OAAA,GAAsD,EAAC,EACX;AAC5C,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI,QAAA;AACJ,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,GAAU,OAAA,CAAQ,OAAA,GAAU,IAAA;AACpD,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,YAAA;AACJ,EAAA,IAAI,cAAA,GAAiB,CAAA;AACrB,EAAA,MAAM,OAAA,GAAU,CAAC,CAAC,OAAA,CAAQ,OAAA;AAC1B,EAAA,MAAM,SAAS,SAAA,IAAa,OAAA;AAC5B,EAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,IAAY,IAAA;AAGrC,EAAA,MAAM,MAAA,GAAS,IAAA,KAAS,CAAA,IAAK,OAAO,WAAW,qBAAA,KAA0B,UAAA;AAEzE,EAAA,IAAI,OAAO,SAAS,UAAA,EAAY;AAC9B,IAAA,MAAM,IAAI,UAAU,qBAAqB,CAAA;AAAA,EAC3C;AAEA,EAAA,SAAS,WAAW,IAAA,EAAc;AAChC,IAAA,MAAM,IAAA,GAAO,QAAA;AACb,IAAA,MAAM,OAAA,GAAU,QAAA;AAEhB,IAAA,QAAA,GAAW,QAAA,GAAW,MAAA;AACtB,IAAA,cAAA,GAAiB,IAAA;AACjB,IAAA,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,OAAA,EAAS,IAAK,CAAA;AAElC,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,SAAS,UAAA,CAAW,aAA8C,YAAA,EAAsB;AACtF,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,IAAI,OAAO,YAAY,QAAA,EAAU;AAC/B,QAAA,UAAA,CAAW,qBAAqB,OAAO,CAAA;AAAA,MACzC;AAEA,MAAA,OAAO,UAAA,CAAW,sBAAsB,WAAW,CAAA;AAAA,IACrD;AAEA,IAAA,OAAO,UAAA,CAAW,aAAa,YAAY,CAAA;AAAA,EAC7C;AAEA,EAAA,SAAS,YAAY,EAAA,EAA4C;AAC/D,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,UAAA,CAAW,qBAAqB,EAAY,CAAA;AAE5C,MAAA;AAAA,IACF;AACA,IAAA,YAAA,CAAa,EAAE,CAAA;AAAA,EACjB;AAEA,EAAA,SAAS,YAAY,IAAA,EAAc;AAEjC,IAAA,cAAA,GAAiB,IAAA;AAEjB,IAAA,OAAA,GAAU,UAAA,CAAW,cAAc,IAAI,CAAA;AAGvC,IAAA,OAAO,OAAA,GAAU,UAAA,CAAW,IAAI,CAAA,GAAI,MAAA;AAAA,EACtC;AAEA,EAAA,SAAS,cAAc,IAAA,EAAc;AACnC,IAAA,MAAM,iBAAA,GAAoB,QAAQ,YAAA,IAAgB,CAAA,CAAA;AAClD,IAAA,MAAM,sBAAsB,IAAA,GAAO,cAAA;AACnC,IAAA,MAAM,cAAc,IAAA,GAAO,iBAAA;AAE3B,IAAA,OAAO,SAAS,IAAA,CAAK,GAAA,CAAI,WAAA,EAAa,OAAA,GAAU,mBAAmB,CAAA,GAAI,WAAA;AAAA,EACzE;AAEA,EAAA,SAAS,aAAa,IAAA,EAAc;AAClC,IAAA,MAAM,iBAAA,GAAoB,QAAQ,YAAA,IAAgB,CAAA,CAAA;AAClD,IAAA,MAAM,sBAAsB,IAAA,GAAO,cAAA;AAKnC,IAAA,OACE,iBAAiB,MAAA,IACjB,iBAAA,IAAqB,QACrB,iBAAA,GAAoB,CAAA,IACnB,UAAU,mBAAA,IAAuB,OAAA;AAAA,EAEtC;AAEA,EAAA,SAAS,YAAA,GAAe;AACtB,IAAA,MAAM,IAAA,GAAO,KAAK,GAAA,EAAI;AAEtB,IAAA,IAAI,YAAA,CAAa,IAAI,CAAA,EAAG;AACtB,MAAA,OAAO,aAAa,IAAI,CAAA;AAAA,IAC1B;AAEA,IAAA,OAAA,GAAU,UAAA,CAAW,YAAA,EAAc,aAAA,CAAc,IAAI,CAAC,CAAA;AAEtD,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,SAAS,aAAa,IAAA,EAAc;AAClC,IAAA,OAAA,GAAU,MAAA;AAIV,IAAA,IAAI,YAAY,QAAA,EAAU;AACxB,MAAA,OAAO,WAAW,IAAI,CAAA;AAAA,IACxB;AACA,IAAA,QAAA,GAAW,QAAA,GAAW,MAAA;AAEtB,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,SAAS,MAAA,GAAS;AAChB,IAAA,IAAI,YAAY,MAAA,EAAW;AACzB,MAAA,WAAA,CAAY,OAAO,CAAA;AAAA,IACrB;AACA,IAAA,cAAA,GAAiB,CAAA;AACjB,IAAA,QAAA,GAAW,YAAA,GAAe,WAAW,OAAA,GAAU,MAAA;AAAA,EACjD;AAEA,EAAA,SAAS,KAAA,GAAQ;AACf,IAAA,OAAO,YAAY,MAAA,GAAY,MAAA,GAAS,YAAA,CAAa,IAAA,CAAK,KAAK,CAAA;AAAA,EACjE;AAEA,EAAA,SAAS,OAAA,GAAU;AACjB,IAAA,OAAO,OAAA,KAAY,MAAA;AAAA,EACrB;AAEA,EAAA,SAAS,aAAwB,IAAA,EAAqB;AACpD,IAAA,MAAM,IAAA,GAAO,KAAK,GAAA,EAAI;AACtB,IAAA,MAAM,UAAA,GAAa,aAAa,IAAI,CAAA;AAEpC,IAAA,QAAA,GAAW,IAAA;AAEX,IAAA,QAAA,GAAW,IAAA;AACX,IAAA,YAAA,GAAe,IAAA;AAEf,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,IAAI,YAAY,MAAA,EAAW;AACzB,QAAA,OAAO,YAAY,YAAY,CAAA;AAAA,MACjC;AACA,MAAA,IAAI,MAAA,EAAQ;AAEV,QAAA,OAAA,GAAU,UAAA,CAAW,cAAc,IAAI,CAAA;AAEvC,QAAA,OAAO,WAAW,YAAY,CAAA;AAAA,MAChC;AAAA,IACF;AACA,IAAA,IAAI,YAAY,MAAA,EAAW;AACzB,MAAA,OAAA,GAAU,UAAA,CAAW,cAAc,IAAI,CAAA;AAAA,IACzC;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,SAAA,CAAU,MAAA,GAAS,MAAA;AACnB,EAAA,SAAA,CAAU,KAAA,GAAQ,KAAA;AAClB,EAAA,SAAA,CAAU,OAAA,GAAU,OAAA;AAEpB,EAAA,OAAO,SAAA;AACT;AAmCO,SAAS,QAAA,CACd,IAAA,EACA,IAAA,EACA,OAAA,GAA4B,EAAC,EACX;AAClB,EAAA,MAAM,OAAA,GAAU,QAAQ,OAAA,IAAW,IAAA;AACnC,EAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,IAAY,IAAA;AAErC,EAAA,IAAI,OAAO,SAAS,UAAA,EAAY;AAC9B,IAAA,MAAM,IAAI,UAAU,qBAAqB,CAAA;AAAA,EAC3C;AAEA,EAAA,OAAO,QAAA,CAAS,MAAM,IAAA,EAAM;AAAA,IAC1B,OAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA,EAAS;AAAA,GACV,CAAA;AACH","file":"chunk-KOHCRCV3.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"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// plugins/Plugin.types.ts
|
|
2
|
+
var ENGINE_HOOKS = {
|
|
3
|
+
onEngineReady: Symbol.for("rb-games:engine:onEngineReady"),
|
|
4
|
+
onPause: Symbol.for("rb-games:engine:onPause"),
|
|
5
|
+
onResume: Symbol.for("rb-games:engine:onResume"),
|
|
6
|
+
onResize: Symbol.for("rb-games:engine:onResize")
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export { ENGINE_HOOKS };
|
|
10
|
+
//# sourceMappingURL=chunk-MI6BP7A6.js.map
|
|
11
|
+
//# sourceMappingURL=chunk-MI6BP7A6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../plugins/Plugin.types.ts"],"names":[],"mappings":";AAQO,IAAM,YAAA,GAAe;AAAA,EAC1B,aAAA,EAAe,MAAA,CAAO,GAAA,CAAI,+BAA+B,CAAA;AAAA,EACzD,OAAA,EAAS,MAAA,CAAO,GAAA,CAAI,yBAAyB,CAAA;AAAA,EAC7C,QAAA,EAAU,MAAA,CAAO,GAAA,CAAI,0BAA0B,CAAA;AAAA,EAC/C,QAAA,EAAU,MAAA,CAAO,GAAA,CAAI,0BAA0B;AACjD","file":"chunk-MI6BP7A6.js","sourcesContent":["import type { PixiEngine } from '../engine/PixiEngine';\n\n/**\n * Internal symbols for engine-only hook access.\n * Use Symbol.for so every published tsup entry (engine, plugins, …) shares\n * the same hook keys. Plain Symbol() is unique per bundle and silently\n * drops resize/pause/ready callbacks in npm consumers.\n */\nexport const ENGINE_HOOKS = {\n onEngineReady: Symbol.for('rb-games:engine:onEngineReady'),\n onPause: Symbol.for('rb-games:engine:onPause'),\n onResume: Symbol.for('rb-games:engine:onResume'),\n onResize: Symbol.for('rb-games:engine:onResize'),\n} as const;\n\n/**\n * Plugin lifecycle states\n */\nexport enum PluginState {\n REGISTERED = 'registered',\n INITIALIZING = 'initializing',\n INITIALIZED = 'initialized',\n READY = 'ready',\n ERROR = 'error',\n}\n\n/**\n * Plugin interface\n */\nexport interface EnginePlugin {\n /**\n * Plugin name. Must be unique.\n */\n name: string;\n\n /**\n * Plugin priority. Lower values represent higher priority.\n */\n priority: number;\n\n /**\n * Current plugin state\n */\n state?: PluginState;\n\n /**\n * Plugin dependencies - other plugins that must be ready before this one\n */\n dependencies?: string[];\n\n /**\n * Method that will be executed when the plugin is first loaded.\n * @param engine PixiEngine instance\n * @returns Promise that resolves when plugin is fully initialized\n */\n initialize(engine: PixiEngine): Promise<void> | void;\n\n /**\n * Called after initialization to mark plugin as ready\n * This is where you can access other plugins safely\n * @param engine PixiEngine instance\n * @returns Promise that resolves when plugin is ready\n */\n onReady?(engine: PixiEngine): Promise<void> | void;\n\n /**\n * Method that will be executed when the plugin is cleaned up.\n */\n cleanup?(): void;\n\n /**\n * Called on every frame update.\n * @param delta Frame duration (ms)\n * @returns Boolean value\n */\n onUpdate?(delta: number): boolean;\n\n /**\n * Index signature to allow symbol-based properties for internal engine hooks\n * @internal - These are accessed via ENGINE_HOOKS symbols by PixiEngine only\n */\n [key: symbol]: any;\n}\n\n/**\n * Common configuration parameters for all plugins\n */\nexport interface PluginConfig {\n priority?: number;\n enabled?: boolean;\n name?: string;\n dependencies?: string[];\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// helpers/resolvePublicPath.ts
|
|
2
|
+
function resolvePublicPath(path) {
|
|
3
|
+
var _a;
|
|
4
|
+
if (path.startsWith("http://") || path.startsWith("https://")) {
|
|
5
|
+
return path;
|
|
6
|
+
}
|
|
7
|
+
const base = typeof import.meta !== "undefined" && ((_a = import.meta.env) == null ? void 0 : _a.BASE_URL) ? import.meta.env.BASE_URL : "/";
|
|
8
|
+
const normalizedBase = base.endsWith("/") ? base : `${base}/`;
|
|
9
|
+
const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
|
|
10
|
+
return `${normalizedBase}${normalizedPath}`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { resolvePublicPath };
|
|
14
|
+
//# sourceMappingURL=chunk-NQMORMNP.js.map
|
|
15
|
+
//# sourceMappingURL=chunk-NQMORMNP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../helpers/resolvePublicPath.ts"],"names":[],"mappings":";AAIO,SAAS,kBAAkB,IAAA,EAAsB;AAJxD,EAAA,IAAA,EAAA;AAKE,EAAA,IAAI,KAAK,UAAA,CAAW,SAAS,KAAK,IAAA,CAAK,UAAA,CAAW,UAAU,CAAA,EAAG;AAC7D,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAA,GACJ,OAAO,MAAA,CAAA,IAAA,KAAgB,WAAA,KAAA,CAAe,EAAA,GAAA,MAAA,CAAA,IAAA,CAAY,QAAZ,IAAA,GAAA,MAAA,GAAA,EAAA,CAAiB,QAAA,CAAA,GACnD,MAAA,CAAA,IAAA,CAAY,GAAA,CAAI,QAAA,GAChB,GAAA;AAEN,EAAA,MAAM,iBAAiB,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,GAAI,IAAA,GAAO,GAAG,IAAI,CAAA,CAAA,CAAA;AAC1D,EAAA,MAAM,cAAA,GAAiB,KAAK,UAAA,CAAW,GAAG,IAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,GAAI,IAAA;AAE9D,EAAA,OAAO,CAAA,EAAG,cAAc,CAAA,EAAG,cAAc,CAAA,CAAA;AAC3C","file":"chunk-NQMORMNP.js","sourcesContent":["/**\n * Resolves a runtime public asset path against Vite's deploy base URL.\n * Use for assets loaded after build (Pixi, i18n, fonts, SVGs, etc.).\n */\nexport function resolvePublicPath(path: string): string {\n if (path.startsWith('http://') || path.startsWith('https://')) {\n return path;\n }\n\n const base =\n typeof import.meta !== 'undefined' && import.meta.env?.BASE_URL\n ? import.meta.env.BASE_URL\n : '/';\n\n const normalizedBase = base.endsWith('/') ? base : `${base}/`;\n const normalizedPath = path.startsWith('/') ? path.slice(1) : path;\n\n return `${normalizedBase}${normalizedPath}`;\n}\n"]}
|