@kya-os/cli 1.1.0 → 1.2.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.
- package/dist/commands/build.d.ts +5 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +173 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +9 -31
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/claim.d.ts +7 -1
- package/dist/commands/claim.d.ts.map +1 -1
- package/dist/commands/claim.js +196 -44
- package/dist/commands/claim.js.map +1 -1
- package/dist/commands/demo.d.ts +10 -0
- package/dist/commands/demo.d.ts.map +1 -0
- package/dist/commands/demo.js +584 -0
- package/dist/commands/demo.js.map +1 -0
- package/dist/commands/dev.d.ts +5 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +111 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/doctor.d.ts +11 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +530 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/env.d.ts +1 -1
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +113 -15
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/identity.d.ts +14 -0
- package/dist/commands/identity.d.ts.map +1 -0
- package/dist/commands/identity.js +204 -0
- package/dist/commands/identity.js.map +1 -0
- package/dist/commands/init.d.ts +6 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +86 -670
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/receipts.d.ts +11 -0
- package/dist/commands/receipts.d.ts.map +1 -0
- package/dist/commands/receipts.js +179 -0
- package/dist/commands/receipts.js.map +1 -0
- package/dist/commands/register.d.ts +15 -0
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/register.js +220 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/rotate.d.ts +7 -1
- package/dist/commands/rotate.d.ts.map +1 -1
- package/dist/commands/rotate.js +149 -109
- package/dist/commands/rotate.js.map +1 -1
- package/dist/commands/start.d.ts +5 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +129 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +9 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +177 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/verify.d.ts +22 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +491 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/components/claim-experience.d.ts +21 -0
- package/dist/components/claim-experience.d.ts.map +1 -0
- package/dist/components/claim-experience.js +138 -0
- package/dist/components/claim-experience.js.map +1 -0
- package/dist/effects/animation-engine.d.ts +173 -0
- package/dist/effects/animation-engine.d.ts.map +1 -0
- package/dist/effects/animation-engine.js +254 -0
- package/dist/effects/animation-engine.js.map +1 -0
- package/dist/effects/cli-integration.js +8 -8
- package/dist/effects/cli-integration.js.map +1 -1
- package/dist/effects/config.d.ts +86 -10
- package/dist/effects/config.d.ts.map +1 -1
- package/dist/effects/config.js +201 -18
- package/dist/effects/config.js.map +1 -1
- package/dist/effects/effect-runner.d.ts +69 -0
- package/dist/effects/effect-runner.d.ts.map +1 -0
- package/dist/effects/effect-runner.js +255 -0
- package/dist/effects/effect-runner.js.map +1 -0
- package/dist/effects/gradient.d.ts +131 -0
- package/dist/effects/gradient.d.ts.map +1 -0
- package/dist/effects/gradient.js +236 -0
- package/dist/effects/gradient.js.map +1 -0
- package/dist/effects/implementations/beams.d.ts +80 -0
- package/dist/effects/implementations/beams.d.ts.map +1 -0
- package/dist/effects/implementations/beams.js +221 -0
- package/dist/effects/implementations/beams.js.map +1 -0
- package/dist/effects/implementations/blackhole.d.ts +98 -0
- package/dist/effects/implementations/blackhole.d.ts.map +1 -0
- package/dist/effects/implementations/blackhole.js +421 -0
- package/dist/effects/implementations/blackhole.js.map +1 -0
- package/dist/effects/implementations/burn.d.ts +74 -0
- package/dist/effects/implementations/burn.d.ts.map +1 -0
- package/dist/effects/implementations/burn.js +234 -0
- package/dist/effects/implementations/burn.js.map +1 -0
- package/dist/effects/implementations/decrypt.d.ts +115 -0
- package/dist/effects/implementations/decrypt.d.ts.map +1 -0
- package/dist/effects/implementations/decrypt.js +394 -0
- package/dist/effects/implementations/decrypt.js.map +1 -0
- package/dist/effects/implementations/waves.d.ts +78 -0
- package/dist/effects/implementations/waves.d.ts.map +1 -0
- package/dist/effects/implementations/waves.js +278 -0
- package/dist/effects/implementations/waves.js.map +1 -0
- package/dist/effects/index.d.ts +34 -0
- package/dist/effects/index.d.ts.map +1 -0
- package/dist/effects/index.js +114 -0
- package/dist/effects/index.js.map +1 -0
- package/dist/effects/motion-engine.d.ts +168 -0
- package/dist/effects/motion-engine.d.ts.map +1 -0
- package/dist/effects/motion-engine.js +353 -0
- package/dist/effects/motion-engine.js.map +1 -0
- package/dist/effects/safe-executor.d.ts +55 -0
- package/dist/effects/safe-executor.d.ts.map +1 -0
- package/dist/effects/safe-executor.js +210 -0
- package/dist/effects/safe-executor.js.map +1 -0
- package/dist/effects/types.d.ts +199 -0
- package/dist/effects/types.d.ts.map +1 -0
- package/dist/effects/types.js +80 -0
- package/dist/effects/types.js.map +1 -0
- package/dist/effects/utils.d.ts +104 -0
- package/dist/effects/utils.d.ts.map +1 -0
- package/dist/effects/utils.js +280 -0
- package/dist/effects/utils.js.map +1 -0
- package/dist/index.js +154 -19
- package/dist/utils/env-manager.d.ts +6 -7
- package/dist/utils/env-manager.d.ts.map +1 -1
- package/dist/utils/env-manager.js +52 -40
- package/dist/utils/env-manager.js.map +1 -1
- package/dist/utils/identity-manager.d.ts +41 -0
- package/dist/utils/identity-manager.d.ts.map +1 -0
- package/dist/utils/identity-manager.js +159 -0
- package/dist/utils/identity-manager.js.map +1 -0
- package/dist/utils/kta-api.d.ts +67 -0
- package/dist/utils/kta-api.d.ts.map +1 -0
- package/dist/utils/kta-api.js +137 -0
- package/dist/utils/kta-api.js.map +1 -0
- package/package.json +8 -7
- package/dist/utils/validation.d.ts +0 -101
- package/dist/utils/validation.d.ts.map +0 -1
- package/dist/utils/validation.js +0 -109
- package/dist/utils/validation.js.map +0 -1
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types and interfaces for the Terminal Effects Engine
|
|
3
|
+
* Based on TerminalTextEffects Python library architecture
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* RGB color string in hex format (without #)
|
|
7
|
+
*/
|
|
8
|
+
export type RGBColor = string;
|
|
9
|
+
/**
|
|
10
|
+
* XTerm 256 color code
|
|
11
|
+
*/
|
|
12
|
+
export type XTermColor = number;
|
|
13
|
+
/**
|
|
14
|
+
* Color can be RGB hex or XTerm-256
|
|
15
|
+
*/
|
|
16
|
+
export type Color = RGBColor | XTermColor | null;
|
|
17
|
+
/**
|
|
18
|
+
* Color pair for foreground and background
|
|
19
|
+
*/
|
|
20
|
+
export interface ColorPair {
|
|
21
|
+
fg: Color;
|
|
22
|
+
bg: Color;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Character visual state at a point in time
|
|
26
|
+
*/
|
|
27
|
+
export interface CharacterVisual {
|
|
28
|
+
symbol: string;
|
|
29
|
+
colors: ColorPair;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Single frame of animation
|
|
33
|
+
*/
|
|
34
|
+
export interface Frame {
|
|
35
|
+
characters: CharacterVisual[];
|
|
36
|
+
duration?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Terminal dimensions
|
|
40
|
+
*/
|
|
41
|
+
export interface TerminalDimensions {
|
|
42
|
+
width: number;
|
|
43
|
+
height: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Coordinate in 2D space
|
|
47
|
+
*/
|
|
48
|
+
export interface Coordinate {
|
|
49
|
+
x: number;
|
|
50
|
+
y: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Animation easing function
|
|
54
|
+
*/
|
|
55
|
+
export type EasingFunction = (t: number) => number;
|
|
56
|
+
/**
|
|
57
|
+
* Effect configuration options
|
|
58
|
+
*/
|
|
59
|
+
export interface EffectConfig {
|
|
60
|
+
/** Target frame rate (fps) */
|
|
61
|
+
frameRate: number;
|
|
62
|
+
/** Use XTerm colors instead of RGB */
|
|
63
|
+
useXTermColors: boolean;
|
|
64
|
+
/** Disable all colors */
|
|
65
|
+
noColor: boolean;
|
|
66
|
+
/** Canvas dimensions */
|
|
67
|
+
canvas?: TerminalDimensions;
|
|
68
|
+
/** Custom parameters for specific effects */
|
|
69
|
+
[key: string]: any;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Base interface for all effects
|
|
73
|
+
*/
|
|
74
|
+
export interface Effect {
|
|
75
|
+
/** Effect name for identification */
|
|
76
|
+
readonly name: string;
|
|
77
|
+
/** Effect description */
|
|
78
|
+
readonly description: string;
|
|
79
|
+
/** Initialize the effect with text and config */
|
|
80
|
+
initialize(text: string, config: Partial<EffectConfig>): void;
|
|
81
|
+
/** Render the next frame of the effect */
|
|
82
|
+
render(): Promise<string[]>;
|
|
83
|
+
/** Render fallback plain text version */
|
|
84
|
+
renderFallback(): string[];
|
|
85
|
+
/** Check if the effect is complete */
|
|
86
|
+
isComplete(): boolean;
|
|
87
|
+
/** Reset the effect to initial state */
|
|
88
|
+
reset(): void;
|
|
89
|
+
/** Cleanup any resources */
|
|
90
|
+
cleanup(): void;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Scene represents a sequence of visual changes
|
|
94
|
+
*/
|
|
95
|
+
export interface Scene {
|
|
96
|
+
id: string;
|
|
97
|
+
frames: Frame[];
|
|
98
|
+
isLooping: boolean;
|
|
99
|
+
currentFrame: number;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Motion path for character movement
|
|
103
|
+
*/
|
|
104
|
+
export interface Path {
|
|
105
|
+
waypoints: Coordinate[];
|
|
106
|
+
currentPosition: number;
|
|
107
|
+
easing?: EasingFunction;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Character state including position and animation
|
|
111
|
+
*/
|
|
112
|
+
export interface EffectCharacter {
|
|
113
|
+
id: string;
|
|
114
|
+
originalSymbol: string;
|
|
115
|
+
originalPosition: Coordinate;
|
|
116
|
+
currentPosition: Coordinate;
|
|
117
|
+
visual: CharacterVisual;
|
|
118
|
+
motion?: Path;
|
|
119
|
+
scene?: Scene;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Effect execution result
|
|
123
|
+
*/
|
|
124
|
+
export interface EffectResult {
|
|
125
|
+
success: boolean;
|
|
126
|
+
frames?: string[];
|
|
127
|
+
error?: Error;
|
|
128
|
+
duration?: number;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Terminal capability detection result
|
|
132
|
+
*/
|
|
133
|
+
export interface TerminalCapabilities {
|
|
134
|
+
supportsColor: boolean;
|
|
135
|
+
supports256Color: boolean;
|
|
136
|
+
supportsTrueColor: boolean;
|
|
137
|
+
dimensions: TerminalDimensions;
|
|
138
|
+
isInteractive: boolean;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Effect registry entry
|
|
142
|
+
*/
|
|
143
|
+
export interface EffectRegistryEntry {
|
|
144
|
+
name: string;
|
|
145
|
+
description: string;
|
|
146
|
+
factory: () => Effect;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Safety configuration for effects
|
|
150
|
+
*/
|
|
151
|
+
export interface SafetyConfig {
|
|
152
|
+
/** Maximum execution time in milliseconds */
|
|
153
|
+
maxExecutionTime: number;
|
|
154
|
+
/** Maximum memory usage in MB */
|
|
155
|
+
maxMemoryUsage: number;
|
|
156
|
+
/** Enable performance monitoring */
|
|
157
|
+
enableMonitoring: boolean;
|
|
158
|
+
/** Force fallback mode */
|
|
159
|
+
forceFallback: boolean;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Performance metrics for monitoring
|
|
163
|
+
*/
|
|
164
|
+
export interface PerformanceMetrics {
|
|
165
|
+
frameCount: number;
|
|
166
|
+
totalDuration: number;
|
|
167
|
+
averageFrameTime: number;
|
|
168
|
+
maxFrameTime: number;
|
|
169
|
+
memoryUsage: number;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Abstract base class for effects
|
|
173
|
+
*/
|
|
174
|
+
export declare abstract class BaseEffect implements Effect {
|
|
175
|
+
abstract readonly name: string;
|
|
176
|
+
abstract readonly description: string;
|
|
177
|
+
protected text: string;
|
|
178
|
+
protected config: EffectConfig;
|
|
179
|
+
protected characters: EffectCharacter[];
|
|
180
|
+
protected frameCount: number;
|
|
181
|
+
protected isInitialized: boolean;
|
|
182
|
+
initialize(text: string, config: Partial<EffectConfig>): void;
|
|
183
|
+
abstract render(): Promise<string[]>;
|
|
184
|
+
abstract renderFallback(): string[];
|
|
185
|
+
abstract isComplete(): boolean;
|
|
186
|
+
reset(): void;
|
|
187
|
+
cleanup(): void;
|
|
188
|
+
protected abstract onInitialize(): void;
|
|
189
|
+
protected abstract onReset(): void;
|
|
190
|
+
protected onCleanup(): void;
|
|
191
|
+
protected createCharacters(text: string): EffectCharacter[];
|
|
192
|
+
protected getCanvasDimensions(): TerminalDimensions;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Type guard for Color types
|
|
196
|
+
*/
|
|
197
|
+
export declare function isRGBColor(color: Color): color is RGBColor;
|
|
198
|
+
export declare function isXTermColor(color: Color): color is XTermColor;
|
|
199
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/effects/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAEhC;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG,QAAQ,GAAG,UAAU,GAAG,IAAI,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,KAAK,CAAC;IACV,EAAE,EAAE,KAAK,CAAC;CACX;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,cAAc,EAAE,OAAO,CAAC;IACxB,yBAAyB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,wBAAwB;IACxB,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,6CAA6C;IAC7C,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,qCAAqC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,yBAAyB;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,iDAAiD;IACjD,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;IAE9D,0CAA0C;IAC1C,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE5B,yCAAyC;IACzC,cAAc,IAAI,MAAM,EAAE,CAAC;IAE3B,sCAAsC;IACtC,UAAU,IAAI,OAAO,CAAC;IAEtB,wCAAwC;IACxC,KAAK,IAAI,IAAI,CAAC;IAEd,4BAA4B;IAC5B,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,SAAS,EAAE,UAAU,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,UAAU,CAAC;IAC7B,eAAe,EAAE,UAAU,CAAC;IAC5B,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,UAAU,EAAE,kBAAkB,CAAC;IAC/B,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,6CAA6C;IAC7C,gBAAgB,EAAE,MAAM,CAAC;IACzB,iCAAiC;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,0BAA0B;IAC1B,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,8BAAsB,UAAW,YAAW,MAAM;IAChD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAEtC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAM;IAC5B,SAAS,CAAC,MAAM,EAAE,YAAY,CAI5B;IAEF,SAAS,CAAC,UAAU,EAAE,eAAe,EAAE,CAAM;IAC7C,SAAS,CAAC,UAAU,EAAE,MAAM,CAAK;IACjC,SAAS,CAAC,aAAa,EAAE,OAAO,CAAS;IAEzC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI;IAQ7D,QAAQ,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAEpC,QAAQ,CAAC,cAAc,IAAI,MAAM,EAAE;IAEnC,QAAQ,CAAC,UAAU,IAAI,OAAO;IAE9B,KAAK,IAAI,IAAI;IAMb,OAAO,IAAI,IAAI;IAKf,SAAS,CAAC,QAAQ,CAAC,YAAY,IAAI,IAAI;IAEvC,SAAS,CAAC,QAAQ,CAAC,OAAO,IAAI,IAAI;IAElC,SAAS,CAAC,SAAS,IAAI,IAAI;IAI3B,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE;IAwB3D,SAAS,CAAC,mBAAmB,IAAI,kBAAkB;CAYpD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,IAAI,QAAQ,CAE1D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,IAAI,UAAU,CAE9D"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types and interfaces for the Terminal Effects Engine
|
|
3
|
+
* Based on TerminalTextEffects Python library architecture
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Abstract base class for effects
|
|
7
|
+
*/
|
|
8
|
+
export class BaseEffect {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.text = "";
|
|
11
|
+
this.config = {
|
|
12
|
+
frameRate: 30,
|
|
13
|
+
useXTermColors: false,
|
|
14
|
+
noColor: false,
|
|
15
|
+
};
|
|
16
|
+
this.characters = [];
|
|
17
|
+
this.frameCount = 0;
|
|
18
|
+
this.isInitialized = false;
|
|
19
|
+
}
|
|
20
|
+
initialize(text, config) {
|
|
21
|
+
this.text = text;
|
|
22
|
+
this.config = { ...this.config, ...config };
|
|
23
|
+
this.characters = this.createCharacters(text);
|
|
24
|
+
this.isInitialized = true;
|
|
25
|
+
this.onInitialize();
|
|
26
|
+
}
|
|
27
|
+
reset() {
|
|
28
|
+
this.frameCount = 0;
|
|
29
|
+
this.characters = this.createCharacters(this.text);
|
|
30
|
+
this.onReset();
|
|
31
|
+
}
|
|
32
|
+
cleanup() {
|
|
33
|
+
this.characters = [];
|
|
34
|
+
this.onCleanup();
|
|
35
|
+
}
|
|
36
|
+
onCleanup() {
|
|
37
|
+
// Optional cleanup hook
|
|
38
|
+
}
|
|
39
|
+
createCharacters(text) {
|
|
40
|
+
const lines = text.split("\n");
|
|
41
|
+
const characters = [];
|
|
42
|
+
lines.forEach((line, y) => {
|
|
43
|
+
[...line].forEach((char, x) => {
|
|
44
|
+
if (char !== " ") {
|
|
45
|
+
characters.push({
|
|
46
|
+
id: `${x}-${y}`,
|
|
47
|
+
originalSymbol: char,
|
|
48
|
+
originalPosition: { x, y },
|
|
49
|
+
currentPosition: { x, y },
|
|
50
|
+
visual: {
|
|
51
|
+
symbol: char,
|
|
52
|
+
colors: { fg: null, bg: null },
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
return characters;
|
|
59
|
+
}
|
|
60
|
+
getCanvasDimensions() {
|
|
61
|
+
if (this.config.canvas) {
|
|
62
|
+
return this.config.canvas;
|
|
63
|
+
}
|
|
64
|
+
// Calculate from text if no canvas specified
|
|
65
|
+
const lines = this.text.split("\n");
|
|
66
|
+
const height = lines.length;
|
|
67
|
+
const width = Math.max(...lines.map((line) => line.length));
|
|
68
|
+
return { width, height };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Type guard for Color types
|
|
73
|
+
*/
|
|
74
|
+
export function isRGBColor(color) {
|
|
75
|
+
return typeof color === "string" && /^[0-9a-fA-F]{6}$/.test(color);
|
|
76
|
+
}
|
|
77
|
+
export function isXTermColor(color) {
|
|
78
|
+
return typeof color === "number" && color >= 0 && color <= 255;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/effects/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for terminal effects
|
|
3
|
+
*/
|
|
4
|
+
import { TerminalCapabilities, TerminalDimensions, Color, RGBColor, XTermColor } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* ANSI escape codes
|
|
7
|
+
*/
|
|
8
|
+
export declare const ANSI: {
|
|
9
|
+
reset: string;
|
|
10
|
+
cursor: {
|
|
11
|
+
hide: string;
|
|
12
|
+
show: string;
|
|
13
|
+
save: string;
|
|
14
|
+
restore: string;
|
|
15
|
+
home: string;
|
|
16
|
+
moveTo: (x: number, y: number) => string;
|
|
17
|
+
};
|
|
18
|
+
clear: {
|
|
19
|
+
screen: string;
|
|
20
|
+
line: string;
|
|
21
|
+
toEnd: string;
|
|
22
|
+
toStart: string;
|
|
23
|
+
};
|
|
24
|
+
color: {
|
|
25
|
+
fg: (color: Color) => string;
|
|
26
|
+
bg: (color: Color) => string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Detect terminal capabilities
|
|
31
|
+
*/
|
|
32
|
+
export declare function detectTerminalCapabilities(): TerminalCapabilities;
|
|
33
|
+
/**
|
|
34
|
+
* Get terminal dimensions
|
|
35
|
+
*/
|
|
36
|
+
export declare function getTerminalDimensions(): TerminalDimensions;
|
|
37
|
+
/**
|
|
38
|
+
* Convert RGB hex to XTerm-256 color
|
|
39
|
+
* Based on the algorithm from https://github.com/Qix-/color-convert
|
|
40
|
+
*/
|
|
41
|
+
export declare function rgbToXterm(hex: RGBColor): XTermColor;
|
|
42
|
+
/**
|
|
43
|
+
* Strip ANSI codes from string
|
|
44
|
+
*/
|
|
45
|
+
export declare function stripAnsi(str: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Measure the visible length of a string (excluding ANSI codes)
|
|
48
|
+
*/
|
|
49
|
+
export declare function measureString(str: string): number;
|
|
50
|
+
/**
|
|
51
|
+
* Pad string to specified width (accounting for ANSI codes)
|
|
52
|
+
*/
|
|
53
|
+
export declare function padString(str: string, width: number, align?: "left" | "right" | "center"): string;
|
|
54
|
+
/**
|
|
55
|
+
* Create a buffer for double-buffered rendering
|
|
56
|
+
*/
|
|
57
|
+
export declare class RenderBuffer {
|
|
58
|
+
private buffer;
|
|
59
|
+
private width;
|
|
60
|
+
private height;
|
|
61
|
+
constructor(width: number, height: number);
|
|
62
|
+
clear(): void;
|
|
63
|
+
setChar(x: number, y: number, char: string, color?: string): void;
|
|
64
|
+
toString(): string;
|
|
65
|
+
getLines(): string[];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Sleep for specified milliseconds
|
|
69
|
+
*/
|
|
70
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Calculate FPS delay from frame rate
|
|
73
|
+
*/
|
|
74
|
+
export declare function calculateFrameDelay(fps: number): number;
|
|
75
|
+
/**
|
|
76
|
+
* Easing functions for smooth animations
|
|
77
|
+
*/
|
|
78
|
+
export declare const Easing: {
|
|
79
|
+
linear: (t: number) => number;
|
|
80
|
+
easeIn: (t: number) => number;
|
|
81
|
+
easeOut: (t: number) => number;
|
|
82
|
+
easeInOut: (t: number) => number;
|
|
83
|
+
easeInCubic: (t: number) => number;
|
|
84
|
+
easeOutCubic: (t: number) => number;
|
|
85
|
+
easeInOutCubic: (t: number) => number;
|
|
86
|
+
easeInOutSine: (t: number) => number;
|
|
87
|
+
};
|
|
88
|
+
export declare const easeInQuad: (t: number) => number;
|
|
89
|
+
export declare const easeOutQuad: (t: number) => number;
|
|
90
|
+
export declare const easeInOutQuad: (t: number) => number;
|
|
91
|
+
export declare const easeInOutSine: (t: number) => number;
|
|
92
|
+
/**
|
|
93
|
+
* Interpolate between two values
|
|
94
|
+
*/
|
|
95
|
+
export declare function lerp(start: number, end: number, t: number): number;
|
|
96
|
+
/**
|
|
97
|
+
* Clamp a value between min and max
|
|
98
|
+
*/
|
|
99
|
+
export declare function clamp(value: number, min: number, max: number): number;
|
|
100
|
+
/**
|
|
101
|
+
* Create a gradient between two colors
|
|
102
|
+
*/
|
|
103
|
+
export declare function createGradient(startColor: RGBColor, endColor: RGBColor, steps: number): RGBColor[];
|
|
104
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/effects/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,EACL,QAAQ,EACR,UAAU,EAGX,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,eAAO,MAAM,IAAI;;;;;;;;oBAQD,MAAM,KAAK,MAAM;;;;;;;;;oBASjB,KAAK;oBAWL,KAAK;;CAYpB,CAAC;AAEF;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,oBAAoB,CAWjE;AA6BD;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,kBAAkB,CAS1D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,QAAQ,GAAG,UAAU,CA2DpD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAM,GAAG,OAAO,GAAG,QAAiB,GAC1C,MAAM,CAcR;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;gBAEX,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAMzC,KAAK,IAAI,IAAI;IAMb,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAMjE,QAAQ,IAAI,MAAM;IAIlB,QAAQ,IAAI,MAAM,EAAE;CAGrB;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED;;GAEG;AACH,eAAO,MAAM,MAAM;gBACL,MAAM;gBACN,MAAM;iBACL,MAAM;mBACJ,MAAM;qBACJ,MAAM;sBACL,MAAM;wBACJ,MAAM;uBAEP,MAAM;CAC1B,CAAC;AAGF,eAAO,MAAM,UAAU,MAXT,MAAM,WAWmB,CAAC;AACxC,eAAO,MAAM,WAAW,MAXT,MAAM,WAWoB,CAAC;AAC1C,eAAO,MAAM,aAAa,MAXT,MAAM,WAWsB,CAAC;AAC9C,eAAO,MAAM,aAAa,MAPL,MAAM,WAOsB,CAAC;AAElD;;GAEG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,QAAQ,EACpB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,GACZ,QAAQ,EAAE,CAyBZ"}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for terminal effects
|
|
3
|
+
*/
|
|
4
|
+
import { isRGBColor, isXTermColor, } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* ANSI escape codes
|
|
7
|
+
*/
|
|
8
|
+
export const ANSI = {
|
|
9
|
+
reset: "\x1b[0m",
|
|
10
|
+
cursor: {
|
|
11
|
+
hide: "\x1b[?25l",
|
|
12
|
+
show: "\x1b[?25h",
|
|
13
|
+
save: "\x1b[s",
|
|
14
|
+
restore: "\x1b[u",
|
|
15
|
+
home: "\x1b[H",
|
|
16
|
+
moveTo: (x, y) => `\x1b[${y + 1};${x + 1}H`,
|
|
17
|
+
},
|
|
18
|
+
clear: {
|
|
19
|
+
screen: "\x1b[2J",
|
|
20
|
+
line: "\x1b[2K",
|
|
21
|
+
toEnd: "\x1b[0J",
|
|
22
|
+
toStart: "\x1b[1J",
|
|
23
|
+
},
|
|
24
|
+
color: {
|
|
25
|
+
fg: (color) => {
|
|
26
|
+
if (isRGBColor(color)) {
|
|
27
|
+
const r = parseInt(color.substr(0, 2), 16);
|
|
28
|
+
const g = parseInt(color.substr(2, 2), 16);
|
|
29
|
+
const b = parseInt(color.substr(4, 2), 16);
|
|
30
|
+
return `\x1b[38;2;${r};${g};${b}m`;
|
|
31
|
+
}
|
|
32
|
+
else if (isXTermColor(color)) {
|
|
33
|
+
return `\x1b[38;5;${color}m`;
|
|
34
|
+
}
|
|
35
|
+
return "";
|
|
36
|
+
},
|
|
37
|
+
bg: (color) => {
|
|
38
|
+
if (isRGBColor(color)) {
|
|
39
|
+
const r = parseInt(color.substr(0, 2), 16);
|
|
40
|
+
const g = parseInt(color.substr(2, 2), 16);
|
|
41
|
+
const b = parseInt(color.substr(4, 2), 16);
|
|
42
|
+
return `\x1b[48;2;${r};${g};${b}m`;
|
|
43
|
+
}
|
|
44
|
+
else if (isXTermColor(color)) {
|
|
45
|
+
return `\x1b[48;5;${color}m`;
|
|
46
|
+
}
|
|
47
|
+
return "";
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Detect terminal capabilities
|
|
53
|
+
*/
|
|
54
|
+
export function detectTerminalCapabilities() {
|
|
55
|
+
const isInteractive = process.stdout.isTTY || false;
|
|
56
|
+
const colorLevel = getColorLevel();
|
|
57
|
+
return {
|
|
58
|
+
supportsColor: colorLevel > 0,
|
|
59
|
+
supports256Color: colorLevel >= 2,
|
|
60
|
+
supportsTrueColor: colorLevel >= 3,
|
|
61
|
+
dimensions: getTerminalDimensions(),
|
|
62
|
+
isInteractive,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get color support level
|
|
67
|
+
* 0 = no color, 1 = basic color, 2 = 256 color, 3 = true color
|
|
68
|
+
*/
|
|
69
|
+
function getColorLevel() {
|
|
70
|
+
if (process.env.NO_COLOR || process.env.TERM === "dumb") {
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
if (process.env.COLORTERM === "truecolor" ||
|
|
74
|
+
process.env.TERM_PROGRAM === "iTerm.app") {
|
|
75
|
+
return 3;
|
|
76
|
+
}
|
|
77
|
+
if (process.env.TERM && /256/.test(process.env.TERM)) {
|
|
78
|
+
return 2;
|
|
79
|
+
}
|
|
80
|
+
if (process.stdout.hasColors?.()) {
|
|
81
|
+
return process.stdout.hasColors(256) ? 2 : 1;
|
|
82
|
+
}
|
|
83
|
+
return 0;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get terminal dimensions
|
|
87
|
+
*/
|
|
88
|
+
export function getTerminalDimensions() {
|
|
89
|
+
if (process.stdout.isTTY) {
|
|
90
|
+
return {
|
|
91
|
+
width: process.stdout.columns || 80,
|
|
92
|
+
height: process.stdout.rows || 24,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return { width: 80, height: 24 };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Convert RGB hex to XTerm-256 color
|
|
99
|
+
* Based on the algorithm from https://github.com/Qix-/color-convert
|
|
100
|
+
*/
|
|
101
|
+
export function rgbToXterm(hex) {
|
|
102
|
+
const r = parseInt(hex.substr(0, 2), 16);
|
|
103
|
+
const g = parseInt(hex.substr(2, 2), 16);
|
|
104
|
+
const b = parseInt(hex.substr(4, 2), 16);
|
|
105
|
+
// Check for exact matches in the basic 16 colors
|
|
106
|
+
const basicColors = [
|
|
107
|
+
[0, 0, 0],
|
|
108
|
+
[128, 0, 0],
|
|
109
|
+
[0, 128, 0],
|
|
110
|
+
[128, 128, 0],
|
|
111
|
+
[0, 0, 128],
|
|
112
|
+
[128, 0, 128],
|
|
113
|
+
[0, 128, 128],
|
|
114
|
+
[192, 192, 192],
|
|
115
|
+
[128, 128, 128],
|
|
116
|
+
[255, 0, 0],
|
|
117
|
+
[0, 255, 0],
|
|
118
|
+
[255, 255, 0],
|
|
119
|
+
[0, 0, 255],
|
|
120
|
+
[255, 0, 255],
|
|
121
|
+
[0, 255, 255],
|
|
122
|
+
[255, 255, 255],
|
|
123
|
+
];
|
|
124
|
+
for (let i = 0; i < basicColors.length; i++) {
|
|
125
|
+
const [br, bg, bb] = basicColors[i];
|
|
126
|
+
if (r === br && g === bg && b === bb) {
|
|
127
|
+
return i;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Check grayscale
|
|
131
|
+
if (r === g && g === b) {
|
|
132
|
+
if (r < 8)
|
|
133
|
+
return 16;
|
|
134
|
+
if (r > 248)
|
|
135
|
+
return 231;
|
|
136
|
+
return Math.round(((r - 8) / 247) * 24) + 232;
|
|
137
|
+
}
|
|
138
|
+
// Use 6x6x6 color cube
|
|
139
|
+
const levels = [0, 95, 135, 175, 215, 255];
|
|
140
|
+
const findClosest = (value) => {
|
|
141
|
+
let minDist = Infinity;
|
|
142
|
+
let closest = 0;
|
|
143
|
+
for (let i = 0; i < levels.length; i++) {
|
|
144
|
+
const dist = Math.abs(value - levels[i]);
|
|
145
|
+
if (dist < minDist) {
|
|
146
|
+
minDist = dist;
|
|
147
|
+
closest = i;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return closest;
|
|
151
|
+
};
|
|
152
|
+
const ri = findClosest(r);
|
|
153
|
+
const gi = findClosest(g);
|
|
154
|
+
const bi = findClosest(b);
|
|
155
|
+
return 16 + 36 * ri + 6 * gi + bi;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Strip ANSI codes from string
|
|
159
|
+
*/
|
|
160
|
+
export function stripAnsi(str) {
|
|
161
|
+
// eslint-disable-next-line no-control-regex
|
|
162
|
+
return str.replace(/\x1b\[[0-9;]*m/g, "");
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Measure the visible length of a string (excluding ANSI codes)
|
|
166
|
+
*/
|
|
167
|
+
export function measureString(str) {
|
|
168
|
+
return stripAnsi(str).length;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Pad string to specified width (accounting for ANSI codes)
|
|
172
|
+
*/
|
|
173
|
+
export function padString(str, width, align = "left") {
|
|
174
|
+
const visibleLength = measureString(str);
|
|
175
|
+
const padding = Math.max(0, width - visibleLength);
|
|
176
|
+
switch (align) {
|
|
177
|
+
case "right":
|
|
178
|
+
return " ".repeat(padding) + str;
|
|
179
|
+
case "center":
|
|
180
|
+
const leftPad = Math.floor(padding / 2);
|
|
181
|
+
const rightPad = padding - leftPad;
|
|
182
|
+
return " ".repeat(leftPad) + str + " ".repeat(rightPad);
|
|
183
|
+
default:
|
|
184
|
+
return str + " ".repeat(padding);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Create a buffer for double-buffered rendering
|
|
189
|
+
*/
|
|
190
|
+
export class RenderBuffer {
|
|
191
|
+
constructor(width, height) {
|
|
192
|
+
this.buffer = [];
|
|
193
|
+
this.width = width;
|
|
194
|
+
this.height = height;
|
|
195
|
+
this.clear();
|
|
196
|
+
}
|
|
197
|
+
clear() {
|
|
198
|
+
this.buffer = Array(this.height)
|
|
199
|
+
.fill(null)
|
|
200
|
+
.map(() => Array(this.width).fill(" "));
|
|
201
|
+
}
|
|
202
|
+
setChar(x, y, char, color) {
|
|
203
|
+
if (x >= 0 && x < this.width && y >= 0 && y < this.height) {
|
|
204
|
+
this.buffer[y][x] = color ? `${color}${char}${ANSI.reset}` : char;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
toString() {
|
|
208
|
+
return this.buffer.map((row) => row.join("")).join("\n");
|
|
209
|
+
}
|
|
210
|
+
getLines() {
|
|
211
|
+
return this.buffer.map((row) => row.join(""));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Sleep for specified milliseconds
|
|
216
|
+
*/
|
|
217
|
+
export function sleep(ms) {
|
|
218
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Calculate FPS delay from frame rate
|
|
222
|
+
*/
|
|
223
|
+
export function calculateFrameDelay(fps) {
|
|
224
|
+
if (fps <= 0)
|
|
225
|
+
return 0;
|
|
226
|
+
return Math.floor(1000 / fps);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Easing functions for smooth animations
|
|
230
|
+
*/
|
|
231
|
+
export const Easing = {
|
|
232
|
+
linear: (t) => t,
|
|
233
|
+
easeIn: (t) => t * t,
|
|
234
|
+
easeOut: (t) => t * (2 - t),
|
|
235
|
+
easeInOut: (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),
|
|
236
|
+
easeInCubic: (t) => t * t * t,
|
|
237
|
+
easeOutCubic: (t) => --t * t * t + 1,
|
|
238
|
+
easeInOutCubic: (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
|
|
239
|
+
easeInOutSine: (t) => -(Math.cos(Math.PI * t) - 1) / 2,
|
|
240
|
+
};
|
|
241
|
+
// Export individual easing functions for convenience
|
|
242
|
+
export const easeInQuad = Easing.easeIn;
|
|
243
|
+
export const easeOutQuad = Easing.easeOut;
|
|
244
|
+
export const easeInOutQuad = Easing.easeInOut;
|
|
245
|
+
export const easeInOutSine = Easing.easeInOutSine;
|
|
246
|
+
/**
|
|
247
|
+
* Interpolate between two values
|
|
248
|
+
*/
|
|
249
|
+
export function lerp(start, end, t) {
|
|
250
|
+
return start + (end - start) * t;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Clamp a value between min and max
|
|
254
|
+
*/
|
|
255
|
+
export function clamp(value, min, max) {
|
|
256
|
+
return Math.max(min, Math.min(max, value));
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Create a gradient between two colors
|
|
260
|
+
*/
|
|
261
|
+
export function createGradient(startColor, endColor, steps) {
|
|
262
|
+
const colors = [];
|
|
263
|
+
const sr = parseInt(startColor.substr(0, 2), 16);
|
|
264
|
+
const sg = parseInt(startColor.substr(2, 2), 16);
|
|
265
|
+
const sb = parseInt(startColor.substr(4, 2), 16);
|
|
266
|
+
const er = parseInt(endColor.substr(0, 2), 16);
|
|
267
|
+
const eg = parseInt(endColor.substr(2, 2), 16);
|
|
268
|
+
const eb = parseInt(endColor.substr(4, 2), 16);
|
|
269
|
+
for (let i = 0; i < steps; i++) {
|
|
270
|
+
const t = i / (steps - 1);
|
|
271
|
+
const r = Math.round(lerp(sr, er, t));
|
|
272
|
+
const g = Math.round(lerp(sg, eg, t));
|
|
273
|
+
const b = Math.round(lerp(sb, eb, t));
|
|
274
|
+
colors.push(r.toString(16).padStart(2, "0") +
|
|
275
|
+
g.toString(16).padStart(2, "0") +
|
|
276
|
+
b.toString(16).padStart(2, "0"));
|
|
277
|
+
}
|
|
278
|
+
return colors;
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=utils.js.map
|