@cosmoledo/gleam 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1195 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ export interface RegisterData {
4
+ path: string;
5
+ name: string;
6
+ volume?: number;
7
+ }
8
+ export declare abstract class AudioBase {
9
+ protected songs: Map<string, HTMLAudioElement>;
10
+ private _enabled;
11
+ private registered;
12
+ get enabled(): boolean;
13
+ set enabled(value: boolean);
14
+ constructor(enabled?: boolean);
15
+ register(defaultVolume?: number, ...songs: (RegisterData | string)[]): void;
16
+ stop(): void;
17
+ private throwOnBadVolume;
18
+ }
19
+ /**
20
+ * Quadratic ease-in (slow start, accelerates).
21
+ */
22
+ export declare function easeIn(t: number): number;
23
+ /**
24
+ * Quadratic ease-in-out (accelerates, then decelerates).
25
+ */
26
+ export declare function easeInOut(t: number): number;
27
+ /**
28
+ * Quadratic ease-out (fast start, decelerates).
29
+ */
30
+ export declare function easeOut(t: number): number;
31
+ /**
32
+ * Identity (constant rate of change).
33
+ */
34
+ export declare function linear(t: number): number;
35
+ export type EasingName = "ease-in" | "ease-in-out" | "ease-out" | "linear";
36
+ export declare const EASINGS: Record<EasingName, (t: number) => number>;
37
+ export declare class Music extends AudioBase {
38
+ private last;
39
+ private current;
40
+ private next;
41
+ private fadeCancel;
42
+ get isPlaying(): boolean;
43
+ get enabled(): boolean;
44
+ set enabled(value: boolean);
45
+ fade(name?: string | null, fadeTime?: number, easing?: {
46
+ cur: EasingName;
47
+ next: EasingName;
48
+ }): void;
49
+ stop(): void;
50
+ private getRandom;
51
+ }
52
+ export declare class Sound extends AudioBase {
53
+ private currentSounds;
54
+ play(name: string): Promise<void>;
55
+ stop(): void;
56
+ }
57
+ export declare class Color {
58
+ static fromHex(hex: string): Color;
59
+ static fromHSL(h: number, s: number, l: number, a?: number): Color;
60
+ private _r;
61
+ private _g;
62
+ private _b;
63
+ private _alpha;
64
+ get r(): number;
65
+ get g(): number;
66
+ get b(): number;
67
+ get alpha(): number;
68
+ constructor(r: number, g: number, b: number, a?: number);
69
+ set(r: number, g: number, b: number, a?: number): this;
70
+ applyMatrix(m1: number, m2: number, m3: number, m4: number, m5: number, m6: number, m7: number, m8: number, m9: number): this;
71
+ brightness(factor: number): this;
72
+ contrast(factor: number): this;
73
+ grayscale(value?: number): this;
74
+ hueRotate(radians: number): this;
75
+ invert(factor?: number): this;
76
+ mix(other: Color, amount: number): this;
77
+ round(): this;
78
+ saturate(value?: number): this;
79
+ sepia(value?: number): this;
80
+ shade(percent: number): this;
81
+ toHex(): string;
82
+ toHSL(): string;
83
+ toHSLObject(): {
84
+ h: number;
85
+ s: number;
86
+ l: number;
87
+ a: number;
88
+ };
89
+ toRGB(): string;
90
+ clone(): Color;
91
+ equals(other: Color, compareAlpha?: boolean): boolean;
92
+ }
93
+ export type RGB = [
94
+ number,
95
+ number,
96
+ number
97
+ ];
98
+ /**
99
+ * Convert an `(r, g, b)` triple (0-255) to a `#rrggbb` hex string.
100
+ * Low-level; prefer `Color.toHex()` outside hot per-pixel loops.
101
+ */
102
+ export declare function rgb2hex(red: number, green: number, blue: number): string;
103
+ /**
104
+ * Pack `(r, g, b[, a])` channels into a single integer key.
105
+ * RGB are 0-255. Alpha is 0-1 (CSS convention); divide canvas byte-alpha by 255 before passing.
106
+ * Without alpha: 24-bit `RGB`. With alpha: 32-bit `RGBA` (forced unsigned).
107
+ * Useful for fast per-pixel lookups: cheaper than building a hex string.
108
+ */
109
+ export declare function rgb2Int(red: number, green: number, blue: number, alpha?: number): number;
110
+ /**
111
+ * Convert a `#rgb` or `#rrggbb` hex string to an `[r, g, b]` integer tuple.
112
+ * Low-level; prefer `Color.fromHex()` outside hot per-pixel loops. Caller must pass a valid hex string.
113
+ */
114
+ export declare function hex2rgb(hex: string): RGB;
115
+ /**
116
+ * HSL → RGB channel helper used by `Color.fromHSL`. Inputs are normalized to `[0, 1]`.
117
+ */
118
+ export declare function hue2rgb(p: number, q: number, t: number): number;
119
+ /**
120
+ * Random `#rgb` short hex color.
121
+ */
122
+ export declare function randomHex(): string;
123
+ /**
124
+ * Random `[r, g, b]` integer tuple; each channel uniform in `[min, max]`.
125
+ */
126
+ export declare function randomRgb(min?: number, max?: number): RGB;
127
+ /**
128
+ * Used when hue-rotate does not work e.g. on dark images
129
+ * Based on https://codepen.io/sosuke/pen/Pjoqqp
130
+ * https://stackoverflow.com/questions/42966641/how-to-transform-black-into-any-given-color-using-only-css-filters/43960991#43960991
131
+ *
132
+ * As the result does vary because of a Math.random(),
133
+ * I would suggest console.log some filters, pick nice ones and hardcode them instead:
134
+ * console.log(colorShifter(randomRgb(1, 10)));
135
+ */
136
+ export declare function colorShifter(rgb: RGB): string;
137
+ export interface PolygonCollisionResult {
138
+ intersect: boolean;
139
+ minimumTranslationVector: Vec2;
140
+ willIntersect: boolean;
141
+ }
142
+ export declare class Polygon {
143
+ /**
144
+ * `angle` is the simplification threshold in radians: vertices whose turn
145
+ * angle wraps to within ±`angle` of straight are dropped.
146
+ */
147
+ static fromCanvas(canvas: HTMLCanvasElement, detail: number, angle: number): Polygon;
148
+ static fromEdges(edges: number, size: Vec2 | number): Polygon;
149
+ static fromRect(rect: Rect): Polygon;
150
+ private _center;
151
+ private _points;
152
+ private edges;
153
+ get center(): Readonly<Vec2>;
154
+ get points(): Readonly<Vec2[]>;
155
+ constructor(...points: Vec2[]);
156
+ draw(context: CanvasRenderingContext2D, offset?: Vec2): void;
157
+ addPoint(x: number, y: number): Polygon;
158
+ addPoints(...points: Vec2[]): Polygon;
159
+ offset(x?: number, y?: number): Polygon;
160
+ rotate(angle: number, pos?: Readonly<Vec2>): this;
161
+ collide(otherPolygon: Polygon, velocity?: Vec2): PolygonCollisionResult;
162
+ clone(): Polygon;
163
+ private update;
164
+ }
165
+ export interface Sides {
166
+ bottom: number;
167
+ centerPos: Vec2;
168
+ halfSize: Vec2;
169
+ right: number;
170
+ }
171
+ export declare class Rect {
172
+ static fromBoundingClientRect(rect: DOMRect | HTMLElement): Rect;
173
+ static fromPolygon(polygon: Polygon): Rect;
174
+ private _h;
175
+ private _w;
176
+ private _x;
177
+ private _y;
178
+ private _sides;
179
+ private sideIsDirty;
180
+ get h(): number;
181
+ set h(value: number);
182
+ get w(): number;
183
+ set w(value: number);
184
+ get x(): number;
185
+ set x(value: number);
186
+ get y(): number;
187
+ set y(value: number);
188
+ get sides(): Readonly<Sides>;
189
+ constructor(x?: number, y?: number, w?: number, h?: number);
190
+ inflate(delta: number): Rect;
191
+ round(): Rect;
192
+ set(x?: Vector4 | Vector2 | number, y?: number, w?: number, h?: number): Rect;
193
+ collide(rect: Rect): boolean;
194
+ collideFull(rect: Rect): boolean;
195
+ collidePoint(vec: Vector2): boolean;
196
+ collideSide(rect: Rect): "none" | "top" | "bottom" | "left" | "right";
197
+ pos(): Vec2;
198
+ size(): Vec2;
199
+ toString(): string;
200
+ clone(): Rect;
201
+ equals(other: Rect, withSize?: boolean): boolean;
202
+ }
203
+ export interface Vector2 {
204
+ x: number;
205
+ y: number;
206
+ }
207
+ export interface Vector4 extends Vector2 {
208
+ w: number;
209
+ h: number;
210
+ }
211
+ /**
212
+ * 2D vector. Scalar args to `set`/`add`/`sub`/`mult`/`div`/`rem`/`mod`/`equals`
213
+ * broadcast to both axes: `vec.add(5)` adds 5 to x and y, `vec.mult(-1)` negates
214
+ * both. Pass `(x, y)` or a `Vector2` for per-axis values.
215
+ */
216
+ export declare class Vec2 {
217
+ static fromAngle(rad: number, scaleX?: number, scaleY?: number): Vec2;
218
+ x: number;
219
+ y: number;
220
+ constructor(x?: Vector2 | number, y?: number);
221
+ set(v: Vector2): Vec2;
222
+ set(x: number, y?: number): Vec2;
223
+ abs(): Vec2;
224
+ add(v: Vector2): Vec2;
225
+ add(x: number, y?: number): Vec2;
226
+ ceil(): Vec2;
227
+ clamp(x: [
228
+ number,
229
+ number
230
+ ], y?: [
231
+ number,
232
+ number
233
+ ]): Vec2;
234
+ div(v: Vector2): Vec2;
235
+ div(x: number, y?: number): Vec2;
236
+ floor(): Vec2;
237
+ map(callback: (value: number, index: number) => number): Vec2;
238
+ mod(v: Vector2): Vec2;
239
+ mod(x: number, y?: number): Vec2;
240
+ mult(v: Vector2): Vec2;
241
+ mult(x: number, y?: number): Vec2;
242
+ negate(): Vec2;
243
+ normalize(): Vec2;
244
+ normalizeManhattan(): Vec2;
245
+ rem(v: Vector2): Vec2;
246
+ rem(x: number, y?: number): Vec2;
247
+ round(): Vec2;
248
+ sub(v: Vector2): Vec2;
249
+ sub(x: number, y?: number): Vec2;
250
+ angle(other?: Vector2): number;
251
+ distance(other: Vector2): number;
252
+ distanceManhattan(other: Vector2): number;
253
+ dotProduct(other: Vector2): number;
254
+ isValid(): boolean;
255
+ length(): number;
256
+ lengthManhattan(): number;
257
+ max(): number;
258
+ min(): number;
259
+ toArray(): [
260
+ number,
261
+ number
262
+ ];
263
+ toRectAddPos(v: Vector2): Rect;
264
+ toRectAddPos(x: number, y?: number): Rect;
265
+ toRectAddSize(v: Vector2): Rect;
266
+ toRectAddSize(x: number, y?: number): Rect;
267
+ toString(): string;
268
+ clone(): Vec2;
269
+ equals(v: Vector2): boolean;
270
+ equals(x: number, y?: number): boolean;
271
+ private calculate;
272
+ private concat;
273
+ private getValues;
274
+ }
275
+ export interface SpriteAnimation {
276
+ default?: boolean;
277
+ name: string;
278
+ sprites: HTMLCanvasElement[] | HTMLImageElement[];
279
+ timing: number;
280
+ }
281
+ export type onEndType = () => void;
282
+ export type onFrameType = Record<number, () => void>;
283
+ export interface BaseEntity {
284
+ pos: Vec2;
285
+ flipX?: number;
286
+ }
287
+ export declare class Animator {
288
+ private static spriteCache;
289
+ /**
290
+ * Drop cached rendered sprites. Pass a namespace to evict only that prefix; omit to clear all.
291
+ */
292
+ static clearSpriteCache(namespace?: string): void;
293
+ active: boolean;
294
+ image: HTMLCanvasElement;
295
+ imageId: number;
296
+ lookLeft: boolean;
297
+ onEnd: onEndType | undefined;
298
+ size: Vec2;
299
+ private animations;
300
+ private currentAnimation;
301
+ private entity;
302
+ private lastPlayed;
303
+ private namespace;
304
+ private onFrame?;
305
+ private playVersion;
306
+ private timer;
307
+ get current(): SpriteAnimation;
308
+ /**
309
+ * We store rendered images in a cache.
310
+ * So if you have the same entity multiple times, the images get computed once and then shared.
311
+ * This reduces overhead and frees time up for other important computations.
312
+ *
313
+ * `namespace` is the cache key prefix for these rendered images.
314
+ * So pass a different key for different Animators; otherwise, you will see wrong images.
315
+ */
316
+ constructor(entity: BaseEntity, namespace: string);
317
+ draw(context: CanvasRenderingContext2D, offset?: Vec2): void;
318
+ update(dt: number): void;
319
+ add(name: string, sprites: HTMLCanvasElement[] | HTMLImageElement[], timing: number, defaultAnim?: boolean): void;
320
+ addAnimation(anim: SpriteAnimation, defaultAnim?: boolean): void;
321
+ drawRotated(context: CanvasRenderingContext2D, angle: number, offset?: Vec2): void;
322
+ play(name: string, onEnd?: onEndType, onFrame?: onFrameType): void;
323
+ playIfNot(name: string, onEnd?: onEndType, onFrame?: onFrameType): boolean;
324
+ playNextOnce(name: string | undefined): void;
325
+ /**
326
+ * Play `name` once, then return to the previously-playing animation. Calling with the currently-playing name re-loops it indefinitely (lastPlayed restores to itself).
327
+ */
328
+ playOnce(name: string, onEnd?: onEndType, onFrame?: onFrameType): void;
329
+ randomTimer(): void;
330
+ removeAllAnimations(): void;
331
+ reset(): void;
332
+ isPlaying(name: string): boolean;
333
+ /**
334
+ * Update `image` and `size` from the current sprite. Assumes uniform sprite size within an animation. Caches rendered canvases per (animation, frame, lookLeft) — if you mutate `entity.flipX` after first render, call `removeAllAnimations()` or recreate the Animator to invalidate.
335
+ */
336
+ protected setImage(): void;
337
+ }
338
+ export declare class Particle {
339
+ protected color: string;
340
+ protected lifetime: number;
341
+ protected maxLifeTime: number;
342
+ protected pos: Vec2;
343
+ protected size: number;
344
+ protected vel: Vec2;
345
+ protected _rect: Rect;
346
+ get alive(): boolean;
347
+ get rect(): Readonly<Rect>;
348
+ constructor(pos: Vec2, color: string, size?: number);
349
+ draw(context: CanvasRenderingContext2D, offset?: Vec2): void;
350
+ update(dt: number): void;
351
+ resetLifetime(): void;
352
+ }
353
+ export declare class Projectile<T = unknown> {
354
+ maxLifetime: number;
355
+ payload?: T;
356
+ speed: number;
357
+ protected image: HTMLCanvasElement;
358
+ protected lifetime: number;
359
+ protected pos: Vec2;
360
+ protected rotation: number;
361
+ protected vel: Vec2;
362
+ protected _rect: Rect;
363
+ private originalImage;
364
+ get alive(): boolean;
365
+ get rect(): Readonly<Rect>;
366
+ constructor(pos: Vec2, image: HTMLCanvasElement, vel?: Vec2);
367
+ draw(context: CanvasRenderingContext2D, offset?: Vec2): void;
368
+ update(dt: number): void;
369
+ /**
370
+ * Allocates a fresh rotated canvas on each call — no internal cache.
371
+ * Caching by quantized rotation could be a feature when projectiles need to re-aim every tick (homing/seeking).
372
+ */
373
+ rebuildRotation(): void;
374
+ remove(): void;
375
+ }
376
+ declare global {
377
+ interface HTMLCanvasElement {
378
+ /** `true` if any pixel has a non-zero RGBA byte. */
379
+ hasAnyColor(): boolean;
380
+ }
381
+ }
382
+ declare global {
383
+ interface HTMLCanvasElement {
384
+ /**
385
+ * Read the pixel at `(x, y)`. Out-of-bounds reads return zero/transparent.
386
+ * Not for hot paths — each call issues a fresh `getImageData`. For bulk reads, call `getImageData` once and index into the buffer.
387
+ * @param output return format. Default `"integer"`.
388
+ */
389
+ getPixelAt(x: number, y: number, output?: "integer"): number;
390
+ getPixelAt(x: number, y: number, output: "array"): [
391
+ ...RGB,
392
+ number
393
+ ];
394
+ getPixelAt(x: number, y: number, output: "json"): {
395
+ r: number;
396
+ g: number;
397
+ b: number;
398
+ a: number;
399
+ };
400
+ getPixelAt(x: number, y: number, output: "string"): string;
401
+ }
402
+ }
403
+ declare global {
404
+ interface HTMLCanvasElement {
405
+ /**
406
+ * Replace pixel colors by RGB hex key. Alpha is ignored — fully-transparent pixels are skipped, semi-transparent pixels keep their alpha.
407
+ */
408
+ replaceColors(replacements: Record<string, string>): HTMLCanvasElement;
409
+ }
410
+ }
411
+ declare global {
412
+ interface HTMLCanvasElement {
413
+ /** Rotate around the center into a new square canvas sized to fit any rotation (`diam = ceil(sqrt(w² + h²))`). */
414
+ rotateBy(radians: number): HTMLCanvasElement;
415
+ }
416
+ }
417
+ declare global {
418
+ interface HTMLCanvasElement {
419
+ /** Rotate around the center within the original `width × height`; corners that fall outside are clipped. */
420
+ rotateByAligned(radians: number): HTMLCanvasElement;
421
+ }
422
+ }
423
+ declare global {
424
+ interface HTMLCanvasElement {
425
+ /** Trim fully-transparent borders. Returns a new canvas cropped to the bounding box of opaque pixels. */
426
+ autoCrop(): HTMLCanvasElement;
427
+ }
428
+ }
429
+ declare global {
430
+ interface HTMLCanvasElement {
431
+ /**
432
+ * Scale into a new canvas. Throws if any factor is `≤ 0`.
433
+ * @param scaleX horizontal scale factor. Default `1`.
434
+ * @param scaleY vertical scale factor. Default = `scaleX`.
435
+ */
436
+ scaleBy(scaleX?: number, scaleY?: number): HTMLCanvasElement;
437
+ }
438
+ }
439
+ declare global {
440
+ interface HTMLCanvasElement {
441
+ /**
442
+ * Scale into a new canvas so the chosen axis equals `size`, preserving aspect ratio.
443
+ * @param isWidth match `size` against width when `true`, height when `false`. Default `true`.
444
+ */
445
+ resize(size: number, isWidth?: boolean): HTMLCanvasElement;
446
+ }
447
+ }
448
+ declare global {
449
+ interface HTMLCanvasElement {
450
+ /**
451
+ * Mirror horizontally into a new canvas.
452
+ * @param offsetX horizontal shift applied after flipping. Default `0`.
453
+ */
454
+ flipX(offsetX?: number): HTMLCanvasElement;
455
+ }
456
+ }
457
+ declare global {
458
+ interface HTMLCanvasElement {
459
+ /**
460
+ * Mirror vertically into a new canvas.
461
+ * @param offsetY vertical shift applied after flipping. Default `0`.
462
+ */
463
+ flipY(offsetY?: number): HTMLCanvasElement;
464
+ }
465
+ }
466
+ declare global {
467
+ interface HTMLCanvasElement {
468
+ /**
469
+ * Crop a `(w, h)` sub-region starting at `(x, y)` into a new canvas.
470
+ * @param w default `this.width`
471
+ * @param h default `this.height`
472
+ */
473
+ subImage(x: number, y: number, w?: number, h?: number): HTMLCanvasElement;
474
+ }
475
+ }
476
+ declare global {
477
+ interface HTMLCanvasElement {
478
+ /** Copy this canvas (same dimensions, content, `id`, and `dataset`) into a new canvas. */
479
+ clone(): HTMLCanvasElement;
480
+ }
481
+ }
482
+ declare global {
483
+ interface HTMLCanvasElement {
484
+ /** Convert image canvas to `Promise<HTMLImageElement>` via `toDataURL`. */
485
+ toImage(): Promise<HTMLImageElement>;
486
+ }
487
+ }
488
+ export interface CanvasConstruct {
489
+ canvas: HTMLCanvasElement;
490
+ context: CanvasRenderingContext2D;
491
+ }
492
+ /**
493
+ * Create a new `<canvas>` of the given size with its 2D context. Antialiasing defaults to `Settings.antialias`.
494
+ */
495
+ export declare function createNewCanvas(width: number, height: number, antialias?: boolean): CanvasConstruct;
496
+ /**
497
+ * Look up an existing canvas by CSS selector and return it with its 2D context.
498
+ */
499
+ export declare function getCanvasConstruct(selector: string): CanvasConstruct;
500
+ /**
501
+ * Apply a CSS `filter` string to an image and return the result as a new canvas.
502
+ */
503
+ export declare function applyFilterOnCanvas(image: HTMLCanvasElement | HTMLImageElement, filter: string, width?: number, height?: number): HTMLCanvasElement;
504
+ /**
505
+ * Rotate the hue of an image by `hue` degrees via CSS `hue-rotate(...)` filter.
506
+ */
507
+ export declare function rotateHue(image: HTMLCanvasElement | HTMLImageElement, hue: number, width?: number, height?: number): HTMLCanvasElement;
508
+ /**
509
+ * Recolor an opaque canvas in place using composite operations,
510
+ * preserving the alpha mask of the source image. Wraps the body in `save`/`restore`
511
+ * so `fillStyle` / `globalCompositeOperation` writes don't leak to the caller's context.
512
+ * https://stackoverflow.com/a/45201094
513
+ */
514
+ export declare function changeColor(context: CanvasRenderingContext2D, oriImg: HTMLCanvasElement, newColor: string): void;
515
+ /**
516
+ * Split a sprite-sheet image into individual sprite canvases laid out as `elementsX × elementsY`.
517
+ * Throws if the image dimensions don't divide evenly — sheets are expected to be authored that way.
518
+ */
519
+ export declare function splitSpriteSheet(img: HTMLCanvasElement, elementsX: number, elementsY: number): HTMLCanvasElement[];
520
+ /**
521
+ * Count occurrences of each color in an image, keyed by `#rrggbb`.
522
+ * `pixelAmount` multiplies each count and floors to int; values < 1 will drop low-count colors entirely (count rounds to 0).
523
+ * `removeLowerThan` / `removeHigherThan` drop entries outside the range; `0` disables either bound.
524
+ */
525
+ export declare function getUsedColors(image: HTMLCanvasElement, pixelAmount?: number, removeLowerThan?: number, removeHigherThan?: number): Map<string, number>;
526
+ export declare const CANVAS_TYPES: {
527
+ readonly ANY: symbol;
528
+ readonly DEFAULT: symbol;
529
+ readonly BACKGROUND: symbol;
530
+ readonly MAIN: symbol;
531
+ };
532
+ export interface CanvasHolder extends CanvasConstruct {
533
+ id: string;
534
+ resize: boolean;
535
+ type: symbol;
536
+ }
537
+ export declare class CanvasManager {
538
+ canvasBoundingClientRect: DOMRect;
539
+ canvasHolder: Record<string, CanvasHolder>;
540
+ ratio: number;
541
+ resizedSize: Vec2;
542
+ private mainHolder;
543
+ get canvas(): HTMLCanvasElement;
544
+ get canvasContext(): CanvasRenderingContext2D;
545
+ get height(): number;
546
+ set height(height: number);
547
+ get size(): Vec2;
548
+ get width(): number;
549
+ set width(width: number);
550
+ finishSetup(): void;
551
+ resize(): void;
552
+ setFontSize(size: number, font?: string): void;
553
+ setupCanvas(canvasType: symbol, selector: string, resize?: boolean): CanvasHolder;
554
+ }
555
+ export declare class Gameloop {
556
+ levelTime: number;
557
+ private _isLooping;
558
+ private accumulator;
559
+ private game;
560
+ private stop;
561
+ get isLooping(): boolean;
562
+ constructor(game: Game);
563
+ startLoop(): void;
564
+ stopLoop(): void;
565
+ private draw;
566
+ private looper;
567
+ }
568
+ export declare const KEYBOARD_KEYS: {
569
+ readonly KEY_0: "Digit0";
570
+ readonly KEY_1: "Digit1";
571
+ readonly KEY_2: "Digit2";
572
+ readonly KEY_3: "Digit3";
573
+ readonly KEY_4: "Digit4";
574
+ readonly KEY_5: "Digit5";
575
+ readonly KEY_6: "Digit6";
576
+ readonly KEY_7: "Digit7";
577
+ readonly KEY_8: "Digit8";
578
+ readonly KEY_9: "Digit9";
579
+ readonly KEY_A: "KeyA";
580
+ readonly KEY_B: "KeyB";
581
+ readonly KEY_C: "KeyC";
582
+ readonly KEY_D: "KeyD";
583
+ readonly KEY_DOWN: "ArrowDown";
584
+ readonly KEY_E: "KeyE";
585
+ readonly KEY_ENTER: "Enter";
586
+ readonly KEY_ESCAPE: "Escape";
587
+ readonly KEY_F: "KeyF";
588
+ readonly KEY_G: "KeyG";
589
+ readonly KEY_H: "KeyH";
590
+ readonly KEY_I: "KeyI";
591
+ readonly KEY_J: "KeyJ";
592
+ readonly KEY_K: "KeyK";
593
+ readonly KEY_L: "KeyL";
594
+ readonly KEY_LEFT: "ArrowLeft";
595
+ readonly KEY_M: "KeyM";
596
+ readonly KEY_N: "KeyN";
597
+ readonly KEY_O: "KeyO";
598
+ readonly KEY_P: "KeyP";
599
+ readonly KEY_Q: "KeyQ";
600
+ readonly KEY_R: "KeyR";
601
+ readonly KEY_RIGHT: "ArrowRight";
602
+ readonly KEY_S: "KeyS";
603
+ readonly KEY_SPACE: "Space";
604
+ readonly KEY_T: "KeyT";
605
+ readonly KEY_TAB: "Tab";
606
+ readonly KEY_U: "KeyU";
607
+ readonly KEY_UP: "ArrowUp";
608
+ readonly KEY_V: "KeyV";
609
+ readonly KEY_W: "KeyW";
610
+ readonly KEY_X: "KeyX";
611
+ readonly KEY_Y: "KeyY";
612
+ readonly KEY_Z: "KeyZ";
613
+ };
614
+ export declare class Keyboard {
615
+ keys: Record<string, boolean>;
616
+ constructor(game: Game);
617
+ reset(): void;
618
+ stopPress(code: string): void;
619
+ isPressed(code: string): boolean;
620
+ }
621
+ export type SettingsOverrides = Partial<Omit<typeof Settings, "prototype" | "init" | "setLocalStorage" | "localStorage">>;
622
+ export declare class Settings {
623
+ static antialias: boolean;
624
+ static autoloop: boolean;
625
+ static backgroundColor: string;
626
+ static debug: boolean;
627
+ static doNotClear: boolean;
628
+ static enableResize: boolean;
629
+ static font: string;
630
+ static fps: number;
631
+ static triedToClose?: () => void;
632
+ static useClearRect: boolean;
633
+ static warnBeforeClose: boolean;
634
+ private static initialized;
635
+ private static readonly _localStorage;
636
+ static get localStorage(): Readonly<typeof Settings._localStorage>;
637
+ static init(overrides: SettingsOverrides, game: Game): void;
638
+ static setLocalStorage<K extends keyof typeof Settings._localStorage>(key: K, value: (typeof Settings._localStorage)[K]): void;
639
+ }
640
+ declare global {
641
+ interface Window {
642
+ /** Translate `key` for the active language. Throws until `prepareLanguage` has run. */
643
+ t(key: string): string;
644
+ }
645
+ }
646
+ export type Languages = Record<string, Record<string, string>>;
647
+ export declare function prepareLanguage(languages: Languages, defaultLanguage?: string): void;
648
+ declare global {
649
+ interface HTMLAudioElement {
650
+ /** Deep-clone this audio element, preserving the current `volume`. */
651
+ clone(): HTMLAudioElement;
652
+ }
653
+ }
654
+ declare global {
655
+ interface HTMLAudioElement {
656
+ /** Volume restored by `stop()` after pausing. If unset, `stop()` leaves `volume` as-is. */
657
+ defaultVolume?: number;
658
+ /** Pause playback, reset `currentTime` to 0, and restore `volume` to `defaultVolume` if set. */
659
+ stop(): void;
660
+ }
661
+ }
662
+ export type Mode = "fill" | "stroke";
663
+ declare global {
664
+ interface CanvasRenderingContext2D {
665
+ /**
666
+ * Fill a two-color bar sized by `amount`. Writes `fillStyle`; persists on the context — wrap in `save()`/`restore()` to preserve prior state.
667
+ * @param c1 background, default `"white"`
668
+ * @param c2 foreground, default `"black"`
669
+ */
670
+ fillBar(rect: Vector4, amount: number, c1?: string, c2?: string): void;
671
+ }
672
+ }
673
+ declare global {
674
+ interface CanvasRenderingContext2D {
675
+ /**
676
+ * Fill a three-layer framed bar (outer band, frame, fill scaled by `amount`). Writes `fillStyle`; persists on the context — wrap in `save()`/`restore()` to preserve prior state.
677
+ * @param amount fill fraction in `[0, 1]`. Default `0.8`. `≤ 0` skips the fill layer.
678
+ * @param padding frame inset on all sides. Default `4`.
679
+ * @param colors outer band, frame, fill. Default `["white", "black", "red"]`.
680
+ */
681
+ fillFramedBar(rect: Vector4, amount?: number, padding?: number, colors?: [
682
+ string,
683
+ string,
684
+ string
685
+ ]): void;
686
+ }
687
+ }
688
+ declare global {
689
+ interface CanvasRenderingContext2D {
690
+ /**
691
+ * Draws a circle centered at `vecPos`.
692
+ * @param amount sweep fraction in `[0, 1]`. Default `1` (full circle).
693
+ */
694
+ drawCircle(vecPos: Vector2, rad: number, mode: Mode, amount?: number): void;
695
+ }
696
+ }
697
+ declare global {
698
+ interface CanvasRenderingContext2D {
699
+ /** Draws a rectangle (from `Vector4` or `x, y, w, h`). */
700
+ drawRect(rect: Vector4, mode: Mode): void;
701
+ drawRect(x: number, y: number, w: number, h: number, mode: Mode): void;
702
+ }
703
+ }
704
+ export interface DrawRoundRectOptions {
705
+ /** Inset from the rect edges. Default `0` (no inset). */
706
+ padding?: number;
707
+ /** Corner radius. Default `16`. */
708
+ radius?: number;
709
+ }
710
+ declare global {
711
+ interface CanvasRenderingContext2D {
712
+ /** Draw a rounded rectangle from a `Vector4` or `x, y, w, h` plus an options bag. Delegates the corner path to native `roundRect` (Safari 16+ / Chrome 99+ / Firefox 113+). */
713
+ drawRoundRect(rect: Vector4, mode: Mode, options?: DrawRoundRectOptions): void;
714
+ drawRoundRect(x: number, y: number, w: number, h: number, mode: Mode, options?: DrawRoundRectOptions): void;
715
+ }
716
+ }
717
+ declare global {
718
+ interface CanvasRenderingContext2D {
719
+ /** Stroke a dotted rectangle. Writes `lineWidth` and `setLineDash` — wrap in `save()`/`restore()` to preserve prior state. */
720
+ strokeDottedRect(rect: Vector4): void;
721
+ }
722
+ }
723
+ declare global {
724
+ interface CanvasRenderingContext2D {
725
+ /** Draw a line segment from `(x1, y1)` to `(x2, y2)`. */
726
+ strokeLine(x1: number, y1: number, x2: number, y2: number): void;
727
+ }
728
+ }
729
+ declare global {
730
+ interface CanvasRenderingContext2D {
731
+ /**
732
+ * Draw a regular polygon centered in `rect`, with vertices on a circle of radius `min(rect.w, rect.h) * 0.5`.
733
+ */
734
+ drawPolygon(sides: number, rect: Vector4, mode: Mode): void;
735
+ }
736
+ }
737
+ declare global {
738
+ interface CanvasRenderingContext2D {
739
+ /** Draw a triangle: top-left → top-right → bottom-center. */
740
+ drawTriangle(rect: Vector4, mode: Mode): void;
741
+ }
742
+ }
743
+ declare global {
744
+ interface CanvasRenderingContext2D {
745
+ /**
746
+ * Write text horizontally offset around `x` by `measureTextOffset` of its measured width.
747
+ * @param measureTextOffset in `[0, 1]`. Default `0.5` (centered around `x`).
748
+ */
749
+ writeText(text: string, x: number, y: number, measureTextOffset?: number): void;
750
+ }
751
+ }
752
+ declare global {
753
+ interface CanvasRenderingContext2D {
754
+ /**
755
+ * Word-wrap `text` into lines of pixel width `width`, drawing each line via `writeText`. Returns `false` and logs to `console.error` if `maxAttempts` is reached.
756
+ * @param lineOffset vertical spacing between lines in px. Default `50`.
757
+ * @param maxAttempts safety cap on wrap iterations. Default `50`.
758
+ */
759
+ writeMultilineText(text: string, x: number, y: number, width: number, lineOffset?: number, maxAttempts?: number): boolean;
760
+ }
761
+ }
762
+ declare global {
763
+ interface CanvasRenderingContext2D {
764
+ /**
765
+ * Draw `image` rotated by `radians` around the center of its placement at `(x, y)`. Saves and restores the transform.
766
+ * @param radians clockwise positive, in radians.
767
+ */
768
+ drawImageRotated(image: HTMLCanvasElement, x: number, y: number, radians: number): void;
769
+ }
770
+ }
771
+ declare global {
772
+ interface CanvasRenderingContext2D {
773
+ /** Build a colored rounded-rect stencil with a `drawPartialRoundRect` helper. The returned helper writes `fillStyle = "white"` on the caller's context — wrap in `save()`/`restore()` to preserve prior state. */
774
+ generateColor(size: number, color: string): {
775
+ colors: [
776
+ number,
777
+ number
778
+ ][];
779
+ image: HTMLCanvasElement;
780
+ drawPartialRoundRect: (rect: Rect, amount: number, offsetX?: number, offsetY?: number) => void;
781
+ };
782
+ }
783
+ }
784
+ declare global {
785
+ interface HTMLImageElement {
786
+ /**
787
+ * Crop a `(w, h)` sub-region starting at `(x, y)` into a new canvas.
788
+ * @param w default `this.width`
789
+ * @param h default `this.height`
790
+ */
791
+ subImage(x: number, y: number, w?: number, h?: number): HTMLCanvasElement;
792
+ }
793
+ }
794
+ export declare abstract class Game {
795
+ canman: CanvasManager;
796
+ gameloop: Gameloop;
797
+ keyboard: Keyboard;
798
+ pointer: Pointer;
799
+ private initialized;
800
+ constructor(settingOverrides?: SettingsOverrides);
801
+ draw(_context: CanvasRenderingContext2D): void;
802
+ update(_dt: number): void;
803
+ init(): Promise<void>;
804
+ protected preInit(doInit?: boolean): Promise<void>;
805
+ }
806
+ export declare const POINTER_KEYS: {
807
+ readonly LEFT: 0;
808
+ readonly MIDDLE: 1;
809
+ readonly RIGHT: 2;
810
+ readonly PREV: 3;
811
+ readonly FORWARD: 4;
812
+ };
813
+ export declare class Pointer {
814
+ hasMoved: boolean;
815
+ lastEvent: PointerEvent | null;
816
+ posReal: Vec2;
817
+ posRealLast: Vec2;
818
+ posScaled: Vec2;
819
+ posScaledLast: Vec2;
820
+ pressed: boolean[];
821
+ private game;
822
+ constructor(game: Game);
823
+ reset(): void;
824
+ private update;
825
+ }
826
+ export interface GameEventMap {
827
+ gameloopStopped: [
828
+ ];
829
+ inputControllerConnected: [
830
+ event: Gamepad
831
+ ];
832
+ inputControllerDisconnected: [
833
+ ];
834
+ inputKeyboard: [
835
+ keys: Record<string, boolean>,
836
+ code: string,
837
+ pressed: boolean
838
+ ];
839
+ inputPointer: [
840
+ pointer: Pointer
841
+ ];
842
+ resized: [
843
+ ];
844
+ }
845
+ export interface EventSystemOptions {
846
+ once?: boolean;
847
+ signal?: AbortSignal;
848
+ }
849
+ export declare class EventSystem {
850
+ private static eventListener;
851
+ private static logListenerError;
852
+ private static nextId;
853
+ static addEventListener<K extends keyof GameEventMap>(eventName: K, callback: (...args: GameEventMap[K]) => void, options?: EventSystemOptions): () => void;
854
+ static dispatchEvent<K extends keyof GameEventMap>(eventName: K, ...params: GameEventMap[K]): void;
855
+ }
856
+ export type CssStyleKey = {
857
+ [K in keyof CSSStyleDeclaration]: K extends string ? CSSStyleDeclaration[K] extends string ? K : never : never;
858
+ }[keyof CSSStyleDeclaration];
859
+ export type CssProxy = (key: CssStyleKey, value: string) => void;
860
+ export interface ShakeType {
861
+ step: number;
862
+ update: (updateCss: CssProxy, time: number) => void;
863
+ }
864
+ export declare const SHAKE_TYPES: {
865
+ NORMAL: {
866
+ step: number;
867
+ update(updateCss: CssProxy, time: number): void;
868
+ };
869
+ FAST: {
870
+ step: number;
871
+ update(updateCss: CssProxy, time: number): void;
872
+ };
873
+ };
874
+ /**
875
+ * Only the built-in shake types (NORMAL, FAST) are supported today.
876
+ * Letting callers define their own could be a possible feature — impact pulses, slow rumble, directional jolts.
877
+ */
878
+ export declare class Screenshake {
879
+ private isShaking;
880
+ private shakeType;
881
+ private style;
882
+ constructor(element: HTMLElement);
883
+ /** Best-effort style restore: each key the shake writes is snapshotted on first write and rewritten when the shake ends or is disposed. */
884
+ shake(shakeType?: ShakeType): null | (() => void);
885
+ }
886
+ export declare class ControllerCursor {
887
+ private axisId;
888
+ private controller;
889
+ private game;
890
+ private pos;
891
+ get centerPos(): Vec2;
892
+ constructor(controller: Controller, game: Game, axisId: number);
893
+ draw(context: CanvasRenderingContext2D): void;
894
+ update(dt: number): void;
895
+ }
896
+ export declare const CONTROLLER_KEYS: {
897
+ readonly A: 0;
898
+ readonly B: 1;
899
+ readonly X: 2;
900
+ readonly Y: 3;
901
+ readonly LB: 4;
902
+ readonly RB: 5;
903
+ readonly LT: 6;
904
+ readonly RT: 7;
905
+ readonly SELECT: 8;
906
+ readonly START: 9;
907
+ readonly LEFT_STICK: 10;
908
+ readonly RIGHT_STICK: 11;
909
+ readonly UP: 12;
910
+ readonly DOWN: 13;
911
+ readonly LEFT: 14;
912
+ readonly RIGHT: 15;
913
+ readonly GUIDE: 16;
914
+ };
915
+ export declare class Controller {
916
+ buttons: boolean[];
917
+ cursors: ControllerCursor[];
918
+ private axes;
919
+ private index;
920
+ private lastTime;
921
+ constructor(game: Game);
922
+ draw(context: CanvasRenderingContext2D): void;
923
+ update(dt: number): void;
924
+ reset(): void;
925
+ vibrate(): boolean;
926
+ stick(index: number): Vec2;
927
+ private getGamepad;
928
+ }
929
+ /**
930
+ * Validates URL format and protocol before any side effects.
931
+ * Throws on invalid URLs or disallowed protocols.
932
+ */
933
+ export declare function validateUrl(url: string): void;
934
+ /**
935
+ * Safe loading wrapper with global timeout and error handling.
936
+ * Use this for any async loading operation that needs timeout protection.
937
+ * Timeout rejects the returned promise but does not cancel the underlying
938
+ * fetch/Image — the request continues until natural completion. Adding
939
+ * AbortSignal support would require a full rewrite (factory-based API).
940
+ * Maybe a future feature, though.
941
+ */
942
+ export declare function safeLoad<T>(promise: Promise<T>, url: string, operationName: string): Promise<T>;
943
+ /**
944
+ * Loads an image with timeout and error handling
945
+ */
946
+ export declare function loadImage(url: string): Promise<HTMLImageElement>;
947
+ /**
948
+ * Loads a canvas from image URL with error handling
949
+ */
950
+ export declare function loadCanvas(url: string): Promise<HTMLCanvasElement>;
951
+ /**
952
+ * Loads text content from URL with error handling
953
+ */
954
+ export declare function loadText(url: string): Promise<string>;
955
+ /**
956
+ * Loads JSON data from URL with error handling
957
+ */
958
+ export declare function loadJson<T = unknown>(url: string): Promise<T>;
959
+ /**
960
+ * Loads JSON with inline comments
961
+ */
962
+ export declare function loadJsonCommented<T = unknown>(url: string): Promise<T>;
963
+ /**
964
+ * Loads image sprites from JSON configuration with error handling
965
+ */
966
+ export declare function loadImageFromJson(baseUrl: string, filenameOrJson: string, jsonInput?: boolean): Promise<Record<string, HTMLCanvasElement>>;
967
+ /**
968
+ * Loads multiple resources concurrently with error handling
969
+ */
970
+ export declare function loadBunch<T extends Record<string, Promise<unknown>>>(bunch: T): Promise<{
971
+ [K in keyof T]: Awaited<T[K]>;
972
+ }>;
973
+ /**
974
+ * Split an array into chunks of at most `maxLength` elements each. Throws when `maxLength < 1`.
975
+ */
976
+ export declare function chunk<T>(array: ReadonlyArray<T>, maxLength: number): T[][];
977
+ /**
978
+ * Pick a uniformly random element from `array`. Throws if `array` is empty — guard at the call site if that's possible.
979
+ */
980
+ export declare function randomItem<T>(array: ReadonlyArray<T>): T;
981
+ /**
982
+ * Remove an entry of an Array
983
+ */
984
+ export declare function remove<T>(arr: T[], item: T): void;
985
+ /**
986
+ * Shuffle array using Fisher-Yates algorithm with custom random signer
987
+ */
988
+ export declare function shuffle<T>(arr: ReadonlyArray<T>): T[];
989
+ export interface CSSVariables {
990
+ root: HTMLElement;
991
+ get(name: string): string;
992
+ set(name: string, value: string): void;
993
+ }
994
+ /**
995
+ * `querySelector` variant that throws when no element matches.
996
+ * Optionally narrow the return type per tag, e.g. `getElement<HTMLCanvasElement>("canvas")`.
997
+ */
998
+ export declare function getElement<T extends Element = HTMLElement>(query: string, parent?: ParentNode): T;
999
+ /**
1000
+ * Apply a partial `CSSStyleDeclaration` to an element.
1001
+ */
1002
+ export declare function styleElement(element: HTMLElement, styles: Partial<CSSStyleDeclaration>): void;
1003
+ /**
1004
+ * Toggle `element.style.display` between `""` (active) and `"none"` (inactive).
1005
+ */
1006
+ export declare function setDisplay(element: HTMLElement, active: boolean): void;
1007
+ /**
1008
+ * Toggle `element.style.visibility` between `""` (active) and `"hidden"` (inactive).
1009
+ */
1010
+ export declare function setVisibility(element: HTMLElement, active: boolean): void;
1011
+ /**
1012
+ * Returns `get` / `set` helpers for CSS custom properties (`--name`) on the `:root` element.
1013
+ */
1014
+ export declare function initCSSVariables(): CSSVariables;
1015
+ /**
1016
+ * Calls `callback` on pointerdown of the matched element, then keeps calling it every `delay` ms
1017
+ * until pointerup or pointercancel. Uses pointer capture so the action persists while the cursor
1018
+ * drags off the element (and over descendants). Unifies mouse, touch, and pen. Throws if no element
1019
+ * matches. Returns a dispose function that removes the listeners and stops any in-flight interval.
1020
+ */
1021
+ export declare function doWhilePressed(querySelector: string, callback: () => void, delay?: number): () => void;
1022
+ /**
1023
+ * Resolves the next time `type` fires on `element` (one-shot listener). Pass an `AbortSignal`
1024
+ * to cancel — rejects with `signal.reason` and removes the listener.
1025
+ */
1026
+ export declare function waitForEvent<K extends keyof HTMLElementEventMap>(element: HTMLElement, type: K, signal?: AbortSignal): Promise<void>;
1027
+ /**
1028
+ * Returns a debounced wrapper that runs `callback` only after `delay` ms of silence (trailing edge).
1029
+ */
1030
+ export declare function debounce<T extends unknown[]>(callback: (...args: T) => void, delay: number): (...args: T) => void;
1031
+ /**
1032
+ * Promise that resolves after `time` milliseconds.
1033
+ */
1034
+ export declare function delay(time: number): Promise<void>;
1035
+ /**
1036
+ * Returns `true` when touch is the primary input right now (game-UI question: show touch controls?).
1037
+ * Mode-aware: a convertible in laptop mode returns `false`, in tablet mode returns `true`.
1038
+ * Snapshot at call time — won't auto-update if the user switches modes mid-game.
1039
+ */
1040
+ export declare function isTouchPrimary(): boolean;
1041
+ /**
1042
+ * Run `tick(dt)` on every animation frame; `dt` is seconds since the previous
1043
+ * frame (0 on the first call). Returns a cancel function that stops the loop —
1044
+ * no further ticks fire after it's called, even if one was already queued.
1045
+ */
1046
+ export declare function rafLoop(tick: (dt: number) => void): () => void;
1047
+ /**
1048
+ * Returns a throttled wrapper that runs `callback` at most once per `delay` ms (leading edge).
1049
+ * The callback receives the number of wrapper calls since the previous firing (inclusive of this one).
1050
+ */
1051
+ export declare function throttle(callback: (callCount: number) => void, delay?: number): () => void;
1052
+ /**
1053
+ * Like `throttle`, but tracks the last firing independently per `key` —
1054
+ * different keys never throttle each other. Use for de-duplicating repeated
1055
+ * error/warning logs by message identity. When the throttle fires, args from
1056
+ * the most recent call for that key are passed through alongside `callCount`.
1057
+ */
1058
+ export declare function throttleByKey<T extends unknown[]>(callback: (callCount: number, ...args: T) => void, delay?: number): (key: string, ...args: T) => void;
1059
+ /**
1060
+ * Filename component of a URL/path, without directory, extension, or query string.
1061
+ * Returns `null` when no usable name can be derived: a path ending in `/`, or a stem containing a malformed percent-escape that `decodeURIComponent` rejects.
1062
+ */
1063
+ export declare function urlBasename(path: string): string | null;
1064
+ /**
1065
+ * Clone a 2D grid; the outer array and each row become independent copies.
1066
+ * Row cells are kept as-is (suitable for primitive cells; for nested structures use `deepClone`).
1067
+ */
1068
+ export declare function cloneGrid<T>(grid: ReadonlyArray<ReadonlyArray<T>>): T[][];
1069
+ /**
1070
+ * Convert a 1D index to `{x, y}` for a 2D grid of the given row width.
1071
+ */
1072
+ export declare function convert1DTo2D(index: number, width: number): Vector2;
1073
+ /**
1074
+ * Convert 2D `(x, y)` coordinates to a 1D index for a grid of the given row width.
1075
+ */
1076
+ export declare function convert2DTo1D(indexX: number, indexY: number, width: number): number;
1077
+ export type GridPrimitive = string | number | boolean | bigint | symbol | null | undefined;
1078
+ /**
1079
+ * Generate a `height × width` 2D grid; every cell holds `defaultValue`. Restricted to primitives at the type level — for object/array cells use the factory overload to avoid every cell sharing the same reference.
1080
+ */
1081
+ export declare function generateGrid<T extends GridPrimitive>(height: number, width: number, defaultValue: T): T[][];
1082
+ /**
1083
+ * Generate a `height × width` 2D grid by invoking `factory(x, y)` for each cell. Use this overload for object/array cells (and for any per-cell computation).
1084
+ */
1085
+ export declare function generateGrid<T>(height: number, width: number, factory: (x: number, y: number) => T): T[][];
1086
+ /**
1087
+ * Recursively clone a value. Returns primitives and functions as-is (no copy).
1088
+ * Cyclic references resolve via an internal `WeakMap`. Explicit branches preserve
1089
+ * `Date`, `RegExp`, `Map`, `Set`, `Array`, `ArrayBuffer`, typed arrays, and `DataView`.
1090
+ * For plain objects / class instances the prototype is preserved via
1091
+ * `Object.create(...)` — the original constructor is *not* called, so no side
1092
+ * effects fire. Symbol keys and non-enumerable data properties are carried via descriptors.
1093
+ * Own accessor properties (`get`/`set`) are snapshotted to a data property by invoking
1094
+ * the getter on the source; this severs any closure binding to the original instance
1095
+ * but also drops live computation on the clone.
1096
+ */
1097
+ export declare function deepClone<T>(obj: T): T;
1098
+ /**
1099
+ * Check if a value is a finite number or a string holding one. Accepts optional leading sign, decimal forms (`.5`, `5.`, `3.14`), and scientific notation (`1e5`, `-3.14e-2`).
1100
+ */
1101
+ export declare function isNumeric(value: unknown): boolean;
1102
+ /**
1103
+ * Generate a random angle between 0 and 2-PI in radians
1104
+ */
1105
+ export declare function random2Pi(): number;
1106
+ /**
1107
+ * Generate a random float between two values. Bounds may be passed in either order.
1108
+ */
1109
+ export declare function randomBetweenFloat(min: number, max: number): number;
1110
+ /**
1111
+ * Generate a random integer in `[min, max]` (both bounds inclusive). Bounds may be passed in either order.
1112
+ */
1113
+ export declare function randomBetweenInt(min: number, max: number): number;
1114
+ /**
1115
+ * Generate a random boolean value
1116
+ */
1117
+ export declare function randomBoolean(): boolean;
1118
+ /**
1119
+ * Generate a random sign (1 or -1)
1120
+ */
1121
+ export declare function randomSign(): number;
1122
+ /**
1123
+ * Format time in seconds as HH:MM:SS string
1124
+ */
1125
+ export declare function toHHMMSS(time: number): string;
1126
+ /**
1127
+ * Convert radians to degrees
1128
+ */
1129
+ export declare function toDegrees(radians: number): number;
1130
+ /**
1131
+ * Convert degrees to radians
1132
+ */
1133
+ export declare function toRadians(degrees: number): number;
1134
+ /**
1135
+ * Wrap an angle in radians into `[-PI, PI)`.
1136
+ */
1137
+ export declare function wrapRadians(angle: number): number;
1138
+ /**
1139
+ * Wrap an angle in degrees into `[-180, 180)`.
1140
+ */
1141
+ export declare function wrapDegrees(angle: number): number;
1142
+ /**
1143
+ * Round a number to a specified number of decimal places
1144
+ */
1145
+ export declare function roundTo(number: number, digitsAfterPoint: number): number;
1146
+ /**
1147
+ * Calculate factorial of a non-negative integer. Memoized — repeat calls reuse cached intermediates.
1148
+ * Returns `Infinity` once `n!` overflows the IEEE 754 double range (around `n = 171`).
1149
+ */
1150
+ export declare function getFactorial(n: number): number;
1151
+ /**
1152
+ * Compare two numbers with float tolerance. Default epsilon absorbs typical accumulated rounding error from normalize/rotate/divide chains.
1153
+ */
1154
+ export declare function approxEqual(a: number, b: number, epsilon?: number): boolean;
1155
+ /**
1156
+ * Clamp values between two values
1157
+ */
1158
+ export declare function clamp(value: number, min: number, max: number): number;
1159
+ /**
1160
+ * Map value from one range to another. Returns `low2` when the source range is degenerate (`low1 === high1`).
1161
+ */
1162
+ export declare function mapUnclamped(value: number, low1: number, high1: number, low2: number, high2: number): number;
1163
+ /**
1164
+ * Map value from one range to another (with clamping). Output range allows to be inverted (`high2 < low2`).
1165
+ */
1166
+ export declare function map(value: number, low1: number, high1: number, low2: number, high2: number): number;
1167
+ /**
1168
+ * Zero out values with `|value| < cutoff`; pass the rest through unchanged.
1169
+ */
1170
+ export declare function threshold(value: number, cutoff: number): number;
1171
+ /**
1172
+ * Format number with dot separators (e.g., 1.000.000). Rounds to the nearest integer via `Math.round`; non-finite values pass through as their `toString()` form.
1173
+ */
1174
+ export declare function toDotted(value: number): string;
1175
+ /**
1176
+ * Wrap `value` into `[min, max)` modulo the range size. Useful for cyclic ranges like angles.
1177
+ * Caller steps via `value + n`; this function handles the wrap-around.
1178
+ * Bounds are swapped if passed in reverse order. Throws when `min ≈ max` (degenerate range, via `approxEqual`).
1179
+ */
1180
+ export declare function wrapValue(value: number, min: number, max: number): number;
1181
+ export type Method<T, K extends keyof T> = T[K] extends (...args: infer A) => infer R ? (this: T, ...args: A) => R : never;
1182
+ /**
1183
+ * Define `name` as a non-enumerable method on `proto`. Carries the declared signature so impl `this` and parameters are inferred from the merged declaration.
1184
+ */
1185
+ export declare function defineMethod<T, K extends keyof T>(proto: T, name: K, value: Method<T, K>): void;
1186
+ /**
1187
+ * Trim `str` and collapse internal whitespace runs to a single space.
1188
+ */
1189
+ export declare function compact(str: string): string;
1190
+ /**
1191
+ * Replace the single character at `index` in `str`. Indexes by code point, so emoji and other supplementary-plane characters count as one. Throws on out-of-range index or multi-character `char`.
1192
+ */
1193
+ export declare function replaceCharAt(str: string, index: number, char: string): string;
1194
+
1195
+ export {};