erosolar-cli 1.7.14 → 1.7.16
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/core/responseVerifier.d.ts +79 -0
- package/dist/core/responseVerifier.d.ts.map +1 -0
- package/dist/core/responseVerifier.js +443 -0
- package/dist/core/responseVerifier.js.map +1 -0
- package/dist/shell/interactiveShell.d.ts +10 -0
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +80 -0
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/ui/ShellUIAdapter.d.ts +3 -0
- package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
- package/dist/ui/ShellUIAdapter.js +4 -10
- package/dist/ui/ShellUIAdapter.js.map +1 -1
- package/dist/ui/persistentPrompt.d.ts +4 -0
- package/dist/ui/persistentPrompt.d.ts.map +1 -1
- package/dist/ui/persistentPrompt.js +10 -11
- package/dist/ui/persistentPrompt.js.map +1 -1
- package/package.json +1 -1
- package/dist/bin/core/agent.js +0 -362
- package/dist/bin/core/agentProfileManifest.js +0 -187
- package/dist/bin/core/agentProfiles.js +0 -34
- package/dist/bin/core/agentRulebook.js +0 -135
- package/dist/bin/core/agentSchemaLoader.js +0 -233
- package/dist/bin/core/contextManager.js +0 -412
- package/dist/bin/core/contextWindow.js +0 -122
- package/dist/bin/core/customCommands.js +0 -80
- package/dist/bin/core/errors/apiKeyErrors.js +0 -114
- package/dist/bin/core/errors/errorTypes.js +0 -340
- package/dist/bin/core/errors/safetyValidator.js +0 -304
- package/dist/bin/core/errors.js +0 -32
- package/dist/bin/core/modelDiscovery.js +0 -755
- package/dist/bin/core/preferences.js +0 -224
- package/dist/bin/core/schemaValidator.js +0 -92
- package/dist/bin/core/secretStore.js +0 -199
- package/dist/bin/core/sessionStore.js +0 -187
- package/dist/bin/core/toolRuntime.js +0 -290
- package/dist/bin/core/types.js +0 -1
- package/dist/bin/shell/bracketedPasteManager.js +0 -350
- package/dist/bin/shell/fileChangeTracker.js +0 -65
- package/dist/bin/shell/interactiveShell.js +0 -2908
- package/dist/bin/shell/liveStatus.js +0 -78
- package/dist/bin/shell/shellApp.js +0 -290
- package/dist/bin/shell/systemPrompt.js +0 -60
- package/dist/bin/shell/updateManager.js +0 -108
- package/dist/bin/ui/ShellUIAdapter.js +0 -459
- package/dist/bin/ui/UnifiedUIController.js +0 -183
- package/dist/bin/ui/animation/AnimationScheduler.js +0 -430
- package/dist/bin/ui/codeHighlighter.js +0 -854
- package/dist/bin/ui/designSystem.js +0 -121
- package/dist/bin/ui/display.js +0 -1222
- package/dist/bin/ui/interrupts/InterruptManager.js +0 -437
- package/dist/bin/ui/layout.js +0 -139
- package/dist/bin/ui/orchestration/StatusOrchestrator.js +0 -403
- package/dist/bin/ui/outputMode.js +0 -38
- package/dist/bin/ui/persistentPrompt.js +0 -183
- package/dist/bin/ui/richText.js +0 -338
- package/dist/bin/ui/shortcutsHelp.js +0 -87
- package/dist/bin/ui/telemetry/UITelemetry.js +0 -443
- package/dist/bin/ui/textHighlighter.js +0 -210
- package/dist/bin/ui/theme.js +0 -116
- package/dist/bin/ui/toolDisplay.js +0 -423
- package/dist/bin/ui/toolDisplayAdapter.js +0 -357
|
@@ -1,430 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AnimationScheduler - Coordinates animations, spinners, progress bars, and elapsed time
|
|
3
|
-
* Provides frame-based animation updates and smooth transitions
|
|
4
|
-
*/
|
|
5
|
-
import { EventEmitter } from 'events';
|
|
6
|
-
import { performance } from 'perf_hooks';
|
|
7
|
-
export class AnimationScheduler extends EventEmitter {
|
|
8
|
-
constructor(targetFPS = 30) {
|
|
9
|
-
super();
|
|
10
|
-
this.animations = new Map();
|
|
11
|
-
this.animationLoop = null;
|
|
12
|
-
this.targetFPS = 30;
|
|
13
|
-
this.lastFrameTime = 0;
|
|
14
|
-
this.isRunning = false;
|
|
15
|
-
this.targetFPS = targetFPS;
|
|
16
|
-
this.frameInterval = 1000 / targetFPS;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Create and register a spinner animation
|
|
20
|
-
*/
|
|
21
|
-
createSpinner(id, message, frames = AnimationScheduler.SpinnerFrames.dots) {
|
|
22
|
-
const animation = {
|
|
23
|
-
id,
|
|
24
|
-
type: 'spinner',
|
|
25
|
-
startTime: performance.now(),
|
|
26
|
-
fps: 10, // Spinners typically run at 10 FPS
|
|
27
|
-
frameCount: frames.length,
|
|
28
|
-
currentFrame: 0,
|
|
29
|
-
data: {
|
|
30
|
-
frames,
|
|
31
|
-
message,
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
this.register(animation);
|
|
35
|
-
return animation;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Create and register a progress animation
|
|
39
|
-
*/
|
|
40
|
-
createProgress(id, current, total, duration = 500) {
|
|
41
|
-
const animation = {
|
|
42
|
-
id,
|
|
43
|
-
type: 'progress',
|
|
44
|
-
startTime: performance.now(),
|
|
45
|
-
duration,
|
|
46
|
-
fps: 60, // Smooth progress animations at 60 FPS
|
|
47
|
-
frameCount: Math.ceil((duration / 1000) * 60),
|
|
48
|
-
currentFrame: 0,
|
|
49
|
-
data: {
|
|
50
|
-
current,
|
|
51
|
-
target: current,
|
|
52
|
-
total,
|
|
53
|
-
},
|
|
54
|
-
easing: AnimationScheduler.Easing.easeOutQuad,
|
|
55
|
-
};
|
|
56
|
-
this.register(animation);
|
|
57
|
-
return animation;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Update progress animation target
|
|
61
|
-
*/
|
|
62
|
-
updateProgress(id, newTarget) {
|
|
63
|
-
const animation = this.animations.get(id);
|
|
64
|
-
if (!animation || animation.type !== 'progress')
|
|
65
|
-
return;
|
|
66
|
-
animation.data.current = this.getCurrentProgressValue(animation);
|
|
67
|
-
animation.data.target = newTarget;
|
|
68
|
-
animation.startTime = performance.now();
|
|
69
|
-
animation.currentFrame = 0;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Create and register an elapsed time animation
|
|
73
|
-
*/
|
|
74
|
-
createElapsed(id, startTime = Date.now()) {
|
|
75
|
-
const animation = {
|
|
76
|
-
id,
|
|
77
|
-
type: 'elapsed',
|
|
78
|
-
startTime: performance.now(),
|
|
79
|
-
fps: 1, // Update once per second
|
|
80
|
-
frameCount: Infinity,
|
|
81
|
-
currentFrame: 0,
|
|
82
|
-
data: {
|
|
83
|
-
startTime,
|
|
84
|
-
format: this.formatElapsedTime,
|
|
85
|
-
},
|
|
86
|
-
};
|
|
87
|
-
this.register(animation);
|
|
88
|
-
return animation;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Create and register a transition animation
|
|
92
|
-
*/
|
|
93
|
-
createTransition(id, from, to, property, duration = 300, easing) {
|
|
94
|
-
const animation = {
|
|
95
|
-
id,
|
|
96
|
-
type: 'transition',
|
|
97
|
-
startTime: performance.now(),
|
|
98
|
-
duration,
|
|
99
|
-
fps: 60,
|
|
100
|
-
frameCount: Math.ceil((duration / 1000) * 60),
|
|
101
|
-
currentFrame: 0,
|
|
102
|
-
data: {
|
|
103
|
-
from,
|
|
104
|
-
to,
|
|
105
|
-
property,
|
|
106
|
-
},
|
|
107
|
-
easing: easing || AnimationScheduler.Easing.easeInOutQuad,
|
|
108
|
-
};
|
|
109
|
-
this.register(animation);
|
|
110
|
-
return animation;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Register an animation
|
|
114
|
-
*/
|
|
115
|
-
register(animation) {
|
|
116
|
-
this.animations.set(animation.id, animation);
|
|
117
|
-
// Start the animation loop if not running
|
|
118
|
-
if (!this.isRunning && this.animations.size > 0) {
|
|
119
|
-
this.start();
|
|
120
|
-
}
|
|
121
|
-
this.emit('animation:registered', animation);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Unregister an animation
|
|
125
|
-
*/
|
|
126
|
-
unregister(id) {
|
|
127
|
-
const animation = this.animations.get(id);
|
|
128
|
-
if (animation) {
|
|
129
|
-
this.animations.delete(id);
|
|
130
|
-
this.emit('animation:unregistered', animation);
|
|
131
|
-
// Stop the loop if no animations remain
|
|
132
|
-
if (this.animations.size === 0) {
|
|
133
|
-
this.stop();
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Start the animation loop
|
|
139
|
-
*/
|
|
140
|
-
start() {
|
|
141
|
-
if (this.isRunning)
|
|
142
|
-
return;
|
|
143
|
-
this.isRunning = true;
|
|
144
|
-
this.lastFrameTime = performance.now();
|
|
145
|
-
this.animationLoop = setInterval(() => this.tick(), this.frameInterval);
|
|
146
|
-
this.emit('scheduler:start');
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Stop the animation loop
|
|
150
|
-
*/
|
|
151
|
-
stop() {
|
|
152
|
-
if (!this.isRunning)
|
|
153
|
-
return;
|
|
154
|
-
if (this.animationLoop) {
|
|
155
|
-
clearInterval(this.animationLoop);
|
|
156
|
-
this.animationLoop = null;
|
|
157
|
-
}
|
|
158
|
-
this.isRunning = false;
|
|
159
|
-
this.emit('scheduler:stop');
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Main animation tick
|
|
163
|
-
*/
|
|
164
|
-
tick() {
|
|
165
|
-
const now = performance.now();
|
|
166
|
-
const deltaTime = now - this.lastFrameTime;
|
|
167
|
-
// Process each animation
|
|
168
|
-
for (const [, animation] of this.animations) {
|
|
169
|
-
// Check if animation should update based on its FPS
|
|
170
|
-
const animationInterval = 1000 / animation.fps;
|
|
171
|
-
const elapsedTime = now - animation.startTime;
|
|
172
|
-
const expectedFrame = Math.floor(elapsedTime / animationInterval);
|
|
173
|
-
if (expectedFrame > animation.currentFrame) {
|
|
174
|
-
animation.currentFrame = expectedFrame;
|
|
175
|
-
// Check if animation is complete
|
|
176
|
-
if (animation.duration &&
|
|
177
|
-
elapsedTime >= animation.duration &&
|
|
178
|
-
animation.frameCount !== Infinity) {
|
|
179
|
-
this.completeAnimation(animation);
|
|
180
|
-
continue;
|
|
181
|
-
}
|
|
182
|
-
// Update animation
|
|
183
|
-
this.updateAnimation(animation, elapsedTime);
|
|
184
|
-
// Call frame callback
|
|
185
|
-
if (animation.onFrame) {
|
|
186
|
-
animation.onFrame(animation);
|
|
187
|
-
}
|
|
188
|
-
this.emit('animation:frame', animation);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
this.lastFrameTime = now;
|
|
192
|
-
this.emit('scheduler:tick', { deltaTime, animationCount: this.animations.size });
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Update animation based on type
|
|
196
|
-
*/
|
|
197
|
-
updateAnimation(animation, elapsedTime) {
|
|
198
|
-
switch (animation.type) {
|
|
199
|
-
case 'spinner':
|
|
200
|
-
this.updateSpinner(animation);
|
|
201
|
-
break;
|
|
202
|
-
case 'progress':
|
|
203
|
-
this.updateProgressAnimation(animation, elapsedTime);
|
|
204
|
-
break;
|
|
205
|
-
case 'elapsed':
|
|
206
|
-
this.updateElapsed(animation);
|
|
207
|
-
break;
|
|
208
|
-
case 'transition':
|
|
209
|
-
this.updateTransition(animation, elapsedTime);
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Update spinner animation
|
|
215
|
-
*/
|
|
216
|
-
updateSpinner(animation) {
|
|
217
|
-
const frameIndex = animation.currentFrame % animation.data.frames.length;
|
|
218
|
-
this.emit('spinner:frame', {
|
|
219
|
-
id: animation.id,
|
|
220
|
-
frame: animation.data.frames[frameIndex],
|
|
221
|
-
message: animation.data.message,
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Update progress animation
|
|
226
|
-
*/
|
|
227
|
-
updateProgressAnimation(animation, elapsedTime) {
|
|
228
|
-
if (!animation.duration)
|
|
229
|
-
return;
|
|
230
|
-
const progress = Math.min(elapsedTime / animation.duration, 1);
|
|
231
|
-
const easedProgress = animation.easing ? animation.easing(progress) : progress;
|
|
232
|
-
const { current, target, total } = animation.data;
|
|
233
|
-
const newValue = current + (target - current) * easedProgress;
|
|
234
|
-
const percentage = Math.round((newValue / total) * 100);
|
|
235
|
-
this.emit('progress:update', {
|
|
236
|
-
id: animation.id,
|
|
237
|
-
value: newValue,
|
|
238
|
-
percentage,
|
|
239
|
-
total,
|
|
240
|
-
formatted: animation.data.format
|
|
241
|
-
? animation.data.format(newValue, total)
|
|
242
|
-
: `${percentage}%`,
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Update elapsed time animation
|
|
247
|
-
*/
|
|
248
|
-
updateElapsed(animation) {
|
|
249
|
-
const elapsed = Date.now() - animation.data.startTime;
|
|
250
|
-
const formatted = animation.data.format
|
|
251
|
-
? animation.data.format(elapsed)
|
|
252
|
-
: this.formatElapsedTime(elapsed);
|
|
253
|
-
this.emit('elapsed:update', {
|
|
254
|
-
id: animation.id,
|
|
255
|
-
elapsed,
|
|
256
|
-
formatted,
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Update transition animation
|
|
261
|
-
*/
|
|
262
|
-
updateTransition(animation, elapsedTime) {
|
|
263
|
-
if (!animation.duration)
|
|
264
|
-
return;
|
|
265
|
-
const progress = Math.min(elapsedTime / animation.duration, 1);
|
|
266
|
-
const easedProgress = animation.easing ? animation.easing(progress) : progress;
|
|
267
|
-
const { from, to } = animation.data;
|
|
268
|
-
let value;
|
|
269
|
-
if (typeof from === 'number' && typeof to === 'number') {
|
|
270
|
-
value = from + (to - from) * easedProgress;
|
|
271
|
-
}
|
|
272
|
-
else {
|
|
273
|
-
// For non-numeric values, switch at 50% progress
|
|
274
|
-
value = easedProgress < 0.5 ? from : to;
|
|
275
|
-
}
|
|
276
|
-
this.emit('transition:update', {
|
|
277
|
-
id: animation.id,
|
|
278
|
-
property: animation.data.property,
|
|
279
|
-
value,
|
|
280
|
-
progress: easedProgress,
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Complete an animation
|
|
285
|
-
*/
|
|
286
|
-
completeAnimation(animation) {
|
|
287
|
-
if (animation.onComplete) {
|
|
288
|
-
animation.onComplete(animation);
|
|
289
|
-
}
|
|
290
|
-
this.emit('animation:complete', animation);
|
|
291
|
-
this.unregister(animation.id);
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* Get current progress value with easing
|
|
295
|
-
*/
|
|
296
|
-
getCurrentProgressValue(animation) {
|
|
297
|
-
const elapsedTime = performance.now() - animation.startTime;
|
|
298
|
-
if (!animation.duration)
|
|
299
|
-
return animation.data.target;
|
|
300
|
-
const progress = Math.min(elapsedTime / animation.duration, 1);
|
|
301
|
-
const easedProgress = animation.easing ? animation.easing(progress) : progress;
|
|
302
|
-
const { current, target } = animation.data;
|
|
303
|
-
return current + (target - current) * easedProgress;
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* Format elapsed time
|
|
307
|
-
*/
|
|
308
|
-
formatElapsedTime(elapsedMs) {
|
|
309
|
-
const seconds = Math.floor(elapsedMs / 1000);
|
|
310
|
-
const minutes = Math.floor(seconds / 60);
|
|
311
|
-
const hours = Math.floor(minutes / 60);
|
|
312
|
-
if (hours > 0) {
|
|
313
|
-
return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
|
|
314
|
-
}
|
|
315
|
-
else if (minutes > 0) {
|
|
316
|
-
return `${minutes}m ${seconds % 60}s`;
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
return `${seconds}s`;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Get animation by ID
|
|
324
|
-
*/
|
|
325
|
-
getAnimation(id) {
|
|
326
|
-
return this.animations.get(id);
|
|
327
|
-
}
|
|
328
|
-
/**
|
|
329
|
-
* Get all active animations
|
|
330
|
-
*/
|
|
331
|
-
getActiveAnimations() {
|
|
332
|
-
return Array.from(this.animations.values());
|
|
333
|
-
}
|
|
334
|
-
/**
|
|
335
|
-
* Check if scheduler is running
|
|
336
|
-
*/
|
|
337
|
-
isActive() {
|
|
338
|
-
return this.isRunning;
|
|
339
|
-
}
|
|
340
|
-
/**
|
|
341
|
-
* Get target FPS
|
|
342
|
-
*/
|
|
343
|
-
getTargetFPS() {
|
|
344
|
-
return this.targetFPS;
|
|
345
|
-
}
|
|
346
|
-
/**
|
|
347
|
-
* Set target FPS
|
|
348
|
-
*/
|
|
349
|
-
setTargetFPS(fps) {
|
|
350
|
-
this.targetFPS = fps;
|
|
351
|
-
this.frameInterval = 1000 / fps;
|
|
352
|
-
// Restart the loop with new interval if running
|
|
353
|
-
if (this.isRunning) {
|
|
354
|
-
this.stop();
|
|
355
|
-
this.start();
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
/**
|
|
359
|
-
* Clear all animations
|
|
360
|
-
*/
|
|
361
|
-
clearAll() {
|
|
362
|
-
for (const animation of this.animations.values()) {
|
|
363
|
-
if (animation.onComplete) {
|
|
364
|
-
animation.onComplete(animation);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
this.animations.clear();
|
|
368
|
-
this.stop();
|
|
369
|
-
this.emit('scheduler:cleared');
|
|
370
|
-
}
|
|
371
|
-
/**
|
|
372
|
-
* Dispose of the scheduler
|
|
373
|
-
*/
|
|
374
|
-
dispose() {
|
|
375
|
-
this.clearAll();
|
|
376
|
-
this.removeAllListeners();
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
// Predefined easing functions
|
|
380
|
-
AnimationScheduler.Easing = {
|
|
381
|
-
linear: (t) => t,
|
|
382
|
-
easeInQuad: (t) => t * t,
|
|
383
|
-
easeOutQuad: (t) => t * (2 - t),
|
|
384
|
-
easeInOutQuad: (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),
|
|
385
|
-
easeInCubic: (t) => t * t * t,
|
|
386
|
-
easeOutCubic: (t) => --t * t * t + 1,
|
|
387
|
-
easeInOutCubic: (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
|
|
388
|
-
easeOutElastic: (t) => {
|
|
389
|
-
const p = 0.3;
|
|
390
|
-
return Math.pow(2, -10 * t) * Math.sin((t - p / 4) * (2 * Math.PI) / p) + 1;
|
|
391
|
-
},
|
|
392
|
-
};
|
|
393
|
-
// Predefined spinner frames
|
|
394
|
-
AnimationScheduler.SpinnerFrames = {
|
|
395
|
-
dots: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],
|
|
396
|
-
dots2: ['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'],
|
|
397
|
-
dots3: ['⠋', '⠙', '⠚', '⠞', '⠖', '⠦', '⠴', '⠲', '⠳', '⠓'],
|
|
398
|
-
line: ['-', '\\', '|', '/'],
|
|
399
|
-
pipe: ['┤', '┘', '┴', '└', '├', '┌', '┬', '┐'],
|
|
400
|
-
simpleDots: ['. ', '.. ', '...', ' '],
|
|
401
|
-
simpleDotsScrolling: ['. ', '.. ', '...', ' ..', ' .', ' '],
|
|
402
|
-
star: ['✶', '✸', '✹', '✺', '✹', '✷'],
|
|
403
|
-
hamburger: ['☱', '☲', '☴'],
|
|
404
|
-
growVertical: ['▁', '▃', '▄', '▅', '▆', '▇', '▆', '▅', '▄', '▃'],
|
|
405
|
-
growHorizontal: ['▏', '▎', '▍', '▌', '▋', '▊', '▉', '▊', '▋', '▌', '▍', '▎'],
|
|
406
|
-
balloon: [' ', '.', 'o', 'O', '@', '*', ' '],
|
|
407
|
-
noise: ['▓', '▒', '░'],
|
|
408
|
-
bounce: ['⠁', '⠂', '⠄', '⠂'],
|
|
409
|
-
boxBounce: ['▖', '▘', '▝', '▗'],
|
|
410
|
-
circle: ['◜', '◠', '◝', '◞', '◡', '◟'],
|
|
411
|
-
arc: ['◜', '◠', '◝', '◞', '◡', '◟'],
|
|
412
|
-
arrow: ['←', '↖', '↑', '↗', '→', '↘', '↓', '↙'],
|
|
413
|
-
bouncingBar: [
|
|
414
|
-
'[ ]',
|
|
415
|
-
'[= ]',
|
|
416
|
-
'[== ]',
|
|
417
|
-
'[=== ]',
|
|
418
|
-
'[ ===]',
|
|
419
|
-
'[ ==]',
|
|
420
|
-
'[ =]',
|
|
421
|
-
'[ ]',
|
|
422
|
-
'[ =]',
|
|
423
|
-
'[ ==]',
|
|
424
|
-
'[ ===]',
|
|
425
|
-
'[====]',
|
|
426
|
-
'[=== ]',
|
|
427
|
-
'[== ]',
|
|
428
|
-
'[= ]',
|
|
429
|
-
],
|
|
430
|
-
};
|